feat: 优化
This commit is contained in:
@@ -7,11 +7,43 @@ import { ref, reactive } from 'vue'
|
||||
import { message } from 'ant-design-vue'
|
||||
import { MaterialService } from '@/api/material'
|
||||
|
||||
/**
|
||||
* 获取视频时长(秒)
|
||||
* @param {File} file - 视频文件对象
|
||||
* @returns {Promise<number|null>} 时长(秒)
|
||||
*/
|
||||
function getVideoDuration(file) {
|
||||
return new Promise((resolve) => {
|
||||
if (!file.type.startsWith('video/')) {
|
||||
resolve(null)
|
||||
return
|
||||
}
|
||||
|
||||
const video = document.createElement('video')
|
||||
video.preload = 'metadata'
|
||||
video.muted = true
|
||||
|
||||
video.onloadedmetadata = function() {
|
||||
const duration = Math.round(video.duration)
|
||||
URL.revokeObjectURL(video.src)
|
||||
resolve(duration)
|
||||
}
|
||||
|
||||
video.onerror = function() {
|
||||
URL.revokeObjectURL(video.src)
|
||||
resolve(null)
|
||||
}
|
||||
|
||||
video.src = URL.createObjectURL(file)
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {Object} UploadOptions
|
||||
* @property {string} fileCategory - 文件分类(video/voice/audio/image)
|
||||
* @property {string} fileCategory - 文件分类(video/voice/audio/image/digital_human)
|
||||
* @property {number|null} groupId - 分组编号(可选,仅素材库模块使用)
|
||||
* @property {string|null} coverBase64 - 封面base64(可选)
|
||||
* @property {number|null} duration - 视频时长(可选,视频文件自动获取)
|
||||
* @property {Function} onProgress - 进度回调(可选)
|
||||
* @property {Function} onStart - 开始回调(可选)
|
||||
* @property {Function} onSuccess - 成功回调(可选)
|
||||
@@ -94,6 +126,7 @@ export function useUpload() {
|
||||
fileCategory,
|
||||
groupId = null,
|
||||
coverBase64 = null,
|
||||
duration: inputDuration,
|
||||
onProgress,
|
||||
onStart,
|
||||
onSuccess,
|
||||
@@ -108,7 +141,13 @@ export function useUpload() {
|
||||
state.progress = 0
|
||||
|
||||
// 通知开始
|
||||
onStart && onStart()
|
||||
onStart?.()
|
||||
|
||||
// 获取视频时长(如果是视频文件且未提供时长)
|
||||
let duration = inputDuration
|
||||
if (duration === undefined && file.type.startsWith('video/')) {
|
||||
duration = await getVideoDuration(file)
|
||||
}
|
||||
|
||||
// 第一步:获取预签名URL
|
||||
const presignedData = await MaterialService.getPresignedUrl({
|
||||
@@ -121,7 +160,7 @@ export function useUpload() {
|
||||
// 第二步:直传文件到OSS
|
||||
await uploadToOSS(file, presignedData.data, (progress) => {
|
||||
state.progress = progress
|
||||
onProgress && onProgress(progress)
|
||||
onProgress?.(progress)
|
||||
})
|
||||
|
||||
// 第三步:确认上传并保存记录
|
||||
@@ -133,7 +172,7 @@ export function useUpload() {
|
||||
fileType: file.type,
|
||||
groupId,
|
||||
coverBase64,
|
||||
duration: file.type.startsWith('video/') ? null : undefined
|
||||
duration
|
||||
})
|
||||
|
||||
state.uploading = false
|
||||
@@ -142,14 +181,14 @@ export function useUpload() {
|
||||
|
||||
const fileId = completeData.data?.infraFileId || completeData.data?.userFileId
|
||||
const fileUrl = presignedData.data.presignedUrl
|
||||
onSuccess && onSuccess(fileId, fileUrl)
|
||||
onSuccess?.(fileId, fileUrl)
|
||||
|
||||
return fileId
|
||||
} catch (error) {
|
||||
state.uploading = false
|
||||
state.status = 'error'
|
||||
state.error = error.message || '上传失败'
|
||||
onError && onError(error)
|
||||
onError?.(error)
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user