feat(consignment): 后台寄卖规格按分类模板动态渲染
This commit is contained in:
@@ -62,6 +62,11 @@ import { fetchAdminSession } from '@/services/admin/auth'
|
||||
import { resolveAdminPermission } from '@/utils/admin-auth'
|
||||
import { formatConsignmentContactSupporter } from '@/utils/consignment-contact'
|
||||
import { describeGiftEvidence, resolveGiftEvidenceBadge } from '@/utils/consignment-evidence'
|
||||
import {
|
||||
CONSIGNMENT_SPEC_TAG_COLORS,
|
||||
resolveConsignmentSpecDisplayItems,
|
||||
resolveConsignmentSpecText,
|
||||
} from '@/utils/consignment-spec-display'
|
||||
import { CONSIGNMENT_SYSTEM_OPTIONS, CONSIGNMENT_ZONE_OPTIONS } from '@/utils/consignment-spec'
|
||||
import { formatDateTime } from '@/utils/date-time'
|
||||
|
||||
@@ -301,14 +306,21 @@ export default function ConsignmentInventoryPanel() {
|
||||
? Math.round(Number(values.depositAmount) * 100)
|
||||
: undefined
|
||||
const selectedWorker = workerOptions.find((w) => w.value === values.workerId)
|
||||
// 有动态规格时规格值走 specValues(后端据此重算 spec_text),旧列不再写,
|
||||
// 否则密钥这类只有「商品」的分类会被顺手写成 1钻0璀璨。
|
||||
const hasDynamicSpecs = Boolean(editingItem.specs?.length)
|
||||
|
||||
await updateAdminConsignmentInventory(editingItem.id, {
|
||||
itemName: values.itemName,
|
||||
system: values.system,
|
||||
serverZone: values.serverZone,
|
||||
series: values.series,
|
||||
diamondLevel: Number(values.diamondLevel || 1),
|
||||
brillianceCount: Number(values.brillianceCount || 0),
|
||||
...(hasDynamicSpecs
|
||||
? {}
|
||||
: {
|
||||
system: values.system,
|
||||
serverZone: values.serverZone,
|
||||
series: values.series,
|
||||
diamondLevel: Number(values.diamondLevel || 1),
|
||||
brillianceCount: Number(values.brillianceCount || 0),
|
||||
}),
|
||||
costPriceFen,
|
||||
salePriceFen:
|
||||
values.salePrice !== undefined
|
||||
@@ -471,28 +483,46 @@ export default function ConsignmentInventoryPanel() {
|
||||
),
|
||||
},
|
||||
{
|
||||
title: '和平精英规格',
|
||||
title: '寄卖规格',
|
||||
key: 'specs',
|
||||
width: 200,
|
||||
render: (_, record) => (
|
||||
<Space direction="vertical" size={2}>
|
||||
<div>
|
||||
<Tag color={record.system === '苹果' ? 'geekblue' : 'green'}>
|
||||
{record.system || '通用'}
|
||||
</Tag>
|
||||
<Tag color={record.serverZone === '微信区' ? 'success' : 'processing'}>
|
||||
{record.serverZone || '全区'}
|
||||
</Tag>
|
||||
</div>
|
||||
<div>
|
||||
<Tag color="orange">{record.series || '通用'}</Tag>
|
||||
<Tag color="gold">{record.diamondLevel} 钻</Tag>
|
||||
{record.brillianceCount > 0 ? (
|
||||
<Tag color="magenta">{record.brillianceCount} 璀璨</Tag>
|
||||
) : null}
|
||||
</div>
|
||||
</Space>
|
||||
),
|
||||
width: 220,
|
||||
render: (_, record) => {
|
||||
// 规格按该分类已发布的寄卖模板渲染;没有规格配置的历史库存才回退旧字段。
|
||||
const specItems = resolveConsignmentSpecDisplayItems(record.specs, record.specValues)
|
||||
if (specItems.length > 0) {
|
||||
return (
|
||||
<Space size={4} wrap>
|
||||
{specItems.map((item, index) => (
|
||||
<Tag
|
||||
key={item.key}
|
||||
color={CONSIGNMENT_SPEC_TAG_COLORS[index % CONSIGNMENT_SPEC_TAG_COLORS.length]}
|
||||
>
|
||||
{item.label} {item.value}
|
||||
</Tag>
|
||||
))}
|
||||
</Space>
|
||||
)
|
||||
}
|
||||
return (
|
||||
<Space direction="vertical" size={2}>
|
||||
<div>
|
||||
<Tag color={record.system === '苹果' ? 'geekblue' : 'green'}>
|
||||
{record.system || '通用'}
|
||||
</Tag>
|
||||
<Tag color={record.serverZone === '微信区' ? 'success' : 'processing'}>
|
||||
{record.serverZone || '全区'}
|
||||
</Tag>
|
||||
</div>
|
||||
<div>
|
||||
<Tag color="orange">{record.series || '通用'}</Tag>
|
||||
<Tag color="gold">{record.diamondLevel} 钻</Tag>
|
||||
{record.brillianceCount > 0 ? (
|
||||
<Tag color="magenta">{record.brillianceCount} 璀璨</Tag>
|
||||
) : null}
|
||||
</div>
|
||||
</Space>
|
||||
)
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '收购价',
|
||||
@@ -1047,34 +1077,36 @@ export default function ConsignmentInventoryPanel() {
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
<Row gutter={16}>
|
||||
<Col span={5}>
|
||||
<Form.Item name="system" label="系统">
|
||||
{/* 后台全量选项:系统 苹果/安卓/通用,区服 微信/QQ/互通(互通=QQ/微信都能收) */}
|
||||
<Select options={[...CONSIGNMENT_SYSTEM_OPTIONS]} />
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col span={5}>
|
||||
<Form.Item name="serverZone" label="区服">
|
||||
<Select options={[...CONSIGNMENT_ZONE_OPTIONS]} />
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col span={5}>
|
||||
<Form.Item name="series" label="系列">
|
||||
<Input />
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col span={5}>
|
||||
<Form.Item name="diamondLevel" label="钻石等级 (1-7)">
|
||||
<InputNumber min={1} max={7} style={{ width: '100%' }} />
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col span={4}>
|
||||
<Form.Item name="brillianceCount" label="璀璨数 (0-7)">
|
||||
<InputNumber min={0} max={7} style={{ width: '100%' }} />
|
||||
</Form.Item>
|
||||
</Col>
|
||||
</Row>
|
||||
{editingItem?.specs?.length ? null : (
|
||||
<Row gutter={16}>
|
||||
<Col span={5}>
|
||||
<Form.Item name="system" label="系统">
|
||||
{/* 后台全量选项:系统 苹果/安卓/通用,区服 微信/QQ/互通(互通=QQ/微信都能收) */}
|
||||
<Select options={[...CONSIGNMENT_SYSTEM_OPTIONS]} />
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col span={5}>
|
||||
<Form.Item name="serverZone" label="区服">
|
||||
<Select options={[...CONSIGNMENT_ZONE_OPTIONS]} />
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col span={5}>
|
||||
<Form.Item name="series" label="系列">
|
||||
<Input />
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col span={5}>
|
||||
<Form.Item name="diamondLevel" label="钻石等级 (1-7)">
|
||||
<InputNumber min={1} max={7} style={{ width: '100%' }} />
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col span={4}>
|
||||
<Form.Item name="brillianceCount" label="璀璨数 (0-7)">
|
||||
<InputNumber min={0} max={7} style={{ width: '100%' }} />
|
||||
</Form.Item>
|
||||
</Col>
|
||||
</Row>
|
||||
)}
|
||||
|
||||
{editingItem?.specs?.length ? (
|
||||
<>
|
||||
@@ -1082,7 +1114,15 @@ export default function ConsignmentInventoryPanel() {
|
||||
<Row gutter={16}>
|
||||
{editingItem.specs.map((field) => (
|
||||
<Col span={8} key={field.key}>
|
||||
<Form.Item name={['specValues', field.key]} label={field.label}>
|
||||
<Form.Item
|
||||
name={['specValues', field.key]}
|
||||
label={field.label}
|
||||
rules={
|
||||
field.required
|
||||
? [{ required: true, message: `请填写「${field.label}」` }]
|
||||
: undefined
|
||||
}
|
||||
>
|
||||
{field.type === 'select' || field.type === 'radio' ? (
|
||||
field.type === 'radio' ? (
|
||||
<Radio.Group
|
||||
@@ -1254,8 +1294,7 @@ export default function ConsignmentInventoryPanel() {
|
||||
)}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="规格">
|
||||
{viewingItem.system} / {viewingItem.serverZone} / {viewingItem.series} /{' '}
|
||||
{viewingItem.diamondLevel}钻 ({viewingItem.brillianceCount}璀璨)
|
||||
{resolveConsignmentSpecText(viewingItem)}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="收购成本">
|
||||
<Text strong style={{ color: '#cf1322' }}>
|
||||
|
||||
@@ -12,6 +12,7 @@ import {
|
||||
Card,
|
||||
Col,
|
||||
Descriptions,
|
||||
Divider,
|
||||
Form,
|
||||
Input,
|
||||
InputNumber,
|
||||
@@ -43,6 +44,11 @@ import type { ConsignmentSubmission, GiftEvidenceReviewStatus } from '@/types/co
|
||||
import { resolveAdminPermission } from '@/utils/admin-auth'
|
||||
import { formatConsignmentContactSupporter } from '@/utils/consignment-contact'
|
||||
import { describeGiftEvidence, resolveGiftEvidenceBadge } from '@/utils/consignment-evidence'
|
||||
import {
|
||||
CONSIGNMENT_SPEC_TAG_COLORS,
|
||||
resolveConsignmentSpecDisplayItems,
|
||||
resolveConsignmentSpecText,
|
||||
} from '@/utils/consignment-spec-display'
|
||||
import { CONSIGNMENT_SYSTEM_OPTIONS, CONSIGNMENT_ZONE_OPTIONS } from '@/utils/consignment-spec'
|
||||
import { formatDateTime } from '@/utils/date-time'
|
||||
|
||||
@@ -154,6 +160,9 @@ export default function ConsignmentSubmissionsPanel() {
|
||||
? Math.round(Number(values.depositAmount) * 100)
|
||||
: undefined
|
||||
const selectedWorker = workerOptions.find((w) => w.value === values.workerId)
|
||||
// 有动态规格时规格值由 specValues 下发给后端推导 spec_text;
|
||||
// 旧的 系统/区服/系列/钻级/璀璨 列只是历史兼容,不能再写(否则密钥类目会被写成 1钻0璀璨)。
|
||||
const hasDynamicSpecs = Boolean(approveModalItem.specs?.length)
|
||||
|
||||
await approveAdminConsignmentSubmission(approveModalItem.id, {
|
||||
costPriceFen,
|
||||
@@ -161,11 +170,15 @@ export default function ConsignmentSubmissionsPanel() {
|
||||
shopName: values.shopName,
|
||||
inboundBatch: values.inboundBatch,
|
||||
itemName: values.itemName,
|
||||
system: values.system,
|
||||
serverZone: values.serverZone,
|
||||
series: values.series,
|
||||
diamondLevel: Number(values.diamondLevel || 1),
|
||||
brillianceCount: Number(values.brillianceCount || 0),
|
||||
...(hasDynamicSpecs
|
||||
? {}
|
||||
: {
|
||||
system: values.system,
|
||||
serverZone: values.serverZone,
|
||||
series: values.series,
|
||||
diamondLevel: Number(values.diamondLevel || 1),
|
||||
brillianceCount: Number(values.brillianceCount || 0),
|
||||
}),
|
||||
specValues:
|
||||
values.specValues && Object.keys(values.specValues).length
|
||||
? values.specValues
|
||||
@@ -229,21 +242,38 @@ export default function ConsignmentSubmissionsPanel() {
|
||||
{
|
||||
title: '提报物品规格',
|
||||
key: 'specs',
|
||||
width: 210,
|
||||
render: (_, record) => (
|
||||
<Space direction="vertical" size={2}>
|
||||
<div style={{ fontWeight: 600 }}>{record.itemName}</div>
|
||||
<Space size={4} wrap>
|
||||
<Tag color={record.system === '苹果' ? 'geekblue' : 'green'}>{record.system}</Tag>
|
||||
<Tag color="cyan">{record.serverZone}</Tag>
|
||||
<Tag color="orange">{record.series}</Tag>
|
||||
<Tag color="gold">{record.diamondLevel} 钻</Tag>
|
||||
{record.brillianceCount > 0 ? (
|
||||
<Tag color="magenta">{record.brillianceCount} 璀璨</Tag>
|
||||
) : null}
|
||||
width: 230,
|
||||
render: (_, record) => {
|
||||
// 规格按该分类已发布的寄卖模板渲染;没配置规格的历史提报才回退旧字段。
|
||||
const specItems = resolveConsignmentSpecDisplayItems(record.specs, record.specValues)
|
||||
return (
|
||||
<Space direction="vertical" size={2}>
|
||||
<div style={{ fontWeight: 600 }}>{record.itemName}</div>
|
||||
<Space size={4} wrap>
|
||||
{specItems.length > 0 ? (
|
||||
specItems.map((item, index) => (
|
||||
<Tag
|
||||
key={item.key}
|
||||
color={CONSIGNMENT_SPEC_TAG_COLORS[index % CONSIGNMENT_SPEC_TAG_COLORS.length]}
|
||||
>
|
||||
{item.label} {item.value}
|
||||
</Tag>
|
||||
))
|
||||
) : (
|
||||
<>
|
||||
<Tag color={record.system === '苹果' ? 'geekblue' : 'green'}>{record.system}</Tag>
|
||||
<Tag color="cyan">{record.serverZone}</Tag>
|
||||
<Tag color="orange">{record.series}</Tag>
|
||||
<Tag color="gold">{record.diamondLevel} 钻</Tag>
|
||||
{record.brillianceCount > 0 ? (
|
||||
<Tag color="magenta">{record.brillianceCount} 璀璨</Tag>
|
||||
) : null}
|
||||
</>
|
||||
)}
|
||||
</Space>
|
||||
</Space>
|
||||
</Space>
|
||||
),
|
||||
)
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '卖家报价',
|
||||
@@ -647,73 +677,85 @@ export default function ConsignmentSubmissionsPanel() {
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
<Row gutter={12}>
|
||||
<Col span={5}>
|
||||
<Form.Item name="system" label="系统" style={{ marginBottom: 16 }}>
|
||||
<Select options={[...CONSIGNMENT_SYSTEM_OPTIONS]} />
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col span={5}>
|
||||
<Form.Item name="serverZone" label="区服" style={{ marginBottom: 16 }}>
|
||||
<Select options={[...CONSIGNMENT_ZONE_OPTIONS]} />
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col span={5}>
|
||||
<Form.Item name="series" label="系列" style={{ marginBottom: 16 }}>
|
||||
<Input placeholder="如 暗潮" />
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col span={4}>
|
||||
<Form.Item name="diamondLevel" label="钻石等级" style={{ marginBottom: 16 }}>
|
||||
<InputNumber min={1} max={7} style={{ width: '100%' }} />
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col span={5}>
|
||||
<Form.Item name="brillianceCount" label="璀璨数" style={{ marginBottom: 16 }}>
|
||||
<InputNumber min={0} max={7} style={{ width: '100%' }} />
|
||||
</Form.Item>
|
||||
</Col>
|
||||
</Row>
|
||||
{approveModalItem?.specs?.length ? null : (
|
||||
<Row gutter={12}>
|
||||
<Col span={5}>
|
||||
<Form.Item name="system" label="系统" style={{ marginBottom: 16 }}>
|
||||
<Select options={[...CONSIGNMENT_SYSTEM_OPTIONS]} />
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col span={5}>
|
||||
<Form.Item name="serverZone" label="区服" style={{ marginBottom: 16 }}>
|
||||
<Select options={[...CONSIGNMENT_ZONE_OPTIONS]} />
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col span={5}>
|
||||
<Form.Item name="series" label="系列" style={{ marginBottom: 16 }}>
|
||||
<Input placeholder="如 暗潮" />
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col span={4}>
|
||||
<Form.Item name="diamondLevel" label="钻石等级" style={{ marginBottom: 16 }}>
|
||||
<InputNumber min={1} max={7} style={{ width: '100%' }} />
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col span={5}>
|
||||
<Form.Item name="brillianceCount" label="璀璨数" style={{ marginBottom: 16 }}>
|
||||
<InputNumber min={0} max={7} style={{ width: '100%' }} />
|
||||
</Form.Item>
|
||||
</Col>
|
||||
</Row>
|
||||
)}
|
||||
|
||||
{approveModalItem?.specs?.length ? (
|
||||
<Row gutter={12}>
|
||||
{approveModalItem.specs.map((field) => (
|
||||
<Col span={8} key={field.key}>
|
||||
<Form.Item
|
||||
name={['specValues', field.key]}
|
||||
label={field.label}
|
||||
style={{ marginBottom: 16 }}
|
||||
>
|
||||
{field.type === 'select' || field.type === 'radio' ? (
|
||||
field.type === 'radio' ? (
|
||||
<Radio.Group
|
||||
options={field.options
|
||||
.filter((option) => option.enabled !== false)
|
||||
.map((option) => ({ label: option.label, value: option.value }))}
|
||||
<>
|
||||
<Divider plain style={{ fontSize: 12, margin: '0 0 12px' }}>
|
||||
规格(按寄卖分类模板)
|
||||
</Divider>
|
||||
<Row gutter={12}>
|
||||
{approveModalItem.specs.map((field) => (
|
||||
<Col span={8} key={field.key}>
|
||||
<Form.Item
|
||||
name={['specValues', field.key]}
|
||||
label={field.label}
|
||||
rules={
|
||||
field.required
|
||||
? [{ required: true, message: `请填写「${field.label}」` }]
|
||||
: undefined
|
||||
}
|
||||
style={{ marginBottom: 16 }}
|
||||
>
|
||||
{field.type === 'select' || field.type === 'radio' ? (
|
||||
field.type === 'radio' ? (
|
||||
<Radio.Group
|
||||
options={field.options
|
||||
.filter((option) => option.enabled !== false)
|
||||
.map((option) => ({ label: option.label, value: option.value }))}
|
||||
/>
|
||||
) : (
|
||||
<Select
|
||||
options={field.options
|
||||
.filter((option) => option.enabled !== false)
|
||||
.map((option) => ({ label: option.label, value: option.value }))}
|
||||
/>
|
||||
)
|
||||
) : field.type === 'number' ? (
|
||||
<InputNumber style={{ width: '100%' }} />
|
||||
) : field.type === 'date' ? (
|
||||
<Input type="date" />
|
||||
) : field.type === 'textarea' ? (
|
||||
<Input.TextArea
|
||||
placeholder={field.placeholder || undefined}
|
||||
autoSize={{ minRows: 2, maxRows: 4 }}
|
||||
/>
|
||||
) : (
|
||||
<Select
|
||||
options={field.options
|
||||
.filter((option) => option.enabled !== false)
|
||||
.map((option) => ({ label: option.label, value: option.value }))}
|
||||
/>
|
||||
)
|
||||
) : field.type === 'number' ? (
|
||||
<InputNumber style={{ width: '100%' }} />
|
||||
) : field.type === 'date' ? (
|
||||
<Input type="date" />
|
||||
) : field.type === 'textarea' ? (
|
||||
<Input.TextArea
|
||||
placeholder={field.placeholder || undefined}
|
||||
autoSize={{ minRows: 2, maxRows: 4 }}
|
||||
/>
|
||||
) : (
|
||||
<Input placeholder={field.placeholder || undefined} />
|
||||
)}
|
||||
</Form.Item>
|
||||
</Col>
|
||||
))}
|
||||
</Row>
|
||||
<Input placeholder={field.placeholder || undefined} />
|
||||
)}
|
||||
</Form.Item>
|
||||
</Col>
|
||||
))}
|
||||
</Row>
|
||||
</>
|
||||
) : null}
|
||||
|
||||
{/* 分组二:履约与打手 */}
|
||||
@@ -888,9 +930,7 @@ export default function ConsignmentSubmissionsPanel() {
|
||||
{viewingSubmission.itemName}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="规格">
|
||||
{viewingSubmission.system} / {viewingSubmission.serverZone} /{' '}
|
||||
{viewingSubmission.series} / {viewingSubmission.diamondLevel}钻 (
|
||||
{viewingSubmission.brillianceCount}璀璨)
|
||||
{resolveConsignmentSpecText(viewingSubmission)}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="卖家报价">
|
||||
<Text strong style={{ color: '#cf1322' }}>
|
||||
|
||||
@@ -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