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>
react文件上传组件----UploadFile
于 2023-05-10 15:31:14 首次发布