import { useState, type ReactNode } from 'react'; import { Button, Image, Input, Modal, Space, Typography, Upload, message } from 'antd'; import { EyeOutlined, FilePdfOutlined, UploadOutlined } from '@ant-design/icons'; import type { UploadProps } from 'antd'; import { uploadFileToOss, type OssMediaType, type UploadFileResult } from '../lib/upload'; type OssUploadProps = { value?: string; onChange?: (url: string) => void; onUploaded?: (result: UploadFileResult) => void; bizType: string; mediaType?: OssMediaType; accept?: string; maxSizeMb?: number; placeholder?: string; uploadHint?: ReactNode; }; function isImageUrl(url: string) { return /\.(png|jpe?g|gif|webp|bmp|svg)(\?|#|$)/i.test(url); } function isPdfUrl(url: string) { return /\.pdf(\?|#|$)/i.test(url); } function formatUploadImageMessage(result: UploadFileResult): string { const img = result.image; if (!img) return '上传成功'; const sizeLabel = `${img.width}×${img.height}`; if (img.compressed && img.originalWidth && img.originalHeight) { const original = `${img.originalWidth}×${img.originalHeight}`; if (original !== sizeLabel) { return `上传成功(${sizeLabel},已由 ${original} 自动压缩)`; } } return `上传成功(${sizeLabel})`; } function formatUploadImageHint(result: UploadFileResult): string | null { const img = result.image; if (!img) return null; const sizeLabel = `${img.width}×${img.height}`; if (img.compressed && img.originalWidth && img.originalHeight) { const original = `${img.originalWidth}×${img.originalHeight}`; if (original !== sizeLabel) { return `${sizeLabel}(已由 ${original} 自动压缩)`; } } return sizeLabel; } export default function OssUpload({ value, onChange, onUploaded, bizType, mediaType = 'IMAGE', accept, placeholder = '上传后自动填入,或手动粘贴 URL', uploadHint, }: OssUploadProps) { const [uploading, setUploading] = useState(false); const [pdfPreviewOpen, setPdfPreviewOpen] = useState(false); const [imageMetaHint, setImageMetaHint] = useState(null); const resolvedAccept = accept ?? (mediaType === 'VIDEO' ? 'video/*' : mediaType === 'FILE' ? undefined : 'image/*'); const customRequest: UploadProps['customRequest'] = async ({ file, onSuccess, onError }) => { const raw = file as File; setUploading(true); try { const result = await uploadFileToOss(raw, { bizType, mediaType }); onChange?.(result.url); onUploaded?.(result); const successMessage = formatUploadImageMessage(result); setImageMetaHint(formatUploadImageHint(result)); message.success(successMessage); onSuccess?.(result); } catch (e) { const err = e instanceof Error ? e : new Error('上传失败'); message.error(err.message); onError?.(err); } finally { setUploading(false); } }; const filePreview = value && mediaType === 'FILE' ? ( isImageUrl(value) ? ( ) : isPdfUrl(value) ? (
PDF 合同
setPdfPreviewOpen(false)} footer={null} width="90vw" styles={{ body: { height: '75vh', padding: 0 } }} destroyOnClose >