permission.js 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. import router from './router'
  2. import store from './store'
  3. import NProgress from 'nprogress' // Progress 进度条
  4. import 'nprogress/nprogress.css' // Progress 进度条样式
  5. import { isArray } from '@/utils/types'
  6. import {
  7. getAuth,
  8. removeAuth
  9. } from '@/utils/auth' // 验权
  10. const whiteList = ['login', 'register', 'link'] // 不重定向白名单
  11. const pathWhiteList = ['/404', '/noAuth'] // 不重定向白名单
  12. let tryCount = 3 // 如果0 清空授权
  13. // 是否能继续出错
  14. function canTryFun() {
  15. return tryCount > 0
  16. }
  17. // 出错
  18. function executeTryFun() {
  19. return tryCount--
  20. }
  21. // 重置
  22. function resetTryFun() {
  23. tryCount = 3
  24. }
  25. // next 到登录
  26. function nextLogin(to, from, next) {
  27. // 没权限
  28. if (whiteList.indexOf(to.name) !== -1) {
  29. next()
  30. } else {
  31. next(`/login?redirect=${pathWhiteList.includes(to.path) ? (to.redirectedFrom || '/') : to.path}`) // 否则全部重定向到登录页
  32. }
  33. }
  34. router.beforeEach(async(to, from, next) => {
  35. store.commit('CLEAR_CANCELTOKENARR') // 取消请求
  36. let redirectedFrom = to.redirectedFrom
  37. if (from.name === 'login' && to.path === '/404') {
  38. redirectedFrom = '/' // 可能因重定向导致404 校准一次
  39. }
  40. if (to.meta.disabled) {
  41. next(false)
  42. return
  43. }
  44. NProgress.start()
  45. // 允许进入登录页面 1005 需要完善信息 不能清除登录信息
  46. if (window.accessLogin) {
  47. next()
  48. NProgress.done()
  49. return
  50. }
  51. // 请求头包含授权信息 并且 页面必须授权 直接进入
  52. try {
  53. await getAuth()
  54. if (to.name === 'login') {
  55. next({
  56. path: '/'
  57. })
  58. } else {
  59. if (store.getters.addRouters.length === 0) { // 判断当前用户是否获取权限
  60. await store.dispatch('QueryModules')
  61. const auths = await store.dispatch('getAuth')
  62. await store.dispatch('GenerateRoutes', auths)
  63. router.addRoutes(store.getters.addRouters)
  64. resetTryFun()
  65. if (pathWhiteList.includes(to.path)) {
  66. if (isArray(store.getters.addRouters) && store.getters.addRouters.length === 0) {
  67. throw new Error('routeError')
  68. } else {
  69. next({
  70. path: redirectedFrom || '/',
  71. replace: true
  72. })
  73. }
  74. } else {
  75. next({
  76. ...to,
  77. replace: true
  78. })
  79. }
  80. } else {
  81. resetTryFun()
  82. next()
  83. }
  84. NProgress.done()
  85. }
  86. } catch (error) {
  87. executeTryFun()
  88. // 302 登录信息失效 1007 企业用户不存在
  89. if (error && (error.code === 302 || error.code === 1007) || !canTryFun()) {
  90. resetTryFun()
  91. await removeAuth()
  92. // 没权限
  93. nextLogin(to, from, next)
  94. NProgress.done()
  95. } else {
  96. // 因为网络原因,但已登录,转404页面。 如果没有,跳转登录
  97. getAuth().then(res => {
  98. if (error) {
  99. to.name === 'noAuth' ? next() : next('/noAuth')
  100. } else {
  101. if (pathWhiteList.includes(to.path)) {
  102. next(redirectedFrom || '/')
  103. } else {
  104. next()
  105. }
  106. }
  107. NProgress.done()
  108. }).catch(() => {
  109. // 没权限
  110. nextLogin(to, from, next)
  111. NProgress.done()
  112. })
  113. }
  114. }
  115. })
  116. router.afterEach(() => {
  117. NProgress.done() // 结束Progress
  118. })
  119. router.onError((error) => {
  120. const pattern = /Loading chunk (\d)+ failed/g
  121. const isChunkLoadFailed = error.message.match(pattern)
  122. const targetPath = router.history.pending.fullPath
  123. if (isChunkLoadFailed) {
  124. router.replace(targetPath)
  125. }
  126. })