diff --git a/src/layouts/BasicLayout.vue b/src/layouts/BasicLayout.vue index 2d5dddcc..0f071b7b 100644 --- a/src/layouts/BasicLayout.vue +++ b/src/layouts/BasicLayout.vue @@ -29,12 +29,15 @@ import { MENU_PATH_INLINE } from '@/constants/menu-constants'; import { RESULT_CODE_SUCCESS } from '@/constants/result-constants'; import { parseDateToStr } from '@/utils/date-utils'; import { parseUrlPath } from '@/plugins/file-static-url'; +import useNeInfoStore from '@/store/modules/neinfo'; + const { proConfig, waterMarkContent } = useLayoutStore(); const { t, currentLocale } = useI18n(); const routerStore = useRouterStore(); const tabsStore = useTabsStore(); const appStore = useAppStore(); const router = useRouter(); +const neListStore = useNeInfoStore(); /**菜单面板 */ const layoutState = reactive({ @@ -65,18 +68,23 @@ watch( ); // 动态路由添加到菜单面板 -const rootRoute = router.getRoutes().find(r => r.name === 'Root'); -if (rootRoute) { - const children = routerStore.setRootRouterData(rootRoute.children); - const buildRouterData = routerStore.buildRouterData; - if (buildRouterData.length > 0) { - rootRoute.children = children.concat(buildRouterData); - } else { - rootRoute.children = children; +const menuData = computed(() => { + const rootRoute = router.getRoutes().find(r => r.name === 'Root'); + if (rootRoute) { + const children = routerStore.setRootRouterData(rootRoute.children); + const buildRouterData = routerStore.buildRouterData; + if (buildRouterData.length > 0) { + rootRoute.children = children.concat(buildRouterData); + } else { + rootRoute.children = children; + } } -} - -const { menuData } = getMenuData(clearMenuItem(router.getRoutes())); + const neTypes = neListStore.getNeSelectOtions.map(v => v.value); + let routes = clearMenuItem(router.getRoutes()); + routes = routerStore.clearMenuItemByNeList(routes, neTypes); + const { menuData } = getMenuData(routes); + return menuData; +}); /**面包屑数据对象,排除根节点和首页不显示 */ const breadcrumb = computed(() => { diff --git a/src/router/index.ts b/src/router/index.ts index b16ea27c..cda59165 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -13,6 +13,7 @@ import { validHttp } from '@/utils/regular-utils'; import useUserStore from '@/store/modules/user'; import useAppStore from '@/store/modules/app'; import useRouterStore from '@/store/modules/router'; +import useNeInfoStore from '@/store/modules/neinfo'; // NProgress Configuration NProgress.configure({ showSpinner: false }); @@ -210,6 +211,8 @@ router.beforeEach(async (to, from, next) => { const user = useUserStore(); if (user.roles && user.roles.length === 0) { try { + // 获取网元信息 + await useNeInfoStore().fnNelist(); // 获取用户信息 await user.fnGetInfo(); // 获取路由信息 @@ -230,6 +233,13 @@ router.beforeEach(async (to, from, next) => { await user.fnLogOut(); next({ name: 'Login' }); } + } else if ( + to.meta.neType && + //Array.isArray(to.meta.neType) && + to.meta.neType.length > 0 && + !useNeInfoStore().fnHasNe(to.meta.neType) + ) { + next({ name: 'NotPermission' }); } else { next(); } diff --git a/src/store/modules/neinfo.ts b/src/store/modules/neinfo.ts index ebe158ee..05271c37 100644 --- a/src/store/modules/neinfo.ts +++ b/src/store/modules/neinfo.ts @@ -109,6 +109,32 @@ const useNeInfoStore = defineStore('neinfo', { } return res; }, + /** + * 含有网元 + * @param metaNeType ['udm', 'ims', 'udm+ims', 'SGWC'] 支持大小写 + * @returns boolean + */ + fnHasNe(metaNeType: string[]) { + if (this.neList.length > 0) { + const neTypes = this.neSelectOtions.map(item => item.value); + let match = false; // 匹配 + for (const netype of metaNeType) { + if (netype.indexOf('+') > -1) { + metaNeType = netype.split('+'); + match = true; + break; + } + } + + if (match) { + // 同时匹配 + return metaNeType.every(item => neTypes.includes(item.toUpperCase())); + } + // 有一种 + return metaNeType.some(item => neTypes.includes(item.toUpperCase())); + } + return false; + }, }, }); diff --git a/src/store/modules/router.ts b/src/store/modules/router.ts index d683a01f..11050f4b 100644 --- a/src/store/modules/router.ts +++ b/src/store/modules/router.ts @@ -3,6 +3,7 @@ import type { RouteComponent, RouteLocationRaw, RouteMeta, + RouteRecord, RouteRecordRaw, } from 'vue-router'; import { getRouters } from '@/api/router'; @@ -54,6 +55,62 @@ const useRouterStore = defineStore('router', { } return []; }, + /** + * 根据网元类型过滤菜单 + * @param routes 经过clearMenuItem(router.getRoutes())处理 + * @param neTypes 网元类型 + * @returns 过滤后的菜单 + */ + clearMenuItemByNeList( + routes: RouteRecord[] | RouteRecordRaw[], + neTypes: string[] + ): RouteRecordRaw[] { + return routes + .map((item: RouteRecord | RouteRecordRaw) => { + const finalItem = { ...item }; + // 过滤网元类型 + if ( + Array.isArray(finalItem.meta?.neType) && + finalItem.meta?.neType.length > 0 + ) { + let metaNeType: string[] = finalItem.meta.neType; + let match = false; // 匹配 + for (const netype of metaNeType) { + if (netype.indexOf('+') > -1) { + metaNeType = netype.split('+'); + match = true; + break; + } + } + + if (match && !metaNeType.every(item => neTypes.includes(item))) { + // 同时匹配 + return null; + } else if (!metaNeType.some(item => neTypes.includes(item))) { + // 有一种 + return null; + } + } + + // 有子菜单进行递归 + if (finalItem.children && finalItem.children.length > 0) { + const children = this.clearMenuItemByNeList( + finalItem.children, + neTypes + ); + // 如果子菜单都被过滤掉了,就不显示 + if (children.length === 0) { + return null; + } + finalItem.children = children; + return finalItem; + } + + delete finalItem.children; + return finalItem; + }) + .filter(item => item) as RouteRecordRaw[]; + }, }, }); diff --git a/src/typings/router.d.ts b/src/typings/router.d.ts index d3ab65fb..295a7093 100644 --- a/src/typings/router.d.ts +++ b/src/typings/router.d.ts @@ -9,5 +9,7 @@ declare module 'vue-router' { permissions?: string[]; /**角色 */ roles?: string[]; + /**网元类型信息 */ + neType?: string[]; } }