diff --git a/src/modules/other/category/CategoryDeepListView.vue b/src/modules/other/category/CategoryDeepListView.vue index ae57fdb..a7eabc0 100644 --- a/src/modules/other/category/CategoryDeepListView.vue +++ b/src/modules/other/category/CategoryDeepListView.vue @@ -6,7 +6,7 @@ * props.type: 1=行业 3=资讯分类 (保持现状数据源) * * 后端端点 (ApiCategoryController /other/category): - * GET categoryDeepPageList?type= 树形列表 + * GET list?type= 平铺列表 (前端按 pid 组装树; categoryDeepPageList 返回平铺不组装, 勿用) * POST save 新增 (body: name/type/level/pid/sort/status) * POST update 修改 (body, 同 save) * GET delete?id= 删除 (递归删子级, 注意是 GET query!) @@ -75,10 +75,32 @@ const displayList = computed(() => filterTree(LIST.value, search.name.trim())) async function load() { loading.value = true try { - const r: any = await httpGet('/other/category/categoryDeepPageList', { type: catType.value, page: 1, limit: 500 }) - LIST.value = r?.list || [] + // 用 /list 平铺接口 + 前端按 pid 组装树 (categoryDeepPageList 返回平铺不组装, 会导致"二级无父级") + const r: any = await httpGet('/other/category/list', { type: catType.value }) + const flat = r?.list || (Array.isArray(r) ? r : []) + LIST.value = buildTree(flat) } catch { LIST.value = [] } finally { loading.value = false } } + +// 按 pid 组装树 (平铺 -> 层级), 排序 sort 升序, 孤立节点挂根 +function buildTree(flat: any[]): Category[] { + const map = new Map() + flat.forEach((n: any) => map.set(String(n.id), { ...n, children: [] })) + const roots: any[] = [] + for (const n of flat) { + const node = map.get(String(n.id)) + const pid = String(n.pid ?? '0') + const parent = pid === '0' ? null : map.get(pid) + if (parent) parent.children.push(node) + else roots.push(node) + } + const sortRec = (nodes: any[]) => { + nodes.sort((a, b) => (a.sort ?? 0) - (b.sort ?? 0)) + nodes.forEach((n) => sortRec(n.children || [])) + } + sortRec(roots) + return roots +} function onSearch() { /* 客户端过滤即时生效 */ } function onReset() { search.name = '' }