permissions.ts 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. import { defineStore } from 'pinia'
  2. import { Permission } from '/admin/types/permission'
  3. import { MenuType } from '/admin/enum/app'
  4. import { Menu } from '/admin/types/Menu'
  5. import { constantRoutes } from '/admin/router'
  6. import { RouteRecordRaw } from 'vue-router'
  7. import { toRaw } from 'vue'
  8. import { getModuleViewComponents } from '/admin/router/constantRoutes'
  9. interface Permissions {
  10. menus: Menu[]
  11. asyncMenus: Menu[]
  12. permissions: Permission[]
  13. menuPathMap: Map<string, string>
  14. }
  15. export const usePermissionsStore = defineStore('PermissionsStore', {
  16. state: (): Permissions => {
  17. return {
  18. menus: [],
  19. asyncMenus: [],
  20. permissions: [],
  21. menuPathMap: new Map(),
  22. }
  23. },
  24. /**
  25. * get
  26. */
  27. getters: {
  28. getMenus(): Menu[] {
  29. return this.menus
  30. },
  31. getAsyncMenus(): Menu[] {
  32. return this.asyncMenus
  33. },
  34. getPermissions(): Permission[] {
  35. return this.permissions
  36. },
  37. getMenuPathMap(): Map<string, string> {
  38. return this.menuPathMap
  39. },
  40. },
  41. /**
  42. * actions
  43. */
  44. actions: {
  45. /**
  46. * generate async menus
  47. * @param permissions
  48. * @param force
  49. * @returns
  50. */
  51. getAsyncMenusFrom(permissions: Permission[], force: boolean = false): Menu[] {
  52. // 如果非强制获取并且 menu 有值,直接返回
  53. if (!force && this.asyncMenus.length > 0) {
  54. return this.asyncMenus
  55. }
  56. const menus: Permission[] = []
  57. permissions.forEach(permission => {
  58. if (permission.type === MenuType.PAGE_TYPE || permission.type === MenuType.TOP_TYPE) {
  59. menus.push(permission)
  60. }
  61. // set map
  62. this.menuPathMap.set(permission.route, permission.permission_name)
  63. })
  64. this.setAsyncMenus(this.getAsnycMenus(menus, 0, '', getModuleViewComponents()))
  65. return this.asyncMenus
  66. },
  67. /**
  68. * get menus
  69. * @param permissions
  70. * @param force
  71. * @returns
  72. */
  73. getMenusFrom(permissions: Permission[], force: boolean = false): Menu[] {
  74. // 如果非强制获取并且 menu 有值,直接返回
  75. if (!force && this.menus.length > 0) {
  76. return this.menus
  77. }
  78. const asyncMenus = this.getAsyncMenusFrom(permissions, force)
  79. this.setMenus(toRaw(asyncMenus))
  80. return this.menus
  81. },
  82. /**
  83. * set menus
  84. *
  85. * @param menus
  86. */
  87. setMenus(menus: Menu[]) {
  88. this.menus = this.transformRoutesToMenus(constantRoutes).concat(menus)
  89. },
  90. setAsyncMenus(menus: Menu[]) {
  91. this.asyncMenus = menus
  92. },
  93. /**
  94. * 生成 Menus
  95. *
  96. * @param permissions
  97. * @param parentId
  98. * @param path
  99. * @param viewComponents
  100. * @returns
  101. */
  102. getAsnycMenus(permissions: Permission[], parentId: number = 0, path: string = '', viewComponents: any): Menu[] {
  103. const menus: Menu[] = []
  104. permissions.forEach(permission => {
  105. if (permission.parent_id === parentId) {
  106. // menu
  107. let importComponent
  108. if (permission.type === MenuType.TOP_TYPE) {
  109. importComponent = () => import('/admin/layout/index.vue')
  110. } else {
  111. importComponent = viewComponents['/modules' + permission.component]
  112. }
  113. const menu: Menu = Object.assign({
  114. path: this.resolveRoutePathRoutePath(permission.route, path),
  115. name: permission.module + '_' + permission.permission_mark,
  116. component: importComponent,
  117. redirect: permission.redirect,
  118. meta: Object.assign({ title: permission.permission_name, icon: permission.icon, hidden: permission.hidden, active_menu: permission.active_menu }),
  119. })
  120. // child menu
  121. const children = this.getAsnycMenus(permissions, permission.id, menu.path, viewComponents)
  122. if (children.length > 0) {
  123. menu.children = children
  124. }
  125. menus.push(menu)
  126. }
  127. })
  128. return menus
  129. },
  130. /**
  131. * transform routes to menus
  132. * @param routes
  133. * @param path
  134. * @returns
  135. */
  136. transformRoutesToMenus(routes: Menu[] | Array<RouteRecordRaw>, path: string = ''): Menu[] {
  137. const menus: Menu[] = []
  138. routes.forEach(route => {
  139. if (route.meta?.hidden) {
  140. return false
  141. }
  142. const menu: Menu = Object.assign({
  143. path: this.resolveRoutePathRoutePath(route.path, path),
  144. name: route.name,
  145. meta: route.meta,
  146. component: route.component,
  147. })
  148. if (route.children?.length) {
  149. menu.children = this.transformRoutesToMenus(route.children, menu.path)
  150. }
  151. menus.push(menu)
  152. })
  153. return menus
  154. },
  155. /**
  156. * resolve path
  157. * @param route
  158. * @param path
  159. * @returns
  160. */
  161. resolveRoutePathRoutePath(route: string, path: string): string {
  162. if (path.length) {
  163. return (path + (route.indexOf('/') === -1 ? '/' : '') + route).replace(/\/$/g, '')
  164. }
  165. // 去除尾部的 /
  166. return route.replace(/\/$/g, '')
  167. },
  168. },
  169. })