From ea129b523c339fa8dd3737057e38de10d02cd5a7 Mon Sep 17 00:00:00 2001 From: LiuJiaNan <15703339975@163.com> Date: Tue, 24 Feb 2026 11:42:08 +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 | 132 +++++++++++++++++++++------------ 1 file changed, 84 insertions(+), 48 deletions(-) diff --git a/src/components/Upload/index.js b/src/components/Upload/index.js index 02906e4..0906cda 100644 --- a/src/components/Upload/index.js +++ b/src/components/Upload/index.js @@ -1,6 +1,6 @@ import { PlusOutlined, UploadOutlined, VideoCameraAddOutlined } from "@ant-design/icons"; 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 [previewImage, setPreviewImage] = useState(""); + // 记录已经提示过错误的文件uid,避免重复提示 + const warnedFileUids = useRef(new Set()); + // 预设的文件格式 const imageAccept = ".jpg,.jpeg,.png"; 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 ratioArr = ratio ? ratio.split("*") : []; - const suffix = file.name.substring( - file.name.lastIndexOf("."), - file.name.length, - ); const maxSize = size * 1024 * 1024; - // 验证文件格式 - if (acceptList.length > 0 && !acceptList.includes(suffix)) { - message.warning(`只能上传${acceptTip}格式的文件`); - const filtered = fileList.filter(item => item.uid !== file.uid); - onChange?.(filtered); - return; - } + // 对整个fileList进行验证和过滤 + const validateFiles = async (files) => { + const validFiles = []; + const invalidFiles = []; - // 验证文件大小 - if (maxSize && file.size > maxSize) { - message.warning(`文件大小不能超过${size}M`); - const filtered = fileList.filter(item => item.uid !== file.uid); - onChange?.(filtered); - return; - } + for (const fileItem of files) { + const suffix = fileItem.name?.substring( + fileItem.name.lastIndexOf("."), + fileItem.name.length, + ) || ""; - // 验证图片分辨率 - if (ratioArr.length === 2 && file.type?.startsWith("image/")) { - const validateImageResolution = (imageUrl) => { - const img = new Image(); - img.onload = () => { - if (img.width !== +ratioArr[0] || img.height !== +ratioArr[1]) { - message.warning(`只能上传${ratio}分辨率的图片`); - const filtered = fileList.filter(item => item.uid !== file.uid); - onChange?.(filtered); - return; + // 验证文件格式 + if (acceptList.length > 0 && !acceptList.includes(suffix)) { + invalidFiles.push(fileItem); + // 只提示未提示过的文件 + if (!warnedFileUids.current.has(fileItem.uid)) { + warnedFileUids.current.add(fileItem.uid); + message.warning(`${fileItem.name}:只能上传${acceptTip}格式的文件`); } - onChange?.(fileList); - }; - img.src = imageUrl; - }; + continue; + } - // 如果有现成的URL则直接使用,否则使用FileReader读取本地文件 - if (file.url) { - validateImageResolution(file.url); + // 验证文件大小 + if (maxSize && fileItem.size > maxSize) { + 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(); - reader.onload = (e) => { - validateImageResolution(e.target.result); - }; - reader.readAsDataURL(file); - } - } - else { - onChange?.(fileList); - } + + return { validFiles, invalidFiles }; + }; + + // 执行验证并更新 + validateFiles(fileList).then(({ validFiles }) => { + onChange?.(validFiles); + }); }; // 删除文件 const handleRemove = (file) => { + // 清理该文件的提示记录 + warnedFileUids.current.delete(file.uid); if (!file.originFileObj) onGetRemoveFile?.(file); return onRemove?.(file);