修复小游戏生成页恢复生成态

按生成状态判定小游戏生成页是否仍在生成中

补充敲木鱼生成中草稿恢复回归测试

记录小游戏生成页恢复 busy 判定踩坑
This commit is contained in:
2026-06-08 19:15:04 +08:00
parent 6f242a290a
commit a4ee6ff698
3 changed files with 65 additions and 13 deletions

View File

@@ -128,6 +128,14 @@
- 验证:`npm run test -- src/components/rpg-entry/RpgEntryFlowShell.agent.interaction.test.tsx -t "persisted generating puzzle draft"`,并确认恢复生成中草稿后 `getPuzzleAgentSession` 不会因为进度刷新继续连发。
- 关联:`src/components/platform-entry/PlatformEntryFlowShellImpl.tsx``src/components/platform-entry/usePlatformCreationAgentFlowController.ts``src/components/platform-entry/usePlatformCreationAgentFlowController.test.tsx`
## 小游戏恢复生成页不要只用请求 busy 判定是否生成中
- 现象:敲木鱼作品架里的生成中草稿点击进入生成页后,页面会显示“重新生成草稿”按钮,而不是继续显示素材生成中的等待态。
- 原因:平台壳恢复 `generationStatus=generating` 草稿时会把 `isBusy` 置回 false只保留 `MiniGameDraftGenerationState` 作为生成事实;生成页如果只把请求 busy 传给 `isGenerating`,共用生成页会误判为空闲态并展示重试按钮。
- 处理:小游戏生成页的 `isGenerating` 必须由 `isBusy || isMiniGameDraftGenerating(generationState)` 推导;跳一跳、拼消消、敲木鱼等从作品架恢复的生成页都要使用同一口径。
- 验证:`npm run test -- src/components/platform-entry/PlatformEntryFlowShellImpl.test.ts` 应覆盖 `busy=false` 但敲木鱼 generation state 仍在生成中时继续隐藏重试入口。
- 关联:`src/components/platform-entry/PlatformEntryFlowShellImpl.tsx``src/components/unified-creation/UnifiedGenerationPage.tsx``docs/【玩法创作】平台入口与玩法链路-2026-05-15.md`
## 拼图试玩恢复 query 必须先切到运行态路径再写
- 现象:拼图试玩或正式运行态打开后,刷新会停在“正在进入拼图关卡”,或地址栏只有 `runtimeProfileId`,缺少草稿 `runtimeSessionId`

View File

@@ -1,9 +1,11 @@
import { describe, expect, test } from 'vitest';
import {
resolveMiniGameGenerationViewBusy,
resolveMiniGameGenerationProgressTickState,
} from './PlatformEntryFlowShellImpl';
import { createMiniGameDraftGenerationState } from '../../services/miniGameDraftGenerationProgress';
import { resolveFinishedMiniGameDraftGenerationState } from './platformMiniGameDraftGenerationStateModel';
describe('resolveMiniGameGenerationProgressTickState', () => {
test('returns jump hop and wooden fish generation states for progress ticking', () => {
@@ -30,3 +32,28 @@ describe('resolveMiniGameGenerationProgressTickState', () => {
).toBeNull();
});
});
describe('resolveMiniGameGenerationViewBusy', () => {
test('敲木鱼恢复生成中草稿时继续隐藏重新生成按钮', () => {
const woodenFishGeneratingState =
createMiniGameDraftGenerationState('wooden-fish');
expect(
resolveMiniGameGenerationViewBusy(false, woodenFishGeneratingState),
).toBe(true);
});
test('生成态结束后只保留真实 busy', () => {
const woodenFishReadyState = resolveFinishedMiniGameDraftGenerationState(
createMiniGameDraftGenerationState('wooden-fish'),
'ready',
);
expect(resolveMiniGameGenerationViewBusy(false, woodenFishReadyState)).toBe(
false,
);
expect(resolveMiniGameGenerationViewBusy(true, woodenFishReadyState)).toBe(
true,
);
});
});

View File

@@ -696,6 +696,13 @@ export function resolveMiniGameGenerationProgressTickState(
return kind ? (states[kind] ?? null) : null;
}
export function resolveMiniGameGenerationViewBusy(
isBusy: boolean,
state: MiniGameDraftGenerationState | null | undefined,
) {
return isBusy || isMiniGameDraftGenerating(state ?? null);
}
type PuzzleDetailReturnTarget = {
tab: PlatformHomeTab;
};
@@ -4454,11 +4461,10 @@ export function PlatformEntryFlowShellImpl({
activeMatch3DBackgroundCompileTask?.payload ?? match3dFormDraftPayload;
const match3dGenerationViewError =
activeMatch3DBackgroundCompileTask?.error ?? match3dError;
const isMatch3DGenerationViewBusy =
isMatch3DBusy ||
isMiniGameDraftGenerating(
activeMatch3DBackgroundCompileTask?.generationState ?? null,
);
const isMatch3DGenerationViewBusy = resolveMiniGameGenerationViewBusy(
isMatch3DBusy,
match3dGenerationViewState,
);
const activePuzzleGenerationSessionId =
selectionStage === 'puzzle-generating'
? (activePuzzleGenerationSessionIdRef.current ??
@@ -4488,11 +4494,22 @@ export function PlatformEntryFlowShellImpl({
}, [puzzleFlow.setSession]);
const puzzleGenerationViewError =
activePuzzleBackgroundCompileTask?.error ?? puzzleError;
const isPuzzleGenerationViewBusy =
isPuzzleBusy ||
isMiniGameDraftGenerating(
activePuzzleBackgroundCompileTask?.generationState ?? null,
);
const isPuzzleGenerationViewBusy = resolveMiniGameGenerationViewBusy(
isPuzzleBusy,
puzzleGenerationViewState,
);
const isJumpHopGenerationViewBusy = resolveMiniGameGenerationViewBusy(
isJumpHopBusy,
jumpHopGenerationState,
);
const isPuzzleClearGenerationViewBusy = resolveMiniGameGenerationViewBusy(
isPuzzleClearBusy,
puzzleClearGenerationState,
);
const isWoodenFishGenerationViewBusy = resolveMiniGameGenerationViewBusy(
isWoodenFishBusy,
woodenFishGenerationState,
);
const platformBootstrapErrorForDisplay = isCreationEntryDisabledErrorMessage(
platformBootstrap.platformError,
)
@@ -15592,7 +15609,7 @@ export function PlatformEntryFlowShellImpl({
jumpHopGenerationState,
miniGameGenerationProgressNowMs,
)}
isGenerating={isJumpHopBusy}
isGenerating={isJumpHopGenerationViewBusy}
error={jumpHopError}
onBack={leaveJumpHopFlow}
onEditSetting={() => {
@@ -15728,7 +15745,7 @@ export function PlatformEntryFlowShellImpl({
puzzleClearGenerationState,
miniGameGenerationProgressNowMs,
)}
isGenerating={isPuzzleClearBusy}
isGenerating={isPuzzleClearGenerationViewBusy}
error={puzzleClearError}
onBack={leavePuzzleClearFlow}
onEditSetting={() => {
@@ -15867,7 +15884,7 @@ export function PlatformEntryFlowShellImpl({
woodenFishGenerationState,
miniGameGenerationProgressNowMs,
)}
isGenerating={isWoodenFishBusy}
isGenerating={isWoodenFishGenerationViewBusy}
error={woodenFishError}
onBack={leaveWoodenFishFlow}
onEditSetting={() => {