Parcourir la source

♻️ refactor(utils): 重构MinIO文件上传实现

- 移除FormData实现,改用Taro.uploadFile API进行文件上传
- 优化类型定义,将formData改为Record<string, string>类型
- 添加上传进度监听,支持进度更新回调
- 实现上传取消功能,支持通过signal中断上传任务
- 移除文件系统读取逻辑,简化上传流程
- 优化错误处理,提供更明确的错误信息

✨ feat(utils): 增强文件上传功能

- 添加上传进度反馈,包括阶段、进度百分比和时间戳
- 支持上传完成回调,提供完整的上传结果信息
- 实现上传任务的取消机制,支持外部信号中断上传
yourname il y a 4 mois
Parent
commit
bd0d1db079
1 fichiers modifiés avec 70 ajouts et 44 suppressions
  1. 70 44
      mini/src/utils/minio.ts

+ 70 - 44
mini/src/utils/minio.ts

@@ -536,8 +536,8 @@ export class TaroMinIOUploader {
     });
     
     return new Promise((resolve, reject) => {
-      // 准备表单数据
-      const formData: Record<string, any> = {};
+      // 准备表单数据 - 使用对象形式,Taro.uploadFile会自动处理
+      const formData: Record<string, string> = {};
       
       // 添加 MinIO 需要的字段
       Object.entries(policy.uploadPolicy).forEach(([k, value]) => {
@@ -548,52 +548,78 @@ export class TaroMinIOUploader {
       
       formData['key'] = key;
       
-      try {
-        const fileSystemManager = Taro?.getFileSystemManager?.();
-        if (!fileSystemManager) {
-          throw new Error('小程序环境不可用');
+      // 使用 Taro.uploadFile 替代 FormData
+      const uploadTask = Taro.uploadFile({
+        url: policy.uploadPolicy.host,
+        filePath: filePath,
+        name: 'file',
+        formData: formData,
+        header: {
+          'Content-Type': 'multipart/form-data'
+        },
+        success: (res) => {
+          if (res.statusCode >= 200 && res.statusCode < 300) {
+            callbacks?.onProgress?.({
+              stage: 'complete',
+              message: '文件上传完成',
+              progress: 100,
+              timestamp: Date.now()
+            });
+            callbacks?.onComplete?.();
+            resolve({
+              fileUrl: `${policy.uploadPolicy.host}/${key}`,
+              fileKey: key,
+              bucketName: policy.uploadPolicy.bucket,
+              fileId: policy.file.id
+            });
+          } else {
+            reject(new Error(`上传失败: ${res.statusCode}`));
+          }
+        },
+        fail: (error) => {
+          reject(new Error(`上传失败: ${error.errMsg}`));
         }
+      });
 
-        const fileData = fileSystemManager.readFileSync(filePath, 'binary');
-        
-        const formDataObj = new FormData();
-        Object.entries(formData).forEach(([k, value]) => {
-          formDataObj.append(k, value);
-        });
-        formDataObj.append('file', new Blob([fileData]));
+      // 监听上传进度
+      uploadTask.progress((res) => {
+        if (res.totalBytesExpectedToSend > 0) {
+          const currentProgress = Math.round((res.totalBytesSent / res.totalBytesExpectedToSend) * 100);
+          callbacks?.onProgress?.({
+            stage: 'uploading',
+            message: `上传中 ${currentProgress}%`,
+            progress: currentProgress,
+            details: {
+              loaded: res.totalBytesSent,
+              total: res.totalBytesExpectedToSend
+            },
+            timestamp: Date.now()
+          });
+        }
+      });
 
-        Taro?.request?.({
-          url: policy.uploadPolicy.host,
-          method: 'POST',
-          data: formDataObj,
-          header: {
-            'Content-Type': 'multipart/form-data'
-          },
-          success: (res) => {
-            if (res.statusCode >= 200 && res.statusCode < 300) {
-              callbacks?.onProgress?.({
-                stage: 'complete',
-                message: '文件上传完成',
-                progress: 100,
-                timestamp: Date.now()
-              });
-              callbacks?.onComplete?.();
-              resolve({
-                fileUrl: `${policy.uploadPolicy.host}/${key}`,
-                fileKey: key,
-                bucketName: policy.uploadPolicy.bucket,
-                fileId: policy.file.id
-              });
-            } else {
-              reject(new Error(`上传失败: ${res.statusCode}`));
-            }
-          },
-          fail: (error: any) => {
-            reject(new Error(`上传失败: ${error.errMsg}`));
+      // 支持取消上传
+      if (callbacks?.signal && 'aborted' in callbacks.signal) {
+        if (callbacks.signal.aborted) {
+          uploadTask.abort();
+          reject(new Error('上传已取消'));
+        }
+        
+        // 监听取消信号
+        const checkAbort = () => {
+          if (callbacks.signal?.aborted) {
+            uploadTask.abort();
+            reject(new Error('上传已取消'));
           }
-        });
-      } catch (error: any) {
-        reject(new Error(`读取文件失败: ${error.message || error.errMsg}`));
+        };
+        
+        // 定期检查取消状态
+        const abortInterval = setInterval(checkAbort, 100);
+        
+        // 清理定时器
+        const cleanup = () => clearInterval(abortInterval);
+        uploadTask.onProgressUpdate = cleanup;
+        uploadTask.onHeadersReceived = cleanup;
       }
     });
   }