import Vue from 'vue'; import NProgress from 'nprogress'; import VueRouter from 'vue-router'; import { WHITE_LIST, REDIRECT_PATH, LAYOUT_PATH, SYSTEM_NAME, HOME_PATH, isHomeAliasPath, } from '@/config/setting'; import store from '@/store'; import { getToken, setToken, getCurrentUser, removeToken } from '@/utils/token-util'; import { routes, getMenuRoutes } from './routes'; import { changeRole } from '@/api/layout'; import { rewriteLegacyHrMenus } from '@/utils/menu-rewrite'; Vue.use(VueRouter); // 与 EOM/WT 一致: // - 乾坤嵌入:base = /page-{SYSTEM_NAME}/(对应主应用 activeRule) // - 独立运行:base = /{SYSTEM_NAME}/(对应 publicPath /hr) const routerOptions = { base: window.__POWERED_BY_QIANKUN__ ? `/page-${SYSTEM_NAME}/` : `/${SYSTEM_NAME}/`, routes, mode: 'history', scrollBehavior() { return { y: 0 }; }, }; function createRouter() { return new VueRouter(routerOptions); } const router = createRouter(); /** 动态路由是否已挂到当前 matcher(用标记,避免 getRoutes 长度比较死循环) */ let dynamicRoutesReady = false; /** 重新登录 / 切角色前清空动态路由,避免重复注册导致白屏 */ export function resetRouter() { const newRouter = createRouter(); router.matcher = newRouter.matcher; dynamicRoutesReady = false; } function registerMenuRoutes(menus, homePath, authoritiesRouter = []) { resetRouter(); const nextMenus = rewriteLegacyHrMenus(menus || []); const nextAuth = rewriteLegacyHrMenus(authoritiesRouter || []); store.commit('user/setMenus', nextMenus); store.commit('user/setAuthoritiesRouter', nextAuth); router.addRoute( getMenuRoutes( [...nextMenus, ...nextAuth], homePath || HOME_PATH || '/home', ), ); dynamicRoutesReady = true; } /** 供登录页等外部主动注册动态路由 */ export function setupDynamicRoutes(menus, homePath, authoritiesRouter = []) { registerMenuRoutes(menus, homePath, authoritiesRouter); } router.beforeEach((to, from, next) => { if (!from.path.includes(REDIRECT_PATH)) { NProgress.start(); } if (getToken()) { // 已登录访问登录页:直接进首页,避免停在空白态 if (to.path === '/login') { next({ path: HOME_PATH || '/home', replace: true }); return; } // 旧首页别名统一跳到 /home,避免再开「首页」可关闭页签 if (isHomeAliasPath(to.path) && to.path !== (HOME_PATH || '/home')) { next({ path: HOME_PATH || '/home', query: to.query, hash: to.hash, replace: true, }); return; } if (!store.state.user.menus?.length) { store .dispatch('user/fetchUserInfo') .then(({ menus, homePath, authoritiesRouter }) => { registerMenuRoutes(menus, homePath, authoritiesRouter); next({ ...to, replace: true }); }) .catch((e) => { console.error(e); removeToken(); store.commit('user/setMenus', null); store.commit('user/setAuthoritiesRouter', []); resetRouter(); next({ path: '/login', replace: true }); }); return; } // 有菜单但动态路由未就绪时补注册(热更新 / reset 后) if (!dynamicRoutesReady) { registerMenuRoutes( store.state.user.menus, HOME_PATH || '/home', store.state.user.authoritiesRouter || [], ); next({ ...to, replace: true }); return; } next(); return; } if (WHITE_LIST.includes(to.path)) { next(); return; } next({ path: '/login', query: to.path === LAYOUT_PATH ? {} : { from: to.path }, }); }); router.afterEach((to) => { if (!to.path.includes(REDIRECT_PATH) && NProgress.isStarted()) { setTimeout(() => { NProgress.done(true); }, 200); } }); router.roleChange = async ({ menus, homePath, authoritiesRouter }) => { const currentUser = getCurrentUser(); if (menus?.length) { registerMenuRoutes(menus, homePath, authoritiesRouter); const target = HOME_PATH || menus[0].redirect || menus[0].path; if (router.currentRoute.path !== target) { await router.replace({ path: target }); } const newToken = await changeRole({ groupId: currentUser.currentGroupId, roleId: currentUser.currentRoleId, }); setToken(newToken); setTimeout(() => { window.location.reload(); }, 100); } }; export function getRouter() { return router; } export default router;