优化Upload

master
LiuJiaNan 2026-02-25 09:49:52 +08:00
parent 04f20eabfd
commit ef1d0cd01d
1 changed files with 97 additions and 56 deletions

View File

@ -145,75 +145,111 @@ const Upload = (props) => {
const ratioArr = ratio ? ratio.split("*") : []; const ratioArr = ratio ? ratio.split("*") : [];
const maxSize = size * 1024 * 1024; const maxSize = size * 1024 * 1024;
// 对整个fileList进行验证和过滤 // 获取新增的文件(只验证新文件,不重复验证已存在的文件)
const validateFiles = async (files) => { const existingUids = new Set(value.map(f => f.uid));
const newFiles = fileList.filter(file => !existingUids.has(file.uid));
// 如果没有新文件,直接更新
if (newFiles.length === 0) {
onChange?.(fileList);
return;
}
// 验证文件格式
const validateFileFormat = (fileItem) => {
const suffix = fileItem.name?.substring(
fileItem.name.lastIndexOf("."),
fileItem.name.length,
) || "";
if (acceptList.length > 0 && !acceptList.includes(suffix)) {
// 只提示未提示过的文件
if (!warnedFileUids.current.has(fileItem.uid)) {
warnedFileUids.current.add(fileItem.uid);
message.warning(`${fileItem.name}:只能上传${acceptTip}格式的文件`);
}
return false;
}
return true;
};
// 验证文件大小
const validateFileSize = (fileItem) => {
if (maxSize && fileItem.size > maxSize) {
// 只提示未提示过的文件
if (!warnedFileUids.current.has(fileItem.uid)) {
warnedFileUids.current.add(fileItem.uid);
message.warning(`${fileItem.name}:文件大小不能超过${size}M`);
}
return false;
}
return true;
};
// 验证图片分辨率
const validateImageResolution = (fileItem) => {
return new Promise((resolve) => {
if (ratioArr.length !== 2 || !fileItem.type?.startsWith("image/")) {
resolve(true);
return;
}
const checkResolution = (imageUrl) => {
return new Promise((resolveInner) => {
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}分辨率的图片`);
}
}
resolveInner(isValid);
};
img.onerror = () => resolveInner(false);
img.src = imageUrl;
});
};
if (fileItem.url) {
checkResolution(fileItem.url).then(resolve);
}
else {
const reader = new FileReader();
reader.onload = (e) => {
checkResolution(e.target.result).then(resolve);
};
reader.onerror = () => resolve(false);
reader.readAsDataURL(fileItem.originFileObj);
}
});
};
// 只验证新增的文件
const validateNewFiles = async (files) => {
const validFiles = []; const validFiles = [];
const invalidFiles = []; const invalidFiles = [];
for (const fileItem of files) { for (const fileItem of files) {
const suffix = fileItem.name?.substring(
fileItem.name.lastIndexOf("."),
fileItem.name.length,
) || "";
// 验证文件格式 // 验证文件格式
if (acceptList.length > 0 && !acceptList.includes(suffix)) { if (!validateFileFormat(fileItem)) {
invalidFiles.push(fileItem); invalidFiles.push(fileItem);
// 只提示未提示过的文件
if (!warnedFileUids.current.has(fileItem.uid)) {
warnedFileUids.current.add(fileItem.uid);
message.warning(`${fileItem.name}:只能上传${acceptTip}格式的文件`);
}
continue; continue;
} }
// 验证文件大小 // 验证文件大小
if (maxSize && fileItem.size > maxSize) { if (!validateFileSize(fileItem)) {
invalidFiles.push(fileItem); invalidFiles.push(fileItem);
// 只提示未提示过的文件
if (!warnedFileUids.current.has(fileItem.uid)) {
warnedFileUids.current.add(fileItem.uid);
message.warning(`${fileItem.name}:文件大小不能超过${size}M`);
}
continue; continue;
} }
// 验证图片分辨率(异步) // 验证图片分辨率(异步)
if (ratioArr.length === 2 && fileItem.type?.startsWith("image/")) { const isValidResolution = await validateImageResolution(fileItem);
const validateImageResolution = (imageUrl) => { if (!isValidResolution) {
return new Promise((resolve) => { invalidFiles.push(fileItem);
const img = new Image(); continue;
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); validFiles.push(fileItem);
@ -223,8 +259,13 @@ const Upload = (props) => {
}; };
// 执行验证并更新 // 执行验证并更新
validateFiles(fileList).then(({ validFiles }) => { validateNewFiles(newFiles).then(({ validFiles: validNewFiles }) => {
onChange?.(validFiles); // 合并已存在的文件和通过验证的新文件
const finalFileList = [
...value, // 已存在的文件
...validNewFiles, // 通过验证的新文件
];
onChange?.(finalFileList);
}); });
}; };