PixelAI-admin/src/router/index.ts

226 lines
8.0 KiB
TypeScript
Raw Normal View History

import { createRouter, createWebHashHistory, RouteRecordRaw } from 'vue-router';
import NProgress from 'nprogress';
import 'nprogress/nprogress.css';
import { store } from '/@/store/index.ts';
import { Session } from '/@/utils/storage';
import { NextLoading } from '/@/utils/loading';
import { staticRoutes, dynamicRoutes } from '/@/router/route';
import { initFrontEndControlRoutes } from '/@/router/frontEnd';
import { initBackEndControlRoutes } from '/@/router/backEnd';
/**
* Vue 使
* @method createRouter(options: RouterOptions): Router
* @link https://next.router.vuejs.org/zh/api/#createrouter
*/
const router = createRouter({
history: createWebHashHistory(),
routes: staticRoutes,
});
/**
* 404
* @link https://next.router.vuejs.org/zh/guide/essentials/history-mode.html#netlify
*/
const pathMatch = {
path: '/:path(.*)*',
redirect: '/404',
};
/**
*
* @param arr
* @returns
*/
export function formatFlatteningRoutes(arr: any) {
if (arr.length <= 0) return false;
for (let i = 0; i < arr.length; i++) {
if (arr[i].children) {
arr = arr.slice(0, i + 1).concat(arr[i].children, arr.slice(i + 1));
}
}
return arr;
}
/**
* keep-alive
* @description isKeepAlive `name`
* @link https://v3.cn.vuejs.org/api/built-in-components.html#keep-alive
* @param arr
* @returns `定义动态路由dynamicRoutes`
*/
export function formatTwoStageRoutes(arr: any) {
if (arr.length <= 0) return false;
const newArr: any = [];
const cacheList: Array<string> = [];
arr.forEach((v: any) => {
if (v.path === '/') {
newArr.push({ component: v.component, name: v.name, path: v.path, redirect: v.redirect, meta: v.meta, children: [] });
} else {
newArr[0].children.push({ ...v });
// 存 name 值keep-alive 中 include 使用,实现路由的缓存
// 路径:/@/layout/routerView/parent.vue
if (newArr[0].meta.isKeepAlive && v.meta.isKeepAlive) {
cacheList.push(v.name);
store.dispatch('keepAliveNames/setCacheKeepAlive', cacheList);
}
}
});
return newArr;
}
/**
*
* @description tagsView(isHide)
*/
2021-01-21 23:36:07 +08:00
export function setCacheTagsViewRoutes() {
// 获取有权限的路由,否则 tagsView、菜单搜索中无权限的路由也将显示
let authsRoutes = setFilterHasAuthMenu(dynamicRoutes, store.state.userInfos.userInfos.authPageList);
// 添加到 vuex setTagsViewRoutes 中
store.dispatch('tagsViewRoutes/setTagsViewRoutes', formatTwoStageRoutes(formatFlatteningRoutes(authsRoutes))[0].children);
2021-01-21 23:36:07 +08:00
}
/**
* `meta.auth`
* @param auths userInfos authPageList
* @param route
* @returns
*/
export function hasAuth(auths: any, route: any) {
if (route.meta && route.meta.auth) return auths.some((auth: any) => route.meta.auth.includes(auth));
else return true;
}
/**
*
* @param routes children
* @param auth userInfos authPageList
* @returns `meta.auth`
*/
export function setFilterHasAuthMenu(routes: any, auth: any) {
const menu: any = [];
routes.forEach((route: any) => {
const item = { ...route };
if (hasAuth(auth, item)) {
if (item.children) item.children = setFilterHasAuthMenu(item.children, auth);
menu.push(item);
}
});
return menu;
}
/**
* vuex routesList
* @description
* @description tagsView(isHide)
*/
export function setFilterMenuAndCacheTagsViewRoutes() {
store.dispatch('routesList/setRoutesList', setFilterHasAuthMenu(dynamicRoutes[0].children, store.state.userInfos.userInfos.authPageList));
setCacheTagsViewRoutes();
}
/**
*
* @description router.addRoute
* @link https://next.router.vuejs.org/zh/api/#addroute
* @param chil dynamicRoutes/@/router/route children
* @returns
*/
export function setFilterRoute(chil: any) {
let filterRoute: any = [];
chil.forEach((route: any) => {
if (route.meta.auth) {
route.meta.auth.forEach((metaAuth: any) => {
store.state.userInfos.userInfos.authPageList.forEach((auth: any) => {
if (metaAuth === auth) filterRoute.push({ ...route });
});
});
}
});
return filterRoute;
}
/**
*
* @description dynamicRoutes/@/router/route children
* @returns
*/
export function setFilterRouteEnd() {
let filterRouteEnd: any = formatTwoStageRoutes(formatFlatteningRoutes(dynamicRoutes));
filterRouteEnd[0].children = [...setFilterRoute(filterRouteEnd[0].children), { ...pathMatch }];
return filterRouteEnd;
}
/**
*
* @method router.addRoute
* @description dynamicRoutes/@/router/route children
* @link https://next.router.vuejs.org/zh/api/#addroute
*/
export function setAddRoute() {
setFilterRouteEnd().forEach((route: RouteRecordRaw) => {
const routeName: any = route.name;
if (!router.hasRoute(routeName)) router.addRoute(route);
});
}
/**
* /
* @method router.removeRoute
* @description dynamicRoutes/@/router/route children
* @link https://next.router.vuejs.org/zh/api/#push
*/
export function resetRoute() {
setFilterRouteEnd().forEach((route: RouteRecordRaw) => {
const routeName: any = route.name;
router.hasRoute(routeName) && router.removeRoute(routeName);
});
}
// isRequestRoutes 为 true则开启后端控制路由路径`/src/store/modules/themeConfig.ts`
const { isRequestRoutes } = store.state.themeConfig.themeConfig;
// 前端控制路由:初始化方法,防止刷新时路由丢失
if (!isRequestRoutes) initFrontEndControlRoutes();
// 路由加载前
router.beforeEach(async (to, from, next) => {
NProgress.configure({ showSpinner: false });
if (to.meta.title) NProgress.start();
const token = Session.get('token');
if (to.path === '/login' && !token) {
next();
NProgress.done();
} else {
if (!token) {
next(`/login?redirect=${to.path}`);
Session.clear();
resetRoute();
NProgress.done();
} else if (token && to.path === '/login') {
next('/home');
NProgress.done();
} else {
if (store.state.routesList.routesList.length === 0) {
if (isRequestRoutes) {
// 后端控制路由:路由数据初始化,防止刷新时丢失
await initBackEndControlRoutes();
// 动态添加路由:防止非首页刷新时跳转回首页的问题
// 确保 addRoute() 时动态添加的路由已经被完全加载上去
next({ ...to, replace: true });
}
} else {
next();
}
}
}
});
// 路由加载后
router.afterEach(() => {
NProgress.done();
NextLoading.done();
});
// 导出路由
export default router;