From 7e5179c54f07bc4c0f96630484975f72df8a3e14 Mon Sep 17 00:00:00 2001 From: HouYunFei <1844025705@qq.com> Date: Tue, 26 May 2026 15:50:36 +0800 Subject: [PATCH] =?UTF-8?q?fix(canvas):=20=E8=A7=A3=E5=86=B3=E7=94=BB?= =?UTF-8?q?=E5=B8=83=E8=8A=82=E7=82=B9=E6=92=A4=E9=94=80=E6=93=8D=E4=BD=9C?= =?UTF-8?q?=E5=90=8E=E5=9B=BE=E7=89=87=E4=B8=A2=E5=A4=B1=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 添加 cleanupCanvasFiles 回调函数用于清理画布资源 - 将 cleanupAssetImages 替换为 cleanupCanvasFiles 以统一资源清理逻辑 - 在节点变更和画布清空时使用新的清理函数 - 修复撤销操作后节点信息恢复但本地图片数据被清理的错误 --- docs/pending-test.md | 1 + .../app/(user)/canvas/[id]/canvas-client-page.tsx | 15 +++++++++++---- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/docs/pending-test.md b/docs/pending-test.md index ea850b2..5867f38 100644 --- a/docs/pending-test.md +++ b/docs/pending-test.md @@ -3,6 +3,7 @@ - 画布项目导出改为下载 `.zip` 压缩包,包内包含 `projects.json` 和当前画布引用到的本地图片、视频文件,避免只导出 JSON 时丢失媒体内容。 - 画布库支持多选后一键导出多个画布项目,导出的压缩包可一次恢复多个项目。 - 画布项目导入改为读取新版 `.zip` 压缩包,会先按 `projects.json` 中的文件映射恢复图片、视频到本地存储,再插入画布项目,导入成功后仍停留在画布库。 +- 修复删除画布图片节点或清空画布后撤销时,节点信息恢复但本地图片数据已被清理导致图片丢失的问题。 - “我的素材”类型筛选区右侧新增文本样式的导出素材和导入素材入口,可将全部素材导出为包含 `assets.json` 与图片、视频文件的压缩包,并从压缩包恢复素材。 - 未登录状态下,画布右上角不再显示用户头像菜单、用户名称、算力点余额和退出登录入口,改为显示登录入口;快捷键入口仍可直接打开。 - 生图工作台的图片参数区复用画布里的紧凑版图像设置面板,尺寸、质量、生成张数的交互保持一致;工作台仍保留独立的模型选择。 diff --git a/web/src/app/(user)/canvas/[id]/canvas-client-page.tsx b/web/src/app/(user)/canvas/[id]/canvas-client-page.tsx index 5248539..0f5671b 100644 --- a/web/src/app/(user)/canvas/[id]/canvas-client-page.tsx +++ b/web/src/app/(user)/canvas/[id]/canvas-client-page.tsx @@ -292,6 +292,13 @@ function InfiniteCanvasPage() { [activeChatId, backgroundMode, chatSessions, showImageInfo], ); + const cleanupCanvasFiles = useCallback( + (extra?: unknown) => { + cleanupAssetImages({ extra, history: historyRef.current, lastHistory: lastHistoryRef.current }); + }, + [cleanupAssetImages], + ); + useEffect(() => { if (!hydrated) return; setProjectLoaded(false); @@ -649,9 +656,9 @@ function InfiniteCanvasPage() { setPreviewNodeId((current) => (current && allIds.has(current) ? null : current)); setRunningNodeId((current) => (current && allIds.has(current) ? null : current)); setContextMenu((current) => (current && allIds.has(current.nodeId) ? null : current)); - cleanupAssetImages({ projectId, nodes: nodesRef.current.filter((node) => !allIds.has(node.id)), chatSessions }); + cleanupCanvasFiles({ projectId, nodes: nodesRef.current.filter((node) => !allIds.has(node.id)), chatSessions }); }, - [chatSessions, cleanupAssetImages, projectId], + [chatSessions, cleanupCanvasFiles, projectId], ); const deselectCanvas = useCallback(() => { @@ -676,8 +683,8 @@ function InfiniteCanvasPage() { setRunningNodeId(null); deselectCanvas(); setClearConfirmOpen(false); - cleanupAssetImages({ projectId, nodes: [], chatSessions: [] }); - }, [cleanupAssetImages, deselectCanvas, projectId]); + cleanupCanvasFiles({ projectId, nodes: [], chatSessions: [] }); + }, [cleanupCanvasFiles, deselectCanvas, projectId]); const duplicateNode = useCallback((nodeId: string) => { const source = nodesRef.current.find((node) => node.id === nodeId);