126 lines
3.8 KiB
TypeScript
126 lines
3.8 KiB
TypeScript
/**
|
||
* 文件输入处理函数
|
||
* 包括文件选择、拖拽处理等
|
||
*/
|
||
|
||
import { isValidMainFileType, detectMaterialType, extractSpuFromFileName } from './upload-utils'
|
||
import type { BatchFileItem } from './upload-types'
|
||
import { createBatchItemFromSingleFile } from './file-handlers'
|
||
import { isVideoMaterialType } from '@/lib/video-material-types'
|
||
|
||
/**
|
||
* 处理文件选择(单文件或批量)
|
||
*/
|
||
export function handleFileSelection(
|
||
files: File[],
|
||
materialType: string,
|
||
currentZipFile: File | null,
|
||
currentBatchFiles: BatchFileItem[],
|
||
categoryName: string,
|
||
sceneName: string,
|
||
platformName: string,
|
||
productCategoryName: string,
|
||
renderer: string,
|
||
onSingleFile: (file: File) => void,
|
||
onBatchFiles: (files: File[]) => void,
|
||
onError: (error: string) => void
|
||
) {
|
||
// 过滤有效文件
|
||
const validFiles = files.filter(f => isValidMainFileType(f, materialType))
|
||
if (validFiles.length === 0) {
|
||
const common = '压缩包格式(.zip / .rar / .7z)'
|
||
const videoTip = '视频文件(.mp4/.mov/.avi/.mkv/.mts/.m4v)'
|
||
const audioTip = '音频文件(.mp3/.wav/.flac/.m4a/.aac/.ogg)'
|
||
const brandTip = 'PDF 文件(.pdf)'
|
||
const message =
|
||
materialType === '音乐'
|
||
? audioTip
|
||
: isVideoMaterialType(materialType)
|
||
? videoTip
|
||
: materialType === '品牌VI灵感'
|
||
? brandTip
|
||
: common
|
||
onError(`请选择有效的素材文件,支持:${message}`)
|
||
return
|
||
}
|
||
|
||
// 如果已经有文件(单文件或批量模式),追加到批量模式
|
||
if (currentZipFile || currentBatchFiles.length > 0) {
|
||
// 如果当前是单文件模式,先将 zipFile 转换为批量模式的第一项
|
||
if (currentZipFile && currentBatchFiles.length === 0) {
|
||
const firstBatchItem = createBatchItemFromSingleFile(
|
||
currentZipFile,
|
||
materialType,
|
||
categoryName,
|
||
sceneName,
|
||
platformName,
|
||
productCategoryName,
|
||
renderer
|
||
)
|
||
// 这里需要调用回调来设置批量文件,但由于函数签名限制,我们返回信息让调用者处理
|
||
// 实际上这个逻辑应该在组件内部处理
|
||
}
|
||
// 追加新文件到批量模式
|
||
onBatchFiles(validFiles)
|
||
return
|
||
}
|
||
|
||
// 如果选择多个文件,进入批量上传模式
|
||
if (validFiles.length > 1) {
|
||
onBatchFiles(validFiles)
|
||
return
|
||
}
|
||
|
||
// 单个文件,且没有已有文件,使用单文件模式
|
||
const file = validFiles[0]
|
||
onSingleFile(file)
|
||
|
||
// 自动识别并设置素材类型
|
||
const detectedType = detectMaterialType(file.name)
|
||
if (detectedType) {
|
||
// 这里需要调用回调来设置素材类型,但由于函数签名限制,我们返回信息让调用者处理
|
||
// 实际上这个逻辑应该在组件内部处理
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 处理拖拽文件
|
||
*/
|
||
export function handleFileDrop(
|
||
files: File[],
|
||
materialType: string,
|
||
currentZipFile: File | null,
|
||
currentBatchFiles: BatchFileItem[],
|
||
categoryName: string,
|
||
sceneName: string,
|
||
platformName: string,
|
||
productCategoryName: string,
|
||
renderer: string,
|
||
onSingleFile: (file: File) => void,
|
||
onBatchFiles: (files: File[]) => void,
|
||
onError: (error: string) => void
|
||
) {
|
||
// 只处理素材文件(包括压缩包/视频/音频/PDF 视类型而定)
|
||
// 图片文件应该拖拽到对应的预览图或展示图区域
|
||
const materialFiles = files.filter((f) => isValidMainFileType(f, materialType))
|
||
if (materialFiles.length > 0) {
|
||
handleFileSelection(
|
||
materialFiles,
|
||
materialType,
|
||
currentZipFile,
|
||
currentBatchFiles,
|
||
categoryName,
|
||
sceneName,
|
||
platformName,
|
||
productCategoryName,
|
||
renderer,
|
||
onSingleFile,
|
||
onBatchFiles,
|
||
onError
|
||
)
|
||
} else {
|
||
onError('请拖拽素材文件到此区域,图片请拖拽到对应的图片上传区域')
|
||
}
|
||
}
|
||
|