From 44e97861d2cc5f4121b6406dac4769d402d9194a Mon Sep 17 00:00:00 2001 From: long <452591453@qq.com> Date: Wed, 20 May 2026 16:59:19 +0800 Subject: [PATCH] fix: use OSS direct upload for video and audio in resource admin --- admin/src/components/upload/index.vue | 8 +++++--- admin/src/views/asset/resource/index.vue | 17 ++++++++++++++++- .../app/common/service/DirectUploadService.php | 3 +++ 3 files changed, 24 insertions(+), 4 deletions(-) diff --git a/admin/src/components/upload/index.vue b/admin/src/components/upload/index.vue index a51838c8..eead4783 100644 --- a/admin/src/components/upload/index.vue +++ b/admin/src/components/upload/index.vue @@ -102,8 +102,8 @@ export default defineComponent({ const visible = ref(false) const fileList = ref([]) - // 仅 video + direct 时才接管 http-request - const useDirect = computed(() => props.direct && props.type === 'video') + // 仅 video/voice + direct 时才接管 http-request + const useDirect = computed(() => props.direct && ['video', 'voice'].includes(props.type)) const handleProgress = () => { visible.value = true @@ -151,6 +151,8 @@ export default defineComponent({ return '.jpg,.png,.gif,.jpeg,.ico' case 'video': return '.wmv,.avi,.mpg,.mpeg,.3gp,.mov,.mp4,.flv,.rmvb,.mkv' + case 'voice': + return '.mp3,.wav,.wma,.m4a,.aac,.amr' default: return '*' } @@ -162,7 +164,7 @@ export default defineComponent({ try { const data = await uploadVideoDirectToCos({ file: options.file, - type: 'video', + type: props.type as any, cid: Number((options.data as any)?.cid ?? 0), onProgress(info) { // 触发 ElUpload 内部进度(保持与默认上传一致的体验) diff --git a/admin/src/views/asset/resource/index.vue b/admin/src/views/asset/resource/index.vue index 992fac9e..0c034dd9 100644 --- a/admin/src/views/asset/resource/index.vue +++ b/admin/src/views/asset/resource/index.vue @@ -59,7 +59,16 @@ - + + + 上传视频 (OSS直传) + + + 上传语音 (OSS直传) + +
+ 已上传: {{ formData.file_url }} +
@@ -80,6 +89,7 @@ import { ref, reactive, onMounted } from 'vue' import { ElMessage, ElMessageBox } from 'element-plus' import { apiAssetResourceList, apiAssetResourceAdd, apiAssetResourceDelete, apiAssetUserList } from '@/api/asset' import MaterialPicker from '@/components/material/picker.vue' +import Upload from '@/components/upload/index.vue' const loading = ref(false) const tableData = ref([]) @@ -143,6 +153,11 @@ const handleAdd = () => { dialogVisible.value = true } +const handleUploadSuccess = (response: any) => { + formData.file_url = response?.data?.uri || response?.data?.url || '' + ElMessage.success('上传成功') +} + const handleDelete = async (row: any) => { try { await ElMessageBox.confirm('确定要删除该资源吗?用户将无法再看到。', '提示', { type: 'warning' }) diff --git a/server/app/common/service/DirectUploadService.php b/server/app/common/service/DirectUploadService.php index aecf432b..cbe991bd 100755 --- a/server/app/common/service/DirectUploadService.php +++ b/server/app/common/service/DirectUploadService.php @@ -19,6 +19,7 @@ class DirectUploadService { /** 视频允许的扩展名(沿用 config/project.file_video) */ public const TYPE_VIDEO = 'video'; + public const TYPE_VOICE = 'voice'; /** 默认凭证有效期 30 分钟 */ public const DEFAULT_DURATION = 1800; @@ -26,6 +27,7 @@ class DirectUploadService /** 允许扩展类型 → 大小上限(字节) */ private const MAX_SIZE = [ self::TYPE_VIDEO => 2 * 1024 * 1024 * 1024, // 2GB + self::TYPE_VOICE => 500 * 1024 * 1024, // 500MB ]; /** @@ -144,6 +146,7 @@ class DirectUploadService { return match ($type) { self::TYPE_VIDEO => FileEnum::VIDEO_TYPE, + self::TYPE_VOICE => FileEnum::FILE_TYPE, default => FileEnum::FILE_TYPE, }; }