收口角色动作提交前校验异常

将角色动作提交计划构建纳入失败状态处理

仅在计划校验通过后切换生成中状态

补充损坏动作来源的用户错误回归测试
This commit is contained in:
2026-08-05 13:26:02 +08:00
parent f0f555ad0b
commit b6f0ab48d8
2 changed files with 68 additions and 33 deletions
@@ -2976,6 +2976,41 @@ describe('useImageCanvasGenerationSubmissionWorkflow', () => {
expect(generateEditorCharacterAnimationMock).not.toHaveBeenCalled();
});
it('reports stale character animation source validation failures', async () => {
render(
<SubmissionWorkflowHarness
initialLayers={[
createLayer({
id: 'character-layer',
assetKind: 'character-animation',
mediaType: 'image-sequence',
imageSequenceFrames: [],
}),
]}
initialCharacterAnimationPanel={{
sourceLayerId: 'character-layer',
promptText: ' 跑步 ',
resolution: '480p',
ratio: 'same',
frameCount: 32,
durationSeconds: 4,
status: 'idle',
}}
/>,
);
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',
@@ -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,