feat(upload): compress images over 10MB before OSS upload (v3.4.13)

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-08-05 22:48:34 +08:00
parent bd1930f6b1
commit fa6fb80d19
15 changed files with 196 additions and 25 deletions
@@ -15,8 +15,6 @@ type OssUploadProps = {
placeholder?: string;
};
const DEFAULT_MAX_MB = 10;
export default function OssUpload({
value,
onChange,
@@ -24,7 +22,6 @@ export default function OssUpload({
bizType,
mediaType = 'IMAGE',
accept,
maxSizeMb = DEFAULT_MAX_MB,
placeholder = '上传后自动填入,或手动粘贴 URL',
}: OssUploadProps) {
const [uploading, setUploading] = useState(false);
@@ -34,12 +31,6 @@ export default function OssUpload({
const customRequest: UploadProps['customRequest'] = async ({ file, onSuccess, onError }) => {
const raw = file as File;
if (raw.size > maxSizeMb * 1024 * 1024) {
const err = new Error(`文件不能超过 ${maxSizeMb}MB`);
message.error(err.message);
onError?.(err);
return;
}
setUploading(true);
try {
const result = await uploadFileToOss(raw, { bizType, mediaType });
+16 -1
View File
@@ -1,4 +1,9 @@
import { apiBase, CLIENT_APP, getToken, clearAuth } from './api';
import {
compressImageFileIfNeeded,
DEFAULT_OSS_MAX_UPLOAD_BYTES,
formatOssMaxSizeMb,
} from '@dukang/shared-ui/compressImage';
export type OssMediaType = 'IMAGE' | 'VIDEO' | 'FILE';
@@ -9,14 +14,24 @@ export type UploadFileResult = {
mock: boolean;
};
async function prepareUploadFile(file: File, mediaType: OssMediaType): Promise<File> {
if (mediaType !== 'IMAGE') return file;
const compressed = await compressImageFileIfNeeded(file);
if (compressed.size > DEFAULT_OSS_MAX_UPLOAD_BYTES) {
throw new Error(`图片压缩后仍超过 ${formatOssMaxSizeMb()}MB,请换一张较小的图片`);
}
return compressed;
}
/** 经 API 服务端转存 OSS,避免浏览器直传跨域 */
export async function uploadFileToOss(
file: File,
options: { bizType: string; mediaType?: OssMediaType },
): Promise<UploadFileResult> {
const mediaType = options.mediaType ?? (file.type.startsWith('video/') ? 'VIDEO' : 'IMAGE');
const prepared = await prepareUploadFile(file, mediaType);
const formData = new FormData();
formData.append('file', file);
formData.append('file', prepared);
formData.append('bizType', options.bizType);
formData.append('mediaType', mediaType);