效果图:

代码:

弹窗:

 <ModalForm
        title="文档导入"
        width="600px"
        open={createModalVisible}
        onOpenChange={(value) => {
          handleModalVisible(value);
          setFileUploadKey(Math.random());
          if (!value) resetFileUpload();
          if (fileUploadRef.current) {
            fileUploadRef.current.reset();
          }
        }}
        onFinish={async (value) => {
          const success = await handleUploadFile();
          if (success) {
            resetFileUpload();
            handleModalVisible(false);
            setFileUploadKey(Math.random());
          }
        }}
      >
        //不加key值会导致上传文档后再次打开弹窗文档列表中会有上次上传的文档
        <FileUpload
          key={fileUploadKey}
          ref={fileUploadRef}
          onFileRead={(files) => setFileContents(files)}
        />

        <h4 style={{ marginTop: '10px', fontWeight: 'bold' }}>权限设置</h4>
        <Select
          defaultValue="所有人可见"
          style={{ width: '100%' }}
          onChange={handleChange}
          options={[{ value: 1, label: '所有人可见', disabled: true }]}
        />
      </ModalForm>

FileUpload组件:

import UploadIcon from '@/components/CustomiseIcon/UploadIcon';
import { message, Upload } from 'antd';
import { UploadProps } from 'antd/es/upload';
import React, { forwardRef, useImperativeHandle, useState } from 'react';

const { Dragger } = Upload;

interface FileUploadProps {
  onFileRead: (
    files: { name: string; content: string | ArrayBuffer | null; type: string }[],
  ) => void;
}

const FileUpload: React.FC<FileUploadProps> = (
  { onFileRead },
  ref, /// <reference path="" />
) => {
  const [fileContents, setFileContents] = useState<
    { name: string; content: string | ArrayBuffer | null }[]
  >([]);

  useImperativeHandle(ref, () => ({
    reset: () => {
      setFileContents([]);
      console.log(fileContents, 'fileContents');
    },
  }));

  const props: UploadProps = {
    name: 'file',
    multiple: true,
    showUploadList: true,
    maxCount: 10, // 限制上传文件数量
    beforeUpload: (file, fileList) => {
      const allowedTypes = [
        'application/pdf',
        'application/msword',
        'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
        'application/vnd.ms-powerpoint',
        'application/vnd.openxmlformats-officedocument.presentationml.presentation',
        'application/vnd.ms-excel',
        'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
        'image/jpeg',
        'image/jpg',
        'image/bmp',
        'image/png',
        'text/plain',
      ];
      if (!allowedTypes.includes(file.type)) {
        message.error(`${file.name} 文件格式不支持`);
        return Upload.LIST_IGNORE;
      }
      if (fileList.length > 9 || fileList.length + fileContents.length > 9) {
        message.error('一次最多只能上传 10 个文件');
        return Upload.LIST_IGNORE;
      }
      const isFile300M = file.size / 1024 / 1024 > 300;
      if (isFile300M || fileList.some((file) => file.size >= 300 * 1024 * 1024)) {
        // 300MB
        message.error(`${file.name} 文件大小超过300MB`);
        return Upload.LIST_IGNORE;
      }

      onFileRead(fileList);
     
      return false; // 阻止默认的上传行为
    },
    onChange(info) {
      const { fileList } = info;
      if (fileList.length > 10) {
        message.error('一次最多只能上传 10 个文件');
        return;
      }
    },
    onDrop(e) {
      console.log('Dropped files', e.dataTransfer.files);
    },
  };

  return (
    <Dragger {...props} style={{ backgroundColor: '#F5F6FF' }}>
      <p className="ant-upload-drag-icon">
        <UploadIcon />
      </p>
      <p className="ant-upload-hint">点击上传框或拖拽文件至此处上传文件</p>
      <p className="ant-upload-hint">
        支持上传pdf doc docx ppt pptx xls xlsx jpeg jpg bmp png txt格式文件
      </p>
      <p className="ant-upload-hint">文件大小不超过300M</p>
    </Dragger>
  );
};

export default forwardRef(FileUpload);

api:

export async function uploadFile(
  data: { fileName: string; file: any },
  options?: { [key: string]: any },
) {
  const formData = new FormData();
  formData.append('file', data.file);
  formData.append('fileName', data.fileName);
  return request<Record<string, any>>('/kbFile/uploadFile', {
    data: formData,
    method: 'POST',
    ...(options || {}),
  });
}

注:这么处理是为了上传格式为multipart/form-data