You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

162 lines
4.5 KiB

  1. import { getConfig } from "/@/config";
  2. import { toRouteType } from "./types";
  3. import NProgress from "/@/utils/progress";
  4. import { findIndex } from "lodash-unified";
  5. import type { StorageConfigs } from "/#/index";
  6. import { transformI18n } from "/@/plugins/i18n";
  7. import { useMultiTagsStoreHook } from "/@/store/modules/multiTags";
  8. import { usePermissionStoreHook } from "/@/store/modules/permission";
  9. import {
  10. Router,
  11. createRouter,
  12. RouteRecordRaw,
  13. RouteComponent
  14. } from "vue-router";
  15. import {
  16. ascending,
  17. initRouter,
  18. getHistoryMode,
  19. findRouteByPath,
  20. handleAliveRoute,
  21. formatTwoStageRoutes,
  22. formatFlatteningRoutes
  23. } from "./utils";
  24. import {
  25. buildHierarchyTree,
  26. openLink,
  27. isUrl,
  28. storageSession
  29. } from "@pureadmin/utils";
  30. import homeRouter from "./modules/home";
  31. import errorRouter from "./modules/error";
  32. import remainingRouter from "./modules/remaining";
  33. // 原始静态路由(未做任何处理)
  34. const routes = [homeRouter, errorRouter];
  35. // 导出处理后的静态路由(三级及以上的路由全部拍成二级)
  36. export const constantRoutes: Array<RouteRecordRaw> = formatTwoStageRoutes(
  37. formatFlatteningRoutes(buildHierarchyTree(ascending(routes)))
  38. );
  39. // 用于渲染菜单,保持原始层级
  40. export const constantMenus: Array<RouteComponent> = ascending(routes).concat(
  41. ...remainingRouter
  42. );
  43. // 不参与菜单的路由
  44. export const remainingPaths = Object.keys(remainingRouter).map(v => {
  45. return remainingRouter[v].path;
  46. });
  47. // 创建路由实例
  48. export const router: Router = createRouter({
  49. history: getHistoryMode(),
  50. routes: constantRoutes.concat(...(remainingRouter as any)),
  51. strict: true,
  52. scrollBehavior(to, from, savedPosition) {
  53. return new Promise(resolve => {
  54. if (savedPosition) {
  55. return savedPosition;
  56. } else {
  57. if (from.meta.saveSrollTop) {
  58. const top: number =
  59. document.documentElement.scrollTop || document.body.scrollTop;
  60. resolve({ left: 0, top });
  61. }
  62. }
  63. });
  64. }
  65. });
  66. // 重置路由
  67. export function resetRouter() {
  68. router.getRoutes().forEach(route => {
  69. const { name, meta } = route;
  70. if (name && router.hasRoute(name) && meta?.backstage) {
  71. router.removeRoute(name);
  72. router.options.routes = formatTwoStageRoutes(
  73. formatFlatteningRoutes(buildHierarchyTree(ascending(routes)))
  74. );
  75. }
  76. });
  77. }
  78. // 路由白名单
  79. const whiteList = ["/login"];
  80. router.beforeEach((to: toRouteType, _from, next) => {
  81. if (to.meta?.keepAlive) {
  82. const newMatched = to.matched;
  83. handleAliveRoute(newMatched, "add");
  84. // 页面整体刷新和点击标签页刷新
  85. if (_from.name === undefined || _from.name === "Redirect") {
  86. handleAliveRoute(newMatched);
  87. }
  88. }
  89. const name = storageSession.getItem<StorageConfigs>("info");
  90. NProgress.start();
  91. const externalLink = isUrl(to?.name as string);
  92. if (!externalLink)
  93. to.matched.some(item => {
  94. if (!item.meta.title) return "";
  95. const Title = getConfig().Title;
  96. if (Title)
  97. document.title = `${transformI18n(item.meta.title)} | ${Title}`;
  98. else document.title = transformI18n(item.meta.title);
  99. });
  100. if (name) {
  101. if (_from?.name) {
  102. // name为超链接
  103. if (externalLink) {
  104. openLink(to?.name as string);
  105. NProgress.done();
  106. } else {
  107. next();
  108. }
  109. } else {
  110. // 刷新
  111. if (usePermissionStoreHook().wholeMenus.length === 0)
  112. initRouter(name.username).then((router: Router) => {
  113. if (!useMultiTagsStoreHook().getMultiTagsCache) {
  114. const { path } = to;
  115. const index = findIndex(remainingRouter, v => {
  116. return v.path == path;
  117. });
  118. const routes: any =
  119. index === -1
  120. ? router.options.routes[0].children
  121. : router.options.routes;
  122. const route = findRouteByPath(path, routes);
  123. // query、params模式路由传参数的标签页不在此处处理
  124. if (route && route.meta?.title) {
  125. useMultiTagsStoreHook().handleTags("push", {
  126. path: route.path,
  127. name: route.name,
  128. meta: route.meta
  129. });
  130. }
  131. }
  132. router.push(to.fullPath);
  133. });
  134. next();
  135. }
  136. } else {
  137. if (to.path !== "/login") {
  138. if (whiteList.indexOf(to.path) !== -1) {
  139. next();
  140. } else {
  141. next({ path: "/login" });
  142. }
  143. } else {
  144. next();
  145. }
  146. }
  147. });
  148. router.afterEach(() => {
  149. NProgress.done();
  150. });
  151. export default router;