效果图:
代码:
弹窗:
<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
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通