permission.js 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. import router, { resetRouter } from './router'
  2. import Layout from '@/layout'
  3. import { checkToken, refreshToken } from '@/api/system'
  4. import {
  5. getToken,
  6. setToken
  7. } from './utils/auth'
  8. import progress from '@/utils/progress'
  9. import store from './store'
  10. import Vue from 'vue'
  11. // 刷新token状态
  12. let isRefreshToken = true
  13. // 路由拦截
  14. router.beforeEach(async (to, from, next) => {
  15. // debugger
  16. // 无需登录无需获取动态路由
  17. if (to?.meta?.noLogin) {
  18. next()
  19. return
  20. }
  21. // 前往登陆页面判断
  22. if (to.path === '/login-local') {
  23. if (!getToken()) {
  24. next()
  25. return
  26. }
  27. next('/')
  28. return
  29. }
  30. if (to.path === '/login') {
  31. next('/')
  32. return
  33. }
  34. progress.start()
  35. try {
  36. if (from.path !== '/login-local') {
  37. if (isRefreshToken) {
  38. isRefreshToken = false
  39. const { data } = await refreshToken()
  40. setToken(data)
  41. } else {
  42. await checkToken()
  43. }
  44. }
  45. // 判断是否已经存在机构信息
  46. if (!store.getters.organizationTree.length) {
  47. store.dispatch('system/getOrganizationTree').catch(e => {
  48. Vue.prototype.$message.error('获取机构信息失败')
  49. }).finally(() => {
  50. onFilterRoutes(to, next)
  51. })
  52. return
  53. }
  54. onFilterRoutes(to, next)
  55. } catch (error) {
  56. Vue.prototype.$message.error(error)
  57. }
  58. })
  59. router.afterEach((to, from) => {
  60. progress.done()
  61. document.title = `${Vue.prototype.$DEFAULT_TITLE} ${to.meta.title ?? ''}`
  62. })
  63. // 路由过滤和跳转
  64. async function onFilterRoutes (to, _next) {
  65. // 无需更新路由
  66. if (!store.getters.refresh) {
  67. _next()
  68. return
  69. }
  70. const _route = store.getters.route
  71. // 监测是否需要更新路由
  72. if (_route && _route.length) {
  73. initRoutes(to, _next, _route)
  74. return
  75. }
  76. try {
  77. const res = await store.dispatch('menu/getMenu2')
  78. if (!res || !res.length) {
  79. // 无权限 返回登录页面
  80. Vue.prototype.$message.error('无权限账户,请联系管理员')
  81. store.dispatch('user/userLogout')
  82. return
  83. }
  84. initRoutes(to, _next, res)
  85. } catch (error) {
  86. store.dispatch('user/userLogout')
  87. Vue.prototype.$message.error(error)
  88. }
  89. }
  90. function initRoutes (to, _next, e) {
  91. store.commit('menu/SET_REFRESH', false) // 关闭路由刷新
  92. // 清除路由
  93. resetRouter()
  94. const routes = mapASyncRoutes(e) // 路由替换
  95. routes.forEach(item => {
  96. router.addRoute(item)
  97. })
  98. router.addRoute({ path: '/', redirect: chooseFirst(routes[0]) })
  99. router.addRoute({ path: '*', redirect: '/404', hidden: true })
  100. _next({ ...to, replace: true })
  101. }
  102. function chooseFirst (item) {
  103. if (item.children && item.children.length > 0 && item.component.name === 'layoutIndex') {
  104. return chooseFirst(item.children[0])
  105. }
  106. return item.path
  107. }
  108. // 递归路由 转换为组件对象和路径
  109. function mapASyncRoutes (data) {
  110. return data.map(item => {
  111. item.meta.title = item.label
  112. item.meta.type = item.type
  113. item.meta.hidden = item.hidden === 0
  114. item.component = item.component === 'Layout' ? Layout : loadView(item.component)
  115. if (item.children && item.children.length > 0) {
  116. item.children = mapASyncRoutes(item.children)
  117. }
  118. return item
  119. })
  120. }
  121. // 路由插件
  122. function loadView (view) {
  123. return !view ? { render: (c) => c('router-view') } : () => import(`@/views/${view}`)
  124. }