This commit is contained in:
@@ -0,0 +1,101 @@
|
||||
import 'nprogress/nprogress.css';
|
||||
|
||||
import NProgress from 'nprogress';
|
||||
import { MessagePlugin } from 'tdesign-vue-next';
|
||||
import type { RouteLocationNormalized } from 'vue-router';
|
||||
|
||||
import { getSetupStatus } from '@/api/setup';
|
||||
import router from '@/router';
|
||||
import { getPermissionStore, useUserStore } from '@/store';
|
||||
import { hasRoleAccess } from '@/store/modules/menu-access';
|
||||
|
||||
NProgress.configure({ showSpinner: false });
|
||||
|
||||
const isPublic = (to: RouteLocationNormalized) =>
|
||||
to.path === '/login' || to.path === '/result/404' || to.path === '/setup';
|
||||
|
||||
let setupStatusRequest: ReturnType<typeof getSetupStatus> | null = null;
|
||||
|
||||
function loadSetupStatus() {
|
||||
setupStatusRequest ||= getSetupStatus();
|
||||
return setupStatusRequest;
|
||||
}
|
||||
|
||||
router.beforeEach(async (to) => {
|
||||
NProgress.start();
|
||||
const userStore = useUserStore();
|
||||
const permissionStore = getPermissionStore();
|
||||
|
||||
let setupRequired = false;
|
||||
let setupStatusAvailable = false;
|
||||
try {
|
||||
const setupStatus = await loadSetupStatus();
|
||||
setupRequired = setupStatus.required;
|
||||
setupStatusAvailable = true;
|
||||
} catch (error) {
|
||||
setupStatusRequest = null;
|
||||
if (to.path === '/setup') {
|
||||
const statusCode = (error as { response?: { status?: number } }).response?.status;
|
||||
if (statusCode !== 404) return true;
|
||||
}
|
||||
}
|
||||
if (setupStatusAvailable && setupRequired && to.path !== '/setup') return '/setup';
|
||||
if (to.path === '/setup') return setupStatusAvailable && setupRequired ? true : '/login';
|
||||
|
||||
if (isPublic(to)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
try {
|
||||
if (!userStore.authenticated) await userStore.restoreSession();
|
||||
permissionStore.initRoutes();
|
||||
} catch {
|
||||
userStore.clearSession();
|
||||
permissionStore.restoreRoutes();
|
||||
if (to.path !== '/login') {
|
||||
MessagePlugin.warning('登录会话已失效,请重新登录');
|
||||
return { path: '/login', query: { redirect: to.fullPath } };
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (to.path !== '/role-select' && to.path !== '/profile' && !userStore.currentRole) {
|
||||
return { path: '/role-select', query: { redirect: to.fullPath } };
|
||||
}
|
||||
|
||||
if (userStore.user.mustChangePassword && to.path !== '/profile') {
|
||||
return { path: '/profile', query: { forcePassword: '1', redirect: to.fullPath } };
|
||||
}
|
||||
|
||||
const roles = (to.meta.roleCodes || []) as string[];
|
||||
const permission = to.meta.permission as string | string[] | undefined;
|
||||
if (!hasRoleAccess(roles, userStore.currentRole)) return '/result/403';
|
||||
if (
|
||||
permission &&
|
||||
(Array.isArray(permission)
|
||||
? !permission.some((item) => userStore.hasPermission(item))
|
||||
: !userStore.hasPermission(permission))
|
||||
) {
|
||||
return '/result/403';
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
router.afterEach(() => NProgress.done());
|
||||
|
||||
let handlingSessionExpiry = false;
|
||||
|
||||
window.addEventListener('kaidi:session-expired', async () => {
|
||||
if (handlingSessionExpiry) return;
|
||||
handlingSessionExpiry = true;
|
||||
const userStore = useUserStore();
|
||||
userStore.clearSession();
|
||||
getPermissionStore().restoreRoutes();
|
||||
try {
|
||||
if (router.currentRoute.value.path !== '/login') {
|
||||
await router.replace({ path: '/login', query: { redirect: router.currentRoute.value.fullPath } });
|
||||
}
|
||||
} finally {
|
||||
handlingSessionExpiry = false;
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user