permission.js 3.2 KB

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