diff --git a/apps/ai-game-creator-shell/src/view/project-development/export/state/useTaonierTab.ts b/apps/ai-game-creator-shell/src/view/project-development/export/state/useTaonierTab.ts index e5b9b2a85..a8059685f 100644 --- a/apps/ai-game-creator-shell/src/view/project-development/export/state/useTaonierTab.ts +++ b/apps/ai-game-creator-shell/src/view/project-development/export/state/useTaonierTab.ts @@ -86,6 +86,12 @@ export function useTaonierTab({ useDirectProjectManifest(projectPath); const manifestRef = useRef(manifest); manifestRef.current = manifest; + /** + * 当前项目路径。`ensurePackage` 在 await 之后要对账「这次打包还是不是当前项目的」, + * 但它闭包里的 `projectPath` 可能已经过期(面板跨项目切换时不会卸载)。 + */ + const projectPathRef = useRef(projectPath); + projectPathRef.current = projectPath; const [allowed, setAllowed] = useState(false); const [availabilityPending, setAvailabilityPending] = useState(true); @@ -175,6 +181,13 @@ export function useTaonierTab({ const ensurePackage = useCallback(async (): Promise => { const currentProjectPath = projectPath?.trim() ?? ''; + /** + * 这次打包发起时的项目是不是还是当前项目:await 回来后 `setPackageResult` 只能写给 + * 发起的那个项目,否则旧项目的包会落进新项目的面板,被发布流程当成新项目的产物。 + */ + const isCurrentProject = () => + mountedRef.current && + (projectPathRef.current?.trim() ?? '') === currentProjectPath; if (!currentProjectPath) { setBlockedMessage('先打开一个项目再发布'); return null; @@ -204,13 +217,13 @@ export function useTaonierTab({ 'export_local_project_package', { projectPath: currentProjectPath }, ); - if (!mountedRef.current) return null; + if (!isCurrentProject()) return null; setProgress(null); setPackageResult(result); appendPublishPermissionLog(currentProjectPath); return result; } catch (error) { - if (!mountedRef.current) return null; + if (!isCurrentProject()) return null; setProgress({ phase: 'failed', message: '发布失败',