react文件上传组件----UploadFile

import { Upload, message } from 'antd';
import { useEffect, useState, useRef } from 'react';

import { uploadFileApi, getFileUrlApi } from '@/services/class';


export default (props) => {
  const {
    accept = 'image/*', // 格式
    limitSize = 10, // 限制大小
    fileType = [],
    disabled = false,
    value = null,
    onChange,
    children,
    ...rest
  } = props;

  const [fileList, setFileList] = useState([]);
  const timer = useRef();
  const uploadApi = uploadFileApi;

  const newAccept = fileType && fileType.length > 0 ? fileType.join(',') : accept;

  useEffect(() => {
    const single = !Array.isArray(value);
    if (value) {
      setFileList(single ? [{ url: value, name: '' }] : value);
    }
  }, [value]);

  /**
   * 移除
   * @param {*} file
   */
  const onRemove = (file) => {
    const files = value?.filter((v) => v.url !== file.url);
    if (onChange) {
      onChange(files);
    }
  };

  /**
   * 上传前校验
   * @param {*} file
   * @returns
   */
  const beforeUpload = async (file) => {
    return new Promise((resolve, reject) => {
      const isLt10M = file.size / 1024 / 1024 <= Number(limitSize);
      if (!isLt10M) {
        const msg = `文件大小不能超过${limitSize}M`;
        message.error(msg);
        reject(new Error(msg));
      } else {
        resolve(true);
      }
    });
  };

  /**
   * 自定义上传
   * @param {*} e
   */
  const customRequest = (e) => {
    const { onSuccess, onError, onProgress, file } = e;
    const formData = new FormData();
    formData.append('file', file);
    // formData.append('fileId', e.file.uid);
    // TODO: 暂时使用模拟上传进度 umi-request fetch暂不支持进度
    const progress = {
      percent: 0,
      status: 'uploading',
    };
    progress.status = 'error';
    progress.percent = 0;

    uploadApi(formData)
      .then((res) => {
        const { data } = res;
        const { name, objectKey, objectUrl } = data;
        const list = [
          // ...fileList
          {
            fileName: name,
            key: objectKey,
            name: '预览',
            url: objectUrl,
          },
        ];
        progress.percent = 100;
        progress.status = 'success';
        onProgress(progress);
        onChange(list);
        onSuccess(res, file);
      })
      .catch(() => {
        onProgress({
          status: 'error',
        });
        onError(new Error('上传失败'));
      });

    timer.current = setInterval(() => {
      if (progress.status === 'error') {
        onProgress(progress);
        clearInterval(timer.current);
      }
      if (progress.percent < 99 || progress.percent + 100 / (file.size / 65000 < 100)) {
        progress.percent += 400 / (file.size / 65000);
        onProgress(progress);
      } else if (progress.percent === 99) {
        progress.percent++;
      } else if (progress.percent >= 100) {
        clearInterval(timer.current);
      }
    }, 100);
  };

  // 预览
  const onPreview = (file) => {
    const { key } = file;
    if (key) {
      getFileUrlApi({ objectKey: key }).then((res) => {
        const url = `${res.data}`;
        if (res?.data) {
          window.open(
            `/ossFile${url.split(window.gridConfig.GRID_SOURCE_SPLIT_STR)[1]}`,
            '_blank',
            'noopener,noreferrer',
          );
        }
      });
    }
  };
  const uploadProps = {
    multiple: true,
    customRequest,
    onRemove,
    beforeUpload,
    disabled,
    accept: newAccept,

    onChange({ fileList: newFileList }) {
      setFileList(newFileList);
    },
    ...rest,
  };

  return (
    <Upload {...uploadProps} fileList={fileList} onPreview={onPreview}>
      {children}
    </Upload>
  );
};


    <UploadFile accept="image/png,image/jpeg,video/*" limitSize={3} maxCount={1}>
    <Button key="primary" icon={<UploadOutlined />} style={{ marginBottom: '8px' }}>
     上传图片
     </Button>
    </UploadFile>

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值