|
|
|
@ -1,15 +1,19 @@ |
|
|
|
import { router } from '/@/router'; |
|
|
|
|
|
|
|
import { createProgressGuard } from './progressGuard'; |
|
|
|
import type { Router, RouteLocationNormalized } from 'vue-router'; |
|
|
|
import { useAppStoreWidthOut } from '/@/store/modules/app'; |
|
|
|
import { useUserStoreWidthOut } from '/@/store/modules/user'; |
|
|
|
import { useTransitionSetting } from '/@/hooks/setting/useTransitionSetting'; |
|
|
|
import { AxiosCanceler } from '/@/utils/http/axios/axiosCancel'; |
|
|
|
import { Modal, notification } from 'ant-design-vue'; |
|
|
|
import { warn } from '/@/utils/log'; |
|
|
|
import { unref } from 'vue'; |
|
|
|
import { setRouteChange } from '/@/logics/mitt/routeChange'; |
|
|
|
import { createPermissionGuard } from './permissionGuard'; |
|
|
|
import { createPageLoadingGuard } from './pageLoadingGuard'; |
|
|
|
import { createMessageGuard } from './messageGuard'; |
|
|
|
import { createScrollGuard } from './scrollGuard'; |
|
|
|
import { createHttpGuard } from './httpGuard'; |
|
|
|
import { createPageGuard } from './pageGuard'; |
|
|
|
import { createStateGuard } from './stateGuard'; |
|
|
|
import nProgress from 'nprogress'; |
|
|
|
import projectSetting from '/@/settings/projectSetting'; |
|
|
|
|
|
|
|
export function setupRouterGuard() { |
|
|
|
// Don't change the order of creation
|
|
|
|
export function setupRouterGuard(router: Router) { |
|
|
|
createPageGuard(router); |
|
|
|
createPageLoadingGuard(router); |
|
|
|
createHttpGuard(router); |
|
|
|
@ -19,3 +23,123 @@ export function setupRouterGuard() { |
|
|
|
createPermissionGuard(router); |
|
|
|
createStateGuard(router); |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* Hooks for handling page state |
|
|
|
*/ |
|
|
|
function createPageGuard(router: Router) { |
|
|
|
const loadedPageMap = new Map<string, boolean>(); |
|
|
|
|
|
|
|
router.beforeEach(async (to) => { |
|
|
|
// The page has already been loaded, it will be faster to open it again, you don’t need to do loading and other processing
|
|
|
|
to.meta.loaded = !!loadedPageMap.get(to.path); |
|
|
|
// Notify routing changes
|
|
|
|
setRouteChange(to); |
|
|
|
|
|
|
|
return true; |
|
|
|
}); |
|
|
|
|
|
|
|
router.afterEach((to) => { |
|
|
|
loadedPageMap.set(to.path, true); |
|
|
|
}); |
|
|
|
} |
|
|
|
|
|
|
|
// Used to handle page loading status
|
|
|
|
function createPageLoadingGuard(router: Router) { |
|
|
|
const userStore = useUserStoreWidthOut(); |
|
|
|
const appStore = useAppStoreWidthOut(); |
|
|
|
const { getOpenPageLoading } = useTransitionSetting(); |
|
|
|
router.beforeEach(async (to) => { |
|
|
|
if (!userStore.getToken) { |
|
|
|
return true; |
|
|
|
} |
|
|
|
if (to.meta.loaded) { |
|
|
|
return true; |
|
|
|
} |
|
|
|
|
|
|
|
if (unref(getOpenPageLoading)) { |
|
|
|
appStore.setPageLoadingAction(true); |
|
|
|
return true; |
|
|
|
} |
|
|
|
|
|
|
|
return true; |
|
|
|
}); |
|
|
|
router.afterEach(async () => { |
|
|
|
if (unref(getOpenPageLoading)) { |
|
|
|
// TODO Looking for a better way
|
|
|
|
// The timer simulates the loading time to prevent flashing too fast,
|
|
|
|
setTimeout(() => { |
|
|
|
appStore.setPageLoading(false); |
|
|
|
}, 220); |
|
|
|
} |
|
|
|
return true; |
|
|
|
}); |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* The interface used to close the current page to complete the request when the route is switched |
|
|
|
* @param router |
|
|
|
*/ |
|
|
|
function createHttpGuard(router: Router) { |
|
|
|
const { removeAllHttpPending } = projectSetting; |
|
|
|
let axiosCanceler: Nullable<AxiosCanceler>; |
|
|
|
if (removeAllHttpPending) { |
|
|
|
axiosCanceler = new AxiosCanceler(); |
|
|
|
} |
|
|
|
router.beforeEach(async () => { |
|
|
|
// Switching the route will delete the previous request
|
|
|
|
axiosCanceler?.removeAllPending(); |
|
|
|
return true; |
|
|
|
}); |
|
|
|
} |
|
|
|
|
|
|
|
// Routing switch back to the top
|
|
|
|
function createScrollGuard(router: Router) { |
|
|
|
const isHash = (href: string) => { |
|
|
|
return /^#/.test(href); |
|
|
|
}; |
|
|
|
|
|
|
|
const body = document.body; |
|
|
|
|
|
|
|
router.afterEach(async (to) => { |
|
|
|
// scroll top
|
|
|
|
isHash((to as RouteLocationNormalized & { href: string })?.href) && body.scrollTo(0, 0); |
|
|
|
return true; |
|
|
|
}); |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* Used to close the message instance when the route is switched |
|
|
|
* @param router |
|
|
|
*/ |
|
|
|
export function createMessageGuard(router: Router) { |
|
|
|
const { closeMessageOnSwitch } = projectSetting; |
|
|
|
|
|
|
|
router.beforeEach(async () => { |
|
|
|
try { |
|
|
|
if (closeMessageOnSwitch) { |
|
|
|
Modal.destroyAll(); |
|
|
|
notification.destroy(); |
|
|
|
} |
|
|
|
} catch (error) { |
|
|
|
warn('message guard error:' + error); |
|
|
|
} |
|
|
|
return true; |
|
|
|
}); |
|
|
|
} |
|
|
|
|
|
|
|
export function createProgressGuard(router: Router) { |
|
|
|
const { getOpenNProgress } = useTransitionSetting(); |
|
|
|
router.beforeEach(async (to) => { |
|
|
|
if (to.meta.loaded) { |
|
|
|
return true; |
|
|
|
} |
|
|
|
unref(getOpenNProgress) && nProgress.start(); |
|
|
|
return true; |
|
|
|
}); |
|
|
|
|
|
|
|
router.afterEach(async () => { |
|
|
|
unref(getOpenNProgress) && nProgress.done(); |
|
|
|
return true; |
|
|
|
}); |
|
|
|
} |
|
|
|
|