generate-routes-frontend.ts 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. import type { RouteRecordRaw } from 'vue-router';
  2. import { filterTree, mapTree } from '@vben-core/toolkit';
  3. /**
  4. * 动态生成路由 - 前端方式
  5. */
  6. async function generateRoutesByFrontend(
  7. routes: RouteRecordRaw[],
  8. roles: string[],
  9. forbiddenComponent?: RouteRecordRaw['component'],
  10. ): Promise<RouteRecordRaw[]> {
  11. // 根据角色标识过滤路由表,判断当前用户是否拥有指定权限
  12. const finalRoutes = filterTree(routes, (route) => {
  13. return hasVisible(route) && hasAuthority(route, roles);
  14. });
  15. if (!forbiddenComponent) {
  16. return finalRoutes;
  17. }
  18. // 如果有禁止访问的页面,将禁止访问的页面替换为403页面
  19. return mapTree(finalRoutes, (route) => {
  20. if (menuHasVisibleWithForbidden(route)) {
  21. route.component = forbiddenComponent;
  22. }
  23. return route;
  24. });
  25. }
  26. /**
  27. * 判断路由是否有权限访问
  28. * @param route
  29. * @param access
  30. */
  31. function hasAuthority(route: RouteRecordRaw, access: string[]) {
  32. const authority = route.meta?.authority;
  33. if (!authority) {
  34. return true;
  35. }
  36. const canAccess = access.some((value) => authority.includes(value));
  37. return canAccess || (!canAccess && menuHasVisibleWithForbidden(route));
  38. }
  39. /**
  40. * 判断路由是否需要在菜单中显示
  41. * @param route
  42. */
  43. function hasVisible(route?: RouteRecordRaw) {
  44. return !route?.meta?.hideInMenu;
  45. }
  46. /**
  47. * 判断路由是否在菜单中显示,但是访问会被重定向到403
  48. * @param route
  49. */
  50. function menuHasVisibleWithForbidden(route: RouteRecordRaw) {
  51. return (
  52. !!route.meta?.authority &&
  53. Reflect.has(route.meta || {}, 'menuVisibleWithForbidden') &&
  54. !!route.meta?.menuVisibleWithForbidden
  55. );
  56. }
  57. export { generateRoutesByFrontend, hasAuthority, hasVisible };