附件上传组件在工作中经常遇到,自己封装设计了一个,大致功能如下:

1、支持多文件上传

2、支持文件数量、大小、格式限制

3、具备自定义上传功能,灵活性高

注意事项:

1、文件格式限制的时候,注意文件名中带.的情况,处理文件名取后缀的时候需要注意

2、自定义上传函数的编写要做异常捕捉,防止系统异常报一些奇怪的错误

3、有时候还涉及到文件服务器上文件删除的操作,可在onRemove函数内操作

index.tsx:

import { FC, useState, useRef } from "react";
import { UploadOutlined } from "@ant-design/icons";
import { Button, Upload, message } from "antd";
import { RcFile } from "antd/lib/upload";

interface FileUploadBean {
  arcCate?: string;
  accept: String[];
  onGetArcNumChange?: (arcNum: string) => void;
}

const FilesUpload: FC<FileUploadBean> = ({
  arcCate = "doc",
  accept,
  onGetArcNumChange,
  onChange,
  value,
}) => {
  const verify = {
    length: 10,
    accept: accept
      ? accept
      : [
          "pdf",
          "png",
          "jpe",
          "jpg",
          "jpeg",
          "doc",
          "docx",
          "xls",
          "xlsx",
          "ppt",
          "pot",
          "pptx",
          "csv",
          "rar",
          "zip",
          "7z",
        ],
    size: 20,
  };
  const [fileList, setFileList] = useState<any>([]);
  const [fileDetailList, setFileDetailList] = useState<any>([]);
  const arcNumRef = useRef<string>("");
  const fileRef = useRef<any>();

  const changeValue = (arr: object[]) => {
    setFileDetailList(arr);
    onChange(arr);
  };

  const handelChange = (info: any) => {
    if (info.file.status) {
      setFileList([...info.fileList]);
      // 删除文件
      if (info.file.status === "removed") {
        const list = Array.from(fileDetailList, (item: any) =>
          item?.minioId !== info.file?.response?.[0]?.ID ? item : null
        ).filter((fileList) => fileList);
        changeValue([...list]);
      }
    }
  };

  // 上传文件前做一些数量、、大小、文件格式类的校验
  const beforeUpload = (file: RcFile, list: RcFile[]) => {
    const { length, size, accept = [] } = verify || {};
    fileRef.current = file;
    // 文件个数
    const fileListLength = fileList ? fileList.length : 0;
    const listLength = list.length;
    if (length && fileListLength + listLength > length) {
      message.error(`附件列表中文件数量不得超过${length}个,请确定附件清单。`);
      return false;
    }
    // 大小限制
    if (size && file.size / 1024 / 1024 > size) {
      message.error(`附件列表中文件大小不得超过${size}MB,请重新选择。`);
      return false;
    }
    // 文件格式校验
    if (accept && accept.length > 0) {
      // 此处注意文件名中带.的情况
      const suffix = file.name.substring(file.name.lastIndexOf(".") + 1);
      if (!suffix || !accept.includes(suffix.toLowerCase())) {
        message.error(`文件格式异常,只允许上传PDF格式文件,请重新选择。`);
        return false;
      }
    }
    return true;
  };

  // 自定义上传
  const UploadFilesAction = async (options: any) => {};

  // 文件删除
  const onRemove = (even: any) => {};

  return (
    <Upload
      fileList={fileList}
      onChange={handelChange}
      beforeUpload={beforeUpload}
      customRequest={UploadFilesAction}
      onRemove={onRemove}
    >
      <Button icon={<UploadOutlined />}>上传附件</Button>
      &nbsp;&nbsp;&nbsp;单个文件20M以内,文件数量10个以内
    </Upload>
  );
};

export default FilesUpload;

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注