diff --git a/src/components/image-editor/useImageCanvasGenerationSubmissionWorkflow.test.tsx b/src/components/image-editor/useImageCanvasGenerationSubmissionWorkflow.test.tsx index 9ce92fd4f..e5853d598 100644 --- a/src/components/image-editor/useImageCanvasGenerationSubmissionWorkflow.test.tsx +++ b/src/components/image-editor/useImageCanvasGenerationSubmissionWorkflow.test.tsx @@ -2976,6 +2976,41 @@ describe('useImageCanvasGenerationSubmissionWorkflow', () => { expect(generateEditorCharacterAnimationMock).not.toHaveBeenCalled(); }); + it('reports stale character animation source validation failures', async () => { + render( + , + ); + + await act(async () => { + fireEvent.click(screen.getByRole('button', { name: '提交角色动画' })); + }); + + await waitFor(() => { + expect(screen.getByTestId('character-animation').textContent).toBe( + 'character-layer:failed:跑步:角色动作缺少正式序列首帧,无法继续生成。:-', + ); + }); + expect(generateEditorCharacterAnimationMock).not.toHaveBeenCalled(); + }); + it('creates an action layer for dialog-driven character animation submissions', async () => { generateEditorCharacterAnimationMock.mockResolvedValueOnce({ taskId: 'animation-task-dialog', diff --git a/src/components/image-editor/useImageCanvasGenerationSubmissionWorkflow.ts b/src/components/image-editor/useImageCanvasGenerationSubmissionWorkflow.ts index adf9b5253..2862f76bd 100644 --- a/src/components/image-editor/useImageCanvasGenerationSubmissionWorkflow.ts +++ b/src/components/image-editor/useImageCanvasGenerationSubmissionWorkflow.ts @@ -2166,40 +2166,39 @@ export function useImageCanvasGenerationSubmissionWorkflow({ ) { return; } - const submissionPlan = buildCharacterAnimationSubmissionPlan({ - panel: characterAnimationPanel, - sourceLayer: characterAnimationSourceLayer, - }); const canvasDialog = characterAnimationDialog; - if (canvasDialog?.mode === 'character-animation') { - updateCanvasGenerationDialogById(canvasDialog.id, (currentDialog) => ({ - ...currentDialog, - prompt: submissionPlan.promptText, - characterAnimationResolution: characterAnimationPanel.resolution, - characterAnimationRatio: characterAnimationPanel.ratio, - characterAnimationFrameCount: characterAnimationPanel.frameCount, - characterAnimationDurationSeconds: - characterAnimationPanel.durationSeconds, - assetLabel: submissionPlan.resultTitle, - characterAnimationResult: undefined, - status: 'generating', - composerOpen: false, - errorMessage: undefined, - })); - } - const nextPanel = { - ...characterAnimationPanel, - promptText: submissionPlan.promptText, - assetLabel: submissionPlan.resultTitle, - status: 'generating' as const, - errorMessage: undefined, - result: undefined, - }; - if (!canvasDialog) { - setCharacterAnimationPanel(nextPanel); - } - try { + const submissionPlan = buildCharacterAnimationSubmissionPlan({ + panel: characterAnimationPanel, + sourceLayer: characterAnimationSourceLayer, + }); + if (canvasDialog?.mode === 'character-animation') { + updateCanvasGenerationDialogById(canvasDialog.id, (currentDialog) => ({ + ...currentDialog, + prompt: submissionPlan.promptText, + characterAnimationResolution: characterAnimationPanel.resolution, + characterAnimationRatio: characterAnimationPanel.ratio, + characterAnimationFrameCount: characterAnimationPanel.frameCount, + characterAnimationDurationSeconds: + characterAnimationPanel.durationSeconds, + assetLabel: submissionPlan.resultTitle, + characterAnimationResult: undefined, + status: 'generating', + composerOpen: false, + errorMessage: undefined, + })); + } + const nextPanel = { + ...characterAnimationPanel, + promptText: submissionPlan.promptText, + assetLabel: submissionPlan.resultTitle, + status: 'generating' as const, + errorMessage: undefined, + result: undefined, + }; + if (!canvasDialog) { + setCharacterAnimationPanel(nextPanel); + } const generationInputs = buildCharacterAnimationGenerationInputs( submissionPlan.promptText, characterAnimationSourceLayer, @@ -2283,7 +2282,7 @@ export function useImageCanvasGenerationSubmissionWorkflow({ if (canvasDialog) { updateCanvasGenerationDialogById(canvasDialog.id, (currentDialog) => ({ ...currentDialog, - prompt: submissionPlan.promptText, + prompt: characterAnimationPanel.promptText.trim(), characterAnimationResolution: characterAnimationPanel.resolution, characterAnimationRatio: characterAnimationPanel.ratio, characterAnimationFrameCount: characterAnimationPanel.frameCount, @@ -2302,6 +2301,7 @@ export function useImageCanvasGenerationSubmissionWorkflow({ currentPanel ? { ...currentPanel, + promptText: characterAnimationPanel.promptText.trim(), status: 'failed', errorMessage: resolveImageGenerationErrorMessage( error,