perf(admin): 实现切页即时导航与列表 loading 壳

非阻塞 session 刷新、侧边栏 chunk 预取、KeepAlive 对齐,以及按 tab 延迟加载重型列表页。
This commit is contained in:
2026-06-18 16:45:01 +08:00
parent ca482b1916
commit 8da730762b
21 changed files with 321 additions and 117 deletions

View File

@@ -414,21 +414,51 @@ function resolveCreateParentLabel(agentId: string) {
}
/* ─── Init ─── */
let pageInitPromise: Promise<void> | null = null;
function ensurePageInit(): Promise<void> {
if (settingsLoaded.value) return Promise.resolve();
if (!pageInitPromise) {
pageInitPromise = loadUsersPageInit().finally(() => {
pageInitPromise = null;
});
}
return pageInitPromise;
}
function loadActiveViewTabData() {
const tab = activeViewTab.value;
if (tab === 'players') {
if (canViewUsers.value) void loadAllPlayers();
return;
}
if (!canViewAgents.value) return;
if (tab === 'tier1Agents') {
void loadTier1Agents();
return;
}
const m = /^agentLevel-(\d+)$/.exec(tab);
if (m) {
void ensurePageInit().then(() => loadSubAgentsAtLevel(Number(m[1])));
}
}
onMounted(() => {
if (canManageSettings.value) {
void loadUsersPageInit();
}
if (canViewUsers.value) {
loadAllPlayers();
}
if (canViewAgents.value) {
loadTier1Agents();
}
loadActiveViewTabData();
});
// KeepAlive 激活时静默刷新列表不重复page-init
// KeepAlive 激活时静默刷新当前 tab 列表(不重复 page-init
onActivated(() => {
if (canViewUsers.value && allPlayers.value.length > 0) void loadAllPlayers();
if (canViewAgents.value && tier1Agents.value.length > 0) void loadTier1Agents();
const tab = activeViewTab.value;
if (tab === 'players' && canViewUsers.value && allPlayers.value.length > 0) void loadAllPlayers();
else if (tab === 'tier1Agents' && canViewAgents.value && tier1Agents.value.length > 0) void loadTier1Agents();
else {
const m = /^agentLevel-(\d+)$/.exec(tab);
if (m) {
const lvl = Number(m[1]);
const st = subAgentLevelState[lvl];
if (st?.agents.length) loadSubAgentsAtLevel(lvl);
}
}
});
async function loadUsersPageInit() {
@@ -456,9 +486,6 @@ async function loadUsersPageInit() {
}
if (payload.agentLevelCounts) {
agentLevelCounts.value = payload.agentLevelCounts;
for (const lvl of visibleSubAgentTabLevels.value) {
loadSubAgentsAtLevel(lvl);
}
}
settingsLoaded.value = true;
} catch {
@@ -670,14 +697,22 @@ function onSubAgentRowClick(row: AgentRow, _column: unknown, event: MouseEvent)
watch(activeViewTab, (tab) => {
const m = /^agentLevel-(\d+)$/.exec(tab);
if (m) loadSubAgentsAtLevel(Number(m[1]));
if (m) {
void ensurePageInit().then(() => loadSubAgentsAtLevel(Number(m[1])));
return;
}
if (tab === 'players' && canViewUsers.value && !allPlayers.value.length) void loadAllPlayers();
if (tab === 'tier1Agents' && canViewAgents.value && !tier1Agents.value.length) void loadTier1Agents();
});
watch(visibleSubAgentTabLevels, (levels, prev) => {
for (const lvl of levels) {
if (!prev?.includes(lvl) || !subAgentLevelState[lvl]?.agents.length) {
loadSubAgentsAtLevel(lvl);
}
watch(visibleSubAgentTabLevels, (levels) => {
const tab = activeViewTab.value;
const m = /^agentLevel-(\d+)$/.exec(tab);
if (!m) return;
const activeLevel = Number(m[1]);
if (levels.includes(activeLevel)) {
const st = subAgentLevelState[activeLevel];
if (!st?.agents.length) loadSubAgentsAtLevel(activeLevel);
}
});