优化Upload
parent
d6ada39fd0
commit
ea129b523c
|
|
@ -1,6 +1,6 @@
|
||||||
import { PlusOutlined, UploadOutlined, VideoCameraAddOutlined } from "@ant-design/icons";
|
import { PlusOutlined, UploadOutlined, VideoCameraAddOutlined } from "@ant-design/icons";
|
||||||
import { Upload as AntUpload, Button, message, Modal } from "antd";
|
import { Upload as AntUpload, Button, message, Modal } from "antd";
|
||||||
import { useState } from "react";
|
import { useRef, useState } from "react";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 文件上传组件
|
* 文件上传组件
|
||||||
|
|
@ -29,6 +29,9 @@ const Upload = (props) => {
|
||||||
const [previewVisible, setPreviewVisible] = useState(false);
|
const [previewVisible, setPreviewVisible] = useState(false);
|
||||||
const [previewImage, setPreviewImage] = useState("");
|
const [previewImage, setPreviewImage] = useState("");
|
||||||
|
|
||||||
|
// 记录已经提示过错误的文件uid,避免重复提示
|
||||||
|
const warnedFileUids = useRef(new Set());
|
||||||
|
|
||||||
// 预设的文件格式
|
// 预设的文件格式
|
||||||
const imageAccept = ".jpg,.jpeg,.png";
|
const imageAccept = ".jpg,.jpeg,.png";
|
||||||
const documentAccept = ".pdf,.doc,.docx";
|
const documentAccept = ".pdf,.doc,.docx";
|
||||||
|
|
@ -137,66 +140,99 @@ const Upload = (props) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
// 文件状态改变
|
// 文件状态改变
|
||||||
const handleChange = ({ file, fileList }) => {
|
const handleChange = ({ fileList }) => {
|
||||||
|
console.log(fileList);
|
||||||
const acceptList = accept ? accept.split(",") : [];
|
const acceptList = accept ? accept.split(",") : [];
|
||||||
const ratioArr = ratio ? ratio.split("*") : [];
|
const ratioArr = ratio ? ratio.split("*") : [];
|
||||||
const suffix = file.name.substring(
|
|
||||||
file.name.lastIndexOf("."),
|
|
||||||
file.name.length,
|
|
||||||
);
|
|
||||||
const maxSize = size * 1024 * 1024;
|
const maxSize = size * 1024 * 1024;
|
||||||
|
|
||||||
// 验证文件格式
|
// 对整个fileList进行验证和过滤
|
||||||
if (acceptList.length > 0 && !acceptList.includes(suffix)) {
|
const validateFiles = async (files) => {
|
||||||
message.warning(`只能上传${acceptTip}格式的文件`);
|
const validFiles = [];
|
||||||
const filtered = fileList.filter(item => item.uid !== file.uid);
|
const invalidFiles = [];
|
||||||
onChange?.(filtered);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 验证文件大小
|
for (const fileItem of files) {
|
||||||
if (maxSize && file.size > maxSize) {
|
const suffix = fileItem.name?.substring(
|
||||||
message.warning(`文件大小不能超过${size}M`);
|
fileItem.name.lastIndexOf("."),
|
||||||
const filtered = fileList.filter(item => item.uid !== file.uid);
|
fileItem.name.length,
|
||||||
onChange?.(filtered);
|
) || "";
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 验证图片分辨率
|
// 验证文件格式
|
||||||
if (ratioArr.length === 2 && file.type?.startsWith("image/")) {
|
if (acceptList.length > 0 && !acceptList.includes(suffix)) {
|
||||||
const validateImageResolution = (imageUrl) => {
|
invalidFiles.push(fileItem);
|
||||||
const img = new Image();
|
// 只提示未提示过的文件
|
||||||
img.onload = () => {
|
if (!warnedFileUids.current.has(fileItem.uid)) {
|
||||||
if (img.width !== +ratioArr[0] || img.height !== +ratioArr[1]) {
|
warnedFileUids.current.add(fileItem.uid);
|
||||||
message.warning(`只能上传${ratio}分辨率的图片`);
|
message.warning(`${fileItem.name}:只能上传${acceptTip}格式的文件`);
|
||||||
const filtered = fileList.filter(item => item.uid !== file.uid);
|
|
||||||
onChange?.(filtered);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
onChange?.(fileList);
|
continue;
|
||||||
};
|
}
|
||||||
img.src = imageUrl;
|
|
||||||
};
|
|
||||||
|
|
||||||
// 如果有现成的URL则直接使用,否则使用FileReader读取本地文件
|
// 验证文件大小
|
||||||
if (file.url) {
|
if (maxSize && fileItem.size > maxSize) {
|
||||||
validateImageResolution(file.url);
|
invalidFiles.push(fileItem);
|
||||||
|
// 只提示未提示过的文件
|
||||||
|
if (!warnedFileUids.current.has(fileItem.uid)) {
|
||||||
|
warnedFileUids.current.add(fileItem.uid);
|
||||||
|
message.warning(`${fileItem.name}:文件大小不能超过${size}M`);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 验证图片分辨率(异步)
|
||||||
|
if (ratioArr.length === 2 && fileItem.type?.startsWith("image/")) {
|
||||||
|
const validateImageResolution = (imageUrl) => {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
const img = new Image();
|
||||||
|
img.onload = () => {
|
||||||
|
const isValid = img.width === +ratioArr[0] && img.height === +ratioArr[1];
|
||||||
|
if (!isValid) {
|
||||||
|
// 只提示未提示过的文件
|
||||||
|
if (!warnedFileUids.current.has(fileItem.uid)) {
|
||||||
|
warnedFileUids.current.add(fileItem.uid);
|
||||||
|
message.warning(`${fileItem.name}:只能上传${ratio}分辨率的图片`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
resolve(isValid);
|
||||||
|
};
|
||||||
|
img.onerror = () => resolve(false);
|
||||||
|
img.src = imageUrl;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const validResolution = fileItem.url
|
||||||
|
? await validateImageResolution(fileItem.url)
|
||||||
|
: await new Promise((resolve) => {
|
||||||
|
const reader = new FileReader();
|
||||||
|
reader.onload = (e) => {
|
||||||
|
validateImageResolution(e.target.result).then(resolve);
|
||||||
|
};
|
||||||
|
reader.onerror = () => resolve(false);
|
||||||
|
reader.readAsDataURL(fileItem.originFileObj);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!validResolution) {
|
||||||
|
invalidFiles.push(fileItem);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
validFiles.push(fileItem);
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
const reader = new FileReader();
|
return { validFiles, invalidFiles };
|
||||||
reader.onload = (e) => {
|
};
|
||||||
validateImageResolution(e.target.result);
|
|
||||||
};
|
// 执行验证并更新
|
||||||
reader.readAsDataURL(file);
|
validateFiles(fileList).then(({ validFiles }) => {
|
||||||
}
|
onChange?.(validFiles);
|
||||||
}
|
});
|
||||||
else {
|
|
||||||
onChange?.(fileList);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// 删除文件
|
// 删除文件
|
||||||
const handleRemove = (file) => {
|
const handleRemove = (file) => {
|
||||||
|
// 清理该文件的提示记录
|
||||||
|
warnedFileUids.current.delete(file.uid);
|
||||||
if (!file.originFileObj)
|
if (!file.originFileObj)
|
||||||
onGetRemoveFile?.(file);
|
onGetRemoveFile?.(file);
|
||||||
return onRemove?.(file);
|
return onRemove?.(file);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue