Просмотр исходного кода

feat(web-admin): add product category tree expand helpers.

Centralize expand-id collection and child meta labels for the mp category list.

Co-authored-by: Cursor <cursoragent@cursor.com>
wuzilong 2 недель назад
Родитель
Сommit
ffd25d93e9

+ 57 - 0
web-admin/src/utils/mp-crm-product-category-tree.test.ts

@@ -0,0 +1,57 @@
+import assert from 'node:assert/strict'
+import { describe, it } from 'node:test'
+import {
+  collectExpandIds,
+  areAllExpandableExpanded,
+  categoryChildCount,
+  categoryChildMetaLabel
+} from './mp-crm-product-category-tree'
+
+type Node = {
+  id: string
+  children?: Node[]
+}
+
+const sample: Node[] = [
+  {
+    id: '1',
+    children: [
+      { id: '11', children: [{ id: '111' }] },
+      { id: '12' }
+    ]
+  },
+  { id: '2' }
+]
+
+describe('collectExpandIds', () => {
+  it('marks every node that has children', () => {
+    assert.deepEqual(collectExpandIds(sample), { '1': true, '11': true })
+  })
+})
+
+describe('areAllExpandableExpanded', () => {
+  it('returns true when all expandable ids are true', () => {
+    assert.equal(areAllExpandableExpanded(sample, { '1': true, '11': true }), true)
+  })
+
+  it('returns false when any expandable id is missing or false', () => {
+    assert.equal(areAllExpandableExpanded(sample, { '1': true }), false)
+    assert.equal(areAllExpandableExpanded(sample, { '1': true, '11': false }), false)
+  })
+
+  it('returns true for empty tree', () => {
+    assert.equal(areAllExpandableExpanded([], {}), true)
+  })
+})
+
+describe('categoryChildCount / categoryChildMetaLabel', () => {
+  it('counts direct children only', () => {
+    assert.equal(categoryChildCount(sample[0]), 2)
+    assert.equal(categoryChildCount(sample[1]), 0)
+  })
+
+  it('labels leaf vs parent', () => {
+    assert.equal(categoryChildMetaLabel(sample[0]), '2 个子类')
+    assert.equal(categoryChildMetaLabel(sample[1]), '末级')
+  })
+})

+ 37 - 0
web-admin/src/utils/mp-crm-product-category-tree.ts

@@ -0,0 +1,37 @@
+export type CategoryTreeNodeLike = {
+  id: string
+  children?: CategoryTreeNodeLike[]
+}
+
+export function categoryChildCount(node: CategoryTreeNodeLike | null | undefined): number {
+  const children = Array.isArray(node?.children) ? node!.children! : []
+  return children.length
+}
+
+export function categoryChildMetaLabel(node: CategoryTreeNodeLike | null | undefined): string {
+  const n = categoryChildCount(node)
+  return n > 0 ? `${n} 个子类` : '末级'
+}
+
+export function collectExpandIds(
+  nodes: CategoryTreeNodeLike[],
+  acc: Record<string, boolean> = {}
+): Record<string, boolean> {
+  for (const node of nodes) {
+    if (categoryChildCount(node) > 0) {
+      acc[node.id] = true
+      collectExpandIds(node.children || [], acc)
+    }
+  }
+  return acc
+}
+
+export function areAllExpandableExpanded(
+  nodes: CategoryTreeNodeLike[],
+  expandedIds: Record<string, boolean>
+): boolean {
+  const required = collectExpandIds(nodes, {})
+  const ids = Object.keys(required)
+  if (!ids.length) return true
+  return ids.every((id) => !!expandedIds[id])
+}