72 lines
2.9 KiB
TypeScript
72 lines
2.9 KiB
TypeScript
/**
|
||
* 原产品名匹配规则(见 data-cleaning/README.md 命名调查):
|
||
* `国家(物流备注)品名-SKU-工艺位置[-仓库名]`
|
||
* 截断到「工艺位置」= 保留按 `-` 分段的前 3 段,丢弃可选的仓库名段。
|
||
* 国家前缀在第 1 段内,天然参与比较(不同国家不合并)。
|
||
*/
|
||
const KEEP_SEGMENTS = 3;
|
||
|
||
export function truncateToProcess(name: string | null | undefined): string {
|
||
if (!name) return '';
|
||
return name.split('-').slice(0, KEEP_SEGMENTS).join('-');
|
||
}
|
||
|
||
export function sameOriginGroup(
|
||
a: string | null | undefined,
|
||
b: string | null | undefined,
|
||
): boolean {
|
||
const ka = truncateToProcess(a);
|
||
return ka !== '' && ka === truncateToProcess(b);
|
||
}
|
||
|
||
/** 链接名结构化解析结果:品名 + 型号(SKU 代码) */
|
||
export interface ParsedLinkName {
|
||
productName: string;
|
||
skuCode: string | null;
|
||
}
|
||
|
||
/**
|
||
* 解析链接名称:`国家(物流备注)品名-SKU-工艺位置[-·仓库名]` → 品名 + 型号。
|
||
* 与 api 端 origin-name.parser.ts 同构;解析失败(无「国家(备注)」前缀结构)返回 null,
|
||
* 调用方应回退显示原始名称 —— 手动维护的品名不走该解析。
|
||
*/
|
||
export function parseLinkName(name: string | null | undefined): ParsedLinkName | null {
|
||
if (!name) return null;
|
||
const segs = name.split('-').map((s) => s.trim());
|
||
const head = segs[0] ?? '';
|
||
const closeIdx = Math.max(head.lastIndexOf(')'), head.lastIndexOf(')'));
|
||
if (closeIdx <= 0 || closeIdx === head.length - 1) return null;
|
||
const productName = head.slice(closeIdx + 1).trim();
|
||
if (!productName) return null;
|
||
const skuCode = segs[1] || null;
|
||
return { productName, skuCode };
|
||
}
|
||
|
||
/** 展示名:`品名 型号`(如「180g纯棉T恤成人款 DG001」);解析失败回退原名 */
|
||
export function cleanLinkName(name: string | null | undefined): string {
|
||
if (!name) return '';
|
||
const parsed = parseLinkName(name);
|
||
if (!parsed) return name;
|
||
return parsed.skuCode ? `${parsed.productName} ${parsed.skuCode}` : parsed.productName;
|
||
}
|
||
|
||
const CRAFT_KEYWORDS = ['直喷', '不打印', '光板'] as const;
|
||
|
||
/**
|
||
* 由链接名称派生标签名(与 api 端 auto-tag-rules.ts 规则一致,仅用于成员行只读展示):
|
||
* 印花数量:双面印花 优先于 单面印花;工艺:直喷/不打印/光板,皆无则默认烫画;
|
||
* 物流:不包邮 优先于 包邮。
|
||
*/
|
||
export function deriveLinkTagNames(name: string | null | undefined): string[] {
|
||
if (!name) return [];
|
||
const names: string[] = [];
|
||
if (name.includes('双面印花')) names.push('双面印花');
|
||
else if (name.includes('单面印花')) names.push('单面印花');
|
||
const craftHits = CRAFT_KEYWORDS.filter((k) => name.includes(k));
|
||
if (craftHits.length > 0) names.push(...craftHits);
|
||
else names.push('烫画');
|
||
if (name.includes('不包邮')) names.push('不包邮');
|
||
else if (name.includes('包邮')) names.push('包邮');
|
||
return names;
|
||
}
|