import React, { useState } from 'react'; import { Upload, Modal, message } from 'antd'; import { PlusOutlined } from '@ant-design/icons'; import { useTusUpload } from "@web/src/hooks/useTusUpload"; import toast from "react-hot-toast"; export interface MultiImageUploadProps { value?: string; placeholder?: string; className?: string; onChange?: (value: string) => void; compressed?: boolean; style?: React.CSSProperties; // 添加style属性 } interface UploadFile { name: string; progress: number; status: "uploading" | "done" | "error"; url?: string; fileKey?: string; uid: string; } const MultiImageUpload: React.FC = ({ value, onChange, compressed = false, className, placeholder = "点击上传", style, // 解构style属性 }) => { const [fileList, setFileList] = useState(null); // 存储已上传的文件列表 const [previewVisible, setPreviewVisible] = useState(false); // 控制预览模态框的显示 const [previewImage, setPreviewImage] = useState(''); // 当前预览的图片URL const { handleFileUpload, uploadProgress } = useTusUpload(); const [compressedUrl, setCompressedUrl] = useState(value || ""); const [url, setUrl] = useState(value || ""); const [uploading, setUploading] = useState(false); // 处理文件上传前的校验 const beforeUpload = (file) => { const isImage = file.type.startsWith('image/'); if (!isImage) { message.error('只能上传图片文件!'); } const isLt10M = file.size / 1024 / 1024 < 10; if (!isLt10M) { message.error('图片大小不能超过10MB!'); } return isImage && isLt10M; }; // 处理文件列表变化 const handleChange = async ({ fileList }) => { //setFileList(fileList); console.log(fileList); const imageUrls = fileList.map(file => { return URL.createObjectURL(file.originFileObj) }); console.log("imageUrls", imageUrls); const newFileList = fileList.map(file => { return { name: file.name, progress: 0, status: "uploading", //uid: file.uid, fileKey: `${file.name}-${Date.now()}`, //url: file.url, } }); console.log("newFileList", newFileList); setUploading(true); try { const resFileList = newFileList.map(async (file, index) => { const uploadedUrl = await new Promise((resolve, reject) => { handleFileUpload( fileList[index].originFileObj, (result) => { () => { return { ...newFileList[index], progress: 100, status: "done", fileId: result.fileId, url: result.url, compressedUrl: result.compressedUrl, } } // setFile((prev) => ({ // ...prev!, // progress: 100, // status: "done", // fileId: result.fileId, // url: result.url, // compressedUrl: result.compressedUrl, // })); setUrl(result.url); setCompressedUrl(result.compressedUrl); // 直接使用 result 中的最新值 resolve(compressed ? result.compressedUrl : result.url); }, (error) => { reject(error); }, newFileList[index]?.fileKey ); }); }) // await new Promise((resolve) => setTimeout(resolve,4999)); // 方法1:使用 await 暂停执行 // 使用 resolved 的最新值调用 onChange // 强制刷新 Avatar 组件 // setAvatarKey((prev) => prev + 1); // 修改 key 强制重新挂载 onChange?.(resFileList); console.log(resFileList); toast.success("图片上传成功"); } catch (error) { console.error("上传错误:", error); toast.error("图片上传失败"); // setFile((prev) => ({ ...prev!, status: "error" })); } finally { setUploading(false); } };uploadProgress // 处理预览 const handlePreview = async (file) => { if (!file.url && !file.preview) { file.preview = await getBase64(file.originFileObj); } setPreviewImage(file.url || file.preview); setPreviewVisible(true); }; // 关闭预览模态框 const handleCancel = () => setPreviewVisible(false); // 将文件转换为Base64格式(用于预览) const getBase64 = (file) => { return new Promise((resolve, reject) => { const reader = new FileReader(); reader.readAsDataURL(file); reader.onload = () => resolve(reader.result); reader.onerror = (error) => reject(error); }); }; return (

点击或拖拽文件到此区域上传

支持单个或批量上传

预览
); }; export default MultiImageUpload;