permission.js 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  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. onFilterRoutes(to, next)
  44. } catch (error) {
  45. Vue.prototype.$message.error(error)
  46. }
  47. })
  48. router.afterEach((to, from) => {
  49. document.title = `${Vue.prototype.$DEFAULT_TITLE} ${to.meta.title ?? ''}`
  50. })
  51. // 路由过滤和跳转
  52. async function onFilterRoutes (to, _next) {
  53. // 无需更新路由
  54. if (!store.getters.refresh) {
  55. _next()
  56. return
  57. }
  58. const _route = store.getters.route
  59. // 监测是否需要更新路由
  60. if (_route && _route.length) {
  61. initRoutes(to, _next, _route)
  62. return
  63. }
  64. try {
  65. const res = await store.dispatch('menu/getMenu2')
  66. if (!res || !res.length) {
  67. // 无权限 返回登录页面
  68. Vue.prototype.$message.error('无权限账户,请联系管理员')
  69. store.dispatch('user/userLogout')
  70. return
  71. }
  72. initRoutes(to, _next, res)
  73. } catch (error) {
  74. store.dispatch('user/userLogout')
  75. Vue.prototype.$message.error(error)
  76. }
  77. }
  78. function initRoutes (to, _next, e) {
  79. store.commit('menu/SET_REFRESH', false) // 关闭路由刷新
  80. // 清除路由
  81. resetRouter()
  82. const routes = mapASyncRoutes(e) // 路由替换
  83. routes.forEach(item => {
  84. router.addRoute(item)
  85. })
  86. router.addRoute({ path: '/', redirect: chooseFirst(routes[0]) })
  87. router.addRoute({ path: '*', redirect: '/404', hidden: true })
  88. _next({ ...to, replace: true })
  89. }
  90. function chooseFirst (item) {
  91. if (item.children && item.children.length > 0 && item.component.name === 'layoutIndex') {
  92. return chooseFirst(item.children[0])
  93. }
  94. return item.path
  95. }
  96. // 递归路由 转换为组件对象和路径
  97. function mapASyncRoutes (data) {
  98. return data.map(item => {
  99. item.meta.title = item.label
  100. item.meta.type = item.type
  101. item.meta.hidden = item.hidden === 0
  102. item.component = item.component === 'Layout' ? Layout : loadView(item.component)
  103. if (item.children && item.children.length > 0) {
  104. item.children = mapASyncRoutes(item.children)
  105. }
  106. return item
  107. })
  108. }
  109. // 路由插件
  110. function loadView (view) {
  111. return !view ? { render: (c) => c('router-view') } : () => import(`@/views/${view}`)
  112. }