feat(art-sidebar-menu): 支持两级菜单结构和 isTopMenu 标识

- firstLevelMenus 优先返回 isTopMenu: true 的一级菜单,保持向后兼容
- menuList 在顶部左侧/双列模式下,优先查找 isTopMenu 标识匹配的一级菜单
- 过滤隐藏菜单 (isHide: true)
- 添加 AppRouteRecord 类型导入并优化 findIframeMenuList 类型标注

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
zlwuandCursor committed 2026-06-12 19:53:21 +08:00
1 parent eab59bfdbf
commit d1d8558c04
1 file changed
+29 -7
@@ -139,6 +139,7 @@
import { isIframe } from '@/utils/navigation'
import { handleMenuJump } from '@/utils/navigation'
import { filterSidebarRoutes } from '@/utils/router/sidebar-menu-filter'
import type { AppRouteRecord } from '@/types/router'
import SidebarSubmenu from './widget/SidebarSubmenu.vue'
import { useCommon } from '@/hooks/core/useCommon'
import { useWindowSize, useTimeoutFn } from '@vueuse/core'
@@ -195,30 +196,51 @@
// 菜单数据
const firstLevelMenus = computed(() => {
return useMenuStore().menuList.filter((menu) => !menu.meta.isHide)
const menuStore = useMenuStore()
const allMenus = menuStore.menuList
// 优先返回 isTopMenu: true 的一级菜单
const topMenus = allMenus.filter((menu) => menu.meta?.isTopMenu)
if (topMenus.length > 0) {
return topMenus
}
// 兼容旧逻辑:返回所有未隐藏的顶级菜单
return allMenus.filter((menu) => !menu.meta.isHide)
})
const menuList = computed(() => {
const menuStore = useMenuStore()
const allMenus = menuStore.menuList
// 如果不是顶部左侧菜单或双列菜单,直接返回完整菜单列表
// 不是顶部左侧或双列模式,返回全部菜单
if (!isTopLeftMenu.value && !isDualMenu.value) {
return allMenus
}
// 处理 iframe 路径
// iframe 路径处理
if (isIframe(route.path)) {
return findIframeMenuList(route.path, allMenus)
}
// 处理一级菜单
// 一级菜单页面(isFirstLevel: true)返回空
if (route.meta.isFirstLevel) {
return []
}
// 返回当前顶级路径对应的子菜单
// 查找当前一级菜单(支持 isTopMenu 标识)
const currentTopPath = `/${route.path.split('/')[1]}`
// 优先查找 isTopMenu: true 的一级菜单
const currentTopMenu = allMenus.find(
(menu) => menu.meta?.isTopMenu && menu.path === currentTopPath
)
if (currentTopMenu?.children) {
return currentTopMenu.children.filter((child) => !child.meta?.isHide)
}
// 兼容旧逻辑
const currentMenu = allMenus.find((menu) => menu.path === currentTopPath)
return currentMenu?.children ?? []
})
@@ -304,9 +326,9 @@
/**
* 查找 iframe 对应的二级菜单列表
*/
const findIframeMenuList = (currentPath: string, menuList: any[]) => {
const findIframeMenuList = (currentPath: string, menuList: AppRouteRecord[]) => {
// 递归查找包含当前路径的菜单项
const hasPath = (items: any[]): boolean => {
const hasPath = (items: AppRouteRecord[]): boolean => {
for (const item of items) {
if (item.path === currentPath) {
return true