From 21a4af6ab61404876979e6d72c52d6f11e257a45 Mon Sep 17 00:00:00 2001 From: "WANGFAN\\wangf" <15871339963@163.com> Date: Tue, 8 Apr 2025 22:46:45 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E6=89=81=E5=B9=B3=E8=B7=AF=E7=94=B1?= =?UTF-8?q?=E8=BD=AC=E6=95=B0=E7=BB=84=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/mock/_data/system_menu.ts | 1 + src/mock/_utils.ts | 44 ++++++++++++++++++++++++++++------- 2 files changed, 36 insertions(+), 9 deletions(-) diff --git a/src/mock/_data/system_menu.ts b/src/mock/_data/system_menu.ts index 8ed9342..a1e77a4 100644 --- a/src/mock/_data/system_menu.ts +++ b/src/mock/_data/system_menu.ts @@ -16,6 +16,7 @@ * | |-- 子节点2-1: '010201' * | |-- 子节点2-2: '010202' * 当然,你们也可以自行设计id结构,只要保证id的唯一性即可,最后接口返回的是一个树形结构 + * 注意:节点id不能与parentId相同,否则在遍历路由树的时候会出现无限循环,在设计id的时候需要避免节点增多而导致id相同的情况 * * * 路由meta对象参数,我们通常将属性放到meta对象中 diff --git a/src/mock/_utils.ts b/src/mock/_utils.ts index b1ff1fe..455c065 100644 --- a/src/mock/_utils.ts +++ b/src/mock/_utils.ts @@ -128,23 +128,49 @@ export function deepClone(data: any) { * @returns 树形结构 */ export const buildTreeOptimized = (nodes: Menu.MenuOptions[]) => { - const nodeMap = new Map(); // 哈希映射存储节点引用 + const nodeMap = new Map(); // 哈希表存储所有节点 const roots = []; // 存储顶层节点 + const duplicates = new Set(); // 检测重复ID - // 单次遍历构建结构(兼容乱序数据) + // 第一次遍历: 注册所有节点 & 检测重复 for (const node of nodes) { - const { id, parentId } = node; - node.children = []; // 初始化子节点数组 + const id = node.id; - // 将当前节点存入哈希表 + // 循环引用检测 + if (node.id === node.parentId) { + throw new Error(`循环引用: ${node.id} -> ${node.parentId}`); + } + + // 重复ID检测 + if (nodeMap.has(id)) { + duplicates.add(id); + continue; + } + + // 初始化子节点数组 + node.children = []; nodeMap.set(id, node); + } + + // 输出重复警告 + if (duplicates.size > 0) { + console.warn(`检测到重复ID: ${Array.from(duplicates).join(", ")}`); + } + + // 第二次遍历: 构建树结构 + for (const node of nodes) { + const { parentId } = node; + + // 跳过已处理的重复节点 + if (duplicates.has(node.id)) continue; - // 处理父子关系 if (parentId === "0") { - roots.push(node); // 顶层节点直接加入结果 - } else { + roots.push(node); // 顶层节点 + } else if (parentId) { const parent = nodeMap.get(parentId); - parent?.children.push(node); // 子节点挂载到父级 + parent?.children.push(node); // 挂载子节点 + } else { + console.warn(`孤儿节点 ${node.id}: parentId为空`); } }