diff --git a/web/hwlab-cloud-web/src/views/workbench/CodeWorkbenchView.vue b/web/hwlab-cloud-web/src/views/workbench/CodeWorkbenchView.vue index 7abc0e20..647c68e6 100644 --- a/web/hwlab-cloud-web/src/views/workbench/CodeWorkbenchView.vue +++ b/web/hwlab-cloud-web/src/views/workbench/CodeWorkbenchView.vue @@ -11,29 +11,30 @@ import HwpodNodeOpsPanel from "@/components/hwpod/HwpodNodeOpsPanel.vue"; import { useAutoRefresh } from "@/composables/useAutoRefresh"; import { shouldReflectWorkbenchSessionUrl } from "@/router/workbench-navigation"; import { useWorkbenchStore } from "@/stores/workbench"; -import { normalizeWorkbenchSessionId } from "@/utils"; +import { normalizeWorkbenchSessionId, normalizeWorkbenchSessionRouteId } from "@/utils"; import { finishWorkbenchOpenFullLoad, startWorkbenchOpenJourney } from "@/utils/workbench-performance"; const workbench = useWorkbenchStore(); const route = useRoute(); const router = useRouter(); -const routeSessionId = computed(() => normalizeWorkbenchSessionId(route.params.sessionId)); +const routeRequestId = computed(() => normalizeWorkbenchSessionRouteId(route.params.sessionId)); const rawRouteSessionId = computed(() => typeof route.params.sessionId === "string" ? route.params.sessionId.trim() : ""); +const routeReflectionTarget = computed(() => routeRequestId.value ?? (rawRouteSessionId.value || null)); const applyingRouteSession = ref(Boolean(rawRouteSessionId.value)); const componentActive = ref(false); onMounted(async () => { componentActive.value = true; applyingRouteSession.value = Boolean(rawRouteSessionId.value); - startWorkbenchOpenJourney({ route: route.path, cache: routeSessionId.value ? "cold" : "warm", authState: "warm" }); + startWorkbenchOpenJourney({ route: route.path, cache: routeRequestId.value ? "cold" : "warm", authState: "warm" }); try { - await workbench.hydrate({ sessionId: routeSessionId.value, invalidRouteId: rawRouteSessionId.value && !routeSessionId.value ? rawRouteSessionId.value : null }); + await workbench.hydrate({ sessionId: routeRequestId.value, invalidRouteId: rawRouteSessionId.value && !routeRequestId.value ? rawRouteSessionId.value : null }); await applyRouteSession(); finishWorkbenchOpenFullLoad(workbench.error ? "error" : "ok"); } finally { applyingRouteSession.value = false; } - if (!routeSessionId.value || routeSessionId.value === workbench.activeSessionId) await reflectActiveSessionInUrl(workbench.activeSessionId); + if (!routeRequestId.value && !rawRouteSessionId.value) await reflectActiveSessionInUrl(workbench.activeSessionId); }); onBeforeUnmount(() => { componentActive.value = false; @@ -43,20 +44,22 @@ watch(() => workbench.activeSessionId, (sessionId) => void reflectActiveSessionI useAutoRefresh(() => workbench.refreshLive(), 30_000); async function applyRouteSession(): Promise { - const sessionId = routeSessionId.value; + const sessionId = routeRequestId.value; if (!sessionId && !rawRouteSessionId.value) return true; applyingRouteSession.value = true; + let selected = false; try { - return sessionId ? await workbench.selectSessionById(sessionId) : await workbench.selectSessionById(rawRouteSessionId.value); + selected = sessionId ? await workbench.selectSessionById(sessionId) : await workbench.selectSessionById(rawRouteSessionId.value); + return selected; } finally { applyingRouteSession.value = false; - await reflectActiveSessionInUrl(workbench.activeSessionId); + if (selected) await reflectActiveSessionInUrl(workbench.activeSessionId); } } async function reflectActiveSessionInUrl(value: string | null): Promise { const sessionId = normalizeWorkbenchSessionId(value); - const routeTarget = routeSessionId.value; + const routeTarget = routeReflectionTarget.value; if (!shouldReflectWorkbenchSessionUrl({ componentActive: componentActive.value, routeName: route.name, diff --git a/web/hwlab-cloud-web/tests/workbench-e2e/specs/deep-link.spec.ts b/web/hwlab-cloud-web/tests/workbench-e2e/specs/deep-link.spec.ts index 059ac488..e5fd89bb 100644 --- a/web/hwlab-cloud-web/tests/workbench-e2e/specs/deep-link.spec.ts +++ b/web/hwlab-cloud-web/tests/workbench-e2e/specs/deep-link.spec.ts @@ -36,6 +36,9 @@ test.describe("legacy cnv deep link canonical authority", () => { await expect(page.locator(`${selectors.messageCard}[data-role="agent"][data-status="completed"]`)).toContainText("新增 Python benchmark 脚本"); await expect(page.locator(`${selectors.traceTimeline}[data-status="completed"]`)).toBeVisible(); const state = await fakeServerState(page); + const detailRequests = (state.requestLedger as Array<{ path?: string }>).filter((item) => /^\/v1\/workbench\/sessions\/[^/]+$/u.test(item.path ?? "")); + expect(detailRequests[0]?.path).toBe("/v1/workbench/sessions/cnv_c5e1330558c94d8e"); + expect(detailRequests.some((item) => item.path === "/v1/workbench/sessions/ses_running")).toBe(false); expect((state.legacyRequestLedger as unknown[]).length).toBe(0); }); });