263 lines
8.3 KiB
TypeScript
263 lines
8.3 KiB
TypeScript
export type StandardFieldConfig = {
|
||
key: string
|
||
label: string
|
||
type: string
|
||
required: boolean
|
||
layoutWidth: string
|
||
visibleOnHomeFilter: boolean
|
||
isSearchable: boolean
|
||
addToCategory?: boolean
|
||
optionsStatic?: string
|
||
isReadOnly?: boolean
|
||
}
|
||
|
||
export const BUILTIN_TEMPLATE_KEYS = [
|
||
'3dmax-material',
|
||
'psd-material',
|
||
'audio-material',
|
||
'video-material',
|
||
'model-material',
|
||
'other-material',
|
||
] as const
|
||
|
||
export const BUILTIN_TEMPLATE_NAMES: Record<string, string> = {
|
||
'3dmax-material': '3DMAX 素材模板',
|
||
'psd-material': 'PSD 素材模板',
|
||
'audio-material': '音频素材模板',
|
||
'video-material': '视频素材模板',
|
||
'model-material': '模特素材模板',
|
||
'other-material': '其他素材模板',
|
||
}
|
||
|
||
export const BUILTIN_TEMPLATE_DESCRIPTIONS: Record<string, string> = {
|
||
'3dmax-material': '适用于 3D 模型类素材,覆盖渲染器、SKU 与品牌等核心字段。',
|
||
'psd-material': '针对平面设计 PSD 素材,包含品牌、颜色模式和输出分辨率。',
|
||
'audio-material': '适用于音频文件素材,支持 MP3、WAV、FLAC、AAC 等格式。',
|
||
'video-material': '适用于视频文件素材。',
|
||
'model-material': '用于模特/人像素材,关注拍摄场景与负责作者。',
|
||
'other-material': '适用于其他类型的素材。',
|
||
}
|
||
|
||
export const BUILTIN_TEMPLATE_TYPES: Record<string, string> = {
|
||
'3dmax-material': '3DMAX',
|
||
'psd-material': 'PSD',
|
||
'audio-material': '音频',
|
||
'video-material': '视频',
|
||
'model-material': '模特',
|
||
'other-material': '其他',
|
||
}
|
||
|
||
export const BUILTIN_TEMPLATE_KINDS: Record<string, 'IMAGE' | 'VIDEO' | 'AUDIO' | 'OTHER'> = {
|
||
'3dmax-material': 'IMAGE',
|
||
'psd-material': 'IMAGE',
|
||
'audio-material': 'AUDIO',
|
||
'video-material': 'VIDEO',
|
||
'model-material': 'IMAGE',
|
||
'other-material': 'OTHER',
|
||
}
|
||
|
||
// 注意:下拉选项字段的 optionsStatic 不再硬编码默认值
|
||
// 用户可以在后台分类管理中自由添加/删除选项
|
||
export const STANDARD_FIELDS: Record<string, StandardFieldConfig> = {
|
||
productModel: { key: 'productModel', label: 'SPU型号', type: 'text', required: true, layoutWidth: 'full', visibleOnHomeFilter: false, isSearchable: true },
|
||
categoryName: {
|
||
key: 'categoryName',
|
||
label: '使用店铺',
|
||
type: 'select',
|
||
required: false,
|
||
layoutWidth: 'full',
|
||
visibleOnHomeFilter: true,
|
||
isSearchable: true,
|
||
addToCategory: true,
|
||
},
|
||
sceneName: {
|
||
key: 'sceneName',
|
||
label: '场景类别',
|
||
type: 'select',
|
||
required: false,
|
||
layoutWidth: 'full',
|
||
visibleOnHomeFilter: true,
|
||
isSearchable: true,
|
||
addToCategory: true,
|
||
},
|
||
platformName: {
|
||
key: 'platformName',
|
||
label: '平台分类',
|
||
type: 'text',
|
||
required: false,
|
||
layoutWidth: 'half',
|
||
visibleOnHomeFilter: false,
|
||
isSearchable: true,
|
||
},
|
||
renderer: {
|
||
key: 'renderer',
|
||
label: '渲染器',
|
||
type: 'select',
|
||
required: false,
|
||
layoutWidth: 'full',
|
||
visibleOnHomeFilter: false,
|
||
isSearchable: true,
|
||
addToCategory: true,
|
||
},
|
||
brandName: {
|
||
key: 'brandName',
|
||
label: '品牌名称',
|
||
type: 'text',
|
||
required: false,
|
||
layoutWidth: 'half',
|
||
visibleOnHomeFilter: false,
|
||
isSearchable: true,
|
||
},
|
||
seriesName: {
|
||
key: 'seriesName',
|
||
label: '系列/产品线',
|
||
type: 'text',
|
||
required: false,
|
||
layoutWidth: 'half',
|
||
visibleOnHomeFilter: false,
|
||
isSearchable: true,
|
||
},
|
||
skuCode: { key: 'skuCode', label: 'SKU编码', type: 'text', required: false, layoutWidth: 'half', visibleOnHomeFilter: false, isSearchable: true },
|
||
materialTexture: {
|
||
key: 'materialTexture',
|
||
label: '材质/工艺',
|
||
type: 'text',
|
||
required: false,
|
||
layoutWidth: 'half',
|
||
visibleOnHomeFilter: false,
|
||
isSearchable: true,
|
||
},
|
||
renderTime: { key: 'renderTime', label: '渲染耗时', type: 'text', required: false, layoutWidth: 'half', visibleOnHomeFilter: false, isSearchable: false },
|
||
imageResolution: { key: 'imageResolution', label: '输出分辨率', type: 'text', required: false, layoutWidth: 'half', visibleOnHomeFilter: false, isSearchable: false },
|
||
colorMode: { key: 'colorMode', label: '颜色模式', type: 'text', required: false, layoutWidth: 'half', visibleOnHomeFilter: false, isSearchable: false },
|
||
authorName: { key: 'authorName', label: '作者', type: 'text', required: false, layoutWidth: 'half', visibleOnHomeFilter: false, isSearchable: true },
|
||
audioDuration: { key: 'audioDuration', label: '时长', type: 'text', required: false, layoutWidth: 'half', visibleOnHomeFilter: false, isSearchable: false, isReadOnly: true },
|
||
audioCategory: {
|
||
key: 'audioCategory',
|
||
label: '音频分类',
|
||
type: 'select',
|
||
required: true,
|
||
layoutWidth: 'full',
|
||
visibleOnHomeFilter: true,
|
||
isSearchable: true,
|
||
addToCategory: true,
|
||
},
|
||
audioScene: {
|
||
key: 'audioScene',
|
||
label: '音频使用场景',
|
||
type: 'select',
|
||
required: true,
|
||
layoutWidth: 'full',
|
||
visibleOnHomeFilter: true,
|
||
isSearchable: true,
|
||
addToCategory: true,
|
||
},
|
||
}
|
||
|
||
export const BASE_TEMPLATE_FIELDS = ['productModel', 'categoryName', 'sceneName'] as const
|
||
|
||
export const BUILTIN_TEMPLATE_FIELDS: Record<string, string[]> = {
|
||
'3dmax-material': ['productModel', 'categoryName', 'sceneName', 'renderer'],
|
||
'psd-material': [...BASE_TEMPLATE_FIELDS],
|
||
'audio-material': ['productModel', 'audioCategory', 'audioScene', 'authorName'],
|
||
'video-material': [...BASE_TEMPLATE_FIELDS],
|
||
'model-material': [...BASE_TEMPLATE_FIELDS],
|
||
'other-material': [...BASE_TEMPLATE_FIELDS],
|
||
}
|
||
|
||
export type BuiltinTemplateField = {
|
||
id: string
|
||
key: string
|
||
label: string
|
||
type: string
|
||
required: boolean
|
||
orderIndex: number
|
||
layoutWidth?: string | null
|
||
validations: null
|
||
optionsSource: null
|
||
optionsStatic: string | null
|
||
allowedExtensions: null
|
||
visibleOnHomeFilter: boolean
|
||
isSearchable: boolean
|
||
isReadOnly?: boolean
|
||
addToCategory?: boolean
|
||
conditions: null
|
||
}
|
||
|
||
export type BuiltinTemplate = {
|
||
id: string
|
||
name: string
|
||
description: string
|
||
status: 'active'
|
||
materialType: string
|
||
materialKind: 'IMAGE' | 'VIDEO' | 'AUDIO' | 'OTHER'
|
||
isBuiltin: true
|
||
fields: BuiltinTemplateField[]
|
||
}
|
||
|
||
export function createBuiltinTemplate(key: string): BuiltinTemplate {
|
||
const fields = BUILTIN_TEMPLATE_FIELDS[key] || []
|
||
const requireRenderer = key === '3dmax-material'
|
||
const isAudioTemplate = key === 'audio-material'
|
||
|
||
const overrides: Record<
|
||
string,
|
||
Partial<{
|
||
required: boolean
|
||
visibleOnHomeFilter: boolean
|
||
isSearchable: boolean
|
||
label: string
|
||
}>
|
||
> = {
|
||
productModel: { required: true, isSearchable: true },
|
||
categoryName: { required: true, visibleOnHomeFilter: true, isSearchable: true },
|
||
sceneName: { required: true, visibleOnHomeFilter: true, isSearchable: true },
|
||
}
|
||
|
||
if (requireRenderer) {
|
||
overrides.renderer = { required: true, isSearchable: true }
|
||
}
|
||
|
||
// 音频模板的字段标签覆盖
|
||
if (isAudioTemplate) {
|
||
overrides.productModel = { ...overrides.productModel, label: '音频名称' }
|
||
// audioCategory 和 audioScene 是独立字段,不需要覆盖
|
||
}
|
||
|
||
return {
|
||
id: `builtin-${key}`,
|
||
name: BUILTIN_TEMPLATE_NAMES[key] || key,
|
||
description: BUILTIN_TEMPLATE_DESCRIPTIONS[key] || '',
|
||
status: 'active',
|
||
materialType: BUILTIN_TEMPLATE_TYPES[key] || '其他',
|
||
materialKind: BUILTIN_TEMPLATE_KINDS[key] || 'IMAGE',
|
||
isBuiltin: true,
|
||
fields: fields
|
||
.map((fieldKey, index) => {
|
||
const fieldConfig = STANDARD_FIELDS[fieldKey]
|
||
if (!fieldConfig) return null
|
||
const override = overrides[fieldKey] || {}
|
||
return {
|
||
id: `builtin-${key}-${fieldKey}`,
|
||
key: fieldConfig.key,
|
||
label: override.label ?? fieldConfig.label,
|
||
type: fieldConfig.type,
|
||
required: override.required ?? fieldConfig.required,
|
||
orderIndex: index,
|
||
layoutWidth: fieldConfig.layoutWidth,
|
||
validations: null,
|
||
optionsSource: null,
|
||
optionsStatic: fieldConfig.optionsStatic || null,
|
||
allowedExtensions: null,
|
||
visibleOnHomeFilter: override.visibleOnHomeFilter ?? fieldConfig.visibleOnHomeFilter ?? false,
|
||
isSearchable: override.isSearchable ?? fieldConfig.isSearchable ?? false,
|
||
isReadOnly: fieldConfig.isReadOnly ?? false,
|
||
addToCategory: fieldConfig.addToCategory ?? false,
|
||
conditions: null,
|
||
}
|
||
})
|
||
.filter(Boolean) as BuiltinTemplateField[],
|
||
}
|
||
}
|
||
|