import router, { resetRouter } from './router' import Layout from '@/layout' import { checkToken, refreshToken } from '@/api/system' import { getToken, setToken } from './utils/auth' import progress from '@/utils/progress' import store from './store' import Vue from 'vue' // 刷新token状态 let isRefreshToken = true let isRefreshTree = true // 路由拦截 router.beforeEach(async (to, from, next) => { // debugger // 无需登录无需获取动态路由 if (to?.meta?.noLogin) { next() return } // 前往登陆页面判断 if (to.path === '/login-local') { if (!getToken()) { next() return } next('/') return } if (to.path === '/login') { next('/') return } progress.start() try { if (from.path !== '/login-local') { if (isRefreshToken) { isRefreshToken = false const { data } = await refreshToken() setToken(data) } else { await checkToken() } } // 判断是否已经存在机构信息 if (isRefreshTree) { store.dispatch('system/getOrganizationTree').then(_ => { isRefreshTree = false }).catch(e => { Vue.prototype.$message.error('获取机构信息失败') }).finally(() => { onFilterRoutes(to, next) }) return } onFilterRoutes(to, next) } catch (error) { Vue.prototype.$message.error(error) } }) router.afterEach((to, from) => { progress.done() document.title = `${Vue.prototype.$DEFAULT_TITLE} ${to.meta.title ?? ''}` }) // 路由过滤和跳转 async function onFilterRoutes (to, _next) { // 无需更新路由 if (!store.getters.refresh) { _next() return } const _route = store.getters.route // 监测是否需要更新路由 if (_route && _route.length) { initRoutes(to, _next, _route) return } try { const res = await store.dispatch('menu/getMenu2') if (!res || !res.length) { // 无权限 返回登录页面 Vue.prototype.$message.error('无权限账户,请联系管理员') store.dispatch('user/userLogout') return } initRoutes(to, _next, res) } catch (error) { store.dispatch('user/userLogout') Vue.prototype.$message.error(error) } } function initRoutes (to, _next, e) { store.commit('menu/SET_REFRESH', false) // 关闭路由刷新 // 清除路由 resetRouter() const routes = mapASyncRoutes(e) // 路由替换 routes.forEach(item => { router.addRoute(item) }) router.addRoute({ path: '/', redirect: chooseFirst(routes[0]) }) router.addRoute({ path: '*', redirect: '/404', hidden: true }) _next({ ...to, replace: true }) } function chooseFirst (item) { if (item.children && item.children.length > 0 && item.component.name === 'layoutIndex') { return chooseFirst(item.children[0]) } return item.path } // 递归路由 转换为组件对象和路径 function mapASyncRoutes (data) { return data.map(item => { item.meta.title = item.label item.meta.type = item.type item.meta.hidden = item.hidden === 0 item.component = item.component === 'Layout' ? Layout : loadView(item.component) if (item.children && item.children.length > 0) { item.children = mapASyncRoutes(item.children) } return item }) } // 路由插件 function loadView (view) { return !view ? { render: (c) => c('router-view') } : () => import(`@/views/${view}`) }