permissionGuard.ts 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. import type { Router, RouteRecordRaw } from 'vue-router';
  2. import { usePermissionStoreWithOut } from '@jeesite/core/store/modules/permission';
  3. import { RootRoute } from '@jeesite/core/router/routes';
  4. import { PageEnum } from '@jeesite/core/enums/pageEnum';
  5. import { PAGE_NOT_FOUND_ROUTE } from '@jeesite/core/router/routes/basic';
  6. const ROOT_PATH = RootRoute.path;
  7. const HOME_PATH = PageEnum.BASE_HOME;
  8. function ensurePageNotFoundRoute(router: Router) {
  9. if (!router.hasRoute(PAGE_NOT_FOUND_ROUTE.name as string)) {
  10. router.addRoute(PAGE_NOT_FOUND_ROUTE as unknown as RouteRecordRaw);
  11. }
  12. }
  13. export function createPermissionGuard(router: Router) {
  14. const permissionStore = usePermissionStoreWithOut();
  15. router.beforeEach(async (to, from, next) => {
  16. // 授权页面在 basicRoutes 中始终存在,不需要权限检查
  17. if (to.path === PageEnum.BASE_AUTHORIZATION) {
  18. next();
  19. return;
  20. }
  21. // 如果路由已经动态添加过,直接放行
  22. if (permissionStore.getIsDynamicAddedRoute) {
  23. if (to.name === PAGE_NOT_FOUND_ROUTE.name) {
  24. next({ path: PageEnum.BASE_HOME, replace: true });
  25. return;
  26. }
  27. next();
  28. return;
  29. }
  30. if (from.path === ROOT_PATH && to.path === HOME_PATH) {
  31. // 首次导航,需要生成路由和菜单数据
  32. const routes = await permissionStore.buildRoutesAction();
  33. routes.forEach((route) => {
  34. router.addRoute(route as unknown as RouteRecordRaw);
  35. });
  36. ensurePageNotFoundRoute(router);
  37. permissionStore.setDynamicAddedRoute(true);
  38. // 已经是目标路径,直接放行
  39. next();
  40. return;
  41. }
  42. const routes = await permissionStore.buildRoutesAction();
  43. routes.forEach((route) => {
  44. router.addRoute(route as unknown as RouteRecordRaw);
  45. });
  46. ensurePageNotFoundRoute(router);
  47. permissionStore.setDynamicAddedRoute(true);
  48. if (to.name === PAGE_NOT_FOUND_ROUTE.name) {
  49. // 动态添加路由后,此处应当重定向到fullPath,否则会加载404页面内容
  50. next({ path: to.fullPath, replace: true, query: to.query });
  51. } else {
  52. const redirectPath = (from.query.redirect || to.path) as string;
  53. const redirect = decodeURIComponent(redirectPath);
  54. const nextData = to.path === redirect ? { ...to, replace: true } : { path: redirect };
  55. next(nextData);
  56. }
  57. });
  58. }