From d735f9011e56b16c13b2614b5f0923dfb11c5fc2 Mon Sep 17 00:00:00 2001 From: johnnyzhang-eng Date: Sat, 29 Aug 2026 04:47:47 +0800 Subject: [PATCH] =?UTF-8?q?fix(workflow-controller):=20=E8=BF=98=E6=B2=A1?= =?UTF-8?q?=E5=86=99=E6=8F=8F=E8=BF=B0=E4=B9=9F=E8=83=BD=E5=85=88=E6=8A=8A?= =?UTF-8?q?=E5=8F=82=E8=80=83=E5=9B=BE=E5=AD=98=E4=B8=8B=E6=9D=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updateCharacterSetup 既保存描述也保存参考图,却在入口拒空描述。用户先传图再想 文案时,上传成功了、回写却被拒,图就丢了 —— 而界面上参考图那栏标的是「选填」, 报错说的是「prompt 不能为空」,两个词也对不上。 实测:新建项目传了牛的正面图,referenceMedia 落库为空,于是「用我上传的图当母版」 那个候选压根不出现。 真正必填的是提交生成那一刻,那道闸在生成按钮上(prompt 为空时按钮置灰), 这里不需要再拦一次。 Closes #907 --- .../workflow-controller/controller.test.ts | 19 +++++++++++++++++++ .../workflow-controller/controller.ts | 6 +++++- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/frontend/src/features/workflow-controller/controller.test.ts b/frontend/src/features/workflow-controller/controller.test.ts index 0f783cd7..e4bd6022 100644 --- a/frontend/src/features/workflow-controller/controller.test.ts +++ b/frontend/src/features/workflow-controller/controller.test.ts @@ -696,6 +696,25 @@ describe('WorkflowController', () => { }) }) + it('还没写描述也能先把参考图存下来', async () => { + // 用户常常先传图再想文案。在这里拒空的话,上传成功了却因为描述为空而回写失败, + // 图就丢了 —— 而界面上参考图那栏标的是「选填」。真正必填的是提交生成那一刻, + // 那道闸在生成按钮上。 + const { controller } = createController() + + await controller.updateCharacterSetup('setup-1', { + prompt: '', + referenceMedia: ['https://img/my-own-character.png' as never], + }) + + expect(controller.getWorkflow().nodes[0]).toMatchObject({ + input: { + prompt: '', + referenceMedia: ['https://img/my-own-character.png'], + }, + }) + }) + it('接受上传母版时完成角色设定和母版节点', async () => { const { controller } = createController() diff --git a/frontend/src/features/workflow-controller/controller.ts b/frontend/src/features/workflow-controller/controller.ts index ed5e43f0..3bbdcff8 100644 --- a/frontend/src/features/workflow-controller/controller.ts +++ b/frontend/src/features/workflow-controller/controller.ts @@ -882,7 +882,11 @@ export function createWorkflowController({ input: Pick, ) { ensureRunning() - const prompt = nonEmpty(input.prompt, 'prompt') + // 描述**允许为空**。这个方法既保存描述也保存参考图,而用户常常先传图再想文案 —— + // 在这里拒空等于「上传成功了,但因为你还没写描述,图丢了」,而界面上参考图那栏 + // 标的是「选填」。真正必填的是**提交生成**那一刻,那道闸在生成按钮上(prompt 为空 + // 时按钮置灰),不需要这里再拦一次。 + const prompt = input.prompt ?? '' return persist((run) => updateNode(run, nodeId, (node) => { if (node.type !== 'character-setup') throw new Error('目标节点不是角色设定')