From ef1d0cd01d9e6bb5e3c99ce08adc998278f75832 Mon Sep 17 00:00:00 2001 From: LiuJiaNan <15703339975@163.com> Date: Wed, 25 Feb 2026 09:49:52 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96Upload?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Upload/index.js | 153 +++++++++++++++++++++------------ 1 file changed, 97 insertions(+), 56 deletions(-) diff --git a/src/components/Upload/index.js b/src/components/Upload/index.js index 8b1207d..3501434 100644 --- a/src/components/Upload/index.js +++ b/src/components/Upload/index.js @@ -145,75 +145,111 @@ const Upload = (props) => { const ratioArr = ratio ? ratio.split("*") : []; 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 invalidFiles = []; 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); - // 只提示未提示过的文件 - if (!warnedFileUids.current.has(fileItem.uid)) { - warnedFileUids.current.add(fileItem.uid); - message.warning(`${fileItem.name}:只能上传${acceptTip}格式的文件`); - } continue; } // 验证文件大小 - if (maxSize && fileItem.size > maxSize) { + if (!validateFileSize(fileItem)) { 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; - } + const isValidResolution = await validateImageResolution(fileItem); + if (!isValidResolution) { + invalidFiles.push(fileItem); + continue; } validFiles.push(fileItem); @@ -223,8 +259,13 @@ const Upload = (props) => { }; // 执行验证并更新 - validateFiles(fileList).then(({ validFiles }) => { - onChange?.(validFiles); + validateNewFiles(newFiles).then(({ validFiles: validNewFiles }) => { + // 合并已存在的文件和通过验证的新文件 + const finalFileList = [ + ...value, // 已存在的文件 + ...validNewFiles, // 通过验证的新文件 + ]; + onChange?.(finalFileList); }); };