feat(assets): add 2GB file size validation and OSS direct upload for large files
- Add MAX_FILE_SIZE (2GB) validation in handleUpload with friendly error message - Route files >100MB through OSS presigned direct upload (uploadAssetDirect) - Keep small file form upload (uploadAsset) for files <=100MB - Update upload hint text to show '单文件不超过 2GB' limit - Add directUploadMutation with proper loading state tracking Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -37,12 +37,18 @@ import {
|
||||
getAssets,
|
||||
deleteAsset,
|
||||
uploadAsset,
|
||||
uploadAssetDirect,
|
||||
} from '@/api/assets';
|
||||
import { getOrCreateDefaultProject } from '@/api/projects';
|
||||
|
||||
const { Title, Text } = Typography;
|
||||
const { Dragger } = Upload;
|
||||
|
||||
/** 最大文件大小:2GB */
|
||||
const MAX_FILE_SIZE = 2 * 1024 * 1024 * 1024; // 2147483648 bytes
|
||||
/** 大文件阈值:100MB,超过此值走 OSS 直传通道 */
|
||||
const LARGE_FILE_THRESHOLD = 100 * 1024 * 1024; // 104857600 bytes
|
||||
|
||||
/** 素材库类型图标 */
|
||||
const KindIcon: React.FC<{ kind: string }> = ({ kind }) => {
|
||||
switch (kind) {
|
||||
@@ -99,7 +105,7 @@ const AssetLibrary: React.FC = () => {
|
||||
onError: (err: any) => { if (!err?.__msgShown) message.error('创建失败') },
|
||||
});
|
||||
|
||||
// 上传素材
|
||||
// 上传素材(小文件表单上传)
|
||||
const uploadMutation = useMutation({
|
||||
mutationFn: uploadAsset,
|
||||
onSuccess: () => {
|
||||
@@ -110,6 +116,17 @@ const AssetLibrary: React.FC = () => {
|
||||
onError: (err: any) => { if (!err?.__msgShown) message.error('上传失败') },
|
||||
});
|
||||
|
||||
// 大文件直传(OSS 预签名)
|
||||
const directUploadMutation = useMutation({
|
||||
mutationFn: uploadAssetDirect,
|
||||
onSuccess: () => {
|
||||
message.success('上传成功');
|
||||
queryClient.invalidateQueries({ queryKey: ['assets', activeLibrary] });
|
||||
queryClient.invalidateQueries({ queryKey: ['asset-libraries'] });
|
||||
},
|
||||
onError: (err: any) => { if (!err?.__msgShown) message.error('上传失败') },
|
||||
});
|
||||
|
||||
// 删除素材
|
||||
const deleteMutation = useMutation({
|
||||
mutationFn: deleteAsset,
|
||||
@@ -127,16 +144,32 @@ const AssetLibrary: React.FC = () => {
|
||||
message.warning('请先选择素材库');
|
||||
return false;
|
||||
}
|
||||
|
||||
// 文件大小校验:上限 2GB
|
||||
if (file.size > MAX_FILE_SIZE) {
|
||||
message.error('文件大小不能超过 2GB');
|
||||
return false;
|
||||
}
|
||||
|
||||
setUploading(true);
|
||||
try {
|
||||
const project = await getOrCreateDefaultProject();
|
||||
const formData = new FormData();
|
||||
formData.append('file', file);
|
||||
formData.append('library_id', activeLibrary);
|
||||
formData.append('project_id', project.id);
|
||||
await uploadMutation.mutateAsync(formData);
|
||||
if (file.size > LARGE_FILE_THRESHOLD) {
|
||||
// 大文件(>100MB)走 OSS 预签名直传通道
|
||||
await directUploadMutation.mutateAsync({
|
||||
file,
|
||||
library_id: activeLibrary,
|
||||
});
|
||||
} else {
|
||||
// 小文件走表单上传
|
||||
const project = await getOrCreateDefaultProject();
|
||||
const formData = new FormData();
|
||||
formData.append('file', file);
|
||||
formData.append('library_id', activeLibrary);
|
||||
formData.append('project_id', project.id);
|
||||
await uploadMutation.mutateAsync(formData);
|
||||
}
|
||||
} catch {
|
||||
// uploadMutation.onError 已处理错误提示
|
||||
// mutation.onError 已处理错误提示
|
||||
} finally {
|
||||
setUploading(false);
|
||||
}
|
||||
@@ -216,7 +249,7 @@ const AssetLibrary: React.FC = () => {
|
||||
beforeUpload={handleUpload}
|
||||
showUploadList={false}
|
||||
multiple
|
||||
disabled={uploading || uploadMutation.isPending}
|
||||
disabled={uploading || uploadMutation.isPending || directUploadMutation.isPending}
|
||||
style={{ marginBottom: 24 }}
|
||||
>
|
||||
<p className="ant-upload-drag-icon">
|
||||
@@ -226,7 +259,7 @@ const AssetLibrary: React.FC = () => {
|
||||
{uploading ? '正在上传,请稍候...' : '点击或拖拽文件到此区域上传'}
|
||||
</p>
|
||||
<p className="ant-upload-hint">
|
||||
支持 {kindLabel[currentLib?.kind || 'video']} 格式文件
|
||||
支持 {kindLabel[currentLib?.kind || 'video']} 格式文件,单文件不超过 2GB
|
||||
</p>
|
||||
</Dragger>
|
||||
)}
|
||||
|
||||
Reference in New Issue
Block a user