permission.js 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. import auth from '@/plugins/auth';
  2. import router, { constantRoutes, dynamicRoutes } from '@/router';
  3. import { getRouters } from '@/api/system/menu.js';
  4. import Layout from '@/layout/index';
  5. import ParentView from '@/components/ParentView';
  6. import InnerLink from '@/layout/components/InnerLink';
  7. // 匹配views里面所有的.vue文件
  8. const modules = import.meta.glob('./../../views/**/*.vue');
  9. const usePermissionStore = defineStore('permission', {
  10. state: () => ({
  11. routes: [],
  12. addRoutes: [],
  13. defaultRoutes: [],
  14. topbarRouters: [],
  15. sidebarRouters: []
  16. }),
  17. actions: {
  18. setRoutes(routes) {
  19. this.addRoutes = routes;
  20. this.routes = constantRoutes.concat(routes);
  21. },
  22. setDefaultRoutes(routes) {
  23. this.defaultRoutes = constantRoutes.concat(routes);
  24. },
  25. setTopbarRoutes(routes) {
  26. this.topbarRouters = routes;
  27. },
  28. setSidebarRouters(routes) {
  29. this.sidebarRouters = routes;
  30. },
  31. generateRoutes(roles) {
  32. return new Promise((resolve) => {
  33. // 向后端请求路由数据
  34. getRouters().then((res) => {
  35. const sdata = JSON.parse(JSON.stringify(res.data));
  36. const rdata = JSON.parse(JSON.stringify(res.data));
  37. const defaultData = JSON.parse(JSON.stringify(res.data));
  38. const sidebarRoutes = filterAsyncRouter(sdata);
  39. const rewriteRoutes = filterAsyncRouter(rdata, false, true);
  40. const defaultRoutes = filterAsyncRouter(defaultData);
  41. const asyncRoutes = filterDynamicRoutes(dynamicRoutes);
  42. asyncRoutes.forEach((route) => {
  43. router.addRoute(route);
  44. });
  45. this.setRoutes(rewriteRoutes);
  46. this.setSidebarRouters(constantRoutes.concat(sidebarRoutes));
  47. this.setDefaultRoutes(sidebarRoutes);
  48. this.setTopbarRoutes(defaultRoutes);
  49. resolve(rewriteRoutes);
  50. });
  51. });
  52. },
  53. updateTopbarRoutes(routes) {
  54. const sdata = JSON.parse(JSON.stringify(routes));
  55. const rdata = JSON.parse(JSON.stringify(routes));
  56. const defaultData = JSON.parse(JSON.stringify(routes));
  57. const sidebarRoutes = filterAsyncRouter(sdata);
  58. const rewriteRoutes = filterAsyncRouter(rdata, false, true);
  59. const defaultRoutes = filterAsyncRouter(defaultData);
  60. this.setRoutes(rewriteRoutes);
  61. this.setSidebarRouters(constantRoutes.concat(sidebarRoutes));
  62. this.setDefaultRoutes(sidebarRoutes);
  63. this.setTopbarRoutes(defaultRoutes);
  64. }
  65. }
  66. });
  67. // 遍历后台传来的路由字符串,转换为组件对象
  68. function filterAsyncRouter(asyncRouterMap, lastRouter = false, type = false) {
  69. return asyncRouterMap.filter((route) => {
  70. if (type && route.children) {
  71. route.children = filterChildren(route.children);
  72. }
  73. if (route.component) {
  74. // Layout ParentView 组件特殊处理
  75. if (route.component === 'Layout') {
  76. route.component = Layout;
  77. } else if (route.component === 'ParentView') {
  78. route.component = ParentView;
  79. } else if (route.component === 'InnerLink') {
  80. route.component = InnerLink;
  81. } else {
  82. route.component = loadView(route.component);
  83. }
  84. }
  85. if (route.children != null && route.children && route.children.length) {
  86. route.children = filterAsyncRouter(route.children, route, type);
  87. } else {
  88. delete route['children'];
  89. delete route['redirect'];
  90. }
  91. return true;
  92. });
  93. }
  94. function filterChildren(childrenMap, lastRouter = false) {
  95. var children = [];
  96. childrenMap.forEach((el, index) => {
  97. if (el.children && el.children.length) {
  98. if (el.component === 'ParentView' && !lastRouter) {
  99. el.children.forEach((c) => {
  100. c.path = el.path + '/' + c.path;
  101. if (c.children && c.children.length) {
  102. children = children.concat(filterChildren(c.children, c));
  103. return;
  104. }
  105. children.push(c);
  106. });
  107. return;
  108. }
  109. }
  110. if (lastRouter) {
  111. el.path = lastRouter.path + '/' + el.path;
  112. if (el.children && el.children.length) {
  113. children = children.concat(filterChildren(el.children, el));
  114. return;
  115. }
  116. }
  117. children = children.concat(el);
  118. });
  119. return children;
  120. }
  121. // 动态路由遍历,验证是否具备权限
  122. export function filterDynamicRoutes(routes) {
  123. const res = [];
  124. routes.forEach((route) => {
  125. if (route.permissions) {
  126. if (auth.hasPermiOr(route.permissions)) {
  127. res.push(route);
  128. }
  129. } else if (route.roles) {
  130. if (auth.hasRoleOr(route.roles)) {
  131. res.push(route);
  132. }
  133. }
  134. });
  135. return res;
  136. }
  137. export const loadView = (view) => {
  138. let res;
  139. for (const path in modules) {
  140. const dir = path.split('views/')[1].split('.vue')[0];
  141. if (dir === view) {
  142. res = () => modules[path]();
  143. }
  144. }
  145. return res;
  146. };
  147. export default usePermissionStore;