index.ts 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. import { isUrl } from "/@/utils/is";
  2. import { getConfig } from "/@/config";
  3. import { toRouteType } from "./types";
  4. import { openLink } from "/@/utils/link";
  5. import NProgress from "/@/utils/progress";
  6. import { findIndex } from "lodash-unified";
  7. import { transformI18n } from "/@/plugins/i18n";
  8. import { storageSession } from "/@/utils/storage";
  9. import { buildHierarchyTree } from "/@/utils/tree";
  10. import { useMultiTagsStoreHook } from "/@/store/modules/multiTags";
  11. import { usePermissionStoreHook } from "/@/store/modules/permission";
  12. import {
  13. Router,
  14. RouteMeta,
  15. createRouter,
  16. RouteRecordRaw,
  17. RouteComponent,
  18. RouteRecordName
  19. } from "vue-router";
  20. import {
  21. ascending,
  22. initRouter,
  23. getHistoryMode,
  24. getParentPaths,
  25. findRouteByPath,
  26. handleAliveRoute,
  27. formatTwoStageRoutes,
  28. formatFlatteningRoutes
  29. } from "./utils";
  30. import pptRouter from "./modules/ppt";
  31. import homeRouter from "./modules/home";
  32. import ableRouter from "./modules/able";
  33. import listRouter from "./modules/list";
  34. import aboutRouter from "./modules/about";
  35. import errorRouter from "./modules/error";
  36. import guideRouter from "./modules/guide";
  37. import resultRouter from "./modules/result";
  38. import editorRouter from "./modules/editor";
  39. import nestedRouter from "./modules/nested";
  40. import flowChartRouter from "./modules/flowchart";
  41. import remainingRouter from "./modules/remaining";
  42. import componentsRouter from "./modules/components";
  43. // 原始静态路由(未做任何处理)
  44. const routes = [
  45. pptRouter,
  46. homeRouter,
  47. ableRouter,
  48. listRouter,
  49. aboutRouter,
  50. errorRouter,
  51. guideRouter,
  52. resultRouter,
  53. nestedRouter,
  54. editorRouter,
  55. flowChartRouter,
  56. componentsRouter
  57. ];
  58. // 导出处理后的静态路由(三级及以上的路由全部拍成二级)
  59. export const constantRoutes: Array<RouteRecordRaw> = formatTwoStageRoutes(
  60. formatFlatteningRoutes(buildHierarchyTree(ascending(routes)))
  61. );
  62. // 用于渲染菜单,保持原始层级
  63. export const constantMenus: Array<RouteComponent> = ascending(routes).concat(
  64. ...remainingRouter
  65. );
  66. // 不参与菜单的路由
  67. export const remainingPaths = Object.keys(remainingRouter).map(v => {
  68. return remainingRouter[v].path;
  69. });
  70. // 创建路由实例
  71. export const router: Router = createRouter({
  72. history: getHistoryMode(),
  73. routes: constantRoutes.concat(...remainingRouter),
  74. strict: true,
  75. scrollBehavior(to, from, savedPosition) {
  76. return new Promise(resolve => {
  77. if (savedPosition) {
  78. return savedPosition;
  79. } else {
  80. if (from.meta.saveSrollTop) {
  81. const top: number =
  82. document.documentElement.scrollTop || document.body.scrollTop;
  83. resolve({ left: 0, top });
  84. }
  85. }
  86. });
  87. }
  88. });
  89. // 路由白名单
  90. const whiteList = ["/login"];
  91. router.beforeEach((to: toRouteType, _from, next) => {
  92. if (to.meta?.keepAlive) {
  93. const newMatched = to.matched;
  94. handleAliveRoute(newMatched, "add");
  95. // 页面整体刷新和点击标签页刷新
  96. if (_from.name === undefined || _from.name === "redirect") {
  97. handleAliveRoute(newMatched);
  98. }
  99. }
  100. const name = storageSession.getItem("info");
  101. NProgress.start();
  102. const externalLink = isUrl(to?.name);
  103. if (!externalLink)
  104. to.matched.some(item => {
  105. if (!item.meta.title) return "";
  106. const Title = getConfig().Title;
  107. if (Title)
  108. document.title = `${transformI18n(
  109. item.meta.title,
  110. item.meta?.i18n
  111. )} | ${Title}`;
  112. else document.title = transformI18n(item.meta.title, item.meta?.i18n);
  113. });
  114. if (name) {
  115. if (_from?.name) {
  116. // name为超链接
  117. if (externalLink) {
  118. openLink(to?.name);
  119. NProgress.done();
  120. } else {
  121. next();
  122. }
  123. } else {
  124. // 刷新
  125. if (usePermissionStoreHook().wholeMenus.length === 0)
  126. initRouter(name.username).then((router: Router) => {
  127. if (!useMultiTagsStoreHook().getMultiTagsCache) {
  128. const handTag = (
  129. path: string,
  130. parentPath: string,
  131. name: RouteRecordName,
  132. meta: RouteMeta
  133. ): void => {
  134. useMultiTagsStoreHook().handleTags("push", {
  135. path,
  136. parentPath,
  137. name,
  138. meta
  139. });
  140. };
  141. // 未开启标签页缓存,刷新页面重定向到顶级路由(参考标签页操作例子,只针对静态路由)
  142. if (to.meta?.refreshRedirect) {
  143. const routes = router.options.routes;
  144. const { refreshRedirect } = to.meta;
  145. const { name, meta } = findRouteByPath(refreshRedirect, routes);
  146. handTag(
  147. refreshRedirect,
  148. getParentPaths(refreshRedirect, routes)[1],
  149. name,
  150. meta
  151. );
  152. return router.push(refreshRedirect);
  153. } else {
  154. const { path } = to;
  155. const index = findIndex(remainingRouter, v => {
  156. return v.path == path;
  157. });
  158. const routes =
  159. index === -1
  160. ? router.options.routes[0].children
  161. : router.options.routes;
  162. const route = findRouteByPath(path, routes);
  163. const routePartent = getParentPaths(path, routes);
  164. // 未开启标签页缓存,刷新页面重定向到顶级路由(参考标签页操作例子,只针对动态路由)
  165. if (
  166. path !== routes[0].path &&
  167. route?.meta?.rank !== 0 &&
  168. routePartent.length === 0
  169. ) {
  170. if (!route?.meta?.refreshRedirect) return;
  171. const { name, meta } = findRouteByPath(
  172. route.meta.refreshRedirect,
  173. routes
  174. );
  175. handTag(
  176. route.meta?.refreshRedirect,
  177. getParentPaths(route.meta?.refreshRedirect, routes)[0],
  178. name,
  179. meta
  180. );
  181. return router.push(route.meta?.refreshRedirect);
  182. } else {
  183. handTag(
  184. route.path,
  185. routePartent[routePartent.length - 1],
  186. route.name,
  187. route.meta
  188. );
  189. return router.push(path);
  190. }
  191. }
  192. }
  193. router.push(to.fullPath);
  194. });
  195. next();
  196. }
  197. } else {
  198. if (to.path !== "/login") {
  199. if (whiteList.indexOf(to.path) !== -1) {
  200. next();
  201. } else {
  202. next({ path: "/login" });
  203. }
  204. } else {
  205. next();
  206. }
  207. }
  208. });
  209. router.afterEach(() => {
  210. NProgress.done();
  211. });
  212. export default router;