permission.ts 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. import {type RouteRecordRaw} from 'vue-router'
  2. import {ElMessage} from 'element-plus'
  3. import {filterRouters, getMenuChildren, getBtnAuth, getQueryString} from './index'
  4. import {saveCommonRoute} from '@common/src/api';
  5. import {COMMON_APP} from '@common/src/constants';
  6. import {useDebounceFn} from '@vueuse/core'
  7. export interface ILoadType {
  8. routePath: any
  9. storeMAppPath: any
  10. hookProgressPath: any
  11. hookTitlePath: any
  12. storeMPermissionPath: any
  13. hookLoadingPath: any
  14. constantsPath: any
  15. storeMUserPath: any
  16. apiLoginPath: any
  17. }
  18. export const loginLoad = async (sys_code, pathModule: ILoadType) => {
  19. const router = await pathModule.routePath
  20. const useAppStoreWithOut = await pathModule.storeMAppPath
  21. const useTitle = await pathModule.hookProgressPath
  22. const useNProgress = await pathModule.hookProgressPath
  23. const usePermissionStoreWithOut = await pathModule.storeMPermissionPath
  24. const usePageLoading = await pathModule.hookLoadingPath
  25. const NO_REDIRECT_WHITE_LIST = await pathModule.constantsPath
  26. const useUserStoreWithOut = await pathModule.storeMUserPath
  27. const {codeLogin, getAuthBtn, getMenuList} = await pathModule.apiLoginPath
  28. const {start, done} = useNProgress()
  29. const {loadStart, loadDone} = usePageLoading()
  30. const SYS_CODE = sys_code
  31. // 防抖处理函数
  32. const debounceFn = useDebounceFn(async (to, flag) => {
  33. // 埋点计数
  34. if (COMMON_APP.includes(to.fullPath)) {
  35. await saveCommonRoute({
  36. "appCode": flag,
  37. "routePath": to.fullPath
  38. })
  39. }
  40. }, 100)
  41. router.beforeEach(async (to, _from, next) => {
  42. start()
  43. loadStart()
  44. const permissionStore = usePermissionStoreWithOut()
  45. const appStore = useAppStoreWithOut()
  46. const userStore = useUserStoreWithOut()
  47. // const queryParams = new URLSearchParams(window.location.search)
  48. const code = getQueryString('code')
  49. const flag = getQueryString('flag') || sessionStorage.getItem('flag')
  50. appStore.setMenuTheme('#373f4e')
  51. debounceFn(to, flag)
  52. if (code && flag) {
  53. if (!userStore.getToken) {
  54. const state = getQueryString('state')
  55. const deptId = JSON.parse(state as string)?.deptId
  56. const {data} = await codeLogin({system: flag, code, deptId})
  57. userStore.setUserInfo(data)
  58. userStore.setToken(data.accessToken)
  59. sessionStorage.setItem('flag', flag || '')
  60. // 门户页进来页面跳转进入该方法
  61. await getRouter()
  62. // queryParams.delete('code')
  63. // queryParams.delete('flag')
  64. // queryParams.delete('state')
  65. const newUrl = `${window.location.pathname}`
  66. window.history.replaceState({}, '', newUrl)
  67. next()
  68. } else {
  69. if (NO_REDIRECT_WHITE_LIST.indexOf(to.path) !== -1) {
  70. next()
  71. } else {
  72. next(`/login?redirect=${to.path}`) // 否则全部重定向到登录页
  73. }
  74. }
  75. } else {
  76. if (userStore.getUserInfo) {
  77. if (to.path === '/login') {
  78. // next({path: '/'})
  79. ElMessage.warning('暂不支持直接键入登录页')
  80. next(false)
  81. } else {
  82. if (permissionStore.getIsAddRouters) {
  83. next()
  84. return
  85. }
  86. // 开发者可根据实际情况进行修改
  87. const roleRouters = userStore.getRoleRouters || []
  88. // 是否使用动态路由
  89. if (appStore.getDynamicRouter) {
  90. appStore.serverDynamicRouter
  91. ? await permissionStore.generateRoutes(
  92. 'server',
  93. roleRouters as AppCustomRouteRecordRaw[]
  94. )
  95. : await permissionStore.generateRoutes('frontEnd', roleRouters as string[])
  96. } else {
  97. await permissionStore.generateRoutes('static')
  98. }
  99. permissionStore.getAddRouters.forEach((route) => {
  100. console.log(route)
  101. router.addRoute(route as unknown as RouteRecordRaw) // 动态添加可访问路由表
  102. })
  103. permissionStore.setIsAddRouters(true)
  104. next(to.path === '/' ? permissionStore.addRouters[0].path : to.fullPath)
  105. }
  106. } else {
  107. if (NO_REDIRECT_WHITE_LIST.indexOf(to.path) !== -1) {
  108. next()
  109. } else {
  110. // userStore.setRoleRouters(routers)
  111. const roleRouters = userStore.getRoleRouters || []
  112. await permissionStore.generateRoutes('frontEnd', roleRouters as string[])
  113. permissionStore.getAddRouters.forEach((route) => {
  114. router.addRoute(route as unknown as RouteRecordRaw) // 动态添加可访问路由表
  115. })
  116. permissionStore.setIsAddRouters(true)
  117. console.log(permissionStore.addRouters)
  118. // next(`/login?redirect=${to.path}`) // 否则全部重定向到登录页
  119. // next(to.path === '/' ? permissionStore.addRouters[0].path : to.fullPath)
  120. next()
  121. }
  122. }
  123. }
  124. })
  125. // 获取角色信息
  126. const getRouter = async () => {
  127. const permissionStore = usePermissionStoreWithOut()
  128. const appStore = useAppStoreWithOut()
  129. const userStore = useUserStoreWithOut()
  130. const res = await getMenuList({})
  131. const btn = await getAuthBtn({})
  132. if (res) {
  133. const routers = filterRouters(getMenuChildren(res.data, SYS_CODE)) || []
  134. const btnAuth = getBtnAuth(btn.data) || []
  135. if (!routers.length) {
  136. ElMessage.error('暂无菜单权限')
  137. return
  138. }
  139. userStore.setRoleRouters(routers)
  140. userStore.setBtnAuth(btnAuth)
  141. appStore.getDynamicRouter && appStore.getServerDynamicRouter
  142. ? await permissionStore.generateRoutes('server', routers).catch(() => {
  143. })
  144. : await permissionStore.generateRoutes('frontEnd', routers).catch(() => {
  145. })
  146. permissionStore.getAddRouters.forEach((route) => {
  147. router.addRoute(route as RouteRecordRaw) // 动态添加可访问路由表
  148. })
  149. permissionStore.setIsAddRouters(true)
  150. // 获取从门户页跳转过来携带的state参数中的path 有该path 说明是门户页跳转常用功能
  151. const state = getQueryString('state')
  152. const path = JSON.parse(state as string)?.path
  153. // 重定向到项目的第一个路由
  154. const redirectPath = await getPath(permissionStore.addRouters, firstPath)
  155. router.push({
  156. // path: toRaw(permissionStore.addRouters[0]).path
  157. // path: path ? path : toRaw(permissionStore.addRouters[0]).path
  158. path: path ? path : redirectPath
  159. })
  160. }
  161. }
  162. // 获取第一个显示的菜单
  163. let firstPath = ''
  164. const getPath = async (routers: AppRouteRecordRaw[], path: string) => {
  165. // 过滤掉 非展示的页面
  166. const arr = routers.filter(i => i.meta.hidden !== true)
  167. if (!arr.length) {
  168. ElMessage.error('暂无菜单权限')
  169. return '/404'
  170. }
  171. firstPath = `${path}${arr[0].path.charAt(0) === '/' ? '' : '/'}${arr[0].path}`
  172. if (arr[0].children) {
  173. return await getPath(arr[0].children, firstPath)
  174. }
  175. return firstPath
  176. }
  177. router.afterEach((to) => {
  178. useTitle(to?.meta?.title as string)
  179. done() // 结束Progress
  180. loadDone()
  181. })
  182. }