antd Upload 分片同步上传文件

1、背景

antd 版本 ^4.20.0

2、分片实现

const [fileList, setFileList] = useState([]);
// 上传前文件格式校验 ---压缩包
const beforeUpload = (file) => {
    let reg = /([^\\/]+)\.([^\\/]+)/i;
    reg.test(file.name);
    const isZip = RegExp.$2 === "zip" || RegExp.$2 === "rar" || RegExp.$2 === "7z"
    if (!isZip) {
      message.warn('请上传正确的文件类型,支持zip,rar,7z格式的压缩包!');
    }
    return isZip;
}
// 分片同步上传
const handleCustomRequest = async({ file, onSuccess, onError, onProgress }) => {
    const sliceSize = 10 * 1024 * 1024; // 切片大小,这里假设每个切片1MB
    const totalSlices = Math.ceil(file.size / sliceSize);  // 获取切片数量
    let chunk = 0;
    let postPromises = []; // 存储每个 POST 请求的 Promise
    let totalUploaded = 0; // 总已上传数据量
    const nameList = file.name.split('.');
    while (chunk < totalSlices) {
      const start = chunk * sliceSize;
      const end = Math.min(start + sliceSize, file.size);
      const slice = file.slice(start, end);  // 上传的分片,通过开始结束截取
      const timestamp = Date.now();
      const formData = new FormData();
      // 上传接口入参
      formData.append('file', slice);
      formData.append('chunk', chunk + 1);
      formData.append('fileName', nameList[0]);
      formData.append('currentFolderPath', file.uid);
      const postPromise = axios.post(url, formData, {
        // 进度条处理
        onUploadProgress: (progressEvent) => {
          if(progressEvent.loaded == progressEvent.total){
            totalUploaded += progressEvent.loaded;
            const overallProgress = Math.round((totalUploaded * 100) / file.size);
            onProgress({ percent: overallProgress });
          } else {
            const loadedSize = totalUploaded + progressEvent.loaded;
            const overallProgress = Math.round((loadedSize * 100) / file.size);
            onProgress({ percent: overallProgress });
          }
        },
      })
      postPromises.push(postPromise);
      chunk ++;
    }
    try {
      const arrList = await Promise.all(postPromises);
      const successList = arrList.filter((v) => (v.data && v.data.code == 0))
      // 所有分片上传成功 才算成功
      if(successList.length == arrList.length){
        onSuccess({ code: 0, data: successList })
      } else {
        onError()
      }
    } catch (error) {
      onError()
    }
}

const onUpdateChange = (info) => {
    const { file } = info;
    const { status, response } = info.file;
    if (utils.helper.isEmptyObj(info.fileList)){
      return ;
    }
    if (fileList && fileList.length > 0 && file.uid != fileList[0].uid) {
      // 若上传分片未结束,改变了上传的文件,需要将上次上传的部分分片删除处理
      // batchImportApi.delPartFile({ currentFolderPath: fileList[0].uid })
    }
    if (status) {
      const newFileList = [...info.fileList];
      setFileList(newFileList);
    }
    if (status === 'done') {
      if (response && response.code === 0) {
        message.success(`${info.file.name} 上传成功!`)
      }
    } else if (status === 'error') {
      message.error(`${info.file.name} 上传失败.`);
      setFileList([]);
    }
}

const onRemoveList = () => {
    // 删除 已成功上传的文件
    // batchImportApi.delPartFile({ currentFolderPath: fileList[0].uid }).then((res) => {
    //   if(res.code == 0){
    //     setFileList([]);
    //   }
    // })
}

const fileProps = {
    name: 'file',
    beforeUpload: beforeUpload,
    onChange: onUpdateChange,
    multiple: false,
    headers: { mappingPath: window.location.pathname.replace(/\//g, '') },
    customRequest: handleCustomRequest,
    onRemove: onRemoveList,
}
<Dragger {...fileProps} maxCount={1} fileList={fileList}>
    <div className={styles.uploadFile}>
        <CloudUploadOutlined style={{ fontSize: 24 }}/>
        <div style={{ marginTop: 8 }}>请上传包含内容文件的压缩文件</div>
    </div>
</Dragger>

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值