feat: 功能优化

This commit is contained in:
2026-01-17 14:43:42 +08:00
parent 5ed0cfff07
commit fecd47e25d
60 changed files with 3529 additions and 827 deletions

View File

@@ -13,6 +13,7 @@ import { VoiceService } from '@/api/voice'
import { MaterialService } from '@/api/material'
import { createDigitalHumanTask, getDigitalHumanTask, cancelTask, retryTask } from '@/api/digitalHuman'
import { extractVideoCover } from '@/utils/video-cover'
import { useUpload } from '@/composables/useUpload'
// 导入 voiceStore 用于获取用户音色
import { useVoiceCopyStore } from '@/stores/voiceCopy'
@@ -34,6 +35,9 @@ const playingPreviewVoiceId = ref('') // 当前正在试听的音色ID
const isPlayingSynthesized = ref(false) // 是否正在播放已合成的音频
const pollingInterval = ref(null) // 轮询间隔ID
// Upload Hook
const { upload } = useUpload()
// 试听音频缓存 - 按音色ID缓存避免重复API调用
const previewAudioCache = new Map()
const MAX_PREVIEW_CACHE_SIZE = 50 // 最多缓存50个音色的试听音频
@@ -506,12 +510,23 @@ const uploadVideoFile = async (file) => {
try {
// 获取封面base64
const coverBase64 = file.coverBase64 || null
const res = await MaterialService.uploadFile(file, 'video', coverBase64)
if (res.code === 0) {
return res.data // res.data就是文件ID
} else {
throw new Error(res.message || '上传失败')
}
// 使用useUpload Hook上传文件
const fileId = await upload(file, {
fileCategory: 'video',
groupId: null, // 数字人视频模块不使用groupId
coverBase64,
onStart: () => {},
onProgress: () => {},
onSuccess: (id) => {
message.success('文件上传成功')
},
onError: (error) => {
message.error(error.message || '上传失败')
}
})
return fileId
} catch (error) {
console.error('uploadVideoFile error:', error)
throw error

View File

@@ -83,9 +83,9 @@
@remove="handleRemoveFile"
@change="handleFileListChange"
>
<a-button type="primary" :loading="uploading">
<UploadOutlined v-if="!uploading" />
{{ uploading ? '上传中...' : (fileList.length > 0 ? '重新上传' : '上传音频文件') }}
<a-button type="primary" :loading="uploadState.uploading">
<UploadOutlined v-if="!uploadState.uploading" />
{{ uploadState.uploading ? '上传中...' : (fileList.length > 0 ? '重新上传' : '上传音频文件') }}
</a-button>
</a-upload>
<div class="upload-hint">
@@ -110,6 +110,7 @@ import { message, Modal } from 'ant-design-vue'
import { PlusOutlined, SearchOutlined, UploadOutlined, PlayCircleOutlined } from '@ant-design/icons-vue'
import { VoiceService } from '@/api/voice'
import { MaterialService } from '@/api/material'
import { useUpload } from '@/composables/useUpload'
import dayjs from 'dayjs'
// ========== 常量 ==========
@@ -126,7 +127,6 @@ const DEFAULT_FORM_DATA = {
// ========== 响应式数据 ==========
const loading = ref(false)
const submitting = ref(false)
const uploading = ref(false)
const voiceList = ref([])
const modalVisible = ref(false)
const formMode = ref('create')
@@ -150,6 +150,9 @@ const pagination = reactive({
const formData = reactive({ ...DEFAULT_FORM_DATA })
// ========== Upload Hook ==========
const { state: uploadState, upload } = useUpload()
// ========== 计算属性 ==========
const isCreateMode = computed(() => formMode.value === 'create')
@@ -300,30 +303,29 @@ const handleBeforeUpload = (file) => {
const handleCustomUpload = async (options) => {
const { file, onSuccess, onError } = options
uploading.value = true
try {
const res = await MaterialService.uploadFile(file, 'voice', null)
const fileId = await upload(file, {
fileCategory: 'voice',
groupId: null, // 配音模块不使用groupId
coverBase64: null,
onStart: () => {},
onProgress: () => {},
onSuccess: (id) => {
formData.fileId = id
message.success('文件上传成功')
onSuccess?.({ code: 0, data: id }, file)
},
onError: (error) => {
const errorMsg = error.message || '上传失败,请稍后重试'
message.error(errorMsg)
onError?.(error)
}
})
if (res.code !== 0) {
const errorMsg = res.msg || '上传失败'
message.error(errorMsg)
onError?.(new Error(errorMsg))
return
}
formData.fileId = res.data
message.success('文件上传成功')
await nextTick()
onSuccess?.(res, file)
return fileId
} catch (error) {
console.error('上传失败:', error)
const errorMsg = error?.message || '上传失败,请稍后重试'
message.error(errorMsg)
onError?.(error)
} finally {
uploading.value = false
}
}