From 61adba1a821bd1b2cac301ae97d03425cdc522a1 Mon Sep 17 00:00:00 2001 From: wangxiang <1827945911@qq.com> Date: Fri, 15 Apr 2022 15:57:20 +0800 Subject: [PATCH] =?UTF-8?q?=E2=9A=97=20=E9=87=8D=E5=86=99=E7=99=BB?= =?UTF-8?q?=E5=BD=95=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kicc/admin/controller/MenuController.java | 6 +- kicc-ui/src/api/sys/menu.ts | 7 +- kicc-ui/src/router/guard/paramMenuGuard.ts | 2 +- kicc-ui/src/router/guard/permissionGuard.ts | 3 - kicc-ui/src/router/helper/menuHelper.ts | 4 +- kicc-ui/src/router/helper/routeHelper.ts | 90 +------------------ kicc-ui/src/router/index.ts | 3 +- kicc-ui/src/store/modules/permission.ts | 51 +++++------ kicc-ui/src/store/modules/user.ts | 7 +- kicc-ui/src/utils/helper/treeHelper.ts | 8 +- 10 files changed, 39 insertions(+), 142 deletions(-) diff --git a/kicc-system/kicc-system-biz/src/main/java/com/cloud/kicc/admin/controller/MenuController.java b/kicc-system/kicc-system-biz/src/main/java/com/cloud/kicc/admin/controller/MenuController.java index a206d657..53b2d092 100644 --- a/kicc-system/kicc-system-biz/src/main/java/com/cloud/kicc/admin/controller/MenuController.java +++ b/kicc-system/kicc-system-biz/src/main/java/com/cloud/kicc/admin/controller/MenuController.java @@ -65,7 +65,7 @@ public class MenuController { @SysLog("菜单新增") @PostMapping("/save") - //@PreAuthorize("@pms.hasPermission('menu_add')") + @PreAuthorize("@pms.hasPermission('menu_add')") public R save(@RequestBody Menu menu) { menuService.save(menu); return R.ok(); @@ -73,7 +73,7 @@ public class MenuController { @SysLog("菜单修改") @PutMapping("/update") - //@PreAuthorize("@pms.hasPermission('menu_edit')") + @PreAuthorize("@pms.hasPermission('menu_edit')") public R update(@RequestBody Menu menu) { menuService.updateById(menu); return R.ok(); @@ -81,7 +81,7 @@ public class MenuController { @SysLog("菜单删除") @DeleteMapping("/remove/{id:\\w+}") - //@PreAuthorize("@pms.hasPermission('menu_del')") + @PreAuthorize("@pms.hasPermission('menu_del')") public R remove(@PathVariable String id) { if (menuService.count(new QueryWrapper().eq("parent_id", id)) > 0) { return R.error("存在子菜单,不允许删除"); diff --git a/kicc-ui/src/api/sys/menu.ts b/kicc-ui/src/api/sys/menu.ts index cec860ca..c106cbee 100644 --- a/kicc-ui/src/api/sys/menu.ts +++ b/kicc-ui/src/api/sys/menu.ts @@ -2,13 +2,10 @@ import { defHttp } from '/@/utils/http/axios'; import { getMenuListResultModel } from './model/menuModel'; enum Api { - GetMenuList = '/system/menu/tree', + GetMenuList = '/admin/system/menu/menus', } -/** - * @description: Get user menu based on id - */ - +/** 获取用户菜单 */ export const getMenuList = () => { return defHttp.get({ url: Api.GetMenuList }); }; diff --git a/kicc-ui/src/router/guard/paramMenuGuard.ts b/kicc-ui/src/router/guard/paramMenuGuard.ts index 50925492..322eb7d6 100644 --- a/kicc-ui/src/router/guard/paramMenuGuard.ts +++ b/kicc-ui/src/router/guard/paramMenuGuard.ts @@ -19,7 +19,7 @@ export function createParamMenuGuard(router: Router) { next(); return; } - // 菜单已建立。 + // 检测是否菜单已建立 if (!permissionStore.getIsDynamicAddedRoute) { next(); return; diff --git a/kicc-ui/src/router/guard/permissionGuard.ts b/kicc-ui/src/router/guard/permissionGuard.ts index 5104392f..3140a70e 100644 --- a/kicc-ui/src/router/guard/permissionGuard.ts +++ b/kicc-ui/src/router/guard/permissionGuard.ts @@ -79,13 +79,10 @@ export function createPermissionGuard(router: Router) { } const routes = await permissionStore.buildRoutesAction(); - routes.forEach((route) => { router.addRoute(route as unknown as RouteRecordRaw); }); - router.addRoute(PAGE_NOT_FOUND_ROUTE as unknown as RouteRecordRaw); - permissionStore.setDynamicAddedRoute(true); if (to.name === PAGE_NOT_FOUND_ROUTE.name) { diff --git a/kicc-ui/src/router/helper/menuHelper.ts b/kicc-ui/src/router/helper/menuHelper.ts index fbec5637..bed0987c 100644 --- a/kicc-ui/src/router/helper/menuHelper.ts +++ b/kicc-ui/src/router/helper/menuHelper.ts @@ -69,9 +69,7 @@ export function transformRouteToMenu(routeModList: AppRouteModule[], routerMappi return cloneDeep(list); } -/** - * 带有给定参数的配置菜单 - */ +/** 带有给定参数的配置菜单 */ const menuParamRegex = /(?::)([\s\S]+?)((?=\/)|$)/g; export function configureDynamicParamsMenu(menu: Menu, params: RouteParams) { const { path, paramPath } = toRaw(menu); diff --git a/kicc-ui/src/router/helper/routeHelper.ts b/kicc-ui/src/router/helper/routeHelper.ts index 3adc994a..4de5570b 100644 --- a/kicc-ui/src/router/helper/routeHelper.ts +++ b/kicc-ui/src/router/helper/routeHelper.ts @@ -7,20 +7,14 @@ */ import type { AppRouteModule, AppRouteRecordRaw } from '/@/router/types'; -import type { Router, RouteRecordNormalized } from 'vue-router'; - import { getParentLayout, LAYOUT } from '/@/router/constant'; -import { cloneDeep, omit } from 'lodash-es'; +import { cloneDeep } from 'lodash-es'; import { warn } from '/@/utils/log'; -import { createRouter, createWebHashHistory } from 'vue-router'; - const IFRAME = () => import('/@/views/sys/iframe/FrameBlank.vue'); - const LayoutMap = new Map Promise>(); LayoutMap.set('LAYOUT', LAYOUT); LayoutMap.set('IFRAME', IFRAME); - let dynamicViewsModules: Record Promise>; function asyncImportRoute(routes: AppRouteRecordRaw[] | undefined) { @@ -46,10 +40,7 @@ function asyncImportRoute(routes: AppRouteRecordRaw[] | undefined) { }); } -function dynamicImport( - dynamicViewsModules: Record Promise>, - component: string -) { +function dynamicImport(dynamicViewsModules: Record Promise>, component: string) { const keys = Object.keys(dynamicViewsModules); const matchKeys = keys.filter((key) => { let k = key.replace('../../views', ''); @@ -62,14 +53,12 @@ function dynamicImport( return dynamicViewsModules[matchKey]; } if (matchKeys?.length > 1) { - warn( - 'Please do not create `.vue` and `.TSX` files with the same file name in the same hierarchical directory under the views folder. This will cause dynamic introduction failure' - ); + warn('Please do not create `.vue` and `.TSX` files with the same file name in the same hierarchical directory under the views folder. This will cause dynamic introduction failure'); return; } } -// 将菜单对象变成路由对象 +/** 将菜单对象变成路由对象 */ export function transformObjToRoute(routeList: AppRouteModule[]): T[] { routeList.forEach((route) => { const component = route.component as string; @@ -91,74 +80,3 @@ export function transformObjToRoute(routeList: AppRouteModul }); return routeList as unknown as T[]; } - -/** - * 将多级路由转换为 2 级路由 - */ -export function flatMultiLevelRoutes(routeModules: AppRouteModule[]) { - const modules: AppRouteModule[] = cloneDeep(routeModules); - for (let index = 0; index < modules.length; index++) { - const routeModule = modules[index]; - if (!isMultipleRoute(routeModule)) { - continue; - } - promoteRouteLevel(routeModule); - } - return modules; -} - -// 路由等级升级 -function promoteRouteLevel(routeModule: AppRouteModule) { - // 使用vue-router拼接菜单 - let router: Router | null = createRouter({ - routes: [routeModule as unknown as RouteRecordNormalized], - history: createWebHashHistory(), - }); - - const routes = router.getRoutes(); - addToChildren(routes, routeModule.children || [], routeModule); - router = null; - - routeModule.children = routeModule.children?.map((item) => omit(item, 'children')); -} - -// 将所有子路由添加到二级路由 -function addToChildren( - routes: RouteRecordNormalized[], - children: AppRouteRecordRaw[], - routeModule: AppRouteModule -) { - for (let index = 0; index < children.length; index++) { - const child = children[index]; - const route = routes.find((item) => item.name === child.name); - if (!route) { - continue; - } - routeModule.children = routeModule.children || []; - if (!routeModule.children.find((item) => item.name === route.name)) { - routeModule.children?.push(route as unknown as AppRouteModule); - } - if (child.children?.length) { - addToChildren(routes, child.children, routeModule); - } - } -} - -// 判断级别是否超过2级 -function isMultipleRoute(routeModule: AppRouteModule) { - if (!routeModule || !Reflect.has(routeModule, 'children') || !routeModule.children?.length) { - return false; - } - - const children = routeModule.children; - - let flag = false; - for (let index = 0; index < children.length; index++) { - const child = children[index]; - if (child.children?.length) { - flag = true; - break; - } - } - return flag; -} diff --git a/kicc-ui/src/router/index.ts b/kicc-ui/src/router/index.ts index 7157ebcb..b1709a45 100644 --- a/kicc-ui/src/router/index.ts +++ b/kicc-ui/src/router/index.ts @@ -22,8 +22,7 @@ getRouteNames(basicRoutes); // 应用路由器 export const router = createRouter({ - // @ts-ignore - history: createWebHashHistory(import.meta.env.VITE_PUBLIC_PATH), + history: createWebHashHistory(import.meta.env.VITE_PUBLIC_PATH as string), routes: basicRoutes as unknown as RouteRecordRaw[], strict: true, scrollBehavior: () => ({ left: 0, top: 0 }), diff --git a/kicc-ui/src/store/modules/permission.ts b/kicc-ui/src/store/modules/permission.ts index d7e563a2..5ee21547 100644 --- a/kicc-ui/src/store/modules/permission.ts +++ b/kicc-ui/src/store/modules/permission.ts @@ -11,7 +11,7 @@ import { defineStore } from 'pinia'; import { store } from '/@/store'; import { useI18n } from '/@/hooks/web/useI18n'; import { useUserStore } from './user'; -import { transformObjToRoute, flatMultiLevelRoutes } from '/@/router/helper/routeHelper'; +import { transformObjToRoute } from '/@/router/helper/routeHelper'; import { transformRouteToMenu } from '/@/router/helper/menuHelper'; import { PAGE_NOT_FOUND_ROUTE } from '/@/router/routes/basic'; import { filter } from '/@/utils/helper/treeHelper'; @@ -75,9 +75,7 @@ export const usePermissionStore = defineStore({ return !ignoreRoute; }; - /** - * 根据设置的首页path,修正routes中的affix标记(固定首页) - */ + /** 根据设置的首页path,修正routes中的affix标记(固定首页) */ const patchHomeAffix = (routes: AppRouteRecordRaw[]) => { if (!routes || routes.length === 0) return; let homePath: string = userStore.getUserInfo.homePath || PageEnum.BASE_HOME; @@ -88,7 +86,7 @@ export const usePermissionStore = defineStore({ const currentPath = path.startsWith('/') ? path : parentPath + path; if (currentPath === homePath) { if (redirect) { - homePath = route.redirect! as string; + homePath = route.redirect as string; } else { route.meta = Object.assign({}, route.meta, { affix: true }); throw new Error('end'); @@ -100,42 +98,33 @@ export const usePermissionStore = defineStore({ try { patcher(routes); } catch (e) { - // 已处理完毕跳出循环 + // 固定首页已处理完毕跳出循环 + return; } - return; }; - // 如果确定不需要做后台动态权限,请在下方评论整个判断 + /** 提示菜单正在加载中 */ const { createMessage } = useMessage(); createMessage.loading({ content: t('sys.app.menuLoading'), duration: 1, }); - // !模拟从后台获取权限码, - // 这个功能可能只需要执行一次,实际项目可以自己放在合适的时间 - let routeList: AppRouteRecordRaw[] = []; - try { - routeList = (await getMenuList()) as AppRouteRecordRaw[]; - } catch (error) { + /** 构建菜单与路由 */ + return (await getMenuList().then(data=> { + let routeList = data; + // 将菜单对象变成路由对象 + routeList = transformObjToRoute(routeList); + const menuList = transformRouteToMenu(routeList); + this.setMenuList(menuList); + // 过滤忽略路由配置项,只构建菜单不构建路由 + routeList = filter(routeList, routeRemoveIgnoreFilter); + routes = [PAGE_NOT_FOUND_ROUTE, ...routeList]; + patchHomeAffix(routes); + return routes; + }).catch(error => { console.error(error); - } - - // 动态引入组件 - routeList = transformObjToRoute(routeList); - - // 后台路由到菜单结构 - const menuList = transformRouteToMenu(routeList); - this.setMenuList(menuList); - - // 删除 meta.ignoreRoute 项目 - routeList = filter(routeList, routeRemoveIgnoreFilter); - routeList = routeList.filter(routeRemoveIgnoreFilter); - routeList = flatMultiLevelRoutes(routeList); - routes = [PAGE_NOT_FOUND_ROUTE, ...routeList]; - - patchHomeAffix(routes); - return routes; + })) as AppRouteRecordRaw[]; }, }, }); diff --git a/kicc-ui/src/store/modules/user.ts b/kicc-ui/src/store/modules/user.ts index 68eba3d2..7a36f17d 100644 --- a/kicc-ui/src/store/modules/user.ts +++ b/kicc-ui/src/store/modules/user.ts @@ -103,16 +103,16 @@ export const useUserStore = defineStore({ const { access_token, refresh_token } = data; this.setAccessToken(access_token); this.setRefreshToken(refresh_token); + // 获取用户信息 const userInfo = await this.getUserInfoAction(); - - const sessionTimeout = this.sessionTimeout; if (sessionTimeout) { this.setSessionTimeout(false); } else if (goHome) { - + // 处理路由与菜单的构建,并且进行缓存 const permissionStore = usePermissionStore(); + // 使用isDynamicAddedRoute字段做菜单路由缓存功能 if (!permissionStore.isDynamicAddedRoute) { const routes = await permissionStore.buildRoutesAction(); routes.forEach((route) => { @@ -122,7 +122,6 @@ export const useUserStore = defineStore({ permissionStore.setDynamicAddedRoute(true); } await router.replace(userInfo.homePath || PageEnum.BASE_HOME); - } return userInfo; } catch (error) { diff --git a/kicc-ui/src/utils/helper/treeHelper.ts b/kicc-ui/src/utils/helper/treeHelper.ts index c4a6e797..0a4acd3e 100644 --- a/kicc-ui/src/utils/helper/treeHelper.ts +++ b/kicc-ui/src/utils/helper/treeHelper.ts @@ -8,12 +8,12 @@ interface TreeHelperConfig { id: string; children: string; - pid: string; + parentId: string; } const DEFAULT_CONFIG: TreeHelperConfig = { id: 'id', children: 'children', - pid: 'pid', + parentId: 'parentId', }; const getConfig = (config: Partial) => Object.assign({}, DEFAULT_CONFIG, config); @@ -23,14 +23,14 @@ export function listToTree(list: any[], config: Partial