替换面板改为非模态浮层,支持在画布上点选替换目标

- 共享选择组件新增 opt-in nonModal:不铺遮罩、不做焦点陷阱、限高 + 内部滚动,Esc 在 document 阶段截断后取消,关掉即卸载;网页端美术画布不传,弹窗行为逐字不变。
- 新增 initialSelectionRevision:面板开着时宿主换了目标才重同步当前选择,面板里的搜索词与分类筛选不被重置。
- AGC 侧把候选面板锚到画布右上角(任务开关下方),壳样式放共享样式表、宿主只负责锚定;面板开着时画布照常可点,点中合法候选落成面板当前选择,写入仍只由「确认」发起。
- 退役旧的「点选替换」按钮、画布提示条与 resourceReplacementPickMode:同一个功能不留两条 UI 路径;合法性判据仍复用 resolveResourceReplacementPick,写入仍是同一个 confirm 函数。
- 确认时用画布点选结果兜底,避免点完当帧按确认误报「请选择一个替换素材」。
- 测试:替换用例 4 条点选路径改写为非模态 + 面板点选(含四类非法目标在面板内报因、Esc 只收面板),新增「画布点选不清掉面板搜索/分类」;共享组件用例新增 nonModal 形态与浮层壳声明级契约。
- 文档:PRD 5.3 / 7.8 第 8 条改写、验收用例 S15a 改写、decision-log 新增 2026-09-21 条目、待办文档登记三项并勾掉对应需求。
This commit is contained in:
2026-09-21 03:48:40 +08:00
parent 9639a080c6
commit de502e9bc3
10 changed files with 511 additions and 302 deletions
@@ -1,6 +1,6 @@
# AI 游戏创作项目开发工作台 PRD
更新时间:`2026-09-21`(2026-09-20 音频生成并入图片类那份后台任务账本、派生/修改类任务并入同一「生成任务」侧栏,2026-09-21 卡片浮层改为「提交即关」、**「生成任务」侧栏从画布左侧贴边改为画布右上角锚点(开关常驻)**、**资源卡可拖到对话栏批量 @ 引用**,见 §3.10 / §7.9 与 [`【功能说明】AGC聊天素材引用`](../【功能说明】AGC聊天素材引用-2026-09-08.md);2026-09-14 图片类生成后台化:入口 IPC 为 `start_local_project_asset_generation` + 项目内任务账本 + 本地排队 + 非模态「生成任务」面板;2026-09-13 新增的功能画布底部工具栏入口矩阵 §3.10 / §7.9,以及右侧 Supervisor 对话气泡、可访问对比度与过程卡布局收口,资源卡预览、分区布局、非破坏性资源编辑、资源替换与 Godot 双根合同保持不变)
更新时间:`2026-09-21`(2026-09-20 音频生成并入图片类那份后台任务账本、派生/修改类任务并入同一「生成任务」侧栏,2026-09-21 卡片浮层改为「提交即关」、**「生成任务」侧栏从画布左侧贴边改为画布右上角锚点(开关常驻)**、**资源卡可拖到对话栏批量 @ 引用**、**替换面板改为非模态浮层并支持在画布上点选目标**,见 §3.10 / §5.3 / §7.8 / §7.9 与 [`【功能说明】AGC聊天素材引用`](../【功能说明】AGC聊天素材引用-2026-09-08.md);2026-09-14 图片类生成后台化:入口 IPC 为 `start_local_project_asset_generation` + 项目内任务账本 + 本地排队 + 非模态「生成任务」面板;2026-09-13 新增的功能画布底部工具栏入口矩阵 §3.10 / §7.9,以及右侧 Supervisor 对话气泡、可访问对比度与过程卡布局收口,资源卡预览、分区布局、非破坏性资源编辑、资源替换与 Godot 双根合同保持不变)
## 1. 产品定位
@@ -448,7 +448,7 @@ type ProjectVersionResourceReplacement = {
- **失败即拒绝**:硬门禁任一项不等、源版本不存在、源版本未绑定该素材、替换素材未登记、替换素材与源素材相同、`expectedProjectId` / `expectedProjectRevision` CAS 冲突,都必须在写入前拒绝并说明原因;拒绝时 manifest、`versions` 与项目 revision 都不变,投影里不得出现新的版本卡或新的"当前使用"高亮。
- **落盘与留痕**:改绑定属于 `versions` 变化,写入后推进一次 `projectRevision`;并追加一条 `asset.version_binding.replace` 审计(`versionId / sourceResourceId / replacementResourceId / projectRevision`)。**没有可回溯的替换历史**:替换前的身份只有这条审计与 manifest 的 `.previous` 恢复副本。
- **入口与可见效果**:入口在资源卡选中工具条,只对「manifest 资产 + 被当前版本绑定」的素材放行;候选弹窗列出全部候选,命中硬门禁的项渲染但禁用并给出原因,只有尺寸规格差异的项仍可选但带提示。成功后**不切换版本**(没有新版本可切),只重读 manifest;可见变化是资源卡"当前使用"高亮移到替换素材、`@` 面板"当前版本素材"更新。按 §7.4 的口径,改绑定不做运行时资源重映射,运行画面本身不会因改绑定而变化;也不自动重载 / 重启运行中的预览(§3.2 末条)。
- **点选替换(2026-09-13 补充)**:候选弹窗 footer 提供「点选替换」,用于"目标就在画布上、不想在面板里筛"的场景。点它**必须关闭弹窗**(弹窗外壳是全屏遮罩,留着它画布上的卡点不到)并进入画布点选态,画布上出现提示条(「在画布上点选要替换成的素材;点击空白处不会退出」+「取消」)。点中合法候选直接走**同一条**写入链路(载荷与弹窗确认逐字一致,不产生第二套替换口径),成功后自动退出点选态;点中非法目标(分类 / 类型不同、不在后端给出的权威候选里、源素材本身、未登记资源)**不写入**,在提示条上说明原因(与候选弹窗同一条翻译口径)并**留在**点选态。退出只有三条路:Esc(在 `document` 阶段截断,画布全局 Esc 的清选中不随之触发)、提示条「取消」、替换成功;**空白点击不退出、也不清画布选中**。点选态下卡片左键只用于点选(不起拖拽、不换选中,靠一次性抑制而不是全局关掉单击),滚轮平移与 `Ctrl/Cmd` 缩放照常可用。
- **替换面板在画布上点选目标(2026-09-21;2026-09-13 的「点选替换」由此取代)**:候选面板是画布右上角的**非模态浮层**(无全屏遮罩、不做焦点陷阱,面板自身限高 + 内部滚动),面板开着的时候画布照常可点——在画布上点目标素材即把它落成**面板里的当前选择**(面板随之高亮;用户在面板里已输入的搜索与分类筛选不被重置),写入仍然只由面板「确认」发起(载荷与旧弹窗确认逐字一致,不产生第二套替换口径)。点中非法目标(分类 / 类型不同、不在后端给出的权威候选里、源素材本身、未登记资源)**不写入**,在面板里说明原因(同一条翻译口径)并保留原选择。退出只有两条路:面板「取消」/ 头部 ×、Esc(在 `document` 阶段截断,画布全局 Esc 的清选中不随之触发);替换成功即关闭面板。面板开着时卡片左键只用于点选(不起拖拽、不换画布选中,靠一次性抑制而不是全局关掉单击),滚轮平移、`Ctrl/Cmd` 缩放与空白处框选照常可用。
- **替换血缘标注(2026-09-13 补充)**:替换成功后只改绑定、光环本来就会从源素材移到替换素材,光靠光环说明不了"谁换成了谁",所以在卡面补一层**关系标注**:源素材卡标「已被 <替换素材显示名> 替换」,替换素材卡标「替换自 <源素材显示名>」,两处分别给出稳定 DOM 判据 `data-resource-replaced-by` / `data-resource-replacement-of`,值是对面资源的 **manifest 资产 id**(不是显示名)。这份关系是**宿主会话内状态**:同一会话里再次替换**整条覆盖**上一条(只保留当前有效的一条 A→B,不做历史链,与 §7.8「只展示当前有效关系」同口径);**切换项目 / 关闭工作台 / 重新加载 manifest 都不保留**——客户端没有替换关系的读侧事实源(写入结果只回 `versionId` / `committedProjectRevision`,审计 `asset.version_binding.replace` 只有写侧),manifest 的 `.previous` 只是原子安装的崩溃兜底副本、安装成功即删,不能当数据源,所以本标注**只在本次会话有效,不假装持久**。
### 5.4 游戏迭代版本(P1)
@@ -657,7 +657,7 @@ type ProjectAgentMudPointAttribution = {
5. 硬门禁任一为 false、源版本不存在、源版本未绑定该素材、替换素材未登记、替换素材与源素材相同、`expectedProjectId` / `expectedProjectRevision` 冲突,都必须在写入前拒绝;拒绝时 manifest、`versions` 与项目 revision 都不变,投影里不得出现新的"当前使用"高亮或版本卡变化。
6. 成功后重读 manifest 并**不切换版本**(没有新版本可切);**不**自动重载或重启运行中的预览(§3.2 末条),也不做运行时资源重映射。可见变化只有:资源卡"当前使用"高亮移到替换素材、`@` 面板"当前版本素材"更新。
7. 替换成功后追加一条 `asset.version_binding.replace` 审计(`versionId / sourceResourceId / replacementResourceId / projectRevision`);**替换历史不可回溯**——替换前身份只有这条审计与 manifest 的 `.previous` 副本,不得声称能查到"某版本历史上换过什么"。
8. 候选弹窗提供「点选替换」(2026-09-13):点它关闭弹窗进入画布点选态,并把「在画布上点选要替换成的素材;点击空白处不会退出」与「取消」放在画布提示条上;点中合法候选按第 3~7 条**同一条**链路提交并自动退出点选态,点中非法目标(分类 / 类型不同、不在权威候选里、源素材本身、未登记资源)零写入、留在点选态并在提示条上说明原因。退出只有 Esc(`document` 阶段截断,不清画布选中)/ 提示条「取消」/ 替换成功三条路,空白点击不退出;点选态下滚轮平移与缩放照常,卡片单击的既有语义在非点选态下不变。
8. 替换面板在画布上点选目标(2026-09-21;取代 2026-09-13 的「点选替换」):候选面板是非模态浮层,面板开着时画布保持可点,点画布上的候选即落进面板的当前选择(搜索与分类筛选不被重置),写入仍由面板「确认」按第 3~7 条**同一条**链路发起;点中非法目标(分类 / 类型不同、不在权威候选里、源素材本身、未登记资源)零写入并在面板里说明原因。退出只有面板「取消」/ × 与 Esc(`document` 阶段截断,不清画布选中)两条路,成功后自动关闭;面板开着时滚轮平移、缩放与空白框选照常,卡片单击的既有语义在面板关闭后不变。
9. 替换血缘标注(2026-09-13):替换成功后,源素材卡带「已被 <替换素材显示名> 替换」、替换素材卡带「替换自 <源素材显示名>」,稳定 DOM 判据 `data-resource-replaced-by` / `data-resource-replacement-of` 的值为对面资源的 manifest 资产 id;未参与替换的资源卡两个属性都不出现。同一会话内再次替换时**只保留当前有效的一条 A→B**(旧标注从卡上消失,不做历史链)。这份标注**只在本次会话有效**:切换项目 / 关闭工作台 / 重新加载 manifest 都不保留,也不得声称可回溯(第 7 条仍成立)。
### 7.9 P1 功能画布底部工具栏验收