fix(canvas): 画布批量生成 - 修复节点丢失、资源引用及刷新状态不一致
This commit is contained in:
@@ -66,7 +66,9 @@ description: 从产品功能快速定位主要代码入口
|
||||
| 3D 导演台 | `web/src/components/canvas/director/` |
|
||||
| 节点生成上下文 | `web/src/components/canvas/canvas-node-generation.ts` |
|
||||
| 布局和连线算法 | `web/src/lib/canvas/canvas-layout.ts`、`canvas-frame.ts` |
|
||||
| 任务结果回填 | `web/src/lib/canvas/canvas-generation-task-sync.ts` |
|
||||
| 任务结果准备与按节点提交 | `web/src/lib/canvas/canvas-generation-task-sync.ts`、`canvas-generation-result.ts`;持久化协调在 `web/src/services/canvas-generation-consumer.ts` |
|
||||
| 编辑命令与批次状态投影 | `web/src/lib/canvas/canvas-editor-state.ts`、`canvas-task-state.ts`、`canvas-image-batch-retry.ts` |
|
||||
| 视口节点选择与输入关系解析 | `web/src/lib/canvas/canvas-node-visibility.ts`、`canvas-resource-references.ts` |
|
||||
| 本地持久化状态 | `web/src/stores/canvas/use-canvas-store.ts` |
|
||||
| 云端 Agent 运行与事件 API | `web/src/services/api/agent.ts`、`web/src/components/canvas/canvas-cloud-agent-panel.tsx` |
|
||||
| Agent 画布上下文、操作与历史 | `web/src/lib/canvas/canvas-context-discovery.ts`、`canvas-operation-contract.ts`、`web/src/pages/canvas/use-canvas-operation-history.ts` |
|
||||
|
||||
@@ -5,6 +5,18 @@ description: 当前项目已实现功能的手工验证清单与未确认边界
|
||||
|
||||
# 待测试
|
||||
|
||||
## 批量生图、刷新恢复与画布节点一致性
|
||||
|
||||
- [x] 专项回归 127 项通过,覆盖同步编辑命令、按节点结果提交、批次汇总、资源槽位、空间索引、相邻媒体逻辑、revision 合并与存储清理;前端类型检查通过。
|
||||
- [x] 真实生成消费及持久化模块集成测试:两张成功、三张失败,在结果保存期间新增节点、改名和移动;重新读取模拟浏览器存储后,结果与用户编辑均保留。该测试曾复现“内存有节点、存储缺节点”,修复后通过。
|
||||
- [ ] 使用真实登录账号连接两张已有参考图,提示词包含 `@图片1` 和 `@图片2`,批量生成五张并重试失败子图;验证生成、提示词标签和参考图顺序一致,分组父图不冒充输入。
|
||||
- [ ] 真实任务两成三败后刷新,检查两张成功图、三个失败节点、父图失败数量和素材 ID;在生成中拖动、改名、新增、删除其他节点,保存后刷新复核。
|
||||
- [ ] 模拟预览尚未恢复但已有 storageKey,取消或重新生成批次,确认不会删除成功图片;删除后重新分组的子图不受旧批次清理影响。
|
||||
- [ ] 真实大画布在明暗主题下反复平移缩放,覆盖 280/420/720 原预算边界、批次折叠/展开和多选拖拽;确认可见节点不缺失,并记录极端缩小的帧率和内存。纯函数可见性测试不代替渲染性能验收。
|
||||
- [ ] 任务发现接口断网、最近任务超过 100 条、切换画布和账号时验证:不能把未知状态标成失败,旧任务不能覆盖新任务,任务中心仍可核对结果。
|
||||
- [ ] 验证浏览器真实存储故障、服务端同步失败、跨设备并发编辑及生成后立即关闭页面;本轮没有启动开发服务、访问真实用户数据或调用付费模型。
|
||||
- [ ] 历史已丢节点需单独恢复;本次修复不自动重建原位置、连线和提示词。架构与已知限制见 `docs/design/canvas-consistency-repair.mdx`。
|
||||
|
||||
## 回收站彻底删除与画布工具引用
|
||||
|
||||
- [ ] 素材卡片选择框恢复左上角,徽章为选择框和更多菜单让位;批量操作条取消吸顶覆盖,并与卡片网格保留间距。需在真实登录页面检查多选边框、长列表滚动、窄屏换行和明暗主题;自动浏览器访问被登录页拦截,样式约束测试不代替视觉验收。
|
||||
|
||||
40
docs/design/canvas-consistency-repair.mdx
Normal file
40
docs/design/canvas-consistency-repair.mdx
Normal file
@@ -0,0 +1,40 @@
|
||||
---
|
||||
title: 画布批量生成一致性治理
|
||||
description: 节点丢失、批次状态、引用解析与持久化边界的调查和修复
|
||||
---
|
||||
|
||||
# 批量生成与画布一致性边界
|
||||
|
||||
“素材库里有图”只能证明素材存在,不能证明画布节点已经保存;“屏幕上看不见”也不能直接认定节点被删除。排查应分别核对任务终态、素材资源、编辑器节点数组、已保存画布和视口渲染列表。
|
||||
|
||||
### 已确认的问题机制
|
||||
|
||||
| 现象 | 可复现或由实现确认的原因 | 当前处理 |
|
||||
| --- | --- | --- |
|
||||
| 连线后批次子图提示缺少引用 | 子图继承父图提示词,但把父图到子图的分组边当成媒体输入;原来的第二张参考图因此不在子图槽位中 | 提示词展示与生成提交共用输入解析;分组边不充当参考图,子图无显式输入时继承父批次输入 |
|
||||
| 并发生成覆盖其他节点或编辑 | 媒体解析跨越异步等待,备用结果回填直接替换等待前的完整节点数组 | 结果准备与提交分离,提交时按目标节点及任务身份合并到最新文档 |
|
||||
| 内存存在,重新读取后新增节点或编辑消失 | 持久化结果与实时编辑合并后,整份快照被跳过保存;store 已接受新编辑,后续同内容更新也不再触发保存 | 只有与已落盘内容一致的快照才能跳过保存;合并进来的编辑继续进入普通保存队列 |
|
||||
| 成功子图刷新后被错误汇总或被清理 | 多处只以 `content` 判断结果存在,忽略预览未恢复时的 `storageKey`;父图可能保留旧任务身份 | 批次结果同时识别预览与存储标识;父图统一由子图投影,不携带独立任务身份;清理验证子图归属 |
|
||||
| 缩放或平移时图片不见 | 空间查询先按预算截断,再过滤折叠节点和屏外缓冲区;真实屏内节点也可能超过硬预算 | 先做可见性过滤,屏内及交互节点不按预算截断;预算只限制屏外预加载 |
|
||||
| 刷新把未知任务误报为失败 | 最近任务列表不完整或查询失败,却被解释成不存在任务 | 已绑定任务独立恢复;发现失败或未命中保留原状态并提示核对任务中心,不伪造终态 |
|
||||
|
||||
这些机制不等于已确认每一份用户现场数据的唯一原因。现场还需检查保存请求、账号作用域、任务 ID、资源 ID,以及刷新前后的画布快照。
|
||||
|
||||
### 职责划分
|
||||
|
||||
1. **编辑命令与 React 显示分离**:`canvas-editor-state.ts` 同步更新编辑器 ref,再向 React 发布快照。命令里的 updater 不交给 React 重放;节点和连线使用同一规则。加载文档仍可显式替换快照,任务结果不能借用这种全量替换权限。
|
||||
2. **异步结果只提交自己的变化**:`canvas-generation-task-sync.ts` 准备结果;`canvas-generation-result.ts` 校验目标节点和任务绑定,合并生成字段,保留其他节点、移动、手动尺寸和改名。目标删除或已经换任务时拒绝回填,不复活节点。
|
||||
3. **持久化继续沿用现有协调机制**:`canvas-generation-consumer.ts` 保留账号作用域锁、revision 合并、幂等标记及持久化确认;真实提交完成前不把普通编辑伪装成已确认生成效果。提交期间的新编辑进入普通保存队列,不能因为生成效果已保存就把新编辑也当作已保存。浏览器本地确认不等于服务端已同步。
|
||||
4. **父批次是子图结果的投影**:生成完成和刷新恢复都调用 `reconcileImageBatchRoot`,汇总主图、存储标识、素材 ID 和失败数量。成功与失败可以同时存在,例如两张成功、三张失败;父图不再继承旧的单图任务终态。重置任务身份放在无副作用的 `canvas-task-state.ts`,不依赖生成请求服务。
|
||||
5. **输入关系与分组关系分开解释**:`canvas-resource-references.ts` 统一解析;保留现有 Config 输入优先级和按连线顺序编号的合同,去重并防止批次循环。子图显式输入优先于父批次继承。
|
||||
6. **媒体身份不依赖预览是否恢复**:有 `storageKey` 的图片不能因为 `content` 暂时为空被当作可删除占位或空白原地生成节点。真正读取资源失败仍需报错;存储标识存在不等于文件已经成功读取。
|
||||
7. **视口只决定绘制,不决定数据存活**:`canvas-node-visibility.ts` 选择渲染节点,不修改节点数组或持久化内容。折叠等显式隐藏规则继续生效。
|
||||
|
||||
### 验证与仍需完善的边界
|
||||
|
||||
- 专项行为测试覆盖:并发回填、同步命令、已删除目标、任务重置、缺预览资源、两成三败汇总、分组引用、错误的批次归属,以及同屏 1000 节点超过 280 预算仍可见。
|
||||
- 存储集成测试调用真实生成消费、store、锁与 revision 合并实现,仅替换浏览器存储及资源输入;模拟两份结果并发提交,并在落盘期间新增、改名和移动节点,最后重新读取存储验证两张成功、三张失败及用户编辑均保留。它不是实际浏览器刷新或真实模型端到端验收。
|
||||
- 当前任务列表接口按数量返回最近记录,没有精确的画布节点历史任务查询或完整游标分页。没有 taskId 且超出发现窗口的节点不会被自动认定失败,但仍需在任务中心人工核对;后续应增加按节点及提交标识精确恢复的服务端合同,而不是无限放大列表上限。
|
||||
- 取消屏内节点硬裁剪后,极端缩小、海量节点同屏可能增加渲染负担。后续应采用保留所有节点位置的缩略层/细节层分级绘制,不能再以随机缺失节点换取性能。
|
||||
- 现有加载、远端同步、历史撤销仍保留各自入口,本次并未迁移成统一的规范化文档 store。跨设备并发编辑和立即关闭页面仍需真实场景验收。
|
||||
- 已经被旧快照覆盖的历史节点不会由本次修复自动重建。素材可用于重新插入,但原节点位置、连线及提示词只能从历史画布或可核对的任务上下文恢复,不能凭空猜测。
|
||||
@@ -4,6 +4,8 @@
|
||||
|
||||
## 设计沉淀
|
||||
|
||||
- [画布批量生成一致性治理](design/canvas-consistency-repair.mdx):节点丢失、批次状态与引用解析的根因、已实施边界重构、回归证据和仍待验收的性能/同步场景。
|
||||
|
||||
- [画布 Agent 外观与 Live2D](content/docs/backend/canvas-agent-appearance.mdx):独立助手名称、文案模板、模型包边界、Core 部署和验收要求。
|
||||
|
||||
- [云端 Agent 架构优化方案](design/cloud-agent-architecture-optimization.md):跨端生成合同、引用绑定、审批依赖、报价预算、运行存储与工作上下文的现状审查、分阶段方案和验收门槛(提案,未实施)。
|
||||
|
||||
Reference in New Issue
Block a user