permission.js 4.2 KB

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