index.ts 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. import type { Router, RouteLocationNormalized } from 'vue-router';
  2. import { useAppStoreWithOut } from '/@/store/modules/app';
  3. import { useUserStoreWithOut } from '/@/store/modules/user';
  4. import { useVentStore } from '/@/store/modules/vent';
  5. import { useTransitionSetting } from '/@/hooks/setting/useTransitionSetting';
  6. import { AxiosCanceler } from '/@/utils/http/axios/axiosCancel';
  7. import { Modal, notification } from 'ant-design-vue';
  8. import { warn } from '/@/utils/log';
  9. import { unref } from 'vue';
  10. import { setRouteChange } from '/@/logics/mitt/routeChange';
  11. import { createPermissionGuard } from './permissionGuard';
  12. import { createStateGuard } from './stateGuard';
  13. import nProgress from 'nprogress';
  14. import projectSetting from '/@/settings/projectSetting';
  15. import { createParamMenuGuard } from './paramMenuGuard';
  16. import { RootRoute } from '/@/router/routes';
  17. import { useGlobSetting } from '/@/hooks/setting';
  18. import { PageEnum } from '/@/enums/pageEnum';
  19. import { unmountMicroApps } from '/@/qiankun';
  20. // Don't change the order of creation
  21. export function setupRouterGuard(router: Router) {
  22. createPageGuard(router);
  23. createPageLoadingGuard(router);
  24. createHttpGuard(router);
  25. createScrollGuard(router);
  26. createMessageGuard(router);
  27. createProgressGuard(router);
  28. createPermissionGuard(router);
  29. createParamMenuGuard(router); // must after createPermissionGuard (menu has been built.)
  30. createStateGuard(router);
  31. }
  32. const glob = useGlobSetting();
  33. RootRoute.redirect = glob.homePath || PageEnum.BASE_HOME;
  34. /**
  35. * Hooks for handling page state
  36. */
  37. function createPageGuard(router: Router) {
  38. const loadedPageMap = new Map<string, boolean>();
  39. router.beforeEach(async (to, from) => {
  40. if (from.path.startsWith('/micro-') && !to.path.startsWith('/micro-')) {
  41. // unmountMicroApps(['/micro-vent-3dModal', '/micro-need-air']);
  42. unmountMicroApps(['/' + from.path.split('/')[1]]);
  43. }
  44. // The page has already been loaded, it will be faster to open it again, you don’t need to do loading and other processing
  45. to.meta.loaded = !!loadedPageMap.get(to.path);
  46. // Notify routing changes
  47. setRouteChange(to);
  48. return true;
  49. });
  50. router.afterEach((to) => {
  51. loadedPageMap.set(to.path, true);
  52. });
  53. }
  54. // Used to handle page loading status
  55. function createPageLoadingGuard(router: Router) {
  56. const ventStore = useVentStore();
  57. const userStore = useUserStoreWithOut();
  58. const appStore = useAppStoreWithOut();
  59. const { getOpenPageLoading } = useTransitionSetting();
  60. router.beforeEach(async (to, from) => {
  61. if (!userStore.getToken) {
  62. return true;
  63. }
  64. if (to.meta.loaded) {
  65. return true;
  66. }
  67. if (!ventStore.allTableHeaderColumns) await ventStore.setAllTableHeaderColumns();
  68. if (unref(getOpenPageLoading)) {
  69. appStore.setPageLoadingAction(true);
  70. return true;
  71. }
  72. return true;
  73. });
  74. router.afterEach(async (to, from) => {
  75. if (unref(getOpenPageLoading)) {
  76. // TODO Looking for a better way
  77. // The timer simulates the loading time to prevent flashing too fast,
  78. setTimeout(() => {
  79. appStore.setPageLoading(false);
  80. }, 220);
  81. }
  82. return true;
  83. });
  84. }
  85. /**
  86. * The interface used to close the current page to complete the request when the route is switched
  87. * @param router
  88. */
  89. function createHttpGuard(router: Router) {
  90. const { removeAllHttpPending } = projectSetting;
  91. let axiosCanceler: Nullable<AxiosCanceler>;
  92. if (removeAllHttpPending) {
  93. axiosCanceler = new AxiosCanceler();
  94. }
  95. router.beforeEach(async () => {
  96. // Switching the route will delete the previous request
  97. axiosCanceler?.removeAllPending();
  98. return true;
  99. });
  100. }
  101. // Routing switch back to the top
  102. function createScrollGuard(router: Router) {
  103. const isHash = (href: string) => {
  104. return /^#/.test(href);
  105. };
  106. const body = document.body;
  107. router.afterEach(async (to) => {
  108. // scroll top
  109. isHash((to as RouteLocationNormalized & { href: string })?.href) && body.scrollTo(0, 0);
  110. return true;
  111. });
  112. }
  113. /**
  114. * Used to close the message instance when the route is switched
  115. * @param router
  116. */
  117. export function createMessageGuard(router: Router) {
  118. const { closeMessageOnSwitch } = projectSetting;
  119. router.beforeEach(async () => {
  120. try {
  121. if (closeMessageOnSwitch) {
  122. Modal.destroyAll();
  123. notification.destroy();
  124. }
  125. } catch (error) {
  126. warn('message guard error:' + error);
  127. }
  128. return true;
  129. });
  130. }
  131. export function createProgressGuard(router: Router) {
  132. const { getOpenNProgress } = useTransitionSetting();
  133. router.beforeEach(async (to) => {
  134. if (to.meta.loaded) {
  135. return true;
  136. }
  137. unref(getOpenNProgress) && nProgress.start();
  138. return true;
  139. });
  140. router.afterEach(async () => {
  141. unref(getOpenNProgress) && nProgress.done();
  142. return true;
  143. });
  144. }