refactor(admin): split GoodsView into dialog components; fix(GoodsView): raw member names, no primary badges, member price grid; feat(tag): 光板 maps to 不打印
This commit is contained in:
@@ -0,0 +1,28 @@
|
||||
import type { CategoryTree } from '@/types'
|
||||
|
||||
/** 在分类树中找目标分类的祖先路径(含自身) */
|
||||
export function findCategoryPath(nodes: CategoryTree[], targetId: string): string[] {
|
||||
for (const n of nodes) {
|
||||
if (n.id === targetId) return [n.id]
|
||||
if (n.children?.length) {
|
||||
const sub = findCategoryPath(n.children, targetId)
|
||||
if (sub.length) return [n.id, ...sub]
|
||||
}
|
||||
}
|
||||
return []
|
||||
}
|
||||
|
||||
export interface CascadeNode {
|
||||
value: string
|
||||
label: string
|
||||
children?: CascadeNode[]
|
||||
}
|
||||
|
||||
/** 分类树 → el-cascader 选项 */
|
||||
export function buildCascader(tree: CategoryTree[]): CascadeNode[] {
|
||||
return tree.map((n) => ({
|
||||
value: n.id,
|
||||
label: n.categoryName,
|
||||
children: n.children?.length ? buildCascader(n.children) : undefined,
|
||||
}))
|
||||
}
|
||||
@@ -89,10 +89,10 @@ describe('deriveLinkTagNames', () => {
|
||||
]);
|
||||
});
|
||||
|
||||
it('不打印 + 光板 + 不包邮 → 两工艺标签 + 不包邮', () => {
|
||||
it('不打印 + 光板 + 不包邮 → 归并为单个不打印(光板即不打印)', () => {
|
||||
expect(
|
||||
deriveLinkTagNames('美国(不包邮光板)180GT恤成人款-JSA002-不打印·美西洛杉矶二仓'),
|
||||
).toEqual(['不打印', '光板', '不包邮']);
|
||||
).toEqual(['不打印', '不包邮']);
|
||||
});
|
||||
|
||||
it('双面印花 + 不包邮,且不误命中包邮', () => {
|
||||
@@ -117,7 +117,7 @@ describe('linkDims', () => {
|
||||
});
|
||||
expect(linkDims('美国(不包邮光板)180GT恤成人款-JSA002-不打印·美西洛杉矶二仓')).toEqual({
|
||||
logistics: '不包邮光板',
|
||||
crafts: ['不打印', '光板'],
|
||||
crafts: ['不打印'],
|
||||
printCount: null,
|
||||
});
|
||||
});
|
||||
|
||||
@@ -50,7 +50,11 @@ export function cleanLinkName(name: string | null | undefined): string {
|
||||
return parsed.skuCode ? `${parsed.productName} ${parsed.skuCode}` : parsed.productName;
|
||||
}
|
||||
|
||||
const CRAFT_KEYWORDS = ['直喷', '不打印', '光板'] as const;
|
||||
const CRAFT_KEYWORD_MAP: Record<string, string> = {
|
||||
直喷: '直喷',
|
||||
不打印: '不打印',
|
||||
光板: '不打印', // 光板即为不打印
|
||||
};
|
||||
|
||||
/** 链接的定价维度(SKU 表展示用):物流备注 / 工艺 / 印花数量 */
|
||||
export interface LinkDims {
|
||||
@@ -68,7 +72,7 @@ export function linkDims(name: string | null | undefined): LinkDims {
|
||||
const closeIdx = Math.max(head.lastIndexOf(')'), head.lastIndexOf(')'));
|
||||
const logistics =
|
||||
openIdx >= 0 && closeIdx > openIdx ? head.slice(openIdx + 1, closeIdx).trim() || null : null;
|
||||
const craftHits = CRAFT_KEYWORDS.filter((k) => name.includes(k));
|
||||
const craftHits = [...new Set(Object.entries(CRAFT_KEYWORD_MAP).filter(([k]) => name.includes(k)).map(([, tag]) => tag))];
|
||||
const printCount = name.includes('双面印花')
|
||||
? '双面印花'
|
||||
: name.includes('单面印花')
|
||||
@@ -83,7 +87,7 @@ export function linkDims(name: string | null | undefined): LinkDims {
|
||||
|
||||
/**
|
||||
* 由链接名称派生标签名(与 api 端 auto-tag-rules.ts 规则一致,仅用于成员行只读展示):
|
||||
* 印花数量:双面印花 优先于 单面印花;工艺:直喷/不打印/光板,皆无则默认烫画;
|
||||
* 印花数量:双面印花 优先于 单面印花;工艺:直喷/不打印/光板→不打印,皆无则默认烫画;
|
||||
* 物流:不包邮 优先于 包邮。
|
||||
*/
|
||||
export function deriveLinkTagNames(name: string | null | undefined): string[] {
|
||||
@@ -91,7 +95,7 @@ export function deriveLinkTagNames(name: string | null | undefined): string[] {
|
||||
const names: string[] = [];
|
||||
if (name.includes('双面印花')) names.push('双面印花');
|
||||
else if (name.includes('单面印花')) names.push('单面印花');
|
||||
const craftHits = CRAFT_KEYWORDS.filter((k) => name.includes(k));
|
||||
const craftHits = [...new Set(Object.entries(CRAFT_KEYWORD_MAP).filter(([k]) => name.includes(k)).map(([, tag]) => tag))];
|
||||
if (craftHits.length > 0) names.push(...craftHits);
|
||||
else names.push('烫画');
|
||||
if (name.includes('不包邮')) names.push('不包邮');
|
||||
|
||||
Reference in New Issue
Block a user