feat(consignment): 后台寄卖规格按分类模板动态渲染
This commit is contained in:
@@ -0,0 +1,90 @@
|
||||
import type { ConsignmentSpecField, ConsignmentSpecValues } from '../types/consignment'
|
||||
|
||||
export type ConsignmentSpecDisplayItem = {
|
||||
key: string
|
||||
label: string
|
||||
value: string
|
||||
}
|
||||
|
||||
/** 旧版内置规格字段(没有动态规格配置的历史分类才会用到)。 */
|
||||
export type ConsignmentLegacySpecRecord = {
|
||||
system?: string
|
||||
serverZone?: string
|
||||
series?: string
|
||||
diamondLevel?: number | null
|
||||
brillianceCount?: number | null
|
||||
}
|
||||
|
||||
/** 动态规格字段按模板顺序展示时的标签配色。 */
|
||||
export const CONSIGNMENT_SPEC_TAG_COLORS = [
|
||||
'geekblue',
|
||||
'cyan',
|
||||
'orange',
|
||||
'gold',
|
||||
'magenta',
|
||||
'green',
|
||||
]
|
||||
|
||||
/** 选项值统一按字符串匹配(配置里 value 是字符串,历史数据可能是数字)。 */
|
||||
function formatSpecValue(field: ConsignmentSpecField, raw: unknown): string {
|
||||
if (raw === undefined || raw === null) return ''
|
||||
const text = String(raw).trim()
|
||||
if (!text) return ''
|
||||
if (field.type === 'select' || field.type === 'radio') {
|
||||
const option = field.options?.find((item) => String(item.value) === text)
|
||||
return option?.label || text
|
||||
}
|
||||
return text
|
||||
}
|
||||
|
||||
/**
|
||||
* 按寄卖分类模板把 specValues 转成可展示的 {label, value}。
|
||||
*
|
||||
* 顺序与后端 buildConsignmentSpecText 保持一致(sortOrder 升序,其次 key),
|
||||
* 选项型字段把存储的选项值映射回选项名称(如 product=15 → 碎梦浮光珍宝礼盒)。
|
||||
*/
|
||||
export function resolveConsignmentSpecDisplayItems(
|
||||
specs: ConsignmentSpecField[] | null | undefined,
|
||||
values: ConsignmentSpecValues | null | undefined,
|
||||
): ConsignmentSpecDisplayItem[] {
|
||||
if (!specs || specs.length === 0) return []
|
||||
return [...specs]
|
||||
.sort((a, b) => (a.sortOrder ?? 0) - (b.sortOrder ?? 0) || a.key.localeCompare(b.key))
|
||||
.map((field) => ({
|
||||
key: field.key,
|
||||
label: field.label,
|
||||
value: formatSpecValue(field, values?.[field.key]),
|
||||
}))
|
||||
.filter((item) => item.value !== '')
|
||||
}
|
||||
|
||||
/** 旧版内置字段拼成一行(历史分类 & 历史数据兜底)。 */
|
||||
export function formatLegacyConsignmentSpec(record: ConsignmentLegacySpecRecord): string {
|
||||
const parts = [
|
||||
record.system,
|
||||
record.serverZone,
|
||||
record.series,
|
||||
record.diamondLevel ? `${record.diamondLevel}钻` : '',
|
||||
record.brillianceCount ? `${record.brillianceCount}璀璨` : '',
|
||||
]
|
||||
.map((part) => String(part ?? '').trim())
|
||||
.filter(Boolean)
|
||||
return parts.join(' / ')
|
||||
}
|
||||
|
||||
/**
|
||||
* 详情页规格文本:后端 specText 优先(已含选项名称),其次按模板现拼,最后回退旧字段。
|
||||
*/
|
||||
export function resolveConsignmentSpecText(
|
||||
input: {
|
||||
specText?: string
|
||||
specs?: ConsignmentSpecField[] | null
|
||||
specValues?: ConsignmentSpecValues | null
|
||||
} & ConsignmentLegacySpecRecord,
|
||||
): string {
|
||||
const specText = String(input.specText ?? '').trim()
|
||||
if (specText) return specText
|
||||
const items = resolveConsignmentSpecDisplayItems(input.specs, input.specValues)
|
||||
if (items.length > 0) return items.map((item) => `${item.label} ${item.value}`).join(' / ')
|
||||
return formatLegacyConsignmentSpec(input) || '-'
|
||||
}
|
||||
Reference in New Issue
Block a user