fix(canvas): 画布保存 - 修复重生成媒体绑定死锁并新增手动保存与强制覆盖保存

This commit is contained in:
VicoHu committed 2026-09-16 18:29:48 +08:00
1 parent da0531f6eb
commit 38bba7a893
8 files changed
+393 -17

No files matched your search

@@ -9,7 +9,7 @@ import { removeCanvasDrawing } from "@/lib/canvas/canvas-drawing-storage";
import { normalizeCanvasNodeTimestamps } from "@/lib/canvas/canvas-node-timestamps";
import { hydrateAssistantImages, resetInterruptedGeneration } from "@/lib/canvas/canvas-project-generation";
import { listAddedSkills, type Skill } from "@/services/api/skills";
import { createCanvasProjectWithRemoteSync, deleteCanvasProjectsWithRemoteSync, loadCanvasProjectForEditing, localSavedRemotePendingMessage, saveRemoteUserDataNow, subscribeAgentCanvasRefresh } from "@/services/user-data-sync";
import { createCanvasProjectWithRemoteSync, deleteCanvasProjectsWithRemoteSync, forceOverwriteRemoteCanvasSync, loadCanvasProjectForEditing, localSavedRemotePendingMessage, saveRemoteUserDataNow, subscribeAgentCanvasRefresh } from "@/services/user-data-sync";
import { flushCanvasStorePersistence, useCanvasStore, type CanvasProject } from "@/stores/canvas/use-canvas-store";
import { useThemeStore } from "@/stores/use-theme-store";
import { useUserStore } from "@/stores/use-user-store";
@@ -242,7 +242,7 @@ export function useCanvasProjectLifecycle({
renameProject(projectId, title);
}, [projectId, renameProject]);
const saveCanvasProject = useCallback(async (): Promise<boolean> => {
const persistCanvasSnapshot = useCallback(async (): Promise<boolean> => {
try {
updateProject(projectId, {
nodes: nodesRef.current,
@@ -256,10 +256,15 @@ export function useCanvasProjectLifecycle({
directorScenes: currentProject?.directorScenes || [],
});
await flushCanvasStorePersistence();
return true;
} catch {
message.error("画布保存失败,请稍后重试");
return false;
}
}, [activeChatId, backgroundMode, canvasAppearance, chatSessions, connectionsRef, currentProject?.directorScenes, message, nodesRef, projectId, showImageInfo, updateProject, viewportRef]);
const saveCanvasProject = useCallback(async (): Promise<boolean> => {
if (!(await persistCanvasSnapshot())) return false;
try {
await saveRemoteUserDataNow();
message.success("画布布局和位置已保存");
@@ -268,7 +273,18 @@ export function useCanvasProjectLifecycle({
message.warning(localSavedRemotePendingMessage("本地画布布局已保存", error));
}
return true;
}, [activeChatId, backgroundMode, canvasAppearance, chatSessions, connectionsRef, currentProject?.directorScenes, message, nodesRef, projectId, showImageInfo, updateProject, viewportRef]);
}, [message, persistCanvasSnapshot]);
const forceSaveCanvasProject = useCallback(async (): Promise<boolean> => {
if (!(await persistCanvasSnapshot())) return false;
try {
const result = await forceOverwriteRemoteCanvasSync();
message.success(result.reboundNodes > 0 ? `已用本地内容覆盖云端,并修复 ${result.reboundNodes} 处媒体与素材的绑定` : "已用本地内容覆盖云端画布");
} catch (error) {
message.error(`强制覆盖保存失败:${error instanceof Error ? error.message : "未知错误"}`);
}
return true;
}, [message, persistCanvasSnapshot]);
const clearCanvasFiles = useCallback(() => {
cleanupCanvasFiles({ projectId, nodes: [], chatSessions: [] });
@@ -285,6 +301,7 @@ export function useCanvasProjectLifecycle({
deleteCurrentProject,
renameCurrentProject,
saveCanvasProject,
forceSaveCanvasProject,
updateProject,
};
}