1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
| import React, { useCallback, useEffect, useRef, useState } from 'react'; import { Upload, message, Button } from 'antd'; import axios from 'axios';
const FileUpload = ({ maxFileSize = 20, maxFileCount = 10, onChange, }) => {
// 文件大小限制 const maxFileSizeRef = useRef(); useEffect(() => { // M转byte maxFileSizeRef.current = maxFileSize * 1024 * 1024; }, [maxFileSize]);
// 文件数量记录 const [fileListCount, setFileListCount] = useState(0); const [isDisabled, setIsDisabled] = useState(false); useEffect(() => { if (fileListCount >= maxFileCount) { setIsDisabled(true); } else { setIsDisabled(false); } }, [fileListCount, maxFileCount]);
// "文件uid-下载url"映射记录 const [downloadUrls, setDownloadUrls] = useState({});
// onChange格式转换 const customOnChange = useCallback( ({ fileList }) => { const outputValue = []; fileList.forEach((one) => { if (one.status === 'done') { outputValue.push({ fileName: one.name, fileUrl: downloadUrls[one.uid], }); } }); // console.log('onChange: ', outputValue); onChange && onChange(outputValue); }, [onChange, downloadUrls] );
return ( <Upload onChange={customOnChange} showUploadList={{ showDownloadIcon: true, }} beforeUpload={(file, fileList) => { const newCount = fileListCount + fileList.length; if (file.size > maxFileSizeRef.current) { message.warn(`文件'${file.name}'超过文件大小限制: ${maxFileSize}M`); return Upload.LIST_IGNORE; } else if (newCount > maxFileCount) { message.warn(`超过最大上传数量: ${maxFileCount}`); return Upload.LIST_IGNORE; } else if (newCount === maxFileCount) { setIsDisabled(true); } }} customRequest={(allData) => { setFileListCount(fileListCount + 1); const { onProgress, onSuccess, onError } = allData; const reqFormData = new FormData(); // 通过组件的data属性传入的额外请求参数,根据接口要求定制 Object.keys(allData.data).forEach((oneKey) => { reqFormData.append(oneKey, allData.data[oneKey]); }); reqFormData.append('file', allData.file); axios({ method: 'post', url: '/common/file/upload', data: reqFormData, onUploadProgress: (progress) => { // 上传进度条 const progNum = progress.loaded / progress.total; onProgress({ percent: progNum }); }, }) .then((resData) => { setDownloadUrls((prevState) => { return { ...prevState, [allData.file.uid]: resData.url, }; }); onSuccess({ url: resData.url }); }) .catch((error) => { onError(error); }); }} multiple={true} data={(file) => { return { typeId: 2, fileName: file.name, }; }} onRemove={() => { setFileListCount(fileListCount - 1); }} openFileDialogOnClick={!isDisabled} onDownload={(file) => { window.open(downloadUrls[file.uid]); }} > {isDisabled ? ( <span style={{ color: '#ff7700' }}> 已达到最大上传数量: {maxFileCount}个 </span> ) : ( <Button>上传</Button>; )} </Upload> ); };
... ...
|