fix: 统一前端菜单类型判断
This commit is contained in:
@@ -12,7 +12,7 @@ export interface ServerMenuItem extends TreeNodeBase {
|
||||
title?: string // 菜单标题
|
||||
title_en?: string // 英文标题
|
||||
code?: string // 菜单编码
|
||||
type?: number // 1:菜单,2:按钮
|
||||
type: number | string // 1:菜单,2:按钮
|
||||
menu_path?: string // 菜单路径,如 '/overview'
|
||||
component?: string // 组件路径,如 'ops/pages/overview'
|
||||
icon?: string
|
||||
@@ -29,6 +29,10 @@ export interface ServerMenuItem extends TreeNodeBase {
|
||||
[key: string]: any
|
||||
}
|
||||
|
||||
export function isMenuPermission(item: Pick<ServerMenuItem, 'type'>): boolean {
|
||||
return item.type === 1 || item.type === '1'
|
||||
}
|
||||
|
||||
// 预定义的视图模块映射(用于 Vite 动态导入)
|
||||
const viewModules = import.meta.glob('@/views/**/*.vue')
|
||||
|
||||
@@ -76,7 +80,7 @@ export function transformMenuToRoutes(menuItems: ServerMenuItem[]): AppRouteReco
|
||||
const routes: AppRouteRecordRaw[] = []
|
||||
|
||||
for (const item of menuItems) {
|
||||
if (item.type !== 1) continue
|
||||
if (!isMenuPermission(item)) continue
|
||||
|
||||
// 根据 is_full 决定如何设置 component
|
||||
let routeComponent: AppRouteRecordRaw['component']
|
||||
@@ -200,44 +204,42 @@ function transformChildRoutes(
|
||||
parentPath?: string,
|
||||
parentIsFull?: boolean
|
||||
): AppRouteRecordRaw[] {
|
||||
return children
|
||||
.filter((child) => child.type === 1)
|
||||
.map((child) => {
|
||||
const childFullPath = String(child.menu_path ?? child.path ?? '').trim()
|
||||
return children.filter(isMenuPermission).map((child) => {
|
||||
const childFullPath = String(child.menu_path ?? child.path ?? '').trim()
|
||||
|
||||
// 已配置 component 的菜单绝不覆盖;仅对许可页做路径/code 兜底,避免 includes 误匹配
|
||||
let componentPath = child.component || parentComponent
|
||||
if (!child.component && (isLicenseCenterMenuPath(childFullPath) || child.code === 'LicenseCenter')) {
|
||||
componentPath = LICENSE_CENTER_VIEW
|
||||
}
|
||||
// 已配置 component 的菜单绝不覆盖;仅对许可页做路径/code 兜底,避免 includes 误匹配
|
||||
let componentPath = child.component || parentComponent
|
||||
if (!child.component && (isLicenseCenterMenuPath(childFullPath) || child.code === 'LicenseCenter')) {
|
||||
componentPath = LICENSE_CENTER_VIEW
|
||||
}
|
||||
|
||||
const relativePath = extractRelativePath(childFullPath, parentPath || '')
|
||||
const relativePath = extractRelativePath(childFullPath, parentPath || '')
|
||||
|
||||
const route: AppRouteRecordRaw = {
|
||||
path: relativePath,
|
||||
name: child.title || child.name || `menu_${child.id}`,
|
||||
meta: {
|
||||
...child,
|
||||
locale: child.locale || child.title,
|
||||
requiresAuth: child.requiresAuth !== false,
|
||||
roles: child.roles,
|
||||
hideInMenu: child.hideInMenu || child.hide_menu,
|
||||
},
|
||||
component: componentPath ? loadViewComponent(componentPath) : () => import('@/views/redirect/index.vue'),
|
||||
}
|
||||
const route: AppRouteRecordRaw = {
|
||||
path: relativePath,
|
||||
name: child.title || child.name || `menu_${child.id}`,
|
||||
meta: {
|
||||
...child,
|
||||
locale: child.locale || child.title,
|
||||
requiresAuth: child.requiresAuth !== false,
|
||||
roles: child.roles,
|
||||
hideInMenu: child.hideInMenu || child.hide_menu,
|
||||
},
|
||||
component: componentPath ? loadViewComponent(componentPath) : () => import('@/views/redirect/index.vue'),
|
||||
}
|
||||
|
||||
// 递归处理子菜单的子菜单
|
||||
if (child.children && child.children.length > 0) {
|
||||
route.children = transformChildRoutes(
|
||||
child.children,
|
||||
child.component || parentComponent,
|
||||
childFullPath, // 传递当前子菜单的完整路径作为下一层的父路径
|
||||
child.is_full || parentIsFull // 传递 is_full 标志
|
||||
)
|
||||
}
|
||||
// 递归处理子菜单的子菜单
|
||||
if (child.children && child.children.length > 0) {
|
||||
route.children = transformChildRoutes(
|
||||
child.children,
|
||||
child.component || parentComponent,
|
||||
childFullPath, // 传递当前子菜单的完整路径作为下一层的父路径
|
||||
child.is_full || parentIsFull // 传递 is_full 标志
|
||||
)
|
||||
}
|
||||
|
||||
return route
|
||||
})
|
||||
return route
|
||||
})
|
||||
}
|
||||
|
||||
// 本地菜单数据 - 接口未准备好时使用
|
||||
|
||||
@@ -2,7 +2,7 @@ import { defineStore } from 'pinia'
|
||||
import type { RouteRecordNormalized } from 'vue-router'
|
||||
import defaultSettings from '@/config/settings.json'
|
||||
import { userPmn } from '@/api/module/user'
|
||||
import { transformMenuToRoutes, type ServerMenuItem } from '@/router/menu-data'
|
||||
import { isMenuPermission, transformMenuToRoutes, type ServerMenuItem } from '@/router/menu-data'
|
||||
import { buildTree } from '@/utils/tree'
|
||||
import SafeStorage, { AppStorageKey } from '@/utils/safeStorage'
|
||||
import router from '@/router'
|
||||
@@ -61,7 +61,7 @@ const useAppStore = defineStore('app', {
|
||||
),
|
||||
]
|
||||
|
||||
const menuPermissions = permissions.filter((permission) => permission.type === 1)
|
||||
const menuPermissions = permissions.filter(isMenuPermission)
|
||||
|
||||
// 使用 buildTree 将扁平数据构建为树结构
|
||||
const treeResult = buildTree(menuPermissions, {
|
||||
|
||||
Reference in New Issue
Block a user