Files
dukang/apps/mini-user/src/lib/store-display.ts
T
jacy fe557c912d
CI / verify (pull_request) Waiting to run
v4.0.9版本更新-门店分类支持多选
2026-09-02 11:12:51 +08:00

156 lines
4.4 KiB
TypeScript

export type StoreCategoryLike = {
id?: string;
name?: string;
parentId?: string | null;
parent?: { name?: string } | null;
};
export type StoreCategoryTreeNode = {
id: string;
name: string;
children?: { id: string; name: string }[];
};
export function storeStarCount(rating?: number | string | null): number {
const n = Number(rating);
if (!Number.isFinite(n) || n <= 0) return 5;
return Math.min(5, Math.max(1, Math.round(n)));
}
export function storeCategoryTags(
store: {
tags?: unknown;
categoryId?: string | null;
category?: StoreCategoryLike | null;
categories?: StoreCategoryLike[] | null;
},
tree: StoreCategoryTreeNode[] = [],
): string[] {
const fromJson = Array.isArray(store.tags)
? store.tags.map((t) => String(t).trim()).filter(Boolean)
: [];
if (fromJson.length) return fromJson;
const multi = Array.isArray(store.categories) ? store.categories : [];
if (multi.length) {
return groupCategoryTags(multi, tree);
}
if (store.category || store.categoryId) {
const grouped = groupCategoryTags(
store.category ? [store.category] : [],
tree,
store.categoryId,
);
if (grouped.length) return grouped;
}
const storeCatId = String(store.categoryId || '');
if (storeCatId) {
for (const root of tree) {
for (const child of root.children ?? []) {
if (child.id === storeCatId) {
return [`${root.name}|${child.name}`];
}
}
}
}
return [];
}
/** 按大类分组:餐饮|火锅·江浙菜、娱乐|KTV */
function groupCategoryTags(
categories: StoreCategoryLike[],
tree: StoreCategoryTreeNode[] = [],
fallbackCategoryId?: string | null,
): string[] {
if (!categories.length && fallbackCategoryId) {
return groupCategoryTags([{ id: String(fallbackCategoryId) }], tree);
}
const groups = new Map<string, { parentName: string; children: string[] }>();
const order: string[] = [];
for (const cat of categories) {
const resolved = resolveCategoryParts(cat, tree);
if (!resolved) continue;
const { parentKey, parentName, childName } = resolved;
if (!groups.has(parentKey)) {
groups.set(parentKey, { parentName, children: [] });
order.push(parentKey);
}
const group = groups.get(parentKey)!;
if (childName && childName !== parentName && !group.children.includes(childName)) {
group.children.push(childName);
}
}
return order
.map((key) => {
const group = groups.get(key)!;
if (group.parentName && group.children.length) {
return `${group.parentName}|${group.children.join('·')}`;
}
if (group.children.length) return group.children.join('·');
return group.parentName;
})
.filter(Boolean);
}
function resolveCategoryParts(
cat: StoreCategoryLike,
tree: StoreCategoryTreeNode[] = [],
): { parentKey: string; parentName: string; childName: string } | null {
const childName = String(cat.name || '').trim();
let parentName = String(cat.parent?.name || '').trim();
const catId = String(cat.id || '');
const parentId = String(cat.parentId || '');
if (!parentName && (parentId || catId)) {
for (const root of tree) {
if (parentId && root.id === parentId) {
parentName = root.name;
break;
}
for (const child of root.children ?? []) {
if (catId && child.id === catId) {
parentName = root.name;
if (!childName) return { parentKey: root.id, parentName, childName: child.name };
break;
}
}
}
}
if (!childName && !parentName) return null;
const parentKey = parentId || parentName || catId;
if (!parentName && catId) {
for (const root of tree) {
for (const child of root.children ?? []) {
if (child.id === catId) {
return { parentKey: root.id, parentName: root.name, childName: child.name };
}
}
}
}
return {
parentKey,
parentName: parentName || childName,
childName: childName || parentName,
};
}
export function storeLeafCategoryIds(store: {
categoryId?: string | null;
category?: StoreCategoryLike | null;
categories?: StoreCategoryLike[] | null;
}): string[] {
if (Array.isArray(store.categories) && store.categories.length) {
return store.categories.map((c) => String(c.id || '')).filter(Boolean);
}
const id = String(store.categoryId || store.category?.id || '');
return id ? [id] : [];
}