uploadService.ts 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. import { apiClient } from './apiClient';
  2. import { IndexingConfig } from '../types';
  3. // web/services/uploadService.ts
  4. export const uploadService = {
  5. async uploadFile(file: File, authToken: string): Promise<any> {
  6. const formData = new FormData();
  7. formData.append('file', file);
  8. const response = await apiClient.request('/upload', {
  9. method: 'POST',
  10. body: formData,
  11. });
  12. if (!response.ok) {
  13. const errorData = await response.json();
  14. throw new Error(errorData.message || 'fileUploadFailed');
  15. }
  16. return response.json();
  17. },
  18. async uploadFileWithConfig(file: File, config: IndexingConfig, authToken: string): Promise<any> {
  19. const formData = new FormData();
  20. formData.append('file', file);
  21. formData.append('chunkSize', config.chunkSize.toString());
  22. formData.append('chunkOverlap', config.chunkOverlap.toString());
  23. formData.append('embeddingModelId', config.embeddingModelId);
  24. // 処理モードを追加(指定されている場合)
  25. if (config.mode) {
  26. formData.append('mode', config.mode);
  27. }
  28. // 分類を追加(指定されている場合)
  29. if (config.groupIds && config.groupIds.length > 0) {
  30. formData.append('groupIds', JSON.stringify(config.groupIds));
  31. }
  32. const response = await apiClient.request('/upload', {
  33. method: 'POST',
  34. body: formData,
  35. });
  36. if (!response.ok) {
  37. const errorData = await response.json();
  38. throw new Error(errorData.message || 'fileUploadFailed');
  39. }
  40. return response.json();
  41. },
  42. async uploadText(content: string, title: string, config: IndexingConfig, authToken: string): Promise<any> {
  43. const { data } = await apiClient.post('/upload/text', {
  44. content,
  45. title,
  46. chunkSize: config.chunkSize.toString(),
  47. chunkOverlap: config.chunkOverlap.toString(),
  48. embeddingModelId: config.embeddingModelId,
  49. mode: config.mode
  50. });
  51. return data;
  52. },
  53. /**
  54. * ファイル処理モードの推奨を取得
  55. * ファイルの種類、サイズなどの要因に基づいて、高速モードまたは高精度モードの使用を推奨します
  56. */
  57. async recommendMode(file: File): Promise<any> {
  58. // セーフティチェック
  59. if (!file || !file.name) {
  60. return {
  61. recommendedMode: 'fast',
  62. reason: 'invalidFile',
  63. warnings: ['incompleteFileInfo'],
  64. };
  65. }
  66. // フロントエンドの簡単な判定ロジック
  67. const ext = file.name.toLowerCase().split('.').pop();
  68. const sizeMB = file.size / (1024 * 1024);
  69. const preciseFormats = ['pdf', 'doc', 'docx', 'ppt', 'pptx'];
  70. const supportedFormats = [...preciseFormats, 'xls', 'xlsx', 'txt', 'md', 'html', 'json', 'csv'];
  71. if (!supportedFormats.includes(ext || '')) {
  72. return {
  73. recommendedMode: 'fast',
  74. reason: `unsupportedFileFormat`,
  75. reasonArgs: [ext],
  76. warnings: ['willUseFastMode'],
  77. };
  78. }
  79. if (!preciseFormats.includes(ext || '')) {
  80. return {
  81. recommendedMode: 'fast',
  82. reason: `formatNoPrecise`,
  83. reasonArgs: [ext],
  84. warnings: ['willUseFastMode'],
  85. };
  86. }
  87. // 小規模なファイルには高速モードを推奨
  88. if (sizeMB < 5) {
  89. return {
  90. recommendedMode: 'fast',
  91. reason: 'smallFileFastOk',
  92. estimatedCost: 0,
  93. estimatedTime: sizeMB * 2,
  94. warnings: [],
  95. };
  96. }
  97. // 中規模なファイルには高精度モードを推奨
  98. if (sizeMB < 50) {
  99. return {
  100. recommendedMode: 'precise',
  101. reason: 'mixedContentPreciseRecommended',
  102. estimatedCost: Math.max(0.01, sizeMB * 0.01),
  103. estimatedTime: sizeMB * 8,
  104. warnings: ['willIncurApiCost'],
  105. };
  106. }
  107. // 大規模なファイルには高精度モードを推奨するが警告を表示
  108. return {
  109. recommendedMode: 'precise',
  110. reason: 'largeFilePreciseRecommended',
  111. estimatedCost: sizeMB * 0.015,
  112. estimatedTime: sizeMB * 12,
  113. warnings: ['longProcessingTime', 'highApiCost', 'considerFileSplitting'],
  114. };
  115. },
  116. };