import { PlusOutlined } from '@ant-design/icons'; import type { GetProp, UploadFile, UploadProps } from 'antd'; import { Image, Upload } from 'antd'; import { useEffect, useState } from 'react'; type FileType = Parameters<GetProp<UploadProps, 'beforeUpload'>>[0]; const getBase64 = (file: FileType): Promise<string> => new Promise((resolve, reject) => { const reader = new FileReader(); reader.readAsDataURL(file); reader.onload = () => resolve(reader.result as string); reader.onerror = (error) => reject(error); }); export default ({ onFilesChange }) => { const [previewOpen, setPreviewOpen] = useState(false); const [previewImage, setPreviewImage] = useState(''); const [fileList, setFileList] = useState<UploadFile[]>([]); const handlePreview = async (file: UploadFile) => { if (!file.url && !file.preview) { file.preview = await getBase64(file.originFileObj as FileType); } setPreviewImage(file.url || (file.preview as string)); setPreviewOpen(true); }; const onPaste = async (e: ClipboardEvent) => { const items = e.clipboardData.items; for (let i = 0; i < items.length; i++) { const item = items[i]; // 检查是否为文件类型,并且类型是图片 if (item.kind === 'file' && item.type.startsWith('image/')) { const file = item.getAsFile(); if (file) { const newFile = { uid: Date.now(), // 生成唯一的 uid name: file.name, status: 'done', url: URL.createObjectURL(file), // 生成临时 URL originFileObj: file, }; // 更新 fileList const newFileList = [...fileList, newFile]; setFileList(newFileList); onFilesChange(newFileList); break; // 只处理第一个图片 } } } }; useEffect(() => { document.addEventListener('paste', onPaste); return () => { document.removeEventListener('paste', onPaste); }; }, [fileList]); // 添加 fileList 依赖 const uploadButton = ( <button style={{ border: 0, background: 'none' }} type="button"> <PlusOutlined /> <div style={{ marginTop: 8 }}>Upload</div> </button> ); return ( <> <Upload listType="picture-card" fileList={fileList} onPreview={handlePreview} onChange={({ fileList: newFileList }) => { setFileList(newFileList); onFilesChange(newFileList); }} > {fileList.length >= 1 ? null : uploadButton} </Upload> {previewImage && ( <Image wrapperStyle={{ display: 'none' }} preview={{ visible: previewOpen, onVisibleChange: (visible) => setPreviewOpen(visible), afterOpenChange: (visible) => !visible && setPreviewImage(''), }} src={previewImage} /> )} </> ); };