From 2204df139c5e6c2bbff1ab9c18b57dc87bfb9488 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=BE=B7=E5=AE=87?= Date: Thu, 24 Sep 2026 21:12:43 +0800 Subject: [PATCH] =?UTF-8?q?3D=20=E5=BC=80=E5=85=B3=E4=BA=92=E6=96=A5?= =?UTF-8?q?=EF=BC=9A=E6=89=93=E5=BC=80=E5=88=86=E4=BB=B6=E5=B0=B1=E5=85=B3?= =?UTF-8?q?=E6=8E=89=E5=9B=9B=E8=BE=B9=E9=9D=A2=20/=20=E6=99=BA=E8=83=BD?= =?UTF-8?q?=E5=87=8F=E9=9D=A2=EF=BC=8C=E5=8F=8D=E4=B9=8B=E4=BA=A6=E7=84=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - `applyModel3dSwitchChange` 不再原样套用改动:收到「生成部件 = 开」时清掉四边面与智能减面,收到任一几何模式打开时清掉生成部件;让刚刚打开的那个赢,面板上不留提交前校验必然拒绝的组合 - 只关掉某个开关时不动其它开关(关分件不该顺带清空几何模式) - 用例:两个方向的互斥各一例 + 只关一个开关不动其它 --- .../Model3dGenerationFormModel.test.ts | 42 +++++++++++++++++++ .../Model3dGenerationFormModel.ts | 20 ++++++++- 2 files changed, 61 insertions(+), 1 deletion(-) diff --git a/src/components/image-editor/model3d-generation/Model3dGenerationFormModel.test.ts b/src/components/image-editor/model3d-generation/Model3dGenerationFormModel.test.ts index 4cdad8ba0..2f551ea9c 100644 --- a/src/components/image-editor/model3d-generation/Model3dGenerationFormModel.test.ts +++ b/src/components/image-editor/model3d-generation/Model3dGenerationFormModel.test.ts @@ -577,6 +577,48 @@ describe('3D 生成面板的参数变更', () => { ).not.toBe(failedDialog.model3dAttemptNonce); }); + it('分件与四边面 / 智能减面互斥:后打开的赢,先打开的自动关掉', () => { + const geometryDialog = createDialog({ + model3dTier: 'geometry-only', + model3dGenerateParts: true, + }); + + const quad = applyModel3dSwitchChange(geometryDialog, { + model3dQuad: true, + }); + expect(quad).toMatchObject({ + model3dQuad: true, + model3dGenerateParts: false, + }); + + const smartLowPoly = applyModel3dSwitchChange( + { ...geometryDialog, model3dGenerateParts: false }, + { model3dSmartLowPoly: true }, + ); + expect(smartLowPoly.model3dQuad).toBe(false); + + const parts = applyModel3dSwitchChange( + { ...geometryDialog, model3dQuad: true, model3dSmartLowPoly: true }, + { model3dGenerateParts: true }, + ); + expect(parts).toMatchObject({ + model3dGenerateParts: true, + model3dQuad: false, + model3dSmartLowPoly: false, + }); + }); + + it('只关掉一个开关时不动其它开关', () => { + const dialog = createDialog({ + model3dTier: 'geometry-only', + model3dQuad: true, + }); + + expect( + applyModel3dSwitchChange(dialog, { model3dGenerateParts: false }), + ).toMatchObject({ model3dQuad: true, model3dGenerateParts: false }); + }); + it('删掉参考图回到空槽位并清掉失败态', () => { const dialog = createDialog({ mode: 'model3d-image-to-model', diff --git a/src/components/image-editor/model3d-generation/Model3dGenerationFormModel.ts b/src/components/image-editor/model3d-generation/Model3dGenerationFormModel.ts index df6daaf44..16bd7d847 100644 --- a/src/components/image-editor/model3d-generation/Model3dGenerationFormModel.ts +++ b/src/components/image-editor/model3d-generation/Model3dGenerationFormModel.ts @@ -447,6 +447,13 @@ export function applyModel3dModelChange( }); } +/** + * 改开关:换代次、清失败态,并把互斥项一起收干净。 + * + * 「生成部件」与「四边面」/「智能减面」不能同时打开(提交前校验会直接拒绝,见 + * `Model3dGenerationValidation`)。这里让刚刚打开的那个赢、另一个自动关掉:面板上不留 + * 一个永远提交不了的组合,也不用用户自己去猜该关哪一个(评审 #86)。 + */ export function applyModel3dSwitchChange( dialog: GenerateDialogState, patch: Partial< @@ -456,7 +463,18 @@ export function applyModel3dSwitchChange( > >, ): GenerateDialogState { - return withNewAttemptNonce({ ...resetFailedStatus(dialog), ...patch }); + const next = { ...resetFailedStatus(dialog), ...patch }; + if (patch.model3dGenerateParts === true) { + return withNewAttemptNonce({ + ...next, + model3dQuad: false, + model3dSmartLowPoly: false, + }); + } + if (patch.model3dQuad === true || patch.model3dSmartLowPoly === true) { + return withNewAttemptNonce({ ...next, model3dGenerateParts: false }); + } + return withNewAttemptNonce(next); } export function applyModel3dPromptChange(