permission.ts 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. import { defineStore } from 'pinia'
  2. import router, { constantRoutes, dynamicRoutes } from '@/router'
  3. import store from '@/store'
  4. import { getRouters } from '@/api/menu'
  5. import Layout from '@/layout/index.vue'
  6. import ParentView from '@/components/ParentView/index.vue'
  7. import InnerLink from '@/layout/components/InnerLink/index.vue'
  8. import auth from '@/plugins/auth'
  9. import { RouteOption } from 'vue-router'
  10. // 匹配views里面所有的.vue文件
  11. const modules = import.meta.glob('./../../views/**/*.vue')
  12. export const usePermissionStore = defineStore('permission', () => {
  13. const routes = ref<RouteOption[]>([])
  14. const addRoutes = ref<RouteOption[]>([])
  15. const defaultRoutes = ref<RouteOption[]>([])
  16. const topbarRouters = ref<RouteOption[]>([])
  17. const sidebarRouters = ref<RouteOption[]>([])
  18. const setRoutes = (newRoutes: RouteOption[]): void => {
  19. addRoutes.value = newRoutes
  20. routes.value = constantRoutes.concat(newRoutes)
  21. }
  22. const setDefaultRoutes = (routes: RouteOption[]): void => {
  23. defaultRoutes.value = constantRoutes.concat(routes)
  24. }
  25. const setTopbarRoutes = (routes: RouteOption[]): void => {
  26. topbarRouters.value = routes
  27. }
  28. const setSidebarRouters = (routes: RouteOption[]): void => {
  29. sidebarRouters.value = routes
  30. }
  31. const generateRoutes = async (): Promise<RouteOption[]> => {
  32. const res = await getRouters()
  33. const { data } = res
  34. const sdata = JSON.parse(JSON.stringify(data))
  35. const rdata = JSON.parse(JSON.stringify(data))
  36. const defaultData = JSON.parse(JSON.stringify(data))
  37. const sidebarRoutes = filterAsyncRouter(sdata)
  38. const rewriteRoutes = filterAsyncRouter(rdata, undefined, true)
  39. const defaultRoutes = filterAsyncRouter(defaultData)
  40. const asyncRoutes = filterDynamicRoutes(dynamicRoutes)
  41. asyncRoutes.forEach((route) => {
  42. router.addRoute(route)
  43. })
  44. setRoutes(rewriteRoutes)
  45. setSidebarRouters(constantRoutes.concat(sidebarRoutes))
  46. setDefaultRoutes(sidebarRoutes)
  47. setTopbarRoutes(defaultRoutes)
  48. return new Promise<RouteOption[]>((resolve) => resolve(rewriteRoutes))
  49. }
  50. /**
  51. * 遍历后台传来的路由字符串,转换为组件对象
  52. * @param asyncRouterMap 后台传来的路由字符串
  53. * @param lastRouter 上一级路由
  54. * @param type 是否是重写路由
  55. */
  56. const filterAsyncRouter = (asyncRouterMap: RouteOption[], lastRouter?: RouteOption, type = false): RouteOption[] => {
  57. return asyncRouterMap.filter((route) => {
  58. if (type && route.children) {
  59. route.children = filterChildren(route.children, undefined)
  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. const filterChildren = (childrenMap: RouteOption[], lastRouter?: RouteOption): RouteOption[] => {
  83. let children: RouteOption[] = []
  84. childrenMap.forEach((el) => {
  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. return { routes, setRoutes, generateRoutes, setSidebarRouters, topbarRouters, sidebarRouters, defaultRoutes }
  106. })
  107. // 动态路由遍历,验证是否具备权限
  108. export const filterDynamicRoutes = (routes: RouteOption[]) => {
  109. const res: RouteOption[] = []
  110. routes.forEach((route) => {
  111. if (route.permissions) {
  112. if (auth.hasPermiOr(route.permissions)) {
  113. res.push(route)
  114. }
  115. } else if (route.roles) {
  116. if (auth.hasRoleOr(route.roles)) {
  117. res.push(route)
  118. }
  119. }
  120. })
  121. return res
  122. }
  123. export const loadView = (view: any) => {
  124. let res
  125. for (const path in modules) {
  126. const dir = path.split('views/')[1].split('.vue')[0]
  127. if (dir === view) {
  128. res = () => modules[path]()
  129. }
  130. }
  131. return res
  132. }
  133. // 非setup
  134. export const usePermissionStoreHook = () => {
  135. return usePermissionStore(store)
  136. }
  137. export default usePermissionStore