permission.ts 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302
  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 adminRoutes: RouteRecordRaw[] = JSON.parse(
  11. JSON.stringify([
  12. {
  13. path: "/",
  14. redirect: "/areaBoard",
  15. meta: {hidden: true, breadcrumb: false, name: "Home"},
  16. },
  17. {
  18. path: "/areaBoard",
  19. component: "AdminIndex",
  20. redirect: "/areaBoard/index",
  21. meta: {title: "区域级数据看板", name: "AreaBoard"},
  22. children: [
  23. {
  24. path: "index",
  25. component: "admin/area/index",
  26. meta: {
  27. title: "区域级数据看板",
  28. name: "DashboardArea",
  29. icon: "board",
  30. keepAlive: true,
  31. breadcrumb: false,
  32. },
  33. },
  34. ],
  35. },
  36. {
  37. path: "/schoolBoard",
  38. component: "AdminIndex",
  39. redirect: "/schoolBoard/index",
  40. meta: {title: "学校级数据看板", name: "SchoolBoard"},
  41. children: [
  42. {
  43. path: "index",
  44. component: "admin/school/index",
  45. meta: {
  46. title: "学校级数据看板",
  47. name: "DashboardSchool",
  48. icon: "board",
  49. keepAlive: true,
  50. breadcrumb: false,
  51. },
  52. },
  53. ],
  54. },
  55. ])
  56. );
  57. // 角色【学校负责人】拥有的权限路由
  58. const schoolRoutes: RouteRecordRaw[] = JSON.parse(
  59. JSON.stringify([
  60. {
  61. path: "/",
  62. redirect: "/dashboard",
  63. meta: {hidden: true, breadcrumb: false, name: "Home"},
  64. },
  65. {
  66. path: "/dashboard",
  67. component: "SchoolIndex",
  68. redirect: "/dashboard/index",
  69. meta: {title: "数据看板", name: "Dashboard"},
  70. children: [
  71. {
  72. path: "index",
  73. component: "customer/dashboard/index",
  74. meta: {
  75. title: "数据看板",
  76. name: "DashboardIndex",
  77. icon: "board",
  78. keepAlive: true,
  79. breadcrumb: false,
  80. },
  81. },
  82. {
  83. path: "example",
  84. component: "customer/dashboard/example",
  85. meta: {
  86. title: "优秀教学效果示例",
  87. name: "DashboardExample",
  88. hidden: true,
  89. },
  90. },
  91. ],
  92. },
  93. {
  94. path: "/grade",
  95. component: "SchoolIndex",
  96. redirect: "/grade/index",
  97. meta: {title: "班级管理", name: "ClassManage"},
  98. children: [
  99. {
  100. path: "index",
  101. component: "customer/grade/index",
  102. meta: {
  103. title: "班级管理",
  104. name: "ClassIndex",
  105. icon: "class",
  106. keepAlive: true,
  107. breadcrumb: false,
  108. },
  109. },
  110. ],
  111. },
  112. {
  113. path: "/teacher",
  114. component: "SchoolIndex",
  115. redirect: "/teacher/index",
  116. meta: {title: "教师管理", name: "TeacherManage"},
  117. children: [
  118. {
  119. path: "index",
  120. component: "customer/teacher/index",
  121. meta: {
  122. title: "教师管理",
  123. name: "TeacherIndex",
  124. icon: "teacher",
  125. keepAlive: true,
  126. breadcrumb: false,
  127. },
  128. },
  129. ],
  130. },
  131. {
  132. path: "/student",
  133. component: "SchoolIndex",
  134. redirect: "/student/index",
  135. meta: {title: "学生管理", name: "StudentManage"},
  136. children: [
  137. {
  138. path: "index",
  139. component: "customer/student/index",
  140. meta: {
  141. title: "学生管理",
  142. name: "StudentIndex",
  143. icon: "student",
  144. keepAlive: true,
  145. breadcrumb: false,
  146. },
  147. },
  148. {
  149. path: "result",
  150. component: "customer/student/result",
  151. meta: {title: "训练效果分析", name: "StudentResult", hidden: true},
  152. },
  153. ],
  154. },
  155. {
  156. path: "/download/student/result",
  157. component: "customer/student/download",
  158. meta: {title: "下载报告预览", name: "StudentDownload", hidden: true},
  159. },
  160. {
  161. path: "/equipment",
  162. component: "SchoolIndex",
  163. redirect: "/equipment/index",
  164. meta: {title: "设备管理", name: "EquipmentManage"},
  165. children: [
  166. {
  167. path: "index",
  168. component: "customer/equipment/index",
  169. meta: {
  170. title: "设备管理",
  171. name: "EquipmentIndex",
  172. icon: "equipment",
  173. keepAlive: true,
  174. breadcrumb: false,
  175. },
  176. },
  177. ],
  178. },
  179. {
  180. path: "/training",
  181. component: "SchoolIndex",
  182. redirect: "/training/index",
  183. meta: {title: "训练管理", name: "TrainingManage"},
  184. children: [
  185. {
  186. path: "index",
  187. component: "customer/training/index",
  188. meta: {
  189. title: "训练记录",
  190. name: "TrainingIndex",
  191. icon: "training",
  192. keepAlive: true,
  193. breadcrumb: false,
  194. },
  195. },
  196. {
  197. path: "result",
  198. component: "customer/training/result",
  199. meta: {title: "报告详情", name: "TrainingResult", hidden: true},
  200. },
  201. ],
  202. },
  203. {
  204. path: "/evaluation",
  205. component: "SchoolIndex",
  206. redirect: "/evaluation/index",
  207. meta: {title: "测评数据看板", name: "EvaluateManage"},
  208. children: [
  209. {
  210. path: "index",
  211. component: "customer/evaluation/index",
  212. meta: {
  213. title: "测评数据看板",
  214. name: "EvaluateIndex",
  215. icon: "evaluation",
  216. keepAlive: true,
  217. breadcrumb: false,
  218. },
  219. },
  220. ],
  221. },
  222. ])
  223. );
  224. /**
  225. * 递归过滤有权限的异步(动态)路由
  226. *
  227. * @param routes 接口返回的异步(动态)路由
  228. * @param role 用户角色集合
  229. * @returns 返回用户有权限的异步(动态)路由
  230. */
  231. const filterAsyncRoutes = (routes: RouteRecordRaw[], role: string | null) => {
  232. const asyncRoutes: RouteRecordRaw[] = [];
  233. routes.forEach((route) => {
  234. const tmpRoute = {...route}; // ES6扩展运算符复制新对象
  235. if (tmpRoute.component?.toString() == "SchoolIndex") {
  236. tmpRoute.component = Layout;
  237. } else if (tmpRoute.component?.toString() == "AdminIndex") {
  238. tmpRoute.component = Admin;
  239. } else {
  240. const component = modules[`../../views/${tmpRoute.component}.vue`];
  241. if (component) {
  242. tmpRoute.component = component;
  243. } else {
  244. tmpRoute.component = modules[`../../views/error-page/404.vue`];
  245. }
  246. }
  247. if (tmpRoute.children) {
  248. tmpRoute.children = filterAsyncRoutes(tmpRoute.children, role);
  249. }
  250. asyncRoutes.push(tmpRoute);
  251. });
  252. return asyncRoutes;
  253. };
  254. // setup
  255. export const usePermissionStore = defineStore("permission", () => {
  256. // state
  257. const routes = ref<RouteRecordRaw[]>([]);
  258. // actions
  259. function setRoutes(newRoutes: RouteRecordRaw[]) {
  260. routes.value = constantRoutes.concat(newRoutes);
  261. }
  262. /**
  263. * 生成动态路由
  264. *
  265. * @param role 用户角色集合
  266. * @returns
  267. */
  268. function generateRoutes(role: string | null) {
  269. return new Promise<RouteRecordRaw[]>((resolve, reject) => {
  270. console.log("role", role);
  271. // 角色【后台管理员】拥有权限
  272. if (role && role == "ADMIN") {
  273. // 根据角色获取有访问权限的路由
  274. const accessedRoutes = filterAsyncRoutes(adminRoutes, role);
  275. setRoutes(accessedRoutes);
  276. resolve(accessedRoutes);
  277. }
  278. // 角色【学校负责人】拥有权限
  279. else if (role && role == "SCHOOL") {
  280. const accessedRoutes = filterAsyncRoutes(schoolRoutes, role);
  281. setRoutes(accessedRoutes);
  282. resolve(accessedRoutes);
  283. } else {
  284. reject("没有访问权限");
  285. }
  286. });
  287. }
  288. return {routes, setRoutes, generateRoutes};
  289. });
  290. // 非setup
  291. export function usePermissionStoreHook() {
  292. return usePermissionStore(store);
  293. }