index.js 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. import Vue from 'vue'
  2. import VueRouter from 'vue-router'
  3. // 进度条
  4. import NProgress from 'nprogress'
  5. import 'nprogress/nprogress.css'
  6. import setting from '@/setting.js'
  7. import store from '@/store/index.js'
  8. import i18n from '@/utils/i18n.js'
  9. import util from '@/utils/util.js'
  10. // 验权
  11. import { getRefreshToken, getToken } from '@/utils/auth'
  12. // 路由数据
  13. import routes from './routes'
  14. // fix vue-router NavigationDuplicated
  15. const VueRouterPush = VueRouter.prototype.push
  16. VueRouter.prototype.push = function push(location) {
  17. return VueRouterPush.call(this, location).catch((err) => err)
  18. }
  19. const VueRouterReplace = VueRouter.prototype.replace
  20. VueRouter.prototype.replace = function replace(location) {
  21. return VueRouterReplace.call(this, location).catch((err) => err)
  22. }
  23. Vue.use(VueRouter)
  24. // 导出路由 在 main.js 里使用
  25. const router = new VueRouter({
  26. routes
  27. })
  28. /**
  29. * 路由拦截
  30. * 权限验证
  31. */
  32. router.beforeEach(async (to, from, next) => {
  33. // 确认已经加载多标签页数据
  34. await store.dispatch('ibps/page/isLoaded')
  35. // 确认已经加载组件尺寸设置
  36. await store.dispatch('ibps/size/isLoaded')
  37. // 关闭搜索面板
  38. store.commit('ibps/search/set', false)
  39. // 进度条
  40. NProgress.start()
  41. const locking = util.cookies.get('locking')
  42. if (locking === 'locked' && to.name !== 'locking') {
  43. // 判断当前是否是锁定状态
  44. next({
  45. replace: true,
  46. name: 'locking'
  47. })
  48. } else if (locking === 'unlock' && to.name === 'locking') {
  49. next(false)
  50. } else {
  51. // 这里将cookie里是否存有token作为验证是否登录的条件
  52. const hasToken = getToken()
  53. if (hasToken && hasToken !== 'undefined') {
  54. // 从cookie 获取用户token
  55. // 登录 锁定 401没权限 403禁止访问
  56. if (
  57. to.name === 'locking' ||
  58. to.name === 'login' ||
  59. to.name === 'error401' ||
  60. to.name === 'error403' ||
  61. to.name === 'nomenu'
  62. ) {
  63. next()
  64. } else {
  65. // 判断是否有子系统和是否有菜单
  66. if (
  67. util.isEmpty(store.getters.system) ||
  68. util.isEmpty(store.getters.menus)
  69. ) {
  70. store
  71. .dispatch('ibps/user/load')
  72. .then((res) => {
  73. // 拉取用户信息,避免刷新用户丢失
  74. const system = store.getters.system
  75. if (util.isEmpty(system) || util.isEmpty(system.id)) {
  76. if (util.isEmpty(store.getters.tenants)) {
  77. if (to.name === 'systemSelect') return next()
  78. return next({ path: '/systemSelect', replace: true })
  79. }
  80. // 租户模式下跳转
  81. if (util.isNotEmpty(store.getters.tenants)) {
  82. if (to.name === 'tenantSelect') return next()
  83. if (to.name === 'systemSelect') return next()
  84. return next({ path: '/tenantSelect', replace: true })
  85. }
  86. }
  87. store
  88. .dispatch('ibps/menu/init', { systemId: system.id })
  89. .then(() => {
  90. // 根据用户菜单权限生成可访问的路由表
  91. if (util.isEmpty(store.getters.menus)) {
  92. next()
  93. } else {
  94. const addRouters = store.getters.routers
  95. if (addRouters && addRouters.length > 0) {
  96. // 动态添加可访问路由表
  97. router.addRoutes(addRouters)
  98. // 初始化加载或用户刷新页面后从数据库加载一系列的设置
  99. store.dispatch('ibps/account/loadInfo', {
  100. addRouters,
  101. menus: store.getters.menus
  102. })
  103. next({ ...to, replace: true }) // hack方法 确保addRoutes已完成
  104. } else {
  105. next({
  106. path: '/403',
  107. replace: true,
  108. query: { noGoBack: true }
  109. })
  110. }
  111. }
  112. })
  113. .catch((e) => {
  114. console.error(e)
  115. NProgress.done() // 结束Progress
  116. })
  117. })
  118. .catch((e) => {
  119. NProgress.done() // 结束Progress
  120. // 前台登出
  121. store
  122. .dispatch('ibps/account/fedLogout')
  123. .then(() => {
  124. next({ name: 'login' })
  125. })
  126. .catch((err) => {
  127. console.error(err)
  128. })
  129. })
  130. } else {
  131. // 动态改变权限,判断是否有菜单权限,或者刷新页面
  132. if (to.matched.length === 0) {
  133. // 不能匹配的路由
  134. return next({
  135. path: '401',
  136. replace: true,
  137. query: { noGoBack: true }
  138. })
  139. } else {
  140. next()
  141. }
  142. }
  143. // end
  144. }
  145. } else {
  146. /* has no token */
  147. // 判断refresh tonken是否过期
  148. const refreshToken = getRefreshToken()
  149. if (util.isNotEmpty(refreshToken)) {
  150. // 刷新tonken
  151. await store
  152. .dispatch('ibps/account/refreshToken')
  153. .then(() => {
  154. next()
  155. })
  156. .catch((err) => {
  157. console.error(err)
  158. })
  159. } else {
  160. // 在免登录白名单,直接进入
  161. if (setting.whiteRouterList.indexOf(to.path) !== -1) {
  162. next()
  163. } else {
  164. // 没有登录的时候跳转到登录界面
  165. // 携带上登陆成功之后需要跳转的页面完整路径
  166. next({
  167. name: 'login',
  168. query: {
  169. redirect: to.fullPath
  170. }
  171. })
  172. NProgress.done()
  173. }
  174. }
  175. }
  176. }
  177. })
  178. router.afterEach((to) => {
  179. // 进度条
  180. NProgress.done()
  181. // 多页控制 打开新的页面
  182. /* store.dispatch('ibps/page/open', to) */
  183. // 更改标题
  184. i18n.setTitle(to.meta.name || to.name, to.meta.title)
  185. })
  186. export default router