diff --git a/apps/ai-game-creator-shell/src/view/ui-editor/index.tsx b/apps/ai-game-creator-shell/src/view/ui-editor/index.tsx index ff8b9f87a..0f688c61e 100644 --- a/apps/ai-game-creator-shell/src/view/ui-editor/index.tsx +++ b/apps/ai-game-creator-shell/src/view/ui-editor/index.tsx @@ -16,6 +16,10 @@ import { PreviewWorkspace } from './components/preview/PreviewWorkspace'; import { RecognitionOverview } from './components/RecognitionOverview'; import { SeparationOverview } from './components/SeparationOverview'; import { ToolNavigation } from './components/ToolNavigation'; +import { + UiEditorSaveResultModal, + type UiEditorSaveResultNotice, +} from './components/UiEditorSaveResultModal'; import { WorkflowActionCard } from './components/WorkflowActionCard'; import { WorkflowCompletionModal } from './components/WorkflowCompletionModal'; import { UI_EDITOR_STEPS, type UiEditorStepId } from './model'; @@ -70,7 +74,8 @@ export default function UiEditorPage({ const [saveWarningOpen, setSaveWarningOpen] = useState(false); const [saveAfterReturn, setSaveAfterReturn] = useState(false); const [generateAfterWarning, setGenerateAfterWarning] = useState(false); - const [generateSuccess, setGenerateSuccess] = useState(null); + const [saveResultNotice, setSaveResultNotice] = + useState(null); const [returnConfirmOpen, setReturnConfirmOpen] = useState(false); const [showFrame, setShowFrame] = useState(true); const [showOriginImage, setShowOriginImage] = useState(true); @@ -115,10 +120,6 @@ export default function UiEditorPage({ const activeImageId = session.input.activeImageId; const deleteNode = session.input.deleteNode; - useEffect(() => { - if (session.save.isDirty) setGenerateSuccess(null); - }, [session.save.isDirty]); - useEffect(() => { const onKeyDown = (event: KeyboardEvent) => handleUiEditorKeyDown(event, { @@ -133,28 +134,51 @@ export default function UiEditorPage({ }, [activeImageId, deleteNode, historyRedo, historyUndo, selectedNodeId]); async function save(afterReturn = false) { - if (await session.save.save()) { + const result = await session.save.save(); + if (result.status === 'saved') { if (afterReturn) { setReturnConfirmOpen(false); onBack?.(); + } else { + setSaveResultNotice({ kind: 'saved' }); } + return; } + setSaveResultNotice({ + kind: 'failure', + message: result.message, + retryLabel: '重试保存', + onRetry: () => void save(afterReturn), + }); } async function saveAndGenerate() { - setGenerateSuccess(null); + setSaveResultNotice(null); const result = await session.save.saveAndGenerateCode(); - if (result) { + if (result.status === 'generated') { setGenerateAfterWarning(false); - setGenerateSuccess(`代码已生成:${result.relativePath}`); + setSaveResultNotice({ + kind: 'generated', + relativePath: result.result.relativePath, + }); + return; } + setSaveResultNotice({ + kind: 'failure', + message: + result.phase === 'generate' + ? `项目已保存,但代码生成失败:${result.message}` + : result.message, + retryLabel: '重试保存并生成', + onRetry: () => void saveAndGenerate(), + }); } function requestSave(afterReturn = false) { if (!resourceId || session.save.isSaving || session.workflow.isAiRunning) { return; } - setGenerateSuccess(null); + setSaveResultNotice(null); setSaveAfterReturn(afterReturn); setGenerateAfterWarning(false); if (session.save.hasWarnings()) { @@ -174,7 +198,7 @@ export default function UiEditorPage({ return; } setSaveAfterReturn(false); - setGenerateSuccess(null); + setSaveResultNotice(null); setGenerateAfterWarning(true); if (session.save.hasWarnings()) { setSaveWarningOpen(true); @@ -289,30 +313,6 @@ export default function UiEditorPage({