permission.ts 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. import { RouteRecordRaw } from "vue-router";
  2. import { defineStore } from "pinia";
  3. import { constantRoutes } from "@/router";
  4. import { store } from "@/store";
  5. const modules = import.meta.glob("../../views/**/**.vue");
  6. // 不同角色,不同首页
  7. const Layout = () => import("@/layout/school.vue");
  8. const Admin = () => import("@/layout/admin.vue");
  9. // 角色【后台管理员】拥有的权限路由
  10. const schoolRoutes: RouteRecordRaw[] = JSON.parse(
  11. JSON.stringify([
  12. {
  13. path: "/",
  14. component: "AdminIndex",
  15. redirect: "/area",
  16. children: [
  17. {
  18. path: "area",
  19. component: "area/index",
  20. meta: { title: "区域级数据看板", icon: "homepage", keepAlive: true },
  21. },
  22. ],
  23. },
  24. ])
  25. );
  26. // 角色【学校负责人】拥有的权限路由
  27. const adminRoutes: RouteRecordRaw[] = JSON.parse(
  28. JSON.stringify([
  29. {
  30. path: "/",
  31. component: "SchoolIndex",
  32. redirect: "/dashboard",
  33. children: [
  34. {
  35. path: "dashboard",
  36. component: "dashboard",
  37. meta: { title: "数据看板", icon: "homepage", keepAlive: true },
  38. },
  39. {
  40. path: "class",
  41. component: "class",
  42. meta: { title: "班级管理", icon: "menu", keepAlive: true },
  43. },
  44. {
  45. path: "teacher",
  46. component: "teacher",
  47. meta: { title: "教师管理", icon: "menu", keepAlive: true },
  48. },
  49. {
  50. path: "student",
  51. component: "student",
  52. meta: { title: "学生管理", icon: "menu", keepAlive: true },
  53. },
  54. {
  55. path: "equipment",
  56. component: "equipment",
  57. meta: { title: "设备管理", icon: "menu", keepAlive: true },
  58. },
  59. {
  60. path: "training",
  61. component: "training",
  62. meta: { title: "训练管理", icon: "menu", keepAlive: true },
  63. },
  64. {
  65. path: "board",
  66. component: "board",
  67. meta: { title: "测评数据看板", icon: "menu", keepAlive: true },
  68. },
  69. ],
  70. },
  71. ])
  72. );
  73. /**
  74. * 递归过滤有权限的异步(动态)路由
  75. *
  76. * @param routes 接口返回的异步(动态)路由
  77. * @param roles 用户角色集合
  78. * @returns 返回用户有权限的异步(动态)路由
  79. */
  80. const filterAsyncRoutes = (routes: RouteRecordRaw[], roles: string[]) => {
  81. const asyncRoutes: RouteRecordRaw[] = [];
  82. routes.forEach((route) => {
  83. const tmpRoute = { ...route }; // ES6扩展运算符复制新对象
  84. if (tmpRoute.component?.toString() == "SchoolIndex") {
  85. tmpRoute.component = Layout;
  86. console.log("SchoolIndex");
  87. } else if (tmpRoute.component?.toString() == "AdminIndex") {
  88. console.log("AdminIndex");
  89. } else {
  90. const component = modules[`../../views/${tmpRoute.component}/index.vue`];
  91. if (component) {
  92. tmpRoute.component = component;
  93. } else {
  94. tmpRoute.component = modules[`../../views/error-page/404.vue`];
  95. }
  96. }
  97. if (tmpRoute.children) {
  98. tmpRoute.children = filterAsyncRoutes(tmpRoute.children, roles);
  99. }
  100. asyncRoutes.push(tmpRoute);
  101. });
  102. return asyncRoutes;
  103. };
  104. // setup
  105. export const usePermissionStore = defineStore("permission", () => {
  106. // state
  107. const routes = ref<RouteRecordRaw[]>([]);
  108. // actions
  109. function setRoutes(newRoutes: RouteRecordRaw[]) {
  110. routes.value = constantRoutes.concat(newRoutes);
  111. }
  112. /**
  113. * 生成动态路由
  114. *
  115. * @param roles 用户角色集合
  116. * @returns
  117. */
  118. function generateRoutes(roles: string[]) {
  119. return new Promise<RouteRecordRaw[]>((resolve, reject) => {
  120. // 角色【后台管理员】拥有权限
  121. if (roles.includes("ADMIN")) {
  122. // 根据角色获取有访问权限的路由
  123. const accessedRoutes = filterAsyncRoutes(adminRoutes, roles);
  124. setRoutes(accessedRoutes);
  125. resolve(accessedRoutes);
  126. }
  127. // 角色【学校负责人】拥有权限
  128. else if (roles.includes("SCHOOL")) {
  129. const accessedRoutes = filterAsyncRoutes(schoolRoutes, roles);
  130. setRoutes(accessedRoutes);
  131. resolve(accessedRoutes);
  132. } else {
  133. reject("没有访问权限");
  134. }
  135. });
  136. }
  137. return { routes, setRoutes, generateRoutes };
  138. });
  139. // 非setup
  140. export function usePermissionStoreHook() {
  141. return usePermissionStore(store);
  142. }