fix: 保留小程序登录上下文

This commit is contained in:
2026-06-05 20:58:40 +08:00
parent 5a6d69bebe
commit 6a03575d68
7 changed files with 112 additions and 17 deletions

View File

@@ -132,7 +132,37 @@ describe('appPageRoutes', () => {
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',
'?sessionId=session-1&profileId=profile-1&draftId=draft-1&workId=work-1&clientRuntime=wechat_mini_program',
);
});
it('preserves mini program runtime context while normalizing app paths', () => {
window.history.replaceState(
null,
'',
'/?clientType=mini_program&clientRuntime=wechat_mini_program&miniProgramEnv=trial',
);
pushAppHistoryPath('/');
expect(window.location.pathname).toBe('/');
expect(window.location.search).toBe(
'?clientType=mini_program&clientRuntime=wechat_mini_program&miniProgramEnv=trial',
);
});
it('keeps mini program runtime context when navigating to explicit query routes', () => {
window.history.replaceState(
null,
'',
'/?clientRuntime=wechat_mini_program',
);
pushAppHistoryPath('/works/detail?work=PZ-7A7B18D9');
expect(window.location.pathname).toBe('/works/detail');
expect(window.location.search).toBe(
'?work=PZ-7A7B18D9&clientRuntime=wechat_mini_program',
);
});

View File

@@ -72,6 +72,12 @@ const ROUTE_STAGE_BY_PATH = new Map(
STAGE_ROUTE_ENTRIES.map(([stage, path]) => [path, stage] as const),
) as Map<string, SelectionStage>;
const APP_RUNTIME_CONTEXT_QUERY_KEYS = [
'clientType',
'clientRuntime',
'miniProgramEnv',
] as const;
export function normalizeAppPath(pathname: string) {
const trimmedPathname = pathname.trim().toLowerCase();
@@ -135,13 +141,12 @@ export function isKnownMainAppPagePath(pathname: string) {
export function pushAppHistoryPath(path: string) {
const nextUrl = new URL(path, window.location.origin);
const normalizedPath = normalizeAppPath(nextUrl.pathname);
const nextSearch =
nextUrl.search ||
buildPreservedAppSearch(
window.location.pathname,
normalizedPath,
window.location.search,
);
const nextSearch = buildPreservedAppSearch(
nextUrl.search,
window.location.pathname,
normalizedPath,
window.location.search,
);
const nextRelativeUrl = `${normalizedPath}${nextSearch}`;
const currentRelativeUrl = `${normalizeAppPath(window.location.pathname)}${window.location.search}`;
if (currentRelativeUrl === nextRelativeUrl) {
@@ -153,16 +158,39 @@ export function pushAppHistoryPath(path: string) {
}
function buildPreservedAppSearch(
explicitNextSearch: string,
currentPathname: string,
normalizedPath: string,
search: string,
) {
const preservedParams = new URLSearchParams(explicitNextSearch);
if (
!isCreationRestorePath(normalizedPath) ||
!isSameCreationFlowPath(currentPathname, normalizedPath)
!explicitNextSearch &&
isCreationRestorePath(normalizedPath) &&
isSameCreationFlowPath(currentPathname, normalizedPath)
) {
return '';
const creationParams = new URLSearchParams(
buildCreationUrlSearchFromParams(search),
);
creationParams.forEach((value, key) => {
preservedParams.set(key, value);
});
}
return buildCreationUrlSearchFromParams(search);
const currentParams = new URLSearchParams(search);
// 中文注释:小程序 WebView 依赖这些宿主上下文判断登录和充值通道,不能被前端阶段导航清掉。
APP_RUNTIME_CONTEXT_QUERY_KEYS.forEach((key) => {
if (preservedParams.has(key)) {
return;
}
const value = currentParams.get(key)?.trim();
if (value) {
preservedParams.set(key, value);
}
});
const queryString = preservedParams.toString();
return queryString ? `?${queryString}` : '';
}