Allow multi-file live clip uploads with shared date/host/platform and per-clip titles, filter materials by live platform and date range, and fix the migration to alter the mapped materials table.
104 lines
3.2 KiB
TypeScript
104 lines
3.2 KiB
TypeScript
// 文件处理函数
|
||
import type { BatchFileItem } from './upload-types'
|
||
import { BATCH_LIMITS } from './upload-constants'
|
||
import { isValidMainFileType, extractSpuFromFileName } from './upload-utils'
|
||
import { requiresRenderer, shouldAutoFillGeneral } from '@/lib/material-validation'
|
||
import { isBatchVideoMaterialType } from '@/lib/video-material-types'
|
||
import { isLiveClipType } from '@/lib/live-clip'
|
||
|
||
/**
|
||
* 获取批量上传限制
|
||
*/
|
||
export function getBatchLimit(materialType: string): number {
|
||
if (materialType === '音乐') return BATCH_LIMITS.music
|
||
if (isLiveClipType(materialType)) return 20
|
||
if (isBatchVideoMaterialType(materialType)) return BATCH_LIMITS.video
|
||
if (materialType === '3D场景') return BATCH_LIMITS['3d']
|
||
if (materialType === '品牌VI灵感') return BATCH_LIMITS.brandVI
|
||
return Infinity
|
||
}
|
||
|
||
/**
|
||
* 处理批量文件添加
|
||
*/
|
||
export function createBatchFileItems(
|
||
files: File[],
|
||
materialType: string,
|
||
categoryName: string,
|
||
sceneName: string,
|
||
platformName: string,
|
||
productCategoryName: string,
|
||
renderer: string
|
||
): BatchFileItem[] {
|
||
const isLiveClip = isLiveClipType(materialType)
|
||
return files.map((file, index) => {
|
||
const extractedSpu = isLiveClip
|
||
? file.name.replace(/\.[^.]+$/, '')
|
||
: extractSpuFromFileName(file.name)
|
||
|
||
return {
|
||
id: `${Date.now()}-${index}`,
|
||
file,
|
||
// 首项默认展开;无法确认 SPU 的项也立即展开,避免错误被折叠隐藏。
|
||
expanded: index === 0 || !extractedSpu,
|
||
productModel: extractedSpu,
|
||
productModelSource: extractedSpu ? 'filename' : undefined, // 从文件名提取的SPU,优先级最低,可被覆盖
|
||
categoryName: shouldAutoFillGeneral(materialType) ? '通用' : categoryName,
|
||
sceneName: shouldAutoFillGeneral(materialType) ? '通用' : sceneName,
|
||
platformName: platformName,
|
||
productCategoryName: productCategoryName,
|
||
renderer: requiresRenderer(materialType) ? renderer : undefined,
|
||
}
|
||
})
|
||
}
|
||
|
||
/**
|
||
* 验证并过滤文件
|
||
*/
|
||
export function validateAndFilterFiles(
|
||
files: File[],
|
||
materialType: string
|
||
): { valid: File[]; invalid: File[] } {
|
||
const valid: File[] = []
|
||
const invalid: File[] = []
|
||
|
||
for (const file of files) {
|
||
if (isValidMainFileType(file, materialType)) {
|
||
valid.push(file)
|
||
} else {
|
||
invalid.push(file)
|
||
}
|
||
}
|
||
|
||
return { valid, invalid }
|
||
}
|
||
|
||
/**
|
||
* 创建单文件转批量文件的项
|
||
*/
|
||
export function createBatchItemFromSingleFile(
|
||
file: File,
|
||
materialType: string,
|
||
categoryName: string,
|
||
sceneName: string,
|
||
platformName: string,
|
||
productCategoryName: string,
|
||
renderer: string
|
||
): BatchFileItem {
|
||
const extractedSpu = extractSpuFromFileName(file.name)
|
||
|
||
return {
|
||
id: `${Date.now()}-0`,
|
||
file,
|
||
expanded: true,
|
||
productModel: extractedSpu,
|
||
productModelSource: extractedSpu ? 'filename' : undefined, // 从文件名提取的SPU,优先级最低,可被覆盖
|
||
categoryName: shouldAutoFillGeneral(materialType) ? '通用' : categoryName,
|
||
sceneName: shouldAutoFillGeneral(materialType) ? '通用' : sceneName,
|
||
platformName: platformName,
|
||
productCategoryName: productCategoryName,
|
||
renderer: requiresRenderer(materialType) ? renderer : undefined,
|
||
}
|
||
}
|
||
|