fix: restore puzzle runtime url state

This commit is contained in:
2026-05-25 22:52:38 +08:00
parent 30cf8abbf7
commit eb6ab404e2
12 changed files with 1917 additions and 177 deletions

View File

@@ -1,6 +1,9 @@
/* @vitest-environment jsdom */
import { describe, expect, it } from 'vitest';
import {
pushAppHistoryPath,
resolvePathForSelectionStage,
resolveSelectionStageFromPath,
} from './appPageRoutes';
@@ -117,4 +120,43 @@ describe('appPageRoutes', () => {
'/creation/baby-object-match',
);
});
it('preserves creation restore query params within the same creation flow', () => {
window.history.replaceState(
null,
'',
'/creation/rpg?sessionId=session-1&profileId=profile-1&draftId=draft-1&workId=work-1&clientRuntime=wechat_mini_program',
);
pushAppHistoryPath('/creation/rpg/result');
expect(window.location.pathname).toBe('/creation/rpg/result');
expect(window.location.search).toBe(
'?sessionId=session-1&profileId=profile-1&draftId=draft-1&workId=work-1',
);
});
it('clears creation restore query params when leaving the flow or switching flows', () => {
window.history.replaceState(
null,
'',
'/creation/rpg?sessionId=session-1&profileId=profile-1',
);
pushAppHistoryPath('/creation/puzzle');
expect(window.location.pathname).toBe('/creation/puzzle');
expect(window.location.search).toBe('');
window.history.replaceState(
null,
'',
'/creation/rpg?sessionId=session-2&profileId=profile-2',
);
pushAppHistoryPath('/');
expect(window.location.pathname).toBe('/');
expect(window.location.search).toBe('');
});
});

View File

@@ -1,4 +1,9 @@
import type { SelectionStage } from '../components/platform-entry';
import {
buildCreationUrlSearchFromParams,
isCreationRestorePath,
isSameCreationFlowPath,
} from '../services/creationUrlState';
export type RuntimePageRoute = 'rpg-character-select' | 'rpg-adventure';
@@ -130,7 +135,14 @@ export function isKnownMainAppPagePath(pathname: string) {
export function pushAppHistoryPath(path: string) {
const nextUrl = new URL(path, window.location.origin);
const normalizedPath = normalizeAppPath(nextUrl.pathname);
const nextRelativeUrl = `${normalizedPath}${nextUrl.search}`;
const nextSearch =
nextUrl.search ||
buildPreservedAppSearch(
window.location.pathname,
normalizedPath,
window.location.search,
);
const nextRelativeUrl = `${normalizedPath}${nextSearch}`;
const currentRelativeUrl = `${normalizeAppPath(window.location.pathname)}${window.location.search}`;
if (currentRelativeUrl === nextRelativeUrl) {
return;
@@ -139,3 +151,18 @@ export function pushAppHistoryPath(path: string) {
// 页面阶段变化是用户可感知导航,写入 history 以支持前进后退。
window.history.pushState(null, '', nextRelativeUrl);
}
function buildPreservedAppSearch(
currentPathname: string,
normalizedPath: string,
search: string,
) {
if (
!isCreationRestorePath(normalizedPath) ||
!isSameCreationFlowPath(currentPathname, normalizedPath)
) {
return '';
}
return buildCreationUrlSearchFromParams(search);
}