v4.0.15上传图片自动压缩

This commit is contained in:
developer_liu
2026-09-03 16:04:10 +08:00
parent b60b16a84f
commit c26ebdde1b
9 changed files with 308 additions and 13 deletions
+44 -3
View File
@@ -1,5 +1,5 @@
import { useState } from 'react';
import { Button, Image, Input, Modal, Space, Upload, message } from 'antd';
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';
@@ -13,6 +13,7 @@ type OssUploadProps = {
accept?: string;
maxSizeMb?: number;
placeholder?: string;
uploadHint?: ReactNode;
};
function isImageUrl(url: string) {
@@ -23,6 +24,32 @@ 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,
@@ -31,9 +58,11 @@ export default function OssUpload({
mediaType = 'IMAGE',
accept,
placeholder = '上传后自动填入,或手动粘贴 URL',
uploadHint,
}: OssUploadProps) {
const [uploading, setUploading] = useState(false);
const [pdfPreviewOpen, setPdfPreviewOpen] = useState(false);
const [imageMetaHint, setImageMetaHint] = useState<string | null>(null);
const resolvedAccept =
accept ?? (mediaType === 'VIDEO' ? 'video/*' : mediaType === 'FILE' ? undefined : 'image/*');
@@ -45,7 +74,9 @@ export default function OssUpload({
const result = await uploadFileToOss(raw, { bizType, mediaType });
onChange?.(result.url);
onUploaded?.(result);
message.success('上传成功');
const successMessage = formatUploadImageMessage(result);
setImageMetaHint(formatUploadImageHint(result));
message.success(successMessage);
onSuccess?.(result);
} catch (e) {
const err = e instanceof Error ? e : new Error('上传失败');
@@ -116,6 +147,16 @@ export default function OssUpload({
<video src={value} controls style={{ maxWidth: '100%', maxHeight: 160, borderRadius: 4 }} />
)}
{filePreview}
{uploadHint ? (
<Typography.Text type="secondary" style={{ fontSize: 12 }}>
{uploadHint}
</Typography.Text>
) : null}
{imageMetaHint ? (
<Typography.Text type="secondary" style={{ fontSize: 12 }}>
{imageMetaHint}
</Typography.Text>
) : null}
<Space wrap>
<Upload
accept={resolvedAccept}