import { createRouter, createWebHashHistory, type RouteRecordRaw } from 'vue-router' import { usePermissionStoreHook } from '@/stores/modules/permission' const Layouts = () => import('@/layouts/index.vue') /** * 路由 name 与 FunctionList key 的映射 * 一级菜单: route name → FunctionList 一级 key * 二级菜单(Settings 子路由): route name → FunctionList Settings 下的 key */ const menuPermissionMap: Record = { // 一级菜单 Settings: 'Settings', RemoteViewing: 'Remote', StandardProtocol: 'Protocol', } const subMenuPermissionMap: Record = { // Settings 下的二级菜单 SystemSettings: 'System_Settings', ImageDisplay: 'Image_Display', AudioVideo: 'Audio_Video', NetSettings: 'Network_Settings', AlarmSettings: 'Alarm_Settings', } export const constantRoutes: RouteRecordRaw[] = [ { path: '/', name: 'PreviewLayout', component: Layouts, redirect: '/preview', children: [ { path: '/preview', component: () => import('@/views/preview/index.vue'), name: 'Preview', meta: { title: 'Preview', isShow: true, icon: 'View' } } ] }, { path: '/settings', name: 'Settings', component: Layouts, redirect: '/settings', meta: { title: 'Settings', isShow: true, icon: 'Setting' }, children: [ { path: '/settings/systemSettings', component: () => import('@/views/settings/systemSettings/index.vue'), name: 'SystemSettings', meta: { title: 'System Settings' } }, { path: '/settings/imageDisplay', component: () => import('@/views/settings/imageDisplay/index.vue'), name: 'ImageDisplay', meta: { title: 'Image Display' } }, { path: '/settings/audioVideo', component: () => import('@/views/settings/audioVideo/index.vue'), name: 'AudioVideo', meta: { title: 'Audio & Video' } }, { path: '/settings/netSetting', component: () => import('@/views/settings/netSettings/index.vue'), name: 'NetSettings', meta: { title: 'Network Settings' } }, { path: '/settings/alarmSettings', component: () => import('@/views/settings/alarmSettings/index.vue'), name: 'AlarmSettings', meta: { title: 'Alarm Settings' } } ] }, { path: '/', name: 'RemoteLayout', component: Layouts, redirect: '/remoteViewing', children: [ { path: '/remoteViewing', component: () => import('@/views/remoteViewing/index.vue'), name: 'RemoteViewing', meta: { title: 'Remote', isShow: true, icon: 'Monitor' } } ] }, { path: '/', name: 'ProtocolLayout', component: Layouts, redirect: '/standardProtocol', children: [ { path: '/standardProtocol', component: () => import('@/views/standardProtocol/index.vue'), name: 'StandardProtocol', meta: { title: 'Protocol', isShow: true, icon: 'Document' } } ] }, ] export const history = createWebHashHistory() const router = createRouter({ history, routes: [ { path: '/login', component: () => import('@/views/login/index.vue'), name: 'Login' } ] }) export default router /** 清除所有动态注册的路由 */ function resetRouter() { // 移除所有 constantRoutes 中定义的路由(按 name 移除) const routeNames: string[] = [] constantRoutes.forEach((route) => { if (route.name) { routeNames.push(route.name as string) } if (route.children) { route.children.forEach((child) => { if (child.name) { routeNames.push(child.name as string) } }) } }) routeNames.forEach((name) => { if (router.hasRoute(name)) { router.removeRoute(name) } }) } /** 根据权限过滤路由并注册 */ export function setRouter() { // 先清除旧路由,避免重复注册 resetRouter() const permissionStore = usePermissionStoreHook() const filteredRoutes = constantRoutes .filter((route) => { // 对于有单个子路由的一级菜单(Preview / Remote / Protocol) if (route.children && route.children.length === 1) { const child = route.children[0] const routeName = child.name as string const permKey = menuPermissionMap[routeName] if (permKey && !permissionStore.isMenuVisible(permKey)) { return false } } // 对于 Settings 这种有多个子路由的一级菜单 if (route.name && menuPermissionMap[route.name as string]) { const permKey = menuPermissionMap[route.name as string] if (!permissionStore.isMenuVisible(permKey)) { return false } } return true }) .map((route) => { // 过滤 Settings 的子路由 if (route.name === 'Settings' && route.children) { const filteredChildren = route.children.filter((child) => { const childName = child.name as string const subPermKey = subMenuPermissionMap[childName] if (subPermKey) { return permissionStore.isSubMenuVisible(subPermKey) } return true }) return { ...route, children: filteredChildren } } return route }) // 如果 Settings 的子路由全被过滤掉了,移除 Settings 本身 .filter((route) => { if (route.name === 'Settings' && route.children && route.children.length === 0) { return false } return true }) filteredRoutes.forEach((item) => { router.addRoute(item) }) }