index.js 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. import Vue from 'vue';
  2. import NProgress from 'nprogress';
  3. import VueRouter from 'vue-router';
  4. import {
  5. WHITE_LIST,
  6. REDIRECT_PATH,
  7. LAYOUT_PATH,
  8. SYSTEM_NAME,
  9. HOME_PATH,
  10. isHomeAliasPath,
  11. } from '@/config/setting';
  12. import store from '@/store';
  13. import { getToken, setToken, getCurrentUser, removeToken } from '@/utils/token-util';
  14. import { routes, getMenuRoutes } from './routes';
  15. import { changeRole } from '@/api/layout';
  16. import { rewriteLegacyHrMenus } from '@/utils/menu-rewrite';
  17. Vue.use(VueRouter);
  18. // 与 EOM/WT 一致:
  19. // - 乾坤嵌入:base = /page-{SYSTEM_NAME}/(对应主应用 activeRule)
  20. // - 独立运行:base = /{SYSTEM_NAME}/(对应 publicPath /hr)
  21. const routerOptions = {
  22. base: window.__POWERED_BY_QIANKUN__
  23. ? `/page-${SYSTEM_NAME}/`
  24. : `/${SYSTEM_NAME}/`,
  25. routes,
  26. mode: 'history',
  27. scrollBehavior() {
  28. return { y: 0 };
  29. },
  30. };
  31. function createRouter() {
  32. return new VueRouter(routerOptions);
  33. }
  34. const router = createRouter();
  35. /** 动态路由是否已挂到当前 matcher(用标记,避免 getRoutes 长度比较死循环) */
  36. let dynamicRoutesReady = false;
  37. /** 重新登录 / 切角色前清空动态路由,避免重复注册导致白屏 */
  38. export function resetRouter() {
  39. const newRouter = createRouter();
  40. router.matcher = newRouter.matcher;
  41. dynamicRoutesReady = false;
  42. }
  43. function registerMenuRoutes(menus, homePath, authoritiesRouter = []) {
  44. resetRouter();
  45. const nextMenus = rewriteLegacyHrMenus(menus || []);
  46. const nextAuth = rewriteLegacyHrMenus(authoritiesRouter || []);
  47. store.commit('user/setMenus', nextMenus);
  48. store.commit('user/setAuthoritiesRouter', nextAuth);
  49. router.addRoute(
  50. getMenuRoutes(
  51. [...nextMenus, ...nextAuth],
  52. homePath || HOME_PATH || '/home',
  53. ),
  54. );
  55. dynamicRoutesReady = true;
  56. }
  57. /** 供登录页等外部主动注册动态路由 */
  58. export function setupDynamicRoutes(menus, homePath, authoritiesRouter = []) {
  59. registerMenuRoutes(menus, homePath, authoritiesRouter);
  60. }
  61. router.beforeEach((to, from, next) => {
  62. if (!from.path.includes(REDIRECT_PATH)) {
  63. NProgress.start();
  64. }
  65. if (getToken()) {
  66. // 已登录访问登录页:直接进首页,避免停在空白态
  67. if (to.path === '/login') {
  68. next({ path: HOME_PATH || '/home', replace: true });
  69. return;
  70. }
  71. // 旧首页别名统一跳到 /home,避免再开「首页」可关闭页签
  72. if (isHomeAliasPath(to.path) && to.path !== (HOME_PATH || '/home')) {
  73. next({
  74. path: HOME_PATH || '/home',
  75. query: to.query,
  76. hash: to.hash,
  77. replace: true,
  78. });
  79. return;
  80. }
  81. if (!store.state.user.menus?.length) {
  82. store
  83. .dispatch('user/fetchUserInfo')
  84. .then(({ menus, homePath, authoritiesRouter }) => {
  85. registerMenuRoutes(menus, homePath, authoritiesRouter);
  86. next({ ...to, replace: true });
  87. })
  88. .catch((e) => {
  89. console.error(e);
  90. removeToken();
  91. store.commit('user/setMenus', null);
  92. store.commit('user/setAuthoritiesRouter', []);
  93. resetRouter();
  94. next({ path: '/login', replace: true });
  95. });
  96. return;
  97. }
  98. // 有菜单但动态路由未就绪时补注册(热更新 / reset 后)
  99. if (!dynamicRoutesReady) {
  100. registerMenuRoutes(
  101. store.state.user.menus,
  102. HOME_PATH || '/home',
  103. store.state.user.authoritiesRouter || [],
  104. );
  105. next({ ...to, replace: true });
  106. return;
  107. }
  108. next();
  109. return;
  110. }
  111. if (WHITE_LIST.includes(to.path)) {
  112. next();
  113. return;
  114. }
  115. next({
  116. path: '/login',
  117. query: to.path === LAYOUT_PATH ? {} : { from: to.path },
  118. });
  119. });
  120. router.afterEach((to) => {
  121. if (!to.path.includes(REDIRECT_PATH) && NProgress.isStarted()) {
  122. setTimeout(() => {
  123. NProgress.done(true);
  124. }, 200);
  125. }
  126. });
  127. router.roleChange = async ({ menus, homePath, authoritiesRouter }) => {
  128. const currentUser = getCurrentUser();
  129. if (menus?.length) {
  130. registerMenuRoutes(menus, homePath, authoritiesRouter);
  131. const target = HOME_PATH || menus[0].redirect || menus[0].path;
  132. if (router.currentRoute.path !== target) {
  133. await router.replace({ path: target });
  134. }
  135. const newToken = await changeRole({
  136. groupId: currentUser.currentGroupId,
  137. roleId: currentUser.currentRoleId,
  138. });
  139. setToken(newToken);
  140. setTimeout(() => {
  141. window.location.reload();
  142. }, 100);
  143. }
  144. };
  145. export function getRouter() {
  146. return router;
  147. }
  148. export default router;