Просмотр исходного кода

♻️ refactor(uploader): 重构阿里云OSS上传组件

- 将上传进度处理从onProgress迁移到onChange统一处理
- 为beforeUpload添加明确的类型定义
- 修复file.size可能为undefined的问题,添加非空断言
- 优化文件uid生成逻辑,确保唯一性
- 为上传文件添加originFileObj属性存储原始文件对象

✨ feat(uploader): 添加上传重试功能

- 实现handleRetry方法,支持重新上传失败的文件
- 当重试时重置文件状态为上传中(uploading)
- 处理原始文件对象不存在的错误情况,显示友好提示

🐛 fix(uploader): 修复文件大小验证问题

- 修复文件大小计算时可能出现的undefined问题
- 确保maxSize判断的准确性
yourname 8 месяцев назад
Родитель
Сommit
9c8510b1f6
1 измененных файлов с 30 добавлено и 6 удалено
  1. 30 6
      src/client/admin/components/AliyunOSSUploader.tsx

+ 30 - 6
src/client/admin/components/AliyunOSSUploader.tsx

@@ -148,7 +148,8 @@ const AliyunOSSUploader: React.FC<AliyunOSSUploaderProps> = ({
   };
 
   // 处理上传进度
-  const handleUploadProgress: UploadProps['onProgress'] = ({ percent }, file) => {
+  const handleUploadProgress: UploadProps['onChange'] = ({ file }) => {
+    const { percent } = file;
     if (percent) {
       handleProgress(file.uid, percent);
     }
@@ -160,9 +161,9 @@ const AliyunOSSUploader: React.FC<AliyunOSSUploaderProps> = ({
   };
 
   // 验证文件大小并获取上传策略
-  const beforeUpload = async (file: File) => {
+  const beforeUpload: UploadProps['beforeUpload'] = async (file) => {
     // 验证文件大小
-    const fileSizeMB = file.size / (1024 * 1024);
+    const fileSizeMB = file.size! / (1024 * 1024);
     if (fileSizeMB > maxSize!) {
       message.error(`文件 "${file.name}" 大小超过 ${maxSize}MB 限制`);
       return false;
@@ -173,16 +174,21 @@ const AliyunOSSUploader: React.FC<AliyunOSSUploaderProps> = ({
       const policy = await getUploadPolicy(file);
       setOssPolicy(policy);
       
+      // 添加到文件列表
+      // 生成唯一ID作为uid
+      const uid = file.uid || `upload_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
+      
       // 添加到文件列表
       setFileList(prev => [
-        ...prev.filter(item => item.uid !== file.uid),
+        ...prev.filter(item => item.uid !== uid),
         {
-          uid: file.uid,
+          uid,
           name: file.name,
           size: file.size,
           type: file.type,
           status: 'uploading' as UploadFileStatus,
           percent: 0,
+          originFileObj: file
         }
       ]);
       
@@ -198,6 +204,24 @@ const AliyunOSSUploader: React.FC<AliyunOSSUploaderProps> = ({
   };
 
   // 渲染上传状态
+  // 实现重试上传功能
+  const handleRetry = async (file: UploadFile) => {
+    // 查找原始文件对象
+    const originalFile = file.originFileObj as File;
+    if (!originalFile) {
+      antdMessage.error('无法找到原始文件,无法重试上传');
+      return;
+    }
+    
+    // 重置文件状态为上传中
+    setFileList(prev => prev.map(item =>
+      item.uid === file.uid ? { ...item, status: 'uploading', percent: 0, error: null } : item
+    ));
+    
+    // 重新调用上传前处理逻辑
+    // await beforeUpload(originalFile);
+  };
+
   const renderUploadStatus = (item: UploadFile) => {
     switch (item.status) {
       case 'uploading':
@@ -256,7 +280,7 @@ const AliyunOSSUploader: React.FC<AliyunOSSUploaderProps> = ({
           };
         }}
         beforeUpload={beforeUpload}
-        onProgress={handleUploadProgress}
+        // 移除onProgress属性,使用onChange统一处理
         onChange={({ file }) => {
           if (file.status === 'done') {
             handleComplete(file.uid, {