feat(material): remove video cover extraction and simplify upload API

- Remove extractVideoCoverOptional function and related video cover processing
- Update MaterialService.uploadFile method signature to remove coverBase64 parameter
- Simplify uploadAndIdentifyVideo function by removing cover generation logic
- Remove loading indicator from VideoSelector component during video preview
- Add presignGetUrlWithProcess method to FileClient interface for processed file URLs
- Add logging support to S3FileClient implementation
This commit is contained in:
2026-03-04 22:37:31 +08:00
parent 07579e27e9
commit 27d1c53b49
23 changed files with 576 additions and 361 deletions

View File

@@ -251,12 +251,10 @@ const handlePreview = async (video) => {
}
// 显示加载提示
const hideLoading = message.loading('正在获取视频地址...', 0)
try {
// 调用后端API获取带签名的视频播放URL
const res = await MaterialService.getVideoPlayUrl(video.id)
hideLoading()
if (res.code === 0 && res.data) {
previewVideo.value = video
@@ -266,7 +264,6 @@ const handlePreview = async (video) => {
message.error(res.msg || '获取视频地址失败')
}
} catch (error) {
hideLoading()
console.error('获取视频播放URL失败:', error)
message.error('获取视频地址失败,请重试')
}

View File

@@ -144,7 +144,6 @@
import { ref, watch, computed } from 'vue'
import { message } from 'ant-design-vue'
import { UploadOutlined, FileOutlined, LoadingOutlined, CheckCircleOutlined, CheckOutlined } from '@ant-design/icons-vue'
import { isVideoFile, extractVideoCover } from '@/utils/video-cover'
import { getFileName, getFileSize, formatFileSize } from '@/utils/file'
import { useUpload } from '@/composables/useUpload'
@@ -153,10 +152,6 @@ const props = defineProps({
type: Boolean,
default: false
},
uploading: {
type: Boolean,
default: false
},
fileCategory: {
type: String,
default: 'video'
@@ -174,8 +169,6 @@ const { upload } = useUpload()
// 数据
const fileList = ref([])
const fileCoverMap = ref(new Map())
const DEFAULT_FILE_CATEGORY = 'video'
const acceptTypes = 'video/*,image/*,audio/*,.mp4,.mov,.avi,.mkv,.jpg,.jpeg,.png,.gif,.webp,.mp3,.wav,.aac'
// 常量
@@ -216,7 +209,6 @@ const getTotalSize = () => {
watch(() => props.visible, (newVal) => {
if (!newVal) {
fileList.value = []
fileCoverMap.value.clear()
resetUploadState()
}
})
@@ -266,7 +258,7 @@ const handleBeforeUpload = (file) => {
}
// 文件列表变化
const handleFileChange = async (info) => {
const handleFileChange = (info) => {
const { file, fileList: newFileList } = info
if (file && file.status !== 'uploading') {
@@ -278,25 +270,6 @@ const handleFileChange = async (info) => {
return item
})
.filter(item => item.status !== 'removed')
// 如果是视频文件,自动提取封面
const fileObj = file.file || file.originFileObj || file
if (fileObj instanceof File && isVideoFile(fileObj)) {
const fileKey = file.uid || fileObj.name
if (!fileCoverMap.value.has(fileKey)) {
try {
const coverResult = await extractVideoCover(fileObj, {
maxWidth: 800,
quality: 0.8
})
fileCoverMap.value.set(fileKey, coverResult.base64)
console.log(`[封面提取成功] ${fileObj.name}`)
} catch (error) {
console.warn(`[封面提取失败] ${fileObj.name}:`, error)
}
}
}
}
}
@@ -307,9 +280,6 @@ const handleRemove = (fileItem) => {
(getFileName(item) === getFileName(fileItem))
)
if (index > -1) {
const removed = fileList.value[index]
const fileKey = removed.uid || getFileName(removed)
fileCoverMap.value.delete(fileKey)
fileList.value.splice(index, 1)
}
}
@@ -327,71 +297,65 @@ const handleConfirm = async () => {
return
}
// 提取文件对象和对应的封面
const filesWithCover = fileList.value
// 提取文件对象
const files = fileList.value
.map(item => {
const fileObj = item.file || item.originFileObj || item
if (!(fileObj instanceof File)) return null
const fileKey = item.uid || fileObj.name
return {
file: fileObj,
coverBase64: fileCoverMap.value.get(fileKey) || null
}
return fileObj
})
.filter(item => item !== null)
if (filesWithCover.length === 0) {
if (files.length === 0) {
message.error('无法获取文件对象,请重新选择文件')
return
}
// 开始上传
await performUpload(filesWithCover)
await performUpload(files)
}
// 执行上传
const performUpload = async (filesWithCover) => {
const performUpload = async (files) => {
uploading.value = true
totalUploadCount.value = filesWithCover.length
totalUploadCount.value = files.length
currentUploadIndex.value = 0
completedFiles.value = []
// 使用传入的fileCategory,如果没有则使用默认值
const category = props.fileCategory || DEFAULT_FILE_CATEGORY
// 使用传入的fileCategory
const category = props.fileCategory || 'video'
let successCount = 0
let failCount = 0
for (let i = 0; i < filesWithCover.length; i++) {
const fileWithCover = filesWithCover[i]
for (let i = 0; i < files.length; i++) {
const file = files[i]
currentUploadIndex.value = i + 1
currentFileName.value = fileWithCover.file.name
currentFileSize.value = fileWithCover.file.size
currentFileName.value = file.name
currentFileSize.value = file.size
currentFileUploaded.value = 0
currentFileProgress.value = 0
try {
await upload(fileWithCover.file, {
await upload(file, {
fileCategory: category,
groupId: props.groupId,
coverBase64: fileWithCover.coverBase64,
onProgress: (progress) => {
currentFileProgress.value = progress
currentFileUploaded.value = Math.round((progress / 100) * currentFileSize.value)
},
onSuccess: () => {
console.log('文件上传成功:', fileWithCover.file.name)
console.log('文件上传成功:', file.name)
successCount++
completedFiles.value.push({
name: fileWithCover.file.name,
name: file.name,
success: true
})
},
onError: (error) => {
console.error('文件上传失败:', fileWithCover.file.name, error)
console.error('文件上传失败:', file.name, error)
failCount++
completedFiles.value.push({
name: fileWithCover.file.name,
name: file.name,
success: false
})
}
@@ -400,7 +364,7 @@ const performUpload = async (filesWithCover) => {
console.error('上传异常:', error)
failCount++
completedFiles.value.push({
name: fileWithCover.file.name,
name: file.name,
success: false
})
}