feat(网页端): 完善登录后工作台与项目管理体验
Client Quality Gates / Shared client and Web (push) Has been cancelled
Client Quality Gates / macOS Desktop (push) Has been cancelled

This commit is contained in:
Cheng Zhou
2026-07-09 14:59:06 +08:00
parent 0aff10fe0d
commit 1dc10f569d
15 changed files with 1418 additions and 185 deletions
+24 -12
View File
@@ -78,20 +78,33 @@ describe("admin project route permissions", () => {
expect(source).not.toContain("[SYSTEM_PERMISSION_MONITORING_METRICS]");
});
it("routes desktop login and missing-project flows through the dedicated entry chooser", () => {
it("routes web and desktop login plus missing-project flows through the entry chooser", () => {
const source = readRouter();
expect(source).not.toContain("findPmAdminLandingPath");
expect(source).not.toContain("pmAdminLandingModules");
expect(source).toContain('path: "/desktop/project-entry"');
expect(source).toContain('component: DesktopProjectEntry');
expect(source).toContain('const WEB_WORKBENCH_ENTRY_PATH = "/workbench";');
expect(source).toContain('const DESKTOP_PROJECT_ENTRY_PATH = "/desktop/project-entry";');
expect(source).toContain("const resolveWorkbenchEntryPath = (isDesktopRuntime: boolean)");
expect(source).toContain("const isWorkbenchEntryPath = (path: string)");
expect(source).toContain('import WebWorkbenchEntry from "../views/WebWorkbenchEntry.vue";');
expect(source).toContain("path: WEB_WORKBENCH_ENTRY_PATH");
expect(source).toContain('name: "WorkbenchEntry"');
expect(source).toContain("component: WebWorkbenchEntry");
expect(source).toContain("path: DESKTOP_PROJECT_ENTRY_PATH");
expect(source).toContain("component: DesktopProjectEntry");
expect(source).toContain("DesktopSessionRestore");
expect(source).toContain("DESKTOP_SESSION_RESTORE_PATH");
expect(source).toContain('if (isDesktopRuntime) {\n next({ path: "/desktop/project-entry" });');
expect(source).toContain('isDesktopRuntime ? "/desktop/project-entry" : isAdmin ? "/admin/users" : "/admin/projects"');
expect(source).toContain("if (isDesktopRuntime && to.path === WEB_WORKBENCH_ENTRY_PATH)");
expect(source).toContain("if (!isDesktopRuntime && to.path === DESKTOP_PROJECT_ENTRY_PATH)");
expect(source).toContain("const workbenchEntryPath = resolveWorkbenchEntryPath(isDesktopRuntime)");
expect(source).toContain("next({ path: workbenchEntryPath });");
expect(source).toContain('if (isDesktopRuntime && token && !isAdmin && to.path.startsWith("/admin"))');
expect(source).toContain('if (isDesktopRuntime && token && to.path === "/desktop/project-entry" && studyStore.currentStudy)');
expect(source).toContain('if (token && !studyStore.currentStudy && !isDesktopRuntime)');
expect(source).toContain('next({ path: DESKTOP_PROJECT_ENTRY_PATH });');
expect(source).toContain("if (token && isWorkbenchEntryPath(to.path) && studyStore.currentStudy)");
expect(source).not.toContain("if (token && !studyStore.currentStudy && !isDesktopRuntime)");
expect(source).not.toContain("ensureDefaultActiveStudy();");
expect(source).not.toContain("ensureDefaultStudy();");
});
it("canonicalizes the legacy file version entry before rendering its loading fallback", () => {
@@ -117,7 +130,7 @@ describe("admin project route permissions", () => {
const restoreRedirectIndex = source.indexOf("next({ path: DESKTOP_SESSION_RESTORE_PATH", preserveIndex);
const logoutIndex = source.indexOf("await auth.logout()", restoreRedirectIndex);
const loginRedirectIndex = source.indexOf('next({ path: "/login" })', logoutIndex);
const projectFallbackIndex = source.indexOf("if (token && !studyStore.currentStudy && !isDesktopRuntime)", restoreGuardIndex);
const workbenchEntryIndex = source.indexOf("const workbenchEntryPath = resolveWorkbenchEntryPath(isDesktopRuntime)", restoreGuardIndex);
expect(restoreGuardIndex).toBeGreaterThan(-1);
expect(fetchMeIndex).toBeGreaterThan(restoreGuardIndex);
@@ -125,7 +138,7 @@ describe("admin project route permissions", () => {
expect(restoreRedirectIndex).toBeGreaterThan(preserveIndex);
expect(logoutIndex).toBeGreaterThan(restoreRedirectIndex);
expect(loginRedirectIndex).toBeGreaterThan(logoutIndex);
expect(fetchMeIndex).toBeLessThan(projectFallbackIndex);
expect(workbenchEntryIndex).toBeGreaterThan(fetchMeIndex);
expect(source).toContain("const isDesktopSessionRestoreRoute = to.path === DESKTOP_SESSION_RESTORE_PATH");
expect(source).toContain("!isDesktopSessionRestoreRoute");
expect(source).toContain("disableNetworkRetry: true");
@@ -135,11 +148,10 @@ describe("admin project route permissions", () => {
it("does not register the removed non-admin personal dashboard route", () => {
const source = readRouter();
const removedComponent = ["My", "Work", "bench"].join("");
const removedPath = `/${["work", "bench"].join("")}`;
expect(source).not.toContain(removedComponent);
expect(source).not.toContain(`path: "${removedPath.slice(1)}"`);
expect(source).not.toContain(`"${removedPath}"`);
expect(source).not.toContain(`component: ${removedComponent}`);
expect(source).not.toContain('path: "workbench"');
});
it("does not register legacy finance contract routes", () => {