index.ts 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. import { defineAsyncComponent, Component } from 'vue'
  2. import { useRoute, useRouter } from 'vue-router'
  3. import { sessionData } from '@/stores'
  4. import { AuthType } from '@/constants/enum/menu'
  5. import { AuthMenu } from './interface'
  6. export function useAuth(code?: string) {
  7. const route = useRoute()
  8. const router = useRouter()
  9. const userMenus = sessionData.getValue('userMenus')
  10. const componentMap = new Map<string, Component>()
  11. /**
  12. * 获取路由菜单(无限级)
  13. * @param level
  14. * @returns
  15. */
  16. const getMenus = (level = 0) => {
  17. // 过滤层级
  18. const filterLevel = (list: Ermcp.UserMenu[], n: number): Ermcp.UserMenu[] => {
  19. if (level) {
  20. return list.map((e) => ({ ...e, children: n <= 1 ? [] : filterLevel(e.children ?? [], n - 1) }))
  21. }
  22. return list
  23. }
  24. // 过滤菜单
  25. const filterMenu = (list: Ermcp.UserMenu[], parentPath = '') => {
  26. const result: AuthMenu[] = []
  27. list.forEach((e) => {
  28. if (e.authType === AuthType.Menu) {
  29. const routePath = (parentPath ? parentPath + '/' : '') + e.url
  30. result.push({
  31. path: routePath,
  32. name: e.code,
  33. label: e.title,
  34. icon: e.icon,
  35. children: e.children ? filterMenu(e.children, routePath) : [],
  36. })
  37. }
  38. })
  39. return result
  40. }
  41. return filterMenu(filterLevel(userMenus, level))
  42. }
  43. /**
  44. * 获取路由子菜单
  45. * @param routeName
  46. * @returns
  47. */
  48. const getChildrenMenus = (routeName?: string) => {
  49. const filter = (list: AuthMenu[]): AuthMenu[] => {
  50. if (routeName) {
  51. for (const item of list) {
  52. const { name, children } = item
  53. if (name === routeName) return children ?? []
  54. if (children) {
  55. const res = filter(children)
  56. if (res.length) return res
  57. }
  58. }
  59. }
  60. return []
  61. }
  62. return filter(getMenus())
  63. }
  64. /**
  65. * 获取权限子菜单
  66. * @returns
  67. */
  68. const getChildrenAuth = () => {
  69. const routeName = code ?? route.name?.toString()
  70. const filter = (list: Ermcp.UserMenu[]): Ermcp.UserMenu | undefined => {
  71. if (routeName) {
  72. for (const item of list) {
  73. const { code, children } = item;
  74. if (code === routeName) return item;
  75. if (children) {
  76. const res = filter(children);
  77. if (res) return res;
  78. }
  79. }
  80. }
  81. return undefined;
  82. }
  83. return filter(userMenus);
  84. }
  85. /**
  86. * 获取操作权限
  87. * @returns
  88. */
  89. const getAuth = (authType: AuthType) => {
  90. const auth = getChildrenAuth();
  91. if (auth && auth.children) {
  92. return auth.children.reduce((res, cur) => {
  93. if (cur.authType === authType) {
  94. if (!componentMap.get(cur.code) && cur.component) {
  95. const componentString = cur.component.replace(/^\/+/, ''); // 过滤字符串前面所有 '/' 字符
  96. const componentPath = componentString.replace(/\.\w+$/, ''); // 过滤后缀名,为了让 import 加入 .vue ,不然会有警告提示...
  97. const asyncComponent = defineAsyncComponent({
  98. loader: () => import('/' + process.env.VUE_APP_ROOT + componentPath + '.vue'),
  99. });
  100. componentMap.set(cur.code, asyncComponent);
  101. }
  102. res.push(cur);
  103. }
  104. return res;
  105. }, [] as Ermcp.UserMenu[])
  106. }
  107. return [];
  108. }
  109. /**
  110. * 过滤操作权限
  111. * @param filtered 过滤的数据项
  112. * @param reverse 是否反向过滤
  113. * @returns
  114. */
  115. const authFilter = (authType: AuthType, filtered: string[], reverse: boolean) => {
  116. const auth = getAuth(authType);
  117. if (filtered.length) {
  118. if (reverse) {
  119. // 返回除指定的权限代码
  120. return auth.filter((e) => !filtered.includes(e.code));
  121. } else {
  122. // 返回指定的权限代码
  123. return auth.filter((e) => filtered.includes(e.code));
  124. }
  125. }
  126. return auth;
  127. }
  128. /**
  129. * 获取权限按钮
  130. * @param filtered
  131. * @param reverse
  132. * @returns
  133. */
  134. const getAuthButton = (filtered: string[] = [], reverse = false) => authFilter(AuthType.Button, filtered, reverse);
  135. /**
  136. * 获取权限组件
  137. * @param filtered
  138. * @param reverse
  139. * @returns
  140. */
  141. const getAuthComponent = (filtered: string[] = [], reverse = false) => authFilter(AuthType.Component, filtered, reverse);
  142. return {
  143. route,
  144. router,
  145. userMenus,
  146. componentMap,
  147. getMenus,
  148. getChildrenMenus,
  149. getAuthButton,
  150. getAuthComponent,
  151. }
  152. }