feat(admin): family-aware goods view - auto tags readonly, clean link names, config badges, locate highlight
This commit is contained in:
@@ -1,5 +1,11 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import { sameOriginGroup, truncateToProcess } from './origin-name';
|
||||
import {
|
||||
cleanLinkName,
|
||||
deriveLinkTagNames,
|
||||
parseLinkName,
|
||||
sameOriginGroup,
|
||||
truncateToProcess,
|
||||
} from './origin-name';
|
||||
|
||||
describe('truncateToProcess', () => {
|
||||
it('keeps first 3 dash segments (drops warehouse)', () => {
|
||||
@@ -44,3 +50,59 @@ describe('sameOriginGroup', () => {
|
||||
expect(sameOriginGroup('', '')).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('parseLinkName / cleanLinkName', () => {
|
||||
it('parses 国家(物流)品名-SKU-工艺 → 品名 + 型号', () => {
|
||||
expect(parseLinkName('美国(包邮)180g纯棉T恤成人款-DG001-单面印花')).toEqual({
|
||||
productName: '180g纯棉T恤成人款',
|
||||
skuCode: 'DG001',
|
||||
});
|
||||
expect(cleanLinkName('美国(包邮)180g纯棉T恤成人款-DG001-单面印花')).toBe(
|
||||
'180g纯棉T恤成人款 DG001',
|
||||
);
|
||||
});
|
||||
|
||||
it('handles half-width parens and warehouse suffix', () => {
|
||||
expect(
|
||||
cleanLinkName('美国(不包邮光板)180GT恤成人款-JSA002-不打印·美西洛杉矶二仓'),
|
||||
).toBe('180GT恤成人款 JSA002');
|
||||
});
|
||||
|
||||
it('returns null / raw fallback for manual names without the country(remark) structure', () => {
|
||||
expect(parseLinkName('180g纯棉T恤成人款')).toBeNull();
|
||||
expect(cleanLinkName('180g纯棉T恤成人款')).toBe('180g纯棉T恤成人款');
|
||||
expect(cleanLinkName(null)).toBe('');
|
||||
});
|
||||
|
||||
it('returns null when product name after parens is empty', () => {
|
||||
expect(parseLinkName('美国(包邮)-DG001-单面印花')).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
describe('deriveLinkTagNames', () => {
|
||||
it('单面印花 + 包邮 + 无工艺关键字 → 单面印花/烫画/包邮', () => {
|
||||
expect(deriveLinkTagNames('美国(包邮)180g纯棉T恤成人款-DG001-单面印花')).toEqual([
|
||||
'单面印花',
|
||||
'烫画',
|
||||
'包邮',
|
||||
]);
|
||||
});
|
||||
|
||||
it('不打印 + 光板 + 不包邮 → 两工艺标签 + 不包邮', () => {
|
||||
expect(
|
||||
deriveLinkTagNames('美国(不包邮光板)180GT恤成人款-JSA002-不打印·美西洛杉矶二仓'),
|
||||
).toEqual(['不打印', '光板', '不包邮']);
|
||||
});
|
||||
|
||||
it('双面印花 + 不包邮,且不误命中包邮', () => {
|
||||
expect(deriveLinkTagNames('美国(不包邮)T恤-DG001-双面印花·美东新泽西仓')).toEqual([
|
||||
'双面印花',
|
||||
'烫画',
|
||||
'不包邮',
|
||||
]);
|
||||
});
|
||||
|
||||
it('空名称返回空数组', () => {
|
||||
expect(deriveLinkTagNames(null)).toEqual([]);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -18,3 +18,54 @@ export function sameOriginGroup(
|
||||
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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user