import { toBottleQuantity } from '@dukang/domain'; const GOODS_NAME_MAX_LEN = 128; export type XfxGoodsInput = { productName: string; /** SKU 规格快照,如「单瓶 / 整箱」 */ productSpec?: string | null; /** SPU 物理规格,如「500ml | 53度」 */ physicalSpec?: string | null; quantity: number; bottlesPerUnit: number; }; export type XfxGoodsPayload = { goodsName: string; goodsNum: number; }; /** 小飞侠创建运单货品:品名+酒精度规格,件数用瓶当量 */ export function buildXfxGoodsPayload(input: XfxGoodsInput): XfxGoodsPayload { const perUnit = input.bottlesPerUnit > 0 ? input.bottlesPerUnit : 1; return { goodsName: buildXfxGoodsName(input), goodsNum: toBottleQuantity(input.quantity, perUnit), }; } function buildXfxGoodsName(input: XfxGoodsInput): string { const name = trimSpec(input.productName); const physical = trimSpec(input.physicalSpec); const skuSpec = trimSpec(input.productSpec); const parts: string[] = []; if (name) parts.push(name); if (physical) { parts.push(physical); if (skuSpec && !isRedundantSpec(physical, skuSpec)) { parts.push(skuSpec); } } else if (skuSpec) { parts.push(skuSpec); } return parts.join(' ').replace(/\s+/g, ' ').trim().slice(0, GOODS_NAME_MAX_LEN); } function trimSpec(raw?: string | null): string { return (raw ?? '').trim(); } function isRedundantSpec(physical: string, skuSpec: string): boolean { const a = physical.replace(/\s+/g, ''); const b = skuSpec.replace(/\s+/g, ''); if (!b || a === b) return true; return a.includes(b) || b.includes(a); }