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.

163 lines
4.6 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. usePermissionStoreHook().clearAllCachePage();
  78. }
  79. /** 路由白名单 */
  80. const whiteList = ["/login"];
  81. router.beforeEach((to: toRouteType, _from, next) => {
  82. if (to.meta?.keepAlive) {
  83. const newMatched = to.matched;
  84. handleAliveRoute(newMatched, "add");
  85. // 页面整体刷新和点击标签页刷新
  86. if (_from.name === undefined || _from.name === "Redirect") {
  87. handleAliveRoute(newMatched);
  88. }
  89. }
  90. const name = storageSession.getItem<StorageConfigs>("info");
  91. NProgress.start();
  92. const externalLink = isUrl(to?.name as string);
  93. if (!externalLink)
  94. to.matched.some(item => {
  95. if (!item.meta.title) return "";
  96. const Title = getConfig().Title;
  97. if (Title)
  98. document.title = `${transformI18n(item.meta.title)} | ${Title}`;
  99. else document.title = transformI18n(item.meta.title);
  100. });
  101. if (name) {
  102. if (_from?.name) {
  103. // name为超链接
  104. if (externalLink) {
  105. openLink(to?.name as string);
  106. NProgress.done();
  107. } else {
  108. next();
  109. }
  110. } else {
  111. // 刷新
  112. if (usePermissionStoreHook().wholeMenus.length === 0)
  113. initRouter(name.username).then((router: Router) => {
  114. if (!useMultiTagsStoreHook().getMultiTagsCache) {
  115. const { path } = to;
  116. const index = findIndex(remainingRouter, v => {
  117. return v.path == path;
  118. });
  119. const routes: any =
  120. index === -1
  121. ? router.options.routes[0].children
  122. : router.options.routes;
  123. const route = findRouteByPath(path, routes);
  124. // query、params模式路由传参数的标签页不在此处处理
  125. if (route && route.meta?.title) {
  126. useMultiTagsStoreHook().handleTags("push", {
  127. path: route.path,
  128. name: route.name,
  129. meta: route.meta
  130. });
  131. }
  132. }
  133. router.push(to.fullPath);
  134. });
  135. next();
  136. }
  137. } else {
  138. if (to.path !== "/login") {
  139. if (whiteList.indexOf(to.path) !== -1) {
  140. next();
  141. } else {
  142. next({ path: "/login" });
  143. }
  144. } else {
  145. next();
  146. }
  147. }
  148. });
  149. router.afterEach(() => {
  150. NProgress.done();
  151. });
  152. export default router;