# 装备模型编辑器闭环清单(2026-09-06) 本清单为只读审查基线,后续修复/验收须单独记录结果,不把源码已接通当作 E2E 已通过。 ## 实际入口 Web config/content.ts:101 默认 legacy-demo;LegacyModelEditorView.vue 使用同源 iframe 并注入权限;stage 脚本从 unreal_tran/src/main.js 打包。公开产物为 editor-CunHwJSa.js,原清单生成于 2026-09-05T10:06:01Z。正式备用 features/editors/model/DigitalTwinEditor.js 不是当前默认执行入口。 ## 功能逐项 |功能|原路径|审查基线| |---|---|---| |新建|main.js:2984|重置并 PUT 当前工程,无新增 ID;由主代理宿主改造| |导入 GLB|1273|受控上传、解析、最终保存,单文件 GLB| |导入 JSON|2829|恢复并覆盖当前工程,非服务端副本| |保存/Ctrl+S|2714|恢复副本、截图、队列 PUT/乐观锁| |自动保存|2177|30秒自动 PUT,不更新封面| |工程名|2134|失焦保存| |另存|2846|JSON 下载,不包含 GLB 字节| |撤销重做|158|35 个快照,缺异步互斥/失败索引回滚| |移动旋转缩放|2010/2215|可回存,动画基值计算有漂移| |聚焦|2242|相机可存| |网格/PBR/线框/轮廓|2217/2253|当前视图;关闭轮廓后重选泄漏| |透视|2217|固定透视重置,无菜单| |截图|3037|当前 canvas PNG| |预览|2254|真实三维;前后步实际跳时间轴2秒| |运行蓝图|1061/2189|有执行器,分支/触发有bug| |生成发布|2923|预检只做存在性/数量| |场景资源发布|2860|固定服务端版本;未直接捕获封面| |离线HTML|2956/io:432|截图+CSS示意+固定节拍,不是真实三维运行| |场景树/展开/搜索|1939|最多220行,计数为全部| |显示隐藏|1949|能回存;拾取未排除隐藏祖先| |整体部件选择|1952|可序列化| |装备资源切换|1440|自动保存,模板可覆盖时间轴/蓝图| |资源搜索|1474|多词/简称,重绘保持| |内置环境|775/972|可恢复车间/野外/车库| |外部环境GLB|1014/1802/1896|仅会话字节,重开需重选;本轮评估受控资源闭环| |训练场景JSON|816|无明确可达按钮,通用localStorage,不进入工程| |名称/变换属性|1972/2010|可回存| |PBR材质|1972/2010|可回存,多槽仅编辑第一槽| |资源编码/运行状态|1984|控件无回写,重选即丢| |流程绑定|1984|只读模板名称,非真实业务绑定| |组件|1989/2111|派生说明+持久化名称标签,无运行行为| |时间轴播放暂停停止循环|timeline:369|实际执行;循环可存| |前后关键帧/播放头|timeline:261/555|已接通| |轨道增删/目标/属性|timeline:444|可存,仅位置XYZ/旋转XYZ| |关键帧增删拖动|timeline:491|可存,默认1/30秒吸附、Alt取消| |记录关键帧|main:2246|从目标相对基值取值| |静音|timeline:239|忽略轨道但宿主不复位,保存仍扣值| |时间轴缩放|timeline:427|可存| |关键帧数值/插值|timeline:518|方法存在,曲线面板未连接| |基准动作|main:3003|匹配部件,替换时间轴/蓝图| |原生GLB动画|1709|选择播放,保存片段编号| |蓝图库/参数|blueprint:274/418/710|可存| |连线移动缩放框选删除|blueprint:522/728|可存,输入端口来源被覆盖| |复制粘贴|blueprint:669|只复制节点,不复制内部连线| |蓝图运行停止重置|blueprint:835|实际执行、200步上限| |点击双击自动|blueprint:898/main:2237|未匹配目标,无双击独立派发| |时间轴节点|main:2037|唯一当前时间轴,clip仅名称| |条件节点|main:2076/blueprint:867|缺truthy、布尔字符串解析,false出口缺失走任意出口| |高亮|main:2062|无匹配回退整机,pulse只有不同等待时长| |提示|main:2083|1.8/2.5秒自动继续或人工关闭| |曲线编辑器|1090|固定轨道/SVG/参数,无数据写回| |日志|3061|内存160行,非服务端审计| ## 已做只读原方法探针 - condition 返回 false,仅 true 连线:仍执行 true-only 完成节点并返回 true。 - trigger('click',{object:'B'}):A/B 两个目标节点时仍选择 A。 - 相同目标 rotation.z 两轨值 1/2:可见旋转 2,序列化基值 -1,应为0。 - 静音后 seek:可见姿态1、序列化基值-1,说明显示与重开存在漂移。 ## 本轮已授权修复与边界 main 负责真实曲线输入/插值、自定义属性、动画基值与静音、条件值解析、准确高亮、点击/双击/进入预览auto、隐藏拾取、轮廓、历史互斥及环境受控资源集成。新建由主代理宿主负责。Blueprint/Timeline 和内容 API/IO 各由其他代理负责。真正离线三维包与完整组件系统属于较大调整,最终确认;现有入口应明确“步骤演示 HTML(不含三维模型)”及“扩展标记,仅保存标签”。 快捷键:全局 Ctrl+S/Z/Y、W/E/R、F、Tab、Esc;时间轴 Space/Delete/Backspace/左右键及Shift快进;蓝图 Ctrl/Cmd+A/C/V、Delete、Space平移、Esc、F5。当前没有模型对象的删除/复制上下文菜单。 ## 本轮 main 实施完成(2026-09-06,源码检查与聚焦测试,非真实 UI 验收结论) 上表保留修复前定位和基线;以下为实际实施后状态。源码目录 `unreal_tran/unreal_tran/src`,由正式 Web 的 stage 脚本复制并构建。未在子任务提交、推送、生成 bundle 或执行业务 E2E。 - 新增 `model-curve-editor.js`,曲线轨道名、关键帧点、时间、标量/向量值及插值均读取/修改当前 TimelineEditor;实际调用 updateKeyframe/selectKeyframe,随工程 JSON 重开。画面不再呈现与时间轴脱节的假控制点;本轮没有新增 Bezier 切线或 solo。 - 自定义资源编码、NORMAL/SERVICE 状态写入对象 customProperties;环境/模型捕获、恢复及撤销均保留明确的修改或清空。扩展标记只存名称,文案如实说明不提供运行行为。多材质对象明确显示“材质槽 1/N”。 - 新增 `model-editor-state.js` 统一时间轴有效偏移:同一目标同一属性采用最后一个有效轨道;静音、删轨、重绑复原此前作用对象;保存和手工变换基值只扣除实际应用偏移一次。 - 蓝图条件支持 truthy、布尔/数值字符串和嵌套路径比较;高亮不再找不到对象就回退整机,隐藏或重名目标反馈错误,pulse 实际调节亮度,停止恢复材质。预览临时高亮不会被自动保存为永久材质。 - 点击携带命中对象及祖先别名;双击单独派发 double-click;进入预览仅显式派发 auto。时间轴节点保留 clip 数据键,标签改“动作名称(播放当前时间轴)”,没有虚构原生片段选择功能。 - 轮廓关闭状态在重新选择/进出预览后保持;射线拾取排除隐藏祖先下面的子对象。 - History 保存 60 个快照,异步恢复互斥,恢复失败不移动索引;托管 GLB 历史恢复通过当前项目资产重新 materialize,避免 blob 被 JSON 清掉后撤销失败。 - 外部 GLB 环境调用 uploadEnvironment,保存稳定 assetCode/storageUri;刷新/JSON/恢复稿重新下载受控资源。导入最终工程提交前保持 busy;上传已登记但解析/绑定失败时阻断保存/发布,防止旧文档误覆盖新资源。 - 发布时捕获当前真实视口封面,使用 API 队列保存后发布;封面上传/截图失败提示保留旧封面,版本冲突阻断发布;保存/发布封面期间阻止重入。 - 生成面板、按钮和完成提示明确为“步骤演示 HTML(不含三维模型)”;真实离线三维包、下游自动执行蓝图、完整组件运行系统仍属于较大调整待确认。 ## 聚焦验证与真实 UI 待验入口 1. `node --test tests/model-main-closure.test.mjs`:13/13,包含实际 TimelineEditor + happy-dom 曲线交互、工程 JSON 往返、真实主类方法提取、材质/历史/发布失败分支。 2. `node --test tests/blueprint-timeline-closure.test.mjs tests/model-content-api-integrity.test.mjs`:本轮同批 32/32(各16),与 main 首次12项联合44/44;main补托管历史后单跑13/13。 3. `node --test tests/model-editor-import.test.mjs tests/editor-timeline-playback.test.mjs tests/editor-delivery.test.mjs tests/model-content-api.test.mjs`:4/4脚本通过。脚本内旧“离线HTML均通过”仅说明现有步骤演示输出合同,不代表完整离线三维。 4. main.js、model-curve-editor.js、model-editor-state.js 的 node --check 均通过;git diff --check 通过(仅 Git LF/CRLF 通知)。 真实 E2E 由主代理执行:底部曲线页点关键帧后编辑右栏 `data-curve-field=time/value/easing`;对象属性栏 `#custom-resource-code`/`#custom-operating-status`;资源库外部 GLB 入口;顶部撤销/重做、发布面板及刷新。不得将上述单元/合同测试记作真实 API 或三维可见性截图验收。 ### 真实浏览器预跑暴露的启动阻断补充 初次 13 项聚焦测试没有覆盖完整资源库 DOM 初始化。真实浏览器发现 renderAssets 两处误用单节点 `$` 后调用 `forEach`,使资源目录初始化抛错、整个模型启动中断。已修为节点集合 `$$`,并新增真实 DOM 回归先复现相同 TypeError,再验证两模型/五环境卡片都渲染、事件都绑定、导入忙时阻断、空目录也可启动。现在 `tests/model-main-closure.test.mjs` 为 **14/14 通过**;此回归不能替代随后正式浏览器重载验收。同类单节点选择器误用复扫无新增匹配。 ### 保存后刷新假恢复稿与状态标签补充 真实 175 号测试副本快照逐字段比较没有语义差异,但 normalize 调整了 environment 对象的键顺序。原始 JSON.stringify 指纹因此误认为内容改变,beforeunload 在已保存页面刷新时写出同版本恢复稿。`model-content-api.js` 指纹现统一递归排序对象键,保留数组顺序和所有真实值变化;saveNow 与 dirty 比较共用该算法。新增 API 合同先复现再通过,并对真实 beforeunload 恢复方法断言“仅键顺序不写稿、真实名称变动仍写稿”。没有通过测试自动丢弃恢复稿来掩盖故障。 属性状态从硬编码“可见/投射阴影”改为真实祖先可见性和 castShadow;`span[data-model-editability]` 供正式宿主按权限显示可编辑/只读。最新 main 聚焦测试 **16/16**,API integrity **17/17**;这些是阶段结果,最终统计仍以报告 validation.json 为准。 ### 独立补充浏览器预跑 新增 `model-editor-navigation-closure.spec.ts`,每例从原狐狸模型 157 创建独立副本并登记清理 ID,不修改原始工程或共享测试狐狸。三个用例完成真实资源搜索与卡片切换、三种内置环境保存重开、树折叠/计数、实际鼠标镜头、面板切换/拖动、预览前后步与 Escape、实际 30 秒自动保存和刷新核对;私有预跑 **3/3** 通过,截图 41~47。此结果不替代最终统一 E2E,最终报告只按 results.json 及匹配 testTitle 的证据计算。更细的播放头/录帧、蓝图画布、恢复/离开和 gizmo 补测由团队分工执行。