From 4745c48798fc7d967a7fd4416c10050d4f79fb98 Mon Sep 17 00:00:00 2001
From: birt <2499248221@qq.com>
Date: 星期日, 13 四月 2025 21:43:49 +0800
Subject: [PATCH] 123

---
 zhitan-vue/src/layout/components/Sidebar/SidebarItem.vue |  106 ++++++++++++++
 zhitan-vue/src/store/modules/permission.js               |   16 ++
 zhitan-vue/src/components/TopNav/index.vue               |   90 ++++++++++++
 zhitan-vue/src/layout/components/Sidebar/index.vue       |   27 +++
 zhitan-vue/src/permission.js                             |  129 +++++++++++++++++-
 5 files changed, 349 insertions(+), 19 deletions(-)

diff --git a/zhitan-vue/src/components/TopNav/index.vue b/zhitan-vue/src/components/TopNav/index.vue
index 7c42971..85bc9e8 100644
--- a/zhitan-vue/src/components/TopNav/index.vue
+++ b/zhitan-vue/src/components/TopNav/index.vue
@@ -135,6 +135,28 @@
   setTimeout(updateScrollButtons, 300);
 }
 
+/**
+ * 鏌ユ壘鏈�娣卞眰鐨勫瓙鑿滃崟锛堝彾瀛愯妭鐐癸級
+ * 閫掑綊鏌ユ壘绗竴涓病鏈塩hildren鐨勫瓙鑿滃崟
+ */
+function findDeepestLeafMenu(route) {
+  if (!route) return null;
+  
+  // 濡傛灉娌℃湁瀛愯彍鍗曟垨瀛愯彍鍗曚负绌猴紝鍒欒繑鍥炲綋鍓嶈矾鐢�
+  if (!route.children || route.children.length === 0) {
+    return route;
+  }
+  
+  // 鎵惧埌绗竴涓潪闅愯棌鐨勫瓙鑿滃崟
+  const firstVisibleChild = route.children.find(child => !child.hidden);
+  if (!firstVisibleChild) {
+    return route; // 濡傛灉鎵�鏈夊瓙鑿滃崟閮芥槸闅愯棌鐨勶紝杩斿洖褰撳墠璺敱
+  }
+  
+  // 閫掑綊鏌ユ壘杩欎釜瀛愯彍鍗曠殑鏈�娣卞眰瀛愯彍鍗�
+  return findDeepestLeafMenu(firstVisibleChild);
+}
+
 function handleSelect(key, keyPath) {
   currentIndex.value = key;
   const route = routers.value.find(item => item.path === key);
@@ -156,12 +178,70 @@
   if (route && route.children && route.children.length > 0) {
     // 鏈夊瓙璺敱锛屾樉绀轰晶杈规爮
     activeRoutes(key);
-    const firstChild = route.children[0];
-    const path = firstChild.path.startsWith('/') ? firstChild.path : `${key}/${firstChild.path}`;
-    if (firstChild.query) {
-      router.push({ path, query: firstChild.query });
+    
+    // 鎸夌収姝g‘鐨勮矾寰勬瀯寤哄眰绾э紝杩欓噷鏄壒娈婂鐞�
+    let targetPath = key; // 浠庡綋鍓嶇偣鍑荤殑鑿滃崟璺緞寮�濮�
+    let targetQuery = null;
+    let currentNode = route;
+    let pathSegments = [];
+    
+    // 褰撳墠璺緞鏄涓�娈�
+    pathSegments.push(currentNode.path);
+    
+    // 閫愬眰娣诲姞瀛愯矾寰�
+    while (currentNode.children && currentNode.children.length > 0) {
+      const firstChild = currentNode.children.find(child => !child.hidden);
+      if (!firstChild) break;
+      
+      // 璺宠繃ParentView绫诲瀷鐨勪腑闂磋妭鐐癸紝鐩存帴浣跨敤鍏跺瓙鑺傜偣鐨刾ath
+      if (firstChild.component === 'ParentView' || firstChild.component.name === 'ParentView') {
+        currentNode = firstChild;
+        pathSegments.push(firstChild.path);
+        continue;
+      }
+      
+      // 鏅�氳妭鐐瑰鐞�
+      currentNode = firstChild;
+      // 濡傛灉璺緞涓嶆槸浠�/寮�澶达紝鍒欐坊鍔犲埌璺緞鐗囨涓�
+      if (!firstChild.path.startsWith('/')) {
+        pathSegments.push(firstChild.path);
+      } else {
+        // 濡傛灉鏄粷瀵硅矾寰勶紝鍒欐浛鎹箣鍓嶆墍鏈夎矾寰�
+        pathSegments = [firstChild.path];
+      }
+      
+      targetQuery = firstChild.query;
+      
+      // 濡傛灉鍒拌揪鍙跺瓙鑺傜偣锛堟病鏈夊瓙鑺傜偣锛夛紝鍒欑粨鏉熸煡鎵�
+      if (!firstChild.children || firstChild.children.length === 0) {
+        break;
+      }
+    }
+    
+    // 鏋勫缓鏈�缁堣矾寰�
+    if (pathSegments.length > 0) {
+      // 濡傛灉绗竴娈典笉鏄互/寮�澶达紝娣诲姞/
+      if (!pathSegments[0].startsWith('/')) {
+        pathSegments[0] = '/' + pathSegments[0];
+      }
+      
+      // 缁勫悎璺緞 - 鎶婃暟缁勪腑鎵�鏈夎矾寰勬嫾鎺ヨ捣鏉ワ紝濡傛灉鏌愭鍖呭惈瀹屾暣璺緞锛堜互/寮�澶达級鍒欎粠璇ユ閲嶆柊寮�濮�
+      targetPath = pathSegments.reduce((fullPath, segment, index) => {
+        if (segment.startsWith('/')) {
+          return segment;
+        } else if (index === 0) {
+          return segment;
+        } else {
+          return `${fullPath}/${segment}`;
+        }
+      });
+    }
+    
+    // 瀵艰埅鍒扮洰鏍囪矾鐢�
+    if (targetQuery) {
+      router.push({ path: targetPath, query: targetQuery });
     } else {
-      router.push({ path });
+      router.push({ path: targetPath });
     }
   } else {
     // 娌℃湁瀛愯矾鐢憋紝闅愯棌渚ц竟鏍�
diff --git a/zhitan-vue/src/layout/components/Sidebar/SidebarItem.vue b/zhitan-vue/src/layout/components/Sidebar/SidebarItem.vue
index 73346ce..7b468d2 100644
--- a/zhitan-vue/src/layout/components/Sidebar/SidebarItem.vue
+++ b/zhitan-vue/src/layout/components/Sidebar/SidebarItem.vue
@@ -9,7 +9,7 @@
       </app-link>
     </template>
 
-    <el-sub-menu v-else ref="subMenu" :index="resolvePath(item.path)" teleported>
+    <el-sub-menu v-else ref="subMenu" :index="resolvePath(item.path)" teleported @click="handleSubMenuClick">
       <template v-if="item.meta" #title>
         <svg-icon :icon-class="item.meta && item.meta.icon" />
         <span class="menu-title" :title="hasTitle(item.meta.title)">{{ item.meta.title }}</span>
@@ -31,6 +31,9 @@
 import { isExternal } from '@/utils/validate'
 import AppLink from './Link'
 import { getNormalPath } from '@/utils/ruoyi'
+import { useRouter } from 'vue-router'
+
+const router = useRouter();
 
 const props = defineProps({
   // route object
@@ -50,6 +53,100 @@
 
 const onlyOneChild = ref({});
 
+/**
+ * 鏌ユ壘鏈�娣卞眰鐨勫瓙鑿滃崟锛堝彾瀛愯妭鐐癸級
+ * 閫掑綊鏌ユ壘绗竴涓病鏈塩hildren鐨勫瓙鑿滃崟
+ */
+function findDeepestLeafMenu(route) {
+  if (!route) return null;
+  
+  // 濡傛灉娌℃湁瀛愯彍鍗曟垨瀛愯彍鍗曚负绌猴紝鍒欒繑鍥炲綋鍓嶈矾鐢�
+  if (!route.children || route.children.length === 0) {
+    return route;
+  }
+  
+  // 鎵惧埌绗竴涓潪闅愯棌鐨勫瓙鑿滃崟
+  const firstVisibleChild = route.children.find(child => !child.hidden);
+  if (!firstVisibleChild) {
+    return route; // 濡傛灉鎵�鏈夊瓙鑿滃崟閮芥槸闅愯棌鐨勶紝杩斿洖褰撳墠璺敱
+  }
+  
+  // 閫掑綊鏌ユ壘杩欎釜瀛愯彍鍗曠殑鏈�娣卞眰瀛愯彍鍗�
+  return findDeepestLeafMenu(firstVisibleChild);
+}
+
+// 澶勭悊瀛愯彍鍗曠偣鍑�
+function handleSubMenuClick(e) {
+  // 闃绘浜嬩欢鍐掓场
+  e.stopPropagation();
+  
+  // 濡傛灉鐐瑰嚮鐨勬槸瀛愯彍鍗曟爣棰橈紝鍒欒嚜鍔ㄥ鑸埌鏈�娣卞眰鐨勫瓙鑿滃崟
+  if (e.target.closest('.el-sub-menu__title')) {
+    // 鎸夌収姝g‘鐨勮矾寰勬瀯寤哄眰绾�
+    let currentNode = props.item;
+    let pathSegments = [];
+    
+    // 棣栧厛娣诲姞褰撳墠鑺傜偣鐨勮矾寰�
+    if (currentNode.path) {
+      pathSegments.push(currentNode.path);
+    }
+    
+    // 閫愬眰娣诲姞瀛愯矾寰�
+    while (currentNode.children && currentNode.children.length > 0) {
+      const firstChild = currentNode.children.find(child => !child.hidden);
+      if (!firstChild) break;
+      
+      // 璺宠繃ParentView绫诲瀷鐨勪腑闂磋妭鐐�
+      if (firstChild.component === 'ParentView' || firstChild.component.name === 'ParentView') {
+        currentNode = firstChild;
+        pathSegments.push(firstChild.path);
+        continue;
+      }
+      
+      // 鏅�氳妭鐐瑰鐞�
+      currentNode = firstChild;
+      // 濡傛灉璺緞涓嶆槸浠�/寮�澶达紝鍒欐坊鍔犲埌璺緞鐗囨涓�
+      if (!firstChild.path.startsWith('/')) {
+        pathSegments.push(firstChild.path);
+      } else {
+        // 濡傛灉鏄粷瀵硅矾寰勶紝鍒欐浛鎹箣鍓嶆墍鏈夎矾寰�
+        pathSegments = [firstChild.path];
+      }
+      
+      // 濡傛灉鍒拌揪鍙跺瓙鑺傜偣锛屽垯缁撴潫鏌ユ壘
+      if (!firstChild.children || firstChild.children.length === 0) {
+        break;
+      }
+    }
+    
+    // 鏋勫缓鏈�缁堣矾寰�
+    if (pathSegments.length > 0) {
+      // 濡傛灉绗竴娈典笉鏄互/寮�澶达紝娣诲姞/
+      if (!pathSegments[0].startsWith('/')) {
+        pathSegments[0] = '/' + pathSegments[0];
+      }
+      
+      // 缁勫悎璺緞
+      const targetPath = pathSegments.reduce((fullPath, segment, index) => {
+        if (segment.startsWith('/')) {
+          return segment;
+        } else if (index === 0) {
+          return segment;
+        } else {
+          return `${fullPath}/${segment}`;
+        }
+      });
+      
+      // 瀵艰埅鍒扮洰鏍囪矾鐢憋紝濡傛灉鏈夋煡璇㈠弬鏁板垯娣诲姞
+      if (currentNode.query) {
+        router.push({ path: targetPath, query: currentNode.query });
+      } else {
+        router.push({ path: targetPath });
+      }
+    }
+  }
+}
+
 function hasOneShowingChild(children = [], parent) {
   if (!children) {
     children = [];
@@ -65,10 +162,15 @@
   })
 
   // When there is only one child router, the child router is displayed by default
-  if (showingChildren.length === 1) {
+  if (showingChildren.length === 1 && !showingChildren[0].children) {
     return true
   }
 
+  // If the single child also has children, don't treat it as a single showing child
+  if (showingChildren.length === 1 && showingChildren[0].children && showingChildren[0].children.length > 0) {
+    return false
+  }
+
   // Show parent if there are no child router to display
   if (showingChildren.length === 0) {
     onlyOneChild.value = { ...parent, path: '', noShowingChildren: true }
diff --git a/zhitan-vue/src/layout/components/Sidebar/index.vue b/zhitan-vue/src/layout/components/Sidebar/index.vue
index 68596a6..fcb7d47 100644
--- a/zhitan-vue/src/layout/components/Sidebar/index.vue
+++ b/zhitan-vue/src/layout/components/Sidebar/index.vue
@@ -162,12 +162,13 @@
 }
 
 :deep(.scrollbar-wrapper) {
-  height: calc(100% - 290px) !important;
+  height: calc(100% - 220px) !important;
   overflow-x: hidden !important;
 }
 
 :deep(.scrollbar-view) {
   height: 100%;
+  padding-bottom: 20px;
 }
 
 :deep(.el-scrollbar__bar.is-vertical) {
@@ -237,6 +238,28 @@
         height: 38px !important;
         line-height: 38px !important;
       }
+      
+      // Add styling for deeply nested submenus (level 3+)
+      .el-sub-menu {
+        .el-menu-item {
+          padding-left: 65px !important;
+          
+          &.is-active {
+            padding-left: 65px !important;
+          }
+        }
+        
+        // Level 4
+        .el-menu {
+          .el-menu-item {
+            padding-left: 85px !important;
+            
+            &.is-active {
+              padding-left: 85px !important;
+            }
+          }
+        }
+      }
     }
   }
 }
@@ -250,7 +273,7 @@
 // 搴曢儴鐢ㄦ埛鍖哄煙鏍峰紡
 .sidebar-footer {
   position: absolute;
-  bottom: 72px;
+  bottom: 0;
   left: 0;
   width: 100%;
   border-top: 1px solid rgba(255, 255, 255, 0.1);
diff --git a/zhitan-vue/src/permission.js b/zhitan-vue/src/permission.js
index a521d95..7fc2c80 100644
--- a/zhitan-vue/src/permission.js
+++ b/zhitan-vue/src/permission.js
@@ -14,6 +14,75 @@
 
 const whiteList = ['/login', '/register', '/energy']
 
+/**
+ * 鏌ユ壘鏈�娣卞眰鐨勫瓙鑿滃崟骞舵瀯寤哄畬鏁磋矾寰�
+ */
+function findDeepestPath(route) {
+  if (!route) return { path: null, query: null };
+  
+  // 棣栧厛娣诲姞褰撳墠鑺傜偣鐨勮矾寰�
+  let currentNode = route;
+  let pathSegments = [];
+  
+  if (currentNode.path) {
+    pathSegments.push(currentNode.path);
+  }
+  
+  // 閫愬眰娣诲姞瀛愯矾寰�
+  while (currentNode.children && currentNode.children.length > 0) {
+    const firstChild = currentNode.children.find(child => !child.hidden);
+    if (!firstChild) break;
+    
+    // 璺宠繃ParentView绫诲瀷鐨勪腑闂磋妭鐐�
+    if (firstChild.component === 'ParentView' || 
+        (typeof firstChild.component === 'object' && firstChild.component.name === 'ParentView')) {
+      currentNode = firstChild;
+      pathSegments.push(firstChild.path);
+      continue;
+    }
+    
+    // 鏅�氳妭鐐瑰鐞�
+    currentNode = firstChild;
+    // 濡傛灉璺緞涓嶆槸浠�/寮�澶达紝鍒欐坊鍔犲埌璺緞鐗囨涓�
+    if (!firstChild.path.startsWith('/')) {
+      pathSegments.push(firstChild.path);
+    } else {
+      // 濡傛灉鏄粷瀵硅矾寰勶紝鍒欐浛鎹箣鍓嶆墍鏈夎矾寰�
+      pathSegments = [firstChild.path];
+    }
+    
+    // 濡傛灉鍒拌揪鍙跺瓙鑺傜偣锛屽垯缁撴潫鏌ユ壘
+    if (!firstChild.children || firstChild.children.length === 0) {
+      break;
+    }
+  }
+  
+  // 鏋勫缓鏈�缁堣矾寰�
+  let targetPath = '';
+  if (pathSegments.length > 0) {
+    // 濡傛灉绗竴娈典笉鏄互/寮�澶达紝娣诲姞/
+    if (!pathSegments[0].startsWith('/')) {
+      pathSegments[0] = '/' + pathSegments[0];
+    }
+    
+    // 缁勫悎璺緞
+    targetPath = pathSegments.reduce((fullPath, segment, index) => {
+      if (segment.startsWith('/')) {
+        return segment;
+      } else if (index === 0) {
+        return segment;
+      } else {
+        return `${fullPath}/${segment}`;
+      }
+    });
+  }
+  
+  return { 
+    path: targetPath, 
+    query: currentNode.query
+  };
+}
+
 router.beforeEach((to, from, next) => {
   NProgress.start()
   if (getToken()) {
@@ -45,11 +114,23 @@
               if (topMenus.length > 0) {
                 // 璺宠浆鍒扮涓�涓彍鍗�
                 const firstMenu = topMenus[0]
-                if (firstMenu.children && firstMenu.children.length > 0) {
-                  // 鏈夊瓙鑿滃崟锛岃烦杞埌绗竴涓瓙鑿滃崟
+                
+                // 鏌ユ壘鏈�娣卞眰鐨勫瓙鑿滃崟骞舵瀯寤鸿矾寰�
+                const { path, query } = findDeepestPath(firstMenu);
+                
+                if (path) {
+                  // 鏈夋渶娣卞眰瀛愯彍鍗曪紝璺宠浆鍒拌鑿滃崟
+                  if (query) {
+                    next({ path, query, replace: true });
+                  } else {
+                    next({ path, replace: true });
+                  }
+                  return;
+                } else if (firstMenu.children && firstMenu.children.length > 0) {
+                  // 浣跨敤鍘熸湁閫昏緫
                   const firstChild = firstMenu.children[0]
-                  const path = firstMenu.path.endsWith('/') ? firstMenu.path + firstChild.path : `${firstMenu.path}/${firstChild.path}`
-                  next({ path: path, replace: true })
+                  const childPath = firstMenu.path.endsWith('/') ? firstMenu.path + firstChild.path : `${firstMenu.path}/${firstChild.path}`
+                  next({ path: childPath, replace: true })
                   return
                 } else {
                   // 娌℃湁瀛愯彍鍗曪紝鐩存帴璺宠浆
@@ -75,11 +156,23 @@
           if (topMenus.length > 0) {
             // 璺宠浆鍒扮涓�涓彍鍗�
             const firstMenu = topMenus[0]
-            if (firstMenu.children && firstMenu.children.length > 0) {
-              // 鏈夊瓙鑿滃崟锛岃烦杞埌绗竴涓瓙鑿滃崟
+            
+            // 鏌ユ壘鏈�娣卞眰鐨勫瓙鑿滃崟骞舵瀯寤鸿矾寰�
+            const { path, query } = findDeepestPath(firstMenu);
+            
+            if (path) {
+              // 鏈夋渶娣卞眰瀛愯彍鍗曪紝璺宠浆鍒拌鑿滃崟
+              if (query) {
+                next({ path, query, replace: true });
+              } else {
+                next({ path, replace: true });
+              }
+              return;
+            } else if (firstMenu.children && firstMenu.children.length > 0) {
+              // 浣跨敤鍘熸湁閫昏緫
               const firstChild = firstMenu.children[0]
-              const path = firstMenu.path.endsWith('/') ? firstMenu.path + firstChild.path : `${firstMenu.path}/${firstChild.path}`
-              next({ path: path, replace: true })
+              const childPath = firstMenu.path.endsWith('/') ? firstMenu.path + firstChild.path : `${firstMenu.path}/${firstChild.path}`
+              next({ path: childPath, replace: true })
               return
             } else {
               // 娌℃湁瀛愯彍鍗曪紝鐩存帴璺宠浆
@@ -88,6 +181,26 @@
             }
           }
         }
+        
+        // 鑷姩澶勭悊甯︽湁閲嶅畾鍚戠殑璺敱
+        if (to.matched.length > 0 && to.matched[0].path === to.path) {
+          const currentRouteConfig = router.getRoutes().find(r => r.path === to.path);
+          
+          if (currentRouteConfig && currentRouteConfig.children && currentRouteConfig.children.length > 0) {
+            // 鏈夊瓙璺敱锛岃嚜鍔ㄥ鑸埌鏈�娣卞眰瀛愯彍鍗�
+            const { path, query } = findDeepestPath(currentRouteConfig);
+            
+            if (path && path !== to.path) {
+              if (query) {
+                next({ path, query, replace: true });
+              } else {
+                next({ path, replace: true });
+              }
+              return;
+            }
+          }
+        }
+        
         next()
       }
     }
diff --git a/zhitan-vue/src/store/modules/permission.js b/zhitan-vue/src/store/modules/permission.js
index c9d09e6..ca7e5a2 100644
--- a/zhitan-vue/src/store/modules/permission.js
+++ b/zhitan-vue/src/store/modules/permission.js
@@ -56,8 +56,13 @@
   })
 
 // 閬嶅巻鍚庡彴浼犳潵鐨勮矾鐢卞瓧绗︿覆锛岃浆鎹负缁勪欢瀵硅薄
-function filterAsyncRouter(asyncRouterMap, lastRouter = false, type = false) {
+function filterAsyncRouter(asyncRouterMap, lastRouter = false, type = false, parentRoute = null) {
   return asyncRouterMap.filter(route => {
+    // 璁剧疆鐖惰矾鐢卞紩鐢�
+    if (parentRoute) {
+      route.parent = parentRoute;
+    }
+    
     if (type && route.children) {
       route.children = filterChildren(route.children)
     }
@@ -82,7 +87,8 @@
       }
     }
     if (route.children != null && route.children && route.children.length) {
-      route.children = filterAsyncRouter(route.children, route, type)
+      // 灏嗗綋鍓嶈矾鐢变綔涓虹埗璺敱浼犻�掔粰瀛愯矾鐢�
+      route.children = filterAsyncRouter(route.children, route, type, route)
     } else {
       delete route['children']
       delete route['redirect']
@@ -97,6 +103,9 @@
     if (el.children && el.children.length) {
       if (el.component === 'ParentView' && !lastRouter) {
         el.children.forEach(c => {
+          // 璁剧疆鐖惰矾鐢卞紩鐢�
+          c.parent = el;
+          
           c.path = el.path + '/' + c.path
           if (c.children && c.children.length) {
             children = children.concat(filterChildren(c.children, c))
@@ -108,6 +117,9 @@
       }
     }
     if (lastRouter) {
+      // 璁剧疆鐖惰矾鐢卞紩鐢�
+      el.parent = lastRouter;
+      
       el.path = lastRouter.path + '/' + el.path
       if (el.children && el.children.length) {
         children = children.concat(filterChildren(el.children, el))

--
Gitblit v1.9.3