fix: 提升管理端启动与导航稳定性

- 等待初始路由就绪并提供可恢复的启动失败页面

- 收敛失效登录导航并按需加载 SVG 图标资源
This commit is contained in:
2026-07-24 19:02:28 +08:00
parent a75f7baf1b
commit da59c713f9
12 changed files with 259 additions and 13 deletions

View File

@@ -20,6 +20,7 @@ import {
removeDevLoginQuery,
shouldAttemptDevLogin,
} from './dev-login';
import { resolveNavigationUserInfo } from './navigation-user-info';
interface NetworkConnectionLike {
effectiveType?: string;
@@ -75,6 +76,13 @@ function setupChunkErrorGuard(router: Router) {
if (!isDynamicImportChunkError(error)) {
return;
}
// 开发环境保留当前页面和调试上下文,避免模块热更新期间反复整页刷新。
if (import.meta.env.DEV) {
console.warn('Dynamic route module loading failed:', error);
return;
}
const fullPath = to?.fullPath;
if (!fullPath) {
return;
@@ -156,6 +164,13 @@ function setupAccessGuard(router: Router) {
query: removeDevLoginQuery(to.query),
}).fullPath;
const resolveUserInfo = () =>
resolveNavigationUserInfo({
cachedUserInfo: userStore.userInfo,
fetchUserInfo: authStore.fetchUserInfo,
getAccessToken: () => accessStore.accessToken,
});
if (devLoginAccount && import.meta.env.DEV && accessStore.accessToken) {
return resolveCleanFullPath();
}
@@ -177,10 +192,6 @@ function setupAccessGuard(router: Router) {
});
await devLoginPromise;
const cleanFullPath = resolveCleanFullPath();
if (window.location.search.includes('devLogin=')) {
window.location.replace(cleanFullPath);
return false;
}
return cleanFullPath;
} catch {
const cleanFullPath = resolveCleanFullPath();
@@ -198,8 +209,10 @@ function setupAccessGuard(router: Router) {
// 基本路由,这些路由不需要进入权限拦截
if (coreRouteNames.includes(to.name as string)) {
if (to.path === LOGIN_PATH && accessStore.accessToken) {
const currentUser =
userStore.userInfo || (await authStore.fetchUserInfo());
const currentUser = await resolveUserInfo();
if (!currentUser) {
return true;
}
if (shouldForcePasswordChange(currentUser)) {
return buildForcePasswordRoute();
}
@@ -239,7 +252,17 @@ function setupAccessGuard(router: Router) {
return to;
}
const userInfo = userStore.userInfo || (await authStore.fetchUserInfo());
const userInfo = await resolveUserInfo();
if (!userInfo) {
return {
path: LOGIN_PATH,
query:
to.fullPath === preferences.app.defaultHomePath
? {}
: { redirect: encodeURIComponent(to.fullPath) },
replace: true,
};
}
if (shouldForcePasswordChange(userInfo) && !isForcePasswordRoute(to)) {
if (from.name) {
notifyForcePasswordChange();