From f4244c09b964351bcf63f02402436a7121c0cc27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E5=BF=97=E5=BC=BA?= <357099073@qq.com> Date: Thu, 6 Nov 2025 17:12:13 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E7=BC=93=E5=AD=98=E5=92=8C?= =?UTF-8?q?=E6=96=87=E4=BB=B6=E5=88=86=E7=B1=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pc/src/components/CommonAside.vue | 70 ++++++++++++++++++---- pc/src/components/CommonHeader.vue | 27 +++++++++ pc/src/views/system/files/FileCategory.vue | 14 ++--- pc/src/views/system/roles/index.vue | 4 +- server/controllers/role.go | 10 ++++ server/models/menu.go | 69 ++++++++++++++++++++- 6 files changed, 171 insertions(+), 23 deletions(-) diff --git a/pc/src/components/CommonAside.vue b/pc/src/components/CommonAside.vue index d4e474e..dab7ea6 100644 --- a/pc/src/components/CommonAside.vue +++ b/pc/src/components/CommonAside.vue @@ -103,23 +103,62 @@ const activeBgColor = computed(() => { // 将后端数据转换为前端需要的格式 const transformMenuData = (menus) => { - // 功能页面路径关键词,这些菜单不应该显示在侧边栏 - const functionPageKeywords = ['/detail', '/add', '/edit', '/delete', '/create', '/update', '/category', '/tag']; + if (!menus || menus.length === 0) { + console.warn('菜单数据为空'); + return []; + } - // 判断是否是功能页面 + console.log('原始菜单数据:', menus); + + // 功能页面路径关键词,这些菜单不应该显示在侧边栏 + // 注意:只过滤真正的功能页面,不过滤包含这些关键词的父菜单 + const functionPageKeywords = ['/detail', '/add', '/edit', '/delete', '/create', '/update']; + + // 需要隐藏的子菜单路径(这些子菜单不应该显示在侧边栏) + const hiddenSubMenuPaths = ['/apps/knowledge/category', '/apps/knowledge/tag']; + + // 判断是否是功能页面(更精确的判断) const isFunctionPage = (path) => { if (!path) return false; const lowerPath = path.toLowerCase(); - return functionPageKeywords.some(keyword => lowerPath.includes(keyword)); + // 检查路径是否以这些关键词结尾,或者是这些关键词的组合 + // 例如:/apps/knowledge/detail 是功能页面 + // 但 /apps/knowledge 不是功能页面 + return functionPageKeywords.some(keyword => { + // 检查路径是否以关键词结尾,或者路径中包含 /keyword/ 或 /keyword + return lowerPath.endsWith(keyword) || + lowerPath.includes(`/${keyword}/`) || + lowerPath.endsWith(`/${keyword}`); + }); + }; + + // 判断是否是需要隐藏的子菜单 + const isHiddenSubMenu = (path) => { + if (!path) return false; + const lowerPath = path.toLowerCase(); + return hiddenSubMenuPaths.some(hiddenPath => { + return lowerPath === hiddenPath || lowerPath.startsWith(hiddenPath + '/'); + }); }; - // 首先映射字段格式,只保留页面菜单(menu_type=1),并过滤掉功能页面 + // 首先映射字段格式,只保留页面菜单(menu_type=1),并过滤掉功能页面和需要隐藏的子菜单 const allMenus = menus .filter(menu => { // 只显示页面菜单,不显示API权限菜单 - if (menu.menuType !== 1) return false; - // 过滤掉功能页面(详情、新增、编辑、删除、分类、标签等) - if (isFunctionPage(menu.path)) return false; + if (menu.menuType !== 1 && menu.menuType !== undefined) { + console.log('过滤掉非页面菜单:', menu); + return false; + } + // 过滤掉功能页面(详情、新增、编辑、删除等) + if (isFunctionPage(menu.path)) { + console.log('过滤掉功能页面:', menu.path); + return false; + } + // 过滤掉需要隐藏的子菜单(如分类管理、标签管理) + if (isHiddenSubMenu(menu.path)) { + console.log('过滤掉隐藏的子菜单:', menu.path); + return false; + } return true; }) .map(menu => ({ @@ -133,16 +172,19 @@ const transformMenuData = (menus) => { children: [] })); + console.log('过滤后的菜单数据:', allMenus); + // 构建菜单映射表(只包含有效的页面菜单) const menuMap = new Map(); allMenus.forEach(menu => { menuMap.set(menu.id, menu); }); - // 构建树形结构,只保留那些父菜单也存在的菜单项 + // 构建树形结构 + // 如果父菜单不在当前数据中,将菜单项作为根菜单显示 const rootMenus = []; allMenus.forEach(menu => { - if (menu.parentId === 0) { + if (menu.parentId === 0 || !menu.parentId) { // 顶级菜单直接加入 rootMenus.push(menu); } else { @@ -154,10 +196,16 @@ const transformMenuData = (menus) => { parent.children = []; } parent.children.push(menu); + } else { + // 如果父菜单不存在,可能是父菜单被过滤掉了,或者父菜单不在当前返回的数据中 + // 这种情况下,将该菜单作为根菜单显示(避免菜单丢失) + console.warn('菜单的父菜单不存在,将作为根菜单显示。菜单ID:', menu.id, '父菜单ID:', menu.parentId, '菜单路径:', menu.path); + rootMenus.push(menu); } - // 如果父菜单不存在(被过滤掉了或者是menu_type=2),则忽略该菜单项,不添加到任何地方 } }); + + console.log('构建后的菜单树:', rootMenus); // 按 order 排序(确保排序正确) const sortMenus = (menus) => { diff --git a/pc/src/components/CommonHeader.vue b/pc/src/components/CommonHeader.vue index 6a2abd2..7be6a5e 100644 --- a/pc/src/components/CommonHeader.vue +++ b/pc/src/components/CommonHeader.vue @@ -193,6 +193,33 @@ const handleCommand = async (command) => { // 清除菜单缓存 menuStore.resetMenus(); + // 清除所有以 menu_cache_ 开头的本地存储项 + const menuCacheKeys: string[] = []; + // 遍历 localStorage + for (let i = 0; i < localStorage.length; i++) { + const key = localStorage.key(i); + if (key && key.startsWith('menu_cache_')) { + menuCacheKeys.push(key); + } + } + // 删除 localStorage 中的 menu_cache_ 项 + menuCacheKeys.forEach(key => { + localStorage.removeItem(key); + }); + + // 遍历 sessionStorage + const sessionMenuCacheKeys: string[] = []; + for (let i = 0; i < sessionStorage.length; i++) { + const key = sessionStorage.key(i); + if (key && key.startsWith('menu_cache_')) { + sessionMenuCacheKeys.push(key); + } + } + // 删除 sessionStorage 中的 menu_cache_ 项 + sessionMenuCacheKeys.forEach(key => { + sessionStorage.removeItem(key); + }); + // 重置 tabs store 状态 const { useTabsStore } = await import('@/stores'); const tabsStore = useTabsStore(); diff --git a/pc/src/views/system/files/FileCategory.vue b/pc/src/views/system/files/FileCategory.vue index 07d71a2..25d82e6 100644 --- a/pc/src/views/system/files/FileCategory.vue +++ b/pc/src/views/system/files/FileCategory.vue @@ -26,21 +26,17 @@ - + - + - + - +