Ai
1 Star 0 Fork 996

半糖芒果酥/vue-pure-admin

forked from zym/vue-pure-admin 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
index.ts 7.58 KB
一键复制 编辑 原始数据 按行查看 历史
半糖芒果酥 提交于 2025-09-29 17:32 +08:00 . Merge branch 'main' into spring-taybct
import "@/utils/sso";
import Cookies from "js-cookie";
import { getConfig } from "@/config";
import NProgress from "@/utils/progress";
import { transformI18n } from "@/plugins/i18n";
import { buildHierarchyTree } from "@/utils/tree";
import remainingRouter from "./modules/remaining";
import { useMultiTagsStoreHook } from "@/store/modules/multiTags";
import { usePermissionStoreHook } from "@/store/modules/permission";
import {
isUrl,
openLink,
cloneDeep,
isAllEmpty,
storageLocal
} from "@pureadmin/utils";
import {
ascending,
getTopMenu,
initRouter,
isOneOfArray,
getHistoryMode,
findRouteByPath,
handleAliveRoute,
formatTwoStageRoutes,
formatFlatteningRoutes
} from "./utils";
import {
type Router,
type RouteRecordRaw,
type RouteComponent,
createRouter
} from "vue-router";
import {
type DataInfo,
userKey,
removeToken,
multipleTabsKey,
ROOTRoleCode
} from "@/utils/auth";
/** 自动导入全部静态路由,无需再手动引入!匹配 src/router/modules 目录(任何嵌套级别)中具有 .ts 扩展名的所有文件,除了 remaining.ts 文件
* 如何匹配所有文件请看:https://github.com/mrmlnc/fast-glob#basic-syntax
* 如何排除文件请看:https://cn.vitejs.dev/guide/features.html#negative-patterns
*/
// const modules: Record<string, any> = import.meta.glob(
// ["./modules/**/*.ts", "!./modules/**/remaining.ts"],
// {
// eager: true
// }
// );
const modules: Record<string, any> = import.meta.env.DEV
? import.meta.glob(["./modules/**/*.ts", "!./modules/**/remaining.ts"], {
eager: true
})
: import.meta.glob(["./modules/home.ts"], {
eager: true
});
// const modules: Record<string, any> = import.meta.glob(
// ["./modules/**/*.ts", "!./modules/**/remaining.ts"],
// {
// eager: true
// }
// );
/** 原始静态路由(未做任何处理) */
const routes = [];
Object.keys(modules).forEach(key => {
routes.push(modules[key].default);
});
/** 导出处理后的静态路由(三级及以上的路由全部拍成二级) */
export const constantRoutes: Array<RouteRecordRaw> = formatTwoStageRoutes(
formatFlatteningRoutes(buildHierarchyTree(ascending(routes.flat(Infinity))))
);
/** 初始的静态路由,用于退出登录时重置路由 */
const initConstantRoutes: Array<RouteRecordRaw> = cloneDeep(constantRoutes);
/** 用于渲染菜单,保持原始层级 */
export const constantMenus: Array<RouteComponent> = ascending(
routes.flat(Infinity)
).concat(...remainingRouter);
/** 不参与菜单的路由 */
export const remainingPaths = Object.keys(remainingRouter).map(v => {
return remainingRouter[v].path;
});
/** 创建路由实例 */
export const router: Router = createRouter({
history: getHistoryMode(import.meta.env.VITE_ROUTER_HISTORY),
routes: constantRoutes.concat(...(remainingRouter as any)),
strict: true,
scrollBehavior(to, from, savedPosition) {
return new Promise(resolve => {
if (savedPosition) {
return savedPosition;
} else {
if (from.meta.saveSrollTop) {
const top: number =
document.documentElement.scrollTop || document.body.scrollTop;
resolve({ left: 0, top });
}
}
});
}
});
/** 记录已经加载的页面路径 */
const loadedPaths = new Set<string>();
/** 重置已加载页面记录 */
export function resetLoadedPaths() {
loadedPaths.clear();
}
/** 重置路由 */
export function resetRouter() {
router.clearRoutes();
for (const route of initConstantRoutes.concat(...(remainingRouter as any))) {
router.addRoute(route);
}
router.options.routes = formatTwoStageRoutes(
formatFlatteningRoutes(buildHierarchyTree(ascending(routes.flat(Infinity))))
);
usePermissionStoreHook().clearAllCachePage();
resetLoadedPaths();
}
/** 路由白名单 */
const whiteList = ["/login"];
const { VITE_HIDE_HOME } = import.meta.env;
router.beforeEach((to: ToRouteType, _from, next) => {
to.meta.loaded = loadedPaths.has(to.path);
if (!to.meta.loaded) {
NProgress.start();
}
if (to.meta?.keepAlive) {
handleAliveRoute(to, "add");
// 页面整体刷新和点击标签页刷新
if (_from.name === undefined || _from.name === "Redirect") {
handleAliveRoute(to);
}
}
const userInfo = storageLocal().getItem<DataInfo<number>>(userKey);
const externalLink = isUrl(to?.name as string);
if (!externalLink) {
to.matched.some(item => {
if (!item.meta.title) return "";
const Title = getConfig().Title;
if (Title)
document.title = `${transformI18n(item.meta.title)} | ${Title}`;
else document.title = transformI18n(item.meta.title);
});
}
/** 如果已经登录并存在登录信息后不能跳转到路由白名单,而是继续保持在当前页面 */
function toCorrectRoute() {
whiteList.includes(to.fullPath) ? next(_from.fullPath) : next();
}
if (Cookies.get(multipleTabsKey) && userInfo) {
// 无权限跳转403页面
if (
// 如果菜单有角色要求
to.meta?.roles &&
// 如果也不是超级管理员
!isOneOfArray(ROOTRoleCode, userInfo?.roles) &&
// 如果当前登录用户的角色不满足菜单要求
!isOneOfArray(to.meta?.roles, userInfo?.roles)
) {
next({ path: "/error/403" });
}
// 开启隐藏首页后在浏览器地址栏手动输入首页welcome路由则跳转到404页面
if (VITE_HIDE_HOME === "true" && to.fullPath === "/welcome") {
next({ path: "/error/404" });
}
if (_from?.name) {
// name为超链接
if (externalLink) {
openLink(to?.name as string);
NProgress.done();
} else {
toCorrectRoute();
}
} else {
// 刷新
if (
usePermissionStoreHook().wholeMenus.length === 0 &&
to.path !== "/login"
) {
initRouter().then((router: Router) => {
if (!useMultiTagsStoreHook().getMultiTagsCache) {
const { path } = to;
const route = findRouteByPath(
path,
router.options.routes[0].children
);
getTopMenu(true);
// query、params模式路由传参数的标签页不在此处处理
if (route && route.meta?.title) {
if (isAllEmpty(route.parentId) && route.meta?.backstage) {
// 此处为动态顶级路由(目录)
const { path, name, meta } = route.children[0];
useMultiTagsStoreHook().handleTags("push", {
path,
name,
meta
});
} else {
const { path, name, meta } = route;
useMultiTagsStoreHook().handleTags("push", {
path,
name,
meta
});
}
}
}
// 确保动态路由完全加入路由列表并且不影响静态路由(注意:动态路由刷新时router.beforeEach可能会触发两次,第一次触发动态路由还未完全添加,第二次动态路由才完全添加到路由列表,如果需要在router.beforeEach做一些判断可以在to.name存在的条件下去判断,这样就只会触发一次)
if (isAllEmpty(to.name)) router.push(to.fullPath);
});
}
toCorrectRoute();
}
} else {
if (to.path !== "/login") {
if (whiteList.indexOf(to.path) !== -1) {
next();
} else {
removeToken();
router.push(`/login?redirect=${to.fullPath}`);
}
} else {
next();
}
}
});
router.afterEach(to => {
loadedPaths.add(to.path);
NProgress.done();
});
export default router;
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
TypeScript
1
https://gitee.com/mangocrisp/vue-pure-admin.git
git@gitee.com:mangocrisp/vue-pure-admin.git
mangocrisp
vue-pure-admin
vue-pure-admin
main

搜索帮助