浏览代码

test(editors): add model and scene closure coverage and screenshot reports

main
leiyun 1周前
父节点
当前提交
517d990b0f
共有 100 个文件被更改,包括 45884 次插入0 次删除
  1. +4
    -0
      .gitattributes
  2. +19
    -0
      model-editor-closure.config.ts
  3. +48
    -0
      reports/model-editor-closure-20260906/README.md
  4. +81
    -0
      reports/model-editor-closure-20260906/artifact-checks.json
  5. +428
    -0
      reports/model-editor-closure-20260906/cleanup.json
  6. +55
    -0
      reports/model-editor-closure-20260906/coverage-plan.md
  7. +4578
    -0
      reports/model-editor-closure-20260906/coverage.json
  8. +43
    -0
      reports/model-editor-closure-20260906/data/final-corrections.json
  9. +115
    -0
      reports/model-editor-closure-20260906/data/inventory-main.md
  10. +24
    -0
      reports/model-editor-closure-20260906/data/kingbase-validation-probe-result.json
  11. +26
    -0
      reports/model-editor-closure-20260906/data/unit-coverage-plan.json
  12. +154
    -0
      reports/model-editor-closure-20260906/data/visual-qa.json
  13. +1326
    -0
      reports/model-editor-closure-20260906/downloads/assets-roundtrip.json
  14. +3414
    -0
      reports/model-editor-closure-20260906/downloads/invalid-import-baseline.json
  15. +104
    -0
      reports/model-editor-closure-20260906/downloads/model-offline-steps.html
  16. +3414
    -0
      reports/model-editor-closure-20260906/downloads/preflight-188.json
  17. +3414
    -0
      reports/model-editor-closure-20260906/downloads/preflight-209.json
  18. +3414
    -0
      reports/model-editor-closure-20260906/downloads/preflight-225.json
  19. +3414
    -0
      reports/model-editor-closure-20260906/downloads/preflight-239.json
  20. +3422
    -0
      reports/model-editor-closure-20260906/downloads/recovery-187-isolated.json
  21. +3422
    -0
      reports/model-editor-closure-20260906/downloads/recovery-208-isolated.json
  22. +3422
    -0
      reports/model-editor-closure-20260906/downloads/recovery-224-isolated.json
  23. +3422
    -0
      reports/model-editor-closure-20260906/downloads/recovery-238-isolated.json
  24. +35
    -0
      reports/model-editor-closure-20260906/evidence/30-assets-roundtrip.json
  25. +18
    -0
      reports/model-editor-closure-20260906/evidence/31-invalid-import.json
  26. +28
    -0
      reports/model-editor-closure-20260906/evidence/32-save-failure-recovery.json
  27. +21
    -0
      reports/model-editor-closure-20260906/evidence/34-publish-fixed-version.json
  28. +25
    -0
      reports/model-editor-closure-20260906/evidence/41-resource-search-switch.json
  29. +52
    -0
      reports/model-editor-closure-20260906/evidence/43-builtin-environments-tree.json
  30. +80
    -0
      reports/model-editor-closure-20260906/evidence/46-navigation-panels-autosave.json
  31. +72
    -0
      reports/model-editor-closure-20260906/evidence/51-gizmos.json
  32. +15
    -0
      reports/model-editor-closure-20260906/evidence/52-leave.json
  33. +17
    -0
      reports/model-editor-closure-20260906/evidence/60-project-recovery.json
  34. +16
    -0
      reports/model-editor-closure-20260906/evidence/63-loading-publish-preflight.json
  35. +17
    -0
      reports/model-editor-closure-20260906/evidence/new-project.json
  36. +18
    -0
      reports/model-editor-closure-20260906/evidence/permissions.json
  37. +56
    -0
      reports/model-editor-closure-20260906/evidence/properties.json
  38. +327
    -0
      reports/model-editor-closure-20260906/evidence/truck-blueprint-events.json
  39. +697
    -0
      reports/model-editor-closure-20260906/evidence/truck-blueprint-tool-supplement.json
  40. +259
    -0
      reports/model-editor-closure-20260906/evidence/truck-blueprint-ui.json
  41. +81
    -0
      reports/model-editor-closure-20260906/evidence/truck-timeline-curve.json
  42. +26
    -0
      reports/model-editor-closure-20260906/evidence/viewport.json
  43. +1447
    -0
      reports/model-editor-closure-20260906/feature-catalog.json
  44. +2624
    -0
      reports/model-editor-closure-20260906/index.html
  45. 二进制
     
  46. 二进制
     
  47. 二进制
     
  48. 二进制
     
  49. 二进制
     
  50. 二进制
     
  51. 二进制
     
  52. 二进制
     
  53. 二进制
     
  54. 二进制
     
  55. 二进制
     
  56. 二进制
     
  57. 二进制
     
  58. 二进制
     
  59. 二进制
     
  60. 二进制
     
  61. 二进制
     
  62. 二进制
     
  63. 二进制
     
  64. 二进制
     
  65. 二进制
     
  66. 二进制
     
  67. 二进制
     
  68. 二进制
     
  69. 二进制
     
  70. 二进制
     
  71. 二进制
     
  72. 二进制
     
  73. 二进制
     
  74. 二进制
     
  75. 二进制
     
  76. 二进制
     
  77. 二进制
     
  78. 二进制
     
  79. 二进制
     
  80. 二进制
     
  81. 二进制
     
  82. 二进制
     
  83. 二进制
     
  84. 二进制
     
  85. +76
    -0
      reports/model-editor-closure-20260906/playwright/index.html
  86. +1473
    -0
      reports/model-editor-closure-20260906/results.json
  87. +100
    -0
      reports/model-editor-closure-20260906/run-history.json
  88. +43
    -0
      reports/model-editor-closure-20260906/screenshot-captions.json
  89. +498
    -0
      reports/model-editor-closure-20260906/screenshot-verification.json
  90. 二进制
     
  91. 二进制
     
  92. 二进制
     
  93. 二进制
     
  94. 二进制
     
  95. 二进制
     
  96. 二进制
     
  97. 二进制
     
  98. 二进制
     
  99. 二进制
     
  100. 二进制
     

+ 4
- 0
.gitattributes 查看文件

@@ -0,0 +1,4 @@
# These generated reports attest exact artifact bytes with SHA-256. Preserve
# their original line endings on Windows and Linux, including embedded bundles.
reports/model-editor-closure-20260906/** -text -whitespace
reports/scene-editor-closure-20260906/** -text -whitespace

+ 19
- 0
model-editor-closure.config.ts 查看文件

@@ -0,0 +1,19 @@
import { defineConfig } from '@playwright/test'

export default defineConfig({
testDir: './tests', testMatch: 'model-editor-*closure.spec.ts',
outputDir: './reports/model-editor-closure-20260906/test-results',
workers: 1, fullyParallel: false, retries: 0, timeout: 180_000,
expect: { timeout: 25_000 },
reporter: [
['list'],
['html', { outputFolder: 'reports/model-editor-closure-20260906/playwright', open: 'never' }],
['json', { outputFile: 'reports/model-editor-closure-20260906/results.json' }],
],
use: {
baseURL: 'http://127.0.0.1:6180', browserName: 'chromium', channel: 'msedge', headless: true,
locale: 'zh-CN', timezoneId: 'Asia/Shanghai', viewport: { width: 1920, height: 1080 },
navigationTimeout: 60_000, actionTimeout: 25_000,
screenshot: 'only-on-failure', trace: 'off', video: 'off',
},
})

+ 48
- 0
reports/model-editor-closure-20260906/README.md 查看文件

@@ -0,0 +1,48 @@
# 装备模型编辑器闭环验收报告

打开 [index.html](index.html)。本报告区分源码实现、单元/合同测试、真实接口、浏览器 UI 与脚本调用运行时,不把截图或套件总通过数替代逐功能验证。

从 `ute2e` 目录生成:

```sh
node tools/build-model-editor-closure-report.mjs
```

- `feature-catalog.json`:103 个实际可达功能的源码位置、边界、修复和验收要求。
- `coverage.json`:生成时逐项关联当前证据的矩阵。
- `results.json`:最终 Playwright JSON 原始结果。
- `run-history.json`:首轮失败和定向重跑的安全摘要;只含次数、标题、时间与源文件哈希,保留失败事实,不用定向重跑替换全量结果。
- `validation.json`:最终构建、单元测试等验证记录;`e2eComplete: true` 标记最终轮已完成。
- `evidence/*.json`:经过脱敏的真实 API、运行时及界面断言记录。
- `screenshots/*`:真实截图,报告自动枚举全部 PNG/JPEG/WebP。
- `screenshot-captions.json`:以文件名或不含后缀文件名为键,值为 `{ "title": "图名", "description": "实际证明的范围" }`。
- `screenshot-verification.json`:每张图片与当前 `results.json` 正式附件的 SHA256 比对;同名重拍或预跑图不自动计当前轮通过。
- `cleanup.json`:临时测试数据的清理或保留记录。
- `artifact-checks.json`:四仓库变动及本轮报告的凭据/令牌、ZIP内元数据和图片文本元数据扫描;`finalArtifactScan: true` 才表示最终文件已扫描,初查不替代最终验收。
- `data/inventory-main.md`:修复前只读基线及本轮源码实现记录。
- `data/final-corrections.json`:只读查看交互与连接健康检查补修的解释和边界;`data/kingbase-validation-probe-result.json` 只含脱敏探针结果,不含连接信息或凭据。

证据推荐格式(仅示例,不是实际通过声明):

```json
{
"time": "真实执行时间",
"data": {
"title": "当前曲线编辑与刷新",
"status": "PASS",
"kind": "e2e",
"testTitle": "与 results.json 完全对应的真实用例名称",
"featureIds": ["timeline.curve", "curve.time", "curve.value", "curve.easing"],
"details": "记录真正执行和断言的内容,不按同类功能推测覆盖",
"screenshots": ["screenshots/实际文件.png"]
}
}
```

`kind` 应明确使用 `e2e`、`api`、`runtime` 或 `unit`,不要把通过脚本调用编辑器方法说成纯 UI 操作。带 `testTitle` 的证据会与当前 Playwright 结果按完整标题及执行时间交叉核对;对应用例不存在、失败,或证据来自不同时段时,不能标为本轮通过。未关联证据的功能保持待验证。

全量首轮的 17/19 和随后仅两条定向重跑的 2/2 不可相加后改写成“全量19/19通过”。必须另跑完整套件,保留新的完整 `results.json` 以及匹配时段证据;历史503的诊断判断和已证明的因果关系要分开陈述。

总状态只有在结果最终完成、最终验证通过、无失败、全矩阵都有证据且最终交付物扫描通过时才为 PASS;已执行用例通过但仍有未覆盖功能时,会如实显示待验证范围。组件运行系统、完整三维离线包、下游自动执行模型动作属于三项另行确认的范围,不应虚构完成证据。

此目录不得存入账号文件、密码、令牌、cookie、私有 fixtures、原始服务日志或数据库备份。原始 PDF 只相对链接至工作区 `文档`,不复制全文。

+ 81
- 0
reports/model-editor-closure-20260906/artifact-checks.json 查看文件

@@ -0,0 +1,81 @@
{
"time": "2026-09-06T08:34:43.610816+00:00",
"status": "PASS",
"secretScan": "PASS",
"phase": "final",
"finalArtifactScan": true,
"scope": "四个仓库相对 HEAD 的变动/新增文件与本轮完整报告;真实本地账号密码精确匹配、可解码 JWT、ZIP/Playwright 内嵌报告逐项解压扫描及 PNG 文本元数据。输出不包含任何命中值或附近正文。",
"baselinePolicy": "只排除 HEAD 已存在且邻近至少64字符完全一致的普通源码/固定库字符串(统一CRLF/LF);新哈希模型bundle另允许至少25个邻近词元在仅归一化压缩变量名后完全一致,且命中须为更长固定常量的子串、不能是完整密码值。唯一经本轮复核的配置例外是 ut_auth/src/main/resources/application.yml 的 bootstrap-admin-password 环境变量默认项:文件、键、整行须与 HEAD 完全相同,且新旧文件各只出现一次;改值、改变量名、复制到其他文件或新增同一行均仍失败。其他真实凭据赋值与ZIP内元数据不作排除。Playwright静态库对比HEAD上一轮报告壳。",
"limitations": [
"图片仅扫描可读元数据,不执行OCR;图像正文由浏览器报告视觉QA核对。",
"只扫描本轮交付范围,不声称已审计整个历史仓库。",
"初查通过不代表最终结果文件已完成,最终需 --final 再执行。"
],
"selfChecks": {
"status": "PASS",
"tests": 15
},
"repositoryHeads": {
"unreal_tran": "d16184acf1686bb4a6ad44949d0587c5373ffbde",
"unreal_tran_web": "3f39e2c94df9cdadf3545ae14bf0df41f2c37bf1",
"unreal_tran_api": "71df00dffa39a8f49a4f0654969a3014c2f78f67",
"ute2e": "b3d4ce8ffd8144090c18c8a28f5ca824170042c8"
},
"changedFileCounts": {
"unreal_tran": 14,
"unreal_tran_web": 8,
"unreal_tran_api": 15,
"ute2e": 184
},
"deletedFileCounts": {
"unreal_tran": 0,
"unreal_tran_web": 2,
"unreal_tran_api": 0,
"ute2e": 0
},
"textArtifactsScanned": 104,
"pngMetadataFilesScanned": 122,
"archives": [
{
"file": "ute2e/reports/model-editor-closure-20260906/playwright/index.html!embedded-report-1.zip",
"entries": 7,
"textEntries": 7
}
],
"finalInputs": {
"results.json": true,
"validation.json": true,
"cleanup.json": true,
"playwright/index.html": true
},
"finalInputSha256": {
"results.json": "f37013658c8c38a5ec5993e636a30ad57eee9d3bcc119650c929952de8d556e9",
"validation.json": "6e0e87d0df73061bc8549d3405f03731fecf077d7425f52eeed45008f7d09959",
"cleanup.json": "ab2776afa143d9937651daa8fa18b531a3fb84c703f5f5b0918930e78c76eb26",
"playwright/index.html": "92dcca3fe570530bde973b9e09199c064fc2b343bb6f8a21b67fb3c72b8949ed"
},
"unchangedBaselineExclusions": [
{
"file": "unreal_tran_api/ut_auth/src/main/resources/application.yml",
"baseline": "unreal_tran_api/HEAD:ut_auth/src/main/resources/application.yml",
"occurrences": 1
},
{
"file": "unreal_tran_api/wiki/11-内容制作模块.md",
"baseline": "unreal_tran_api/HEAD:wiki/11-内容制作模块.md",
"occurrences": 17
},
{
"file": "unreal_tran_web/public/legacy-model-editor/assets/editor-BAqfQ3VC.js",
"baseline": "unreal_tran_web/HEAD:public/legacy-model-editor/assets/editor-CunHwJSa.js",
"occurrences": 1
},
{
"file": "ute2e/reports/model-editor-closure-20260906/playwright/index.html",
"baseline": "ute2e/HEAD:reports/role-permissions-20260906/playwright/index.html",
"occurrences": 1
}
],
"unscannedBinaryFiles": [],
"findings": []
}

+ 428
- 0
reports/model-editor-closure-20260906/cleanup.json 查看文件

@@ -0,0 +1,428 @@
{
"time": "2026-09-06T08:27:13.581Z",
"status": "PASS",
"originals": [
{
"id": "157",
"name": "实测模型-狐狸动画-已验证-20260905",
"version": 15,
"unchanged": true
},
{
"id": "156",
"name": "实测模型-牛奶卡车-已验证-20260905",
"version": 20,
"unchanged": true
},
{
"id": "94",
"name": "桥梁架设装备整机模型",
"version": 253,
"unchanged": true
}
],
"projects": [
{
"id": "168",
"alreadyAbsent": true
},
{
"id": "169",
"alreadyAbsent": true
},
{
"id": "170",
"alreadyAbsent": true
},
{
"id": "171",
"alreadyAbsent": true
},
{
"id": "172",
"alreadyAbsent": true
},
{
"id": "173",
"alreadyAbsent": true
},
{
"id": "174",
"alreadyAbsent": true
},
{
"id": "175",
"alreadyAbsent": true
},
{
"id": "176",
"alreadyAbsent": true
},
{
"id": "177",
"alreadyAbsent": true
},
{
"id": "178",
"alreadyAbsent": true
},
{
"id": "179",
"alreadyAbsent": true
},
{
"id": "180",
"alreadyAbsent": true
},
{
"id": "181",
"alreadyAbsent": true
},
{
"id": "182",
"alreadyAbsent": true
},
{
"id": "183",
"name": "闭环导航名称-183",
"withdrawn": false,
"removed": true
},
{
"id": "184",
"name": "闭环验收-资源往返-mtph19ll",
"withdrawn": false,
"removed": true
},
{
"id": "185",
"name": "闭环验收-三维手柄-1788678747289",
"withdrawn": false,
"removed": true
},
{
"id": "186",
"name": "闭环验收-离开保护-1788678780620",
"withdrawn": false,
"removed": true
},
{
"id": "187",
"name": "闭环验收-恢复副本-mtph6hw8",
"withdrawn": false,
"removed": true
},
{
"id": "188",
"name": "闭环验收-加载与预检-mtph6ubj",
"withdrawn": false,
"removed": true
},
{
"id": "189",
"name": "闭环验收-三维手柄-1788678838243",
"withdrawn": false,
"removed": true
},
{
"id": "190",
"name": "闭环验收-离开保护-1788678850196",
"withdrawn": false,
"removed": true
},
{
"id": "191",
"name": "闭环工具补充-卡车控件-mtpha049",
"withdrawn": false,
"removed": true
},
{
"id": "192",
"name": "闭环工具补充-卡车控件-mtphbg8t",
"withdrawn": false,
"removed": true
},
{
"id": "193",
"name": "闭环工具补充-基准匹配-mtphbpqq",
"withdrawn": false,
"removed": true
},
{
"id": "194",
"name": "闭环工具补充-卡车控件-mtphfk1m",
"withdrawn": false,
"removed": true
},
{
"id": "195",
"name": "闭环工具补充-基准匹配-mtphfu32",
"withdrawn": false,
"removed": true
},
{
"id": "196",
"name": "闭环验收-资源往返-mtphjhoi",
"withdrawn": false,
"removed": true
},
{
"id": "197",
"name": "闭环验收-拒绝非法资源-mtphjv5x",
"withdrawn": false,
"removed": true
},
{
"id": "198",
"name": "闭环验收-保存失败恢复-mtphk0kk",
"withdrawn": false,
"removed": true
},
{
"id": "199",
"name": "闭环验收-发布封面版本-mtphk960",
"withdrawn": true,
"removed": true
},
{
"id": "200",
"name": "闭环工具补充-卡车控件-mtphkrbz",
"withdrawn": false,
"removed": true
},
{
"id": "201",
"name": "闭环工具补充-基准匹配-mtphkzlj",
"withdrawn": false,
"removed": true
},
{
"id": "202",
"name": "闭环新建-1788679561949",
"withdrawn": false,
"removed": true
},
{
"id": "203",
"name": "闭环验收-三维手柄-1788679613072",
"withdrawn": false,
"removed": true
},
{
"id": "204",
"name": "闭环验收-离开保护-1788679623529",
"withdrawn": false,
"removed": true
},
{
"id": "205",
"name": "闭环补充-资源库-mtphobxb",
"withdrawn": false,
"removed": true
},
{
"id": "206",
"name": "闭环补充-内置环境-mtphomov",
"withdrawn": false,
"removed": true
},
{
"id": "207",
"name": "闭环导航名称-207",
"withdrawn": false,
"removed": true
},
{
"id": "208",
"name": "闭环验收-恢复副本-mtphpz7v",
"withdrawn": false,
"removed": true
},
{
"id": "209",
"name": "闭环验收-加载与预检-mtphq9y1",
"withdrawn": false,
"removed": true
},
{
"id": "210",
"name": "闭环验收-离开保护-1788681347476",
"withdrawn": false,
"removed": true
},
{
"id": "211",
"name": "闭环补充-内置环境-mtpip60q",
"withdrawn": false,
"removed": true
},
{
"id": "212",
"name": "闭环验收-资源往返-mtpjbnl2",
"withdrawn": false,
"removed": true
},
{
"id": "213",
"name": "闭环验收-拒绝非法资源-mtpjbyqo",
"withdrawn": false,
"removed": true
},
{
"id": "214",
"name": "闭环验收-保存失败恢复-mtpjc2vu",
"withdrawn": false,
"removed": true
},
{
"id": "215",
"name": "闭环验收-发布封面版本-mtpjcafv",
"withdrawn": true,
"removed": true
},
{
"id": "216",
"name": "闭环工具补充-卡车控件-mtpjcof8",
"withdrawn": false,
"removed": true
},
{
"id": "217",
"name": "闭环工具补充-基准匹配-mtpjcvxe",
"withdrawn": false,
"removed": true
},
{
"id": "218",
"name": "闭环新建-1788682528069",
"withdrawn": false,
"removed": true
},
{
"id": "219",
"name": "闭环验收-三维手柄-1788682536810",
"withdrawn": false,
"removed": true
},
{
"id": "220",
"name": "闭环验收-离开保护-1788682545004",
"withdrawn": false,
"removed": true
},
{
"id": "221",
"name": "闭环补充-资源库-mtpjesgj",
"withdrawn": false,
"removed": true
},
{
"id": "222",
"name": "闭环补充-内置环境-mtpjezfi",
"withdrawn": false,
"removed": true
},
{
"id": "223",
"name": "闭环导航名称-223",
"withdrawn": false,
"removed": true
},
{
"id": "224",
"name": "闭环验收-恢复副本-mtpjg6y2",
"withdrawn": false,
"removed": true
},
{
"id": "225",
"name": "闭环验收-加载与预检-mtpjgfnd",
"withdrawn": false,
"removed": true
},
{
"id": "226",
"name": "闭环验收-资源往返-mtpjkcpq",
"withdrawn": false,
"removed": true
},
{
"id": "227",
"name": "闭环验收-拒绝非法资源-mtpjko7g",
"withdrawn": false,
"removed": true
},
{
"id": "228",
"name": "闭环验收-保存失败恢复-mtpjkshn",
"withdrawn": false,
"removed": true
},
{
"id": "229",
"name": "闭环验收-发布封面版本-mtpjkzt1",
"withdrawn": true,
"removed": true
},
{
"id": "230",
"name": "闭环工具补充-卡车控件-mtpjlf69",
"withdrawn": false,
"removed": true
},
{
"id": "231",
"name": "闭环工具补充-基准匹配-mtpjlmiy",
"withdrawn": false,
"removed": true
},
{
"id": "232",
"name": "闭环新建-1788682938712",
"withdrawn": false,
"removed": true
},
{
"id": "233",
"name": "闭环验收-三维手柄-1788682951454",
"withdrawn": false,
"removed": true
},
{
"id": "234",
"name": "闭环验收-离开保护-1788682960426",
"withdrawn": false,
"removed": true
},
{
"id": "235",
"name": "闭环补充-资源库-mtpjnoh9",
"withdrawn": false,
"removed": true
},
{
"id": "236",
"name": "闭环补充-内置环境-mtpjnv0t",
"withdrawn": false,
"removed": true
},
{
"id": "237",
"name": "闭环导航名称-237",
"withdrawn": false,
"removed": true
},
{
"id": "238",
"name": "闭环验收-恢复副本-mtpjp3nr",
"withdrawn": false,
"removed": true
},
{
"id": "239",
"name": "闭环验收-加载与预检-mtpjpdaj",
"withdrawn": false,
"removed": true
}
]
}

+ 55
- 0
reports/model-editor-closure-20260906/coverage-plan.md 查看文件

@@ -0,0 +1,55 @@
# 全功能证据映射与未覆盖规划

本文件是测试设计与源码断言核对,不是执行通过证据。最终结果由 `results.json`、`validation.json`、`evidence/*.json` 与 `coverage.json` 决定。

## 已校准的浏览器脚本

|脚本|实际范围|证据边界|
|---|---|---|
|model-editor-closure.spec.ts|属性数值、PBR首槽、扩展标记、保存重开、撤销重做、视图开关/原生片段、新建/权限|已删除不存在的 object.* / viewport.* / permissions.* ID;变换模式按钮不等同真实 gizmo 拖拽,不能代填 view.move/rotate/scale|
|model-editor-assets-closure.spec.ts|主模型/外部环境真实上传、JSON往返、无效导入、保存失败和重试、发布封面/固定版本/离线步骤HTML|异常通过定向请求中断注入;恢复副本“存在”不等于恢复/隔离/下载全部UI已测;固定版本可取得不等于下游自动运行|
|model-editor-blueprint-closure.spec.ts|真实轨道/帧/曲线/蓝图库/接线/剪贴板/执行控制、真实点击/双击/auto事件;另有刻度/按键/录帧/分量、基准动作匹配/不匹配、搜索拖入/工具栏添加/画布操作专项|条件真假出口的补充检查标记为 runtime;第4专项才覆盖搜索/拖入和曲线分量路径断言,不把第1例仅切换选择器当成已验|
|model-editor-navigation-closure.spec.ts|独立原模型157副本;资源搜索/卡片切换、三内置环境保存重开、折叠树、鼠标镜头/聚焦、页签/分割条/Tab、预览±2秒/Esc、日志/统计、名称保存/真实30秒自动保存|三项真实用例已在私有预跑通过,截图41~47;此预跑不替代最终results,最终统一结果仍须核对|
|model-editor-interaction-closure.spec.ts|真实三维 gizmo 平移/旋转/缩放,撤销重做、保存重开;离开时关闭确认、保存失败保留、重试成功再离开|独立副本;只读投影定位手柄,不脚本改变模型姿态;注入503验证失败分支|
|model-editor-recovery-closure.spec.ts|同版本真实未存恢复→显式保存、旧版本下载隔离;受控GLB下载失败→UI重试、预检开关无写入和错误资源导入拒绝|恢复稿来自真实beforeunload,不预注入localStorage;较新服务端内容不被旧稿覆盖;服务端发布严格合同另由API测试验证|

首批四份脚本显式计划关联 **88/103** 个功能 ID;随后新增交互/恢复两份脚本补上其中 7 项,时间轴/蓝图专项补 7 项,最终六份脚本显式关联 **102/103** 个功能 ID,多轨计算以明确 unit 证据关联。全部 ID 与 catalog 对齐,未发现未知 ID。这里记录的是“已写断言计划”,不是最终通过数;最终结果以 coverage.json 为准。

后续并行补测分工:时间轴/蓝图专项负责 `timeline.seek/record/baseline`、`curve.axis`、`blueprint.palette/add/canvas`;资产专项负责恢复稿/加载失败/发布预检;宿主专项负责真实 gizmo 拖拽与离开确认。`timeline.multitrack` 以真实计算方法单元测试作独立证据,映射在 [unit-coverage-plan.json](data/unit-coverage-plan.json),该计划文件本身不代表通过。最终生成器按实际证据动态计算,下面保留补测前的差距,便于对照补测来源。

## 补测前的15项差距(追溯记录)

|功能 ID|补测前已有的验证|据此安排的补测范围|
|---|---|---|
|project.recovery|本轮 API 指纹回归与真实 beforeunload 方法回归:键顺序相同内容不写假稿;真实变化仍保留;现有 API 恢复合同|用户明确恢复/放弃/隔离/下载的真实对话框;同版本真实修改与旧版本分叉|
|project.leave|上一轮角色/权限回归及宿主聚焦合同|本轮模型编辑器脏状态取消、放弃、保存失败与上传忙时离开;不能用干净页面切路由代替|
|resource.loading|启动后readyFrame状态;本轮renderAssets真实DOM空目录/卡片回归|GLB下载或解析失败后中性失败状态、重试成功;不能把未加载空白当成功|
|view.move|属性XYZ保存重开;多轨中性基值单测|真实TransformControls平移手柄拖动、保存重开;当前只点击W模式|
|view.rotate|旋转数值输入保存;多轨旋转单测|真实旋转环拖动及撤销重做;当前只点击E模式|
|view.scale|缩放数值输入保存重开|真实缩放手柄拖动及保存;当前只点击R模式|
|timeline.seek|时间轴拖帧触发timechange合同;键盘/seek运行时已有回归|真实播放头/刻度点击、左右/Shift按键、时间码与视口同步|
|timeline.record|主类addKeyframeFromSelection源码已接;中性姿态单测|真实“记录关键帧”按钮捕获当前帧偏移,保存后回放一致|
|timeline.multitrack|本轮main实际capture/apply方法单测:最后有效轨道、静音/删除/重绑、保存基值|可用unit证据明确覆盖计算合同;需要多轨真实视口可见性截图时另加UI,不能冒称已拍|
|timeline.baseline|既有装备profile/动作生成合同|有匹配实际载入并保存;无匹配保留数据;当前没有单独确认框,不能写“取消验证通过”|
|curve.axis|现有UI只选Y再选X;向量其他分量保持的unit回归|修改不同轴数值后切显示轴,断言曲线变化且不改其他数据|
|blueprint.palette|当前点选创建七类型节点|搜索/清空、HTML5拖入节点,不能用脚本addNode冒充拖放|
|blueprint.add|当前节点库点选与节点新增unit|工具栏“添加节点”确实新增默认提示节点并进入历史/JSON|
|blueprint.canvas|现有用例点击“适应画布”;节点自身拖动|蓝图画布滚轮缩放、Space平移/适应,并验证节点图数据未意外变化|
|publish.preflight|发布API拒绝非法资源/固定版本合同;当前面板打开并真实发布|界面校验清单和服务端阻断对应,打开/关闭不改变工程;不能仅凭绿标判定有效|

## 已有测试中的局部限制

- `property.identity` 新增可见性/阴影真实DOM回归;补充UI目前检查只读标识与流程绑定字段。权限注入的“只读”标签需由宿主最终用例确认。
- `timeline.drag-key` 已有真实拖动与碰撞合同,Alt取消吸附尚未单独通过浏览器验证。
- `blueprint.move` 有单节点真实拖动与全选剪贴板;多选框选拖移并未单独截图。
- `blueprint.highlight` 有真实执行与缺目标/隐藏目标/临时材质单测;呼吸幅度当前不是像素级曲线验收。
- `publish.cover` 的真实成功上传、版本、封面URI已测;503/409失败保旧图由独立API合同补充,不能称该真实服务自然出现503。
- `selection.scope` 补充用例增加明确整机根/部件对象断言;仍需避免把仅点击按钮当成三维目标操作。

## 本轮新增阻断回归

1. 资源库启动:真实DOM复现两处单节点选择器误用后修复,覆盖卡片绑定/空目录。
2. 保存后刷新假恢复稿:真实175快照逐字段无差异,仅environment键顺序不同;指纹统一递归排序对象键,保留数组顺序和真实值变化;beforeunload假稿/真稿均有回归。
3. 状态标签:真实DOM验证隐藏祖先及castShadow;宿主通过span[data-model-editability]显示会话权限。

以上属于修复和证据分层,不新增 solo,也不把组件运行系统、完整离线三维包、下游自动运行三项待确认范围伪装成已实现。

+ 4578
- 0
reports/model-editor-closure-20260906/coverage.json
文件差异内容过多而无法显示
查看文件


+ 43
- 0
reports/model-editor-closure-20260906/data/final-corrections.json 查看文件

@@ -0,0 +1,43 @@
{
"kind": "implementation-notes",
"scope": "补修说明与已确认的聚焦验证;不替代最终完整浏览器结果、后端构建或最终验证记录。",
"items": [
{
"title": "只读模型的搜索、原生动画选择与键盘预览",
"problem": "权限桥误把查看控件的键盘交互当成内容编辑,导致只读用户不能在搜索框输入、切换原生动画或按 Enter 进入预览。",
"change": "按实际查看控件放行键盘输入/选择/激活;模型编辑、内容上传/保存/发布仍依对应权限阻断。",
"validation": "真实 DOM 权限桥 14/14 通过;最终完整19条E2E全部通过,其中管理员用例验证真实键盘搜索、原生动画切换与Enter播放/暂停,期间没有内容写请求,直接创建接口返回403。",
"featureIds": [
"project.permissions",
"resource.search",
"tree.search",
"timeline.native",
"view.preview"
],
"source": "../../../unreal_tran_web/src/features/editors/model/legacy-iframe-permissions.ts",
"testSource": "../../tools/content-permissions.test.mjs"
},
{
"title": "Auth / Tran 连接有效性检查增加时限与空闲保活",
"problem": "数据库连接健康检查可能在驱动网络读取上长时间阻塞,拖住借用连接的请求;不能据此把每个历史503都逐条归因为此缺陷。",
"change": "两个模块统一使用有时限的 SELECT 1 健康检查,默认临时网络时限 2 秒;检查结束恢复原连接超时,开启空闲检查和保活。已有普通业务 SQL 超时策略不变。",
"validation": "实际 Kingbase 驱动隔离探针:正常检查 12ms,原0ms和原7000ms网络超时均恢复;隔离网络黑洞约2010ms抛出 SocketTimeoutException 并关闭连接。探针不是整个平台可用性测试,后端打包和全量E2E结果另记。",
"source": "../../../unreal_tran_api/ut_auth/src/main/java/com/unrealtran/auth/config/BoundedConnectionValidator.java",
"secondSource": "../../../unreal_tran_api/ut_tran/src/main/java/com/unrealtran/tran/config/BoundedConnectionValidator.java",
"evidence": "data/kingbase-validation-probe-result.json"
},
{
"title": "曲线轨道与分量控件的可读性",
"problem": "曲线轨道改为按钮后遗漏背景和边框样式,显示为灰底灰字;分量下拉沿用浏览器默认样式并与数值标签重叠。",
"change": "补齐整宽暗色轨道按钮、主副文字与选中/悬停/键盘焦点样式;分量下拉使用暗色样式并定位右上。仅修改曲线面板CSS。",
"validation": "最终浏览器轮次重新操作轨道、关键帧、五种插值和分量选择并截图;可视效果以最终22与28号截图核对。",
"featureIds": [
"timeline.curve",
"curve.easing",
"curve.value"
],
"source": "../../../unreal_tran/src/style.css",
"evidence": "screenshots/22-truck-curve-value-five.png"
}
]
}

+ 115
- 0
reports/model-editor-closure-20260906/data/inventory-main.md 查看文件

@@ -0,0 +1,115 @@
# 装备模型编辑器闭环清单(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 补测由团队分工执行。

+ 24
- 0
reports/model-editor-closure-20260906/data/kingbase-validation-probe-result.json 查看文件

@@ -0,0 +1,24 @@
{
"exitCode": 0,
"checks": [
{
"case": "actual-driver-check",
"valid": true,
"beforeMs": 0,
"afterMs": 0,
"elapsedMs": 12
},
{
"case": "actual-driver-nonzero-restore",
"beforeMs": 7000,
"afterMs": 7000
},
{
"case": "actual-driver-blackhole",
"elapsedMs": 2010,
"closed": true,
"exceptionType": "KSQLException",
"causeType": "SocketTimeoutException"
}
]
}

+ 26
- 0
reports/model-editor-closure-20260906/data/unit-coverage-plan.json 查看文件

@@ -0,0 +1,26 @@
{
"kind": "unit-coverage-plan",
"status": "PENDING",
"note": "本文件只说明真实测试与功能的对应关系,不声明执行成功。最终通过状态须由 validation.json 中对应命令的退出码与测试结果确认;单元测试不等同浏览器操作。",
"sourceFile": "../../../../unreal_tran/tests/model-main-closure.test.mjs",
"command": "node --test tests/model-main-closure.test.mjs",
"cwd": "unreal_tran/unreal_tran",
"tests": [
{ "title": "resource catalog startup renders all model/environment cards and binds every action with a real DOM", "featureIds": ["resource.catalog"], "scope": "真实 DOM 渲染、卡片绑定、空目录及 busy 保护;不包含 GLB 网络加载。" },
{ "title": "curve edits real scalar key values, time and interpolation, persisting through document reload", "featureIds": ["timeline.curve", "curve.time", "curve.value", "curve.easing"], "scope": "真实曲线控件与 TimelineEditor,标量编辑与文档往返。" },
{ "title": "curve vector editing preserves other components and selected track; invalid values do not mutate", "featureIds": ["curve.value"], "scope": "向量其它分量保留,当前轨道、非法值保护;不包含显示轴切换或可视像素验收。" },
{ "title": "multiple tracks on one property use last effective value; capture subtracts it only once", "featureIds": ["timeline.multitrack"], "scope": "调用实际 apply/capture/update 基值方法;验证同属性最后有效轨道、静音/删除后中性姿态,偏移只扣一次。" },
{ "title": "changing a binding resets the former target and keeps manual transform edits as base", "featureIds": ["timeline.multitrack", "timeline.target"], "scope": "轨道重绑后旧目标复位,手动变换成为新基值;不假称鼠标拖动已验。" },
{ "title": "custom properties and extension labels survive actual capture, project JSON and object restore", "featureIds": ["property.code", "property.status", "component.tag"], "scope": "真实对象 capture、normalization、JSON 与 restore 往返;清空和撤销到未存在字段状态。" },
{ "title": "boolean, numeric and nested blueprint conditions select their true/false branches", "featureIds": ["blueprint.condition"], "scope": "布尔、数字、truthy 与嵌套路径值解析。" },
{ "title": "visible child under a hidden ancestor cannot be picked or highlighted; trigger aliases include ancestors", "featureIds": ["tree.visibility", "blueprint.highlight"], "scope": "共用可见性和祖先别名函数;鼠标事件另由 E2E 验证。" },
{ "title": "inspector state tags reflect ancestor visibility and actual shadow flags, with a host editability hook", "featureIds": ["property.identity"], "scope": "真实属性 DOM 显示隐藏/阴影状态,并提供宿主权限标签 hook;不伪称此单测完成会话鉴权。" },
{ "title": "history retains 60 states, truncates redo after edits and ignores duplicate snapshots", "featureIds": ["project.undo", "project.redo"], "scope": "60 个快照上限、重复状态忽略及新编辑截断 redo 分支。" },
{ "title": "history serializes async restores and leaves index unchanged when restoration fails", "featureIds": ["project.undo", "project.redo"], "scope": "异步互斥、下载失败不移动索引,解除锁后可继续操作。" },
{ "title": "managed-GLB history downloads the snapshot stable reference before restoring, without rewriting it", "featureIds": ["project.undo", "project.redo"], "scope": "受控 GLB 快照先物化再恢复,不把临时 URL 写回快照。" },
{ "title": "beforeunload recovery does not create a draft for key order alone, but preserves real unsaved changes", "featureIds": ["project.recovery"], "scope": "同语义对象键顺序不产生假恢复稿;真正修改仍保留。不包含全部恢复/隔离/下载 UI 分支。" },
{ "title": "highlight rejects missing/hidden targets and transient colors never enter a saved project", "featureIds": ["blueprint.highlight"], "scope": "目标不存在/隐藏报错,执行时暂态发光颜色不进入保存文档,结束恢复原材质。" },
{ "title": "API publish supplies current cover, blocks duplicate publication and reports preserved old cover once", "featureIds": ["publish.api", "publish.cover", "feedback.toast"], "scope": "实际发布宿主方法传封面、重入阻断和上传失败只提示一次;模拟 API,不是实际服务响应。" },
{ "title": "API conflict leaves publication failed and releases the cover guard", "featureIds": ["project.conflict", "publish.api", "publish.cover"], "scope": "409 分支不误报已发布并释放 busy 标记;模拟 API。" }
]
}

+ 154
- 0
reports/model-editor-closure-20260906/data/visual-qa.json 查看文件

@@ -0,0 +1,154 @@
{
"recordedAt": "2026-09-06T08:24:22Z",
"kind": "manual-visual-review",
"status": "PASS_WITH_NOTES",
"scope": "逐张只读查看报告 screenshots 目录当前 41 张原始 PNG,并核对各自图注;没有运行业务接口、E2E,没有创建、修改或重拍图片。此记录仅说明视觉复核,不替代最终 E2E、附件一致性或凭据扫描。",
"imageCount": 41,
"missingCaptions": [],
"findings": [
{
"topic": "真实模型可见性",
"result": "狐狸在属性重开、预览、受控环境导入重开和下载重试成功等图中清楚可辨;牛奶卡车在时间轴零秒、蓝图运行和点击/双击/自动触发预览图中完整可辨。没有将树节点名称或成功提示单独作为模型可见的证据。",
"examples": [
"02-properties-reopened.png",
"03-fox-preview.png",
"21-truck-timeline-controls.png",
"27-truck-preview-click.png",
"27-truck-preview-double-click.png",
"27-truck-preview-auto.png",
"30-assets-environment-reopened.png",
"64-controlled-glb-retry-loaded.png"
]
},
{
"topic": "故意改变的测试姿态",
"result": "22 的车身 X=5、28 的 X=5/Y=-2,以及 29/30 延续的录制偏移导致车身与轮子分离;51 中狐狸侧立和 X 轴压缩用于真实手柄测试。已按对应图注理解为测试姿态,没有误判为模型丢失或加载变形。",
"examples": [
"22-truck-curve-value-five.png",
"28-curve-axis-y-negative.png",
"29-timeline-seek-record.png",
"30-blueprint-palette-canvas.png",
"51-transform-gizmos.png"
]
},
{
"topic": "失败与恢复证据",
"result": "04、31、32、52、63 的失败提示与故障注入/非法输入图注相符;60/62 的模态遮罩用于真实恢复保护。63 空视口明确标为加载失败且保留重试,不作为成功加载证据。64 显示重试后真实狐狸。",
"examples": [
"04-new-retry-dialog.png",
"31-invalid-import-keeps-model.png",
"32-save-conflict-keeps-recovery.png",
"52-leave-save-failure.png",
"60-same-version-real-recovery.png",
"62-stale-version-recovery-protection.png",
"63-controlled-glb-download-failed.png",
"64-controlled-glb-retry-loaded.png"
]
},
{
"topic": "环境全景的边界",
"result": "43/44 以环境全景为主,狐狸较小;45 中狐狸被车库外墙遮挡。45 图注只声称车库 GLB 加载和保存重开,未声称该图证明狐狸可见。35 为真实导出的静态步骤演示 HTML,图注没有将它称为完整三维离线运行包。",
"examples": [
"35-offline-step-demo-actual-file.png",
"43-builtin-workshop-reopened.png",
"44-builtin-outdoor-reopened.png",
"45-builtin-depot-reopened.png"
]
},
{
"topic": "可见敏感信息",
"result": "在本次逐图目视范围内未发现密码、令牌、JWT 或登录凭据。画面中的角色显示名、测试模型名称/编号及故障注入请求标识属于测试上下文;此结论不覆盖文件内嵌元数据,元数据由独立 artifact-checks 扫描。"
}
],
"notes": [
{
"image": "05-new-separate-project.png",
"observation": "本次较早读取的成功图仍留有前一故障注入的红色提示。主代理已在最终用例中增加等待其自然消失后重拍;最终新版图片需由主代理再次核对。"
},
{
"image": "33-save-retry-success.png",
"observation": "截图同时显示上一轮注入的 409 红色提示与当前重试保存成功提示,属于提示自动消退周期重叠。已补充图注,明确当前成功由 PUT 响应及刷新断言验证;没有重拍或覆盖已关联附件。"
},
{
"images": [
"22-truck-curve-value-five.png",
"28-curve-axis-y-negative.png"
],
"observation": "本次较早读取的曲线图存在已知低对比/分量选择器布局问题,随后读取的 28 文件中文字与选择器已清楚。主代理正在最后 CSS 修复后的完整重拍,需以最终 22/28 原图复核为准。"
}
],
"finalRetakeCaveat": "截图目录会在最终全量用例运行时原路径重拍。本记录说明实际读取时的 41 张图,不推定覆盖之后的新图已逐张复核;主代理最终重点复核 05、22、28、33,并用最终结果与附件校验确认报告关联。",
"images": [
"01-components-saved.png",
"02-properties-reopened.png",
"03-fox-preview.png",
"04-new-retry-dialog.png",
"05-new-separate-project.png",
"06-readonly-permissions.png",
"21-truck-timeline-controls.png",
"22-truck-curve-value-five.png",
"23-truck-blueprint-seven-nodes.png",
"24-truck-blueprint-real-message.png",
"25-truck-blueprint-completed-log.png",
"26-truck-condition-branches-runtime.png",
"27-truck-preview-auto.png",
"27-truck-preview-click.png",
"27-truck-preview-double-click.png",
"28-curve-axis-y-negative.png",
"29-timeline-seek-record.png",
"30-assets-environment-reopened.png",
"30-blueprint-palette-canvas.png",
"31-bridge-baseline-reopened.png",
"31-invalid-import-keeps-model.png",
"32-save-conflict-keeps-recovery.png",
"33-save-retry-success.png",
"34-published-current-cover.png",
"35-offline-step-demo-actual-file.png",
"41-resource-search-restored.png",
"42-resource-card-switch-reopened.png",
"43-builtin-workshop-reopened.png",
"44-builtin-outdoor-reopened.png",
"45-builtin-depot-reopened.png",
"46-preview-navigation.png",
"47-navigation-autosave-log.png",
"51-transform-gizmos.png",
"52-leave-save-failure.png",
"60-same-version-real-recovery.png",
"61-recovered-draft-explicitly-saved.png",
"62-stale-version-recovery-protection.png",
"63-controlled-glb-download-failed.png",
"64-controlled-glb-retry-loaded.png",
"65-publish-preflight-readonly.png",
"66-depot-saved-return-list.png"
],
"finalRecheck": {
"time": "2026-09-06T08:28:08.093Z",
"reviewer": "主代理逐张查看最终PNG",
"items": [
{
"file": "screenshots/05-new-separate-project.png",
"sha256": "bdcdff92c9ea09f4a8d0d477de7f23c4628823f98030b7f631ae2d28b8f70899",
"note": "新建成功画面已无上一轮注入失败提示;独立新工程可见。",
"status": "PASS"
},
{
"file": "screenshots/22-truck-curve-value-five.png",
"sha256": "9dc49ad7aac39f0c5119a3dfb3d19130c5ae323fd71c95396697726a0b736af1",
"note": "轨道文字与暗色背景清晰,分量下拉位于右上不重叠;车身X=5为测试姿态。",
"status": "PASS"
},
{
"file": "screenshots/28-curve-axis-y-negative.png",
"sha256": "afa1ced1f79603933e04b59462507903c1bbc9be70a1c374a6636f41fc1c3686",
"note": "已选轨道、负数曲线和Y分量清晰可读;部件分离与图注一致。",
"status": "PASS"
},
{
"file": "screenshots/33-save-retry-success.png",
"sha256": "a04c75c96960a149781ab3274c52b75ce64c1e7f7f1501736bdcaddf7f3ee09f",
"note": "狐狸真实可见;旧409提示与当前成功提示短暂并存,图注已解释,以成功PUT和刷新断言为准。",
"status": "PASS"
}
]
}
}

+ 1326
- 0
reports/model-editor-closure-20260906/downloads/assets-roundtrip.json
文件差异内容过多而无法显示
查看文件


+ 3414
- 0
reports/model-editor-closure-20260906/downloads/invalid-import-baseline.json
文件差异内容过多而无法显示
查看文件


+ 104
- 0
reports/model-editor-closure-20260906/downloads/model-offline-steps.html
文件差异内容过多而无法显示
查看文件


+ 3414
- 0
reports/model-editor-closure-20260906/downloads/preflight-188.json
文件差异内容过多而无法显示
查看文件


+ 3414
- 0
reports/model-editor-closure-20260906/downloads/preflight-209.json
文件差异内容过多而无法显示
查看文件


+ 3414
- 0
reports/model-editor-closure-20260906/downloads/preflight-225.json
文件差异内容过多而无法显示
查看文件


+ 3414
- 0
reports/model-editor-closure-20260906/downloads/preflight-239.json
文件差异内容过多而无法显示
查看文件


+ 3422
- 0
reports/model-editor-closure-20260906/downloads/recovery-187-isolated.json
文件差异内容过多而无法显示
查看文件


+ 3422
- 0
reports/model-editor-closure-20260906/downloads/recovery-208-isolated.json
文件差异内容过多而无法显示
查看文件


+ 3422
- 0
reports/model-editor-closure-20260906/downloads/recovery-224-isolated.json
文件差异内容过多而无法显示
查看文件


+ 3422
- 0
reports/model-editor-closure-20260906/downloads/recovery-238-isolated.json
文件差异内容过多而无法显示
查看文件


+ 35
- 0
reports/model-editor-closure-20260906/evidence/30-assets-roundtrip.json 查看文件

@@ -0,0 +1,35 @@
{
"time": "2026-09-06T08:20:27.495Z",
"data": {
"status": "PASS",
"kind": "e2e+api",
"testTitle": "受控模型与外部环境 GLB 上传、JSON 往返和刷新重开",
"featureIds": [
"project.import-glb",
"environment.external",
"project.import-json",
"project.export-json",
"project.save"
],
"projectId": "226",
"mainCode": "MODEL_MTPJKFPW_09-FOX",
"environmentCode": "ENV_MODEL_MTPJKH7H_01-BOX",
"mainUri": "fsvc://unreal-tran/model/2026/09/06/b85bd2722c4e133e61469c9f413380f0.glb",
"environmentUri": "fsvc://unreal-tran/model/2026/09/06/9bd7351f3ee917431354690f44a449b5.glb",
"modelMeshes": 1,
"environmentMeshes": 1,
"nativeClips": 3,
"environmentPosition": [
6,
0,
-7
],
"environmentScale": [
0.15,
0.15,
0.15
],
"result": "PASS",
"scope": "真实上传、注册、保存、JSON重导入、刷新后的实际网格和原生动画目录;未断言下游场景执行动画。"
}
}

+ 18
- 0
reports/model-editor-closure-20260906/evidence/31-invalid-import.json 查看文件

@@ -0,0 +1,18 @@
{
"time": "2026-09-06T08:20:33.535Z",
"data": {
"status": "PASS",
"kind": "e2e+api",
"testTitle": "非法 JSON 与未登记 blob 引用导入失败时保留当前文档",
"featureIds": [
"project.import-json"
],
"projectId": "227",
"result": "PASS",
"cases": [
"JSON语法错误",
"无受控资源编号/地址的跨页面blob引用"
],
"retainedVersion": 1
}
}

+ 28
- 0
reports/model-editor-closure-20260906/evidence/32-save-failure-recovery.json 查看文件

@@ -0,0 +1,28 @@
{
"time": "2026-09-06T08:20:43.214Z",
"data": {
"status": "PASS",
"kind": "e2e+api",
"testTitle": "保存请求超时和 409 保留恢复副本,解除故障后可重试",
"featureIds": [
"project.conflict",
"project.save",
"feedback.toast"
],
"projectId": "228",
"result": "PASS",
"intercepted": [
{
"mode": "timedout",
"method": "PUT",
"projectId": "228"
},
{
"mode": "409",
"method": "PUT",
"projectId": "228"
}
],
"scope": "真实页面保存及真实服务端重试;失败由浏览器定向注入 timedout/409,非宣称自然发生的服务故障。"
}
}

+ 21
- 0
reports/model-editor-closure-20260906/evidence/34-publish-fixed-version.json 查看文件

@@ -0,0 +1,21 @@
{
"time": "2026-09-06T08:20:51.047Z",
"data": {
"status": "PASS",
"kind": "e2e+api",
"testTitle": "直接发布同步截图封面、固定版本目录与真实离线步骤 HTML",
"featureIds": [
"publish.api",
"publish.cover",
"publish.html",
"publish.downstream"
],
"projectId": "229",
"result": "PASS",
"versionId": "283",
"coverUri": "fsvc://unreal-tran/image/2026/09/06/14ab7b4e1e7a9d21f13f3504cb8b89ae.jpg",
"priorCoverUri": "fsvc://unreal-tran/image/2026/09/05/c09a49efd4423dcf8ccbc46b46d1e209.jpg",
"mainCode": "MODEL_MTO6V5W6_09-FOX",
"scope": "目录可取得固定发布版本及同版封面;HTML已真实打开并确认演示边界,未声明下游动画执行或完整离线三维运行。"
}
}

+ 25
- 0
reports/model-editor-closure-20260906/evidence/41-resource-search-switch.json 查看文件

@@ -0,0 +1,25 @@
{
"time": "2026-09-06T08:22:56.960Z",
"data": {
"status": "PASS",
"kind": "e2e+api",
"testTitle": "补充资源库:搜索清空、真实卡片切换与刷新保留",
"featureIds": [
"resource.search",
"resource.catalog"
],
"projectId": "235",
"original": {
"id": "imported-model_mto6v5w6_09-fox",
"name": "09-Fox",
"code": "MODEL_MTO6V5W6_09-FOX"
},
"boxId": "imported-model_mtpjnqqk_01-box",
"restored": {
"id": "imported-model_mto6v5w6_09-fox",
"code": "MODEL_MTO6V5W6_09-FOX",
"meshes": 1
},
"scope": "真实搜索与资源卡片点击、服务端保存、刷新后原模型网格;副本独立登记待清理。"
}
}

+ 52
- 0
reports/model-editor-closure-20260906/evidence/43-builtin-environments-tree.json 查看文件

@@ -0,0 +1,52 @@
{
"time": "2026-09-06T08:23:19.759Z",
"data": {
"status": "PASS",
"kind": "e2e+api",
"testTitle": "补充环境与树:内置三环境保存重开、节点计数与折叠展开",
"featureIds": [
"environment.builtin",
"tree.browse",
"tree.expand",
"project.leave"
],
"projectId": "236",
"snapshots": [
{
"type": "workshop",
"mode": "placeholder",
"sourceKind": "placeholder",
"nodes": 48,
"meshes": 45,
"id": "ee302132-152c-4575-a2ec-0a56b4820079",
"shownRows": 76,
"totalNodes": 76
},
{
"type": "outdoor",
"mode": "placeholder",
"sourceKind": "placeholder",
"nodes": 70,
"meshes": 65,
"id": "bf88db35-635d-4012-8df6-dd41382e624f",
"shownRows": 98,
"totalNodes": 98
},
{
"type": "depot",
"mode": "placeholder",
"sourceKind": "builtin-gltf",
"nodes": 41,
"meshes": 32,
"id": "cebab0bb-6910-4dff-b846-9978adcb3450",
"shownRows": 69,
"totalNodes": 69
}
],
"depotSavedLeave": {
"promptedForUnsavedChanges": false,
"version": 5
},
"scope": "真实切换、保存和刷新三种环境;树计数与展开折叠;装备车库保存后返回列表不误报未保存。树220行上限仍属已说明边界。"
}
}

+ 80
- 0
reports/model-editor-closure-20260906/evidence/46-navigation-panels-autosave.json 查看文件

@@ -0,0 +1,80 @@
{
"time": "2026-09-06T08:23:54.656Z",
"data": {
"status": "PASS",
"kind": "e2e+api",
"testTitle": "补充视口与工作区:鼠标镜头、聚焦、面板、预览导航、日志与自动保存",
"featureIds": [
"project.name",
"project.autosave",
"view.orbit",
"view.focus",
"view.panels",
"view.preview-step",
"feedback.log",
"feedback.stats",
"property.identity",
"property.binding",
"selection.scope",
"component.inspect"
],
"projectId": "237",
"focused": {
"position": [
11.153569378931522,
8.526809324389628,
13.922975975299929
],
"target": [
0.01518877997232826,
2.4006999949620704,
2.266009371254541e-7
],
"distance": 18.853169271563605
},
"rotated": {
"position": [
1.7511663652214757,
6.181727848275404,
18.38837160033089
],
"target": [
0.01518877997232826,
2.4006999949620704,
2.266009371254541e-7
],
"distance": 18.853169271563594
},
"panned": {
"position": [
-5.273341581654527,
5.082450786888863,
17.990688935160133
],
"target": [
-0.5866856170824521,
2.73698783970429,
-0.11942014831462
],
"distance": 18.85316927156359
},
"focusTargetScreen": [
-5.177525136316571e-19,
-1.227265217497261e-16,
0.9980999049952497
],
"panelModes": [
"timeline",
"blueprint",
"curve",
"console"
],
"logCount": 8,
"stats": {
"objects": "98 节点 / 66 网格",
"triangles": "1,438",
"fps": "54"
},
"scope": "真实鼠标镜头操作;聚焦只验证相机目标;真实30秒自动保存,无测试加速定时器;统计内存估值未当作性能结论。"
}
}

+ 72
- 0
reports/model-editor-closure-20260906/evidence/51-gizmos.json 查看文件

@@ -0,0 +1,72 @@
{
"time": "2026-09-06T08:22:38.815Z",
"data": {
"status": "PASS",
"kind": "e2e+runtime-readback",
"testTitle": "真实三维移动、旋转、缩放手柄拖动及撤销重做保存重开",
"featureIds": [
"view.move",
"view.rotate",
"view.scale"
],
"projectId": "233",
"changes": [
{
"mode": "translate",
"before": [
0,
0,
0
],
"after": [
0.7257266613731312,
0,
0
]
},
{
"mode": "rotate",
"before": [
0,
0,
0
],
"after": [
-1.194547194225429,
0,
0
]
},
{
"mode": "scale",
"before": [
1,
1,
1
],
"after": [
0.30167729043770014,
1,
1
]
}
],
"reopened": {
"position": [
0.7257266613731312,
0,
0
],
"rotation": [
-1.194547194225429,
0,
0
],
"scale": [
0.30167729043770014,
1,
1
]
}
}
}

+ 15
- 0
reports/model-editor-closure-20260906/evidence/52-leave.json 查看文件

@@ -0,0 +1,15 @@
{
"time": "2026-09-06T08:22:48.155Z",
"data": {
"status": "PASS",
"kind": "e2e+api",
"testTitle": "未保存离开:关闭确认保留工作、保存失败留在原页、重试保存后离开",
"featureIds": [
"project.leave"
],
"projectId": "234",
"closeKeptDraft": true,
"failureKeptDraft": true,
"retriedSavePersisted": true
}
}

+ 17
- 0
reports/model-editor-closure-20260906/evidence/60-project-recovery.json 查看文件

@@ -0,0 +1,17 @@
{
"time": "2026-09-06T08:24:07.184Z",
"data": {
"status": "PASS",
"kind": "e2e+api",
"testTitle": "真实未保存稿同版本恢复并显式保存;旧版本恢复稿下载隔离保留",
"featureIds": [
"project.recovery"
],
"projectId": "238",
"sameVersion": 1,
"explicitSaveVersion": 2,
"concurrentVersion": 3,
"retainedFilename": "recovery-238-isolated.json",
"scope": "通过真实beforeunload创建未保存稿;同版恢复后仅显式保存落库;旧版只下载隔离,不自动覆盖服务端。丢弃/跨标签竞态另由既有恢复合同测试覆盖。"
}
}

+ 16
- 0
reports/model-editor-closure-20260906/evidence/63-loading-publish-preflight.json 查看文件

@@ -0,0 +1,16 @@
{
"time": "2026-09-06T08:24:17.025Z",
"data": {
"status": "PASS",
"kind": "e2e+api",
"testTitle": "受控 GLB 下载失败阻止编辑,重试成功;发布预检开关无写入且拒绝错误资源 JSON",
"featureIds": [
"resource.loading",
"publish.preflight"
],
"projectId": "239",
"failedDownloads": 1,
"retainedVersion": 1,
"scope": "真实受控下载定向503→中性失败与禁止编辑→解除故障后UI重试成功;预检面板开关不写项目,错误资源JSON在替换当前模型之前被拒绝。服务端发布时code/URI一致性拒绝由ContentProjectServiceTest合同回归覆盖,未把面板绿标代替服务端校验。"
}
}

+ 17
- 0
reports/model-editor-closure-20260906/evidence/new-project.json 查看文件

@@ -0,0 +1,17 @@
{
"time": "2026-09-06T08:22:24.723Z",
"data": {
"status": "PASS",
"kind": "e2e+api",
"testTitle": "新建工程取消及失败保留输入;成功创建新ID且不覆盖当前模型",
"featureIds": [
"project.new"
],
"oldId": "168",
"newId": "232",
"cancelPreserved": true,
"failureRetainedName": true,
"originalVersion": 17,
"sourceUnchanged": true
}
}

+ 18
- 0
reports/model-editor-closure-20260906/evidence/permissions.json 查看文件

@@ -0,0 +1,18 @@
{
"time": "2026-09-06T08:22:29.489Z",
"data": {
"status": "PASS",
"kind": "e2e+api",
"testTitle": "管理员只读权限:编辑、新建、导入、保存发布均不可越权",
"featureIds": [
"project.permissions"
],
"scope": "管理员只读UI、真实键盘搜索、原生片段切换与Enter播放/暂停、预览无内容写请求及创建403;纯publisher无需update的发布流程由独立权限合同回归补充。",
"readonlyUi": true,
"readonlySearch": true,
"nativeClipChanged": true,
"keyboardPreview": true,
"previewWriteRequests": 0,
"createStatus": 403
}
}

+ 56
- 0
reports/model-editor-closure-20260906/evidence/properties.json 查看文件

@@ -0,0 +1,56 @@
{
"time": "2026-09-06T08:21:58.738Z",
"data": {
"status": "PASS",
"kind": "e2e+api",
"testTitle": "对象名称、变换、PBR、属性与扩展标记保存重开;撤销重做",
"featureIds": [
"property.name",
"property.position",
"property.rotation",
"property.scale",
"property.color",
"property.metalness",
"property.roughness",
"property.opacity",
"property.code",
"property.status",
"component.tag",
"project.undo",
"project.redo",
"project.save"
],
"scope": "真实属性输入/材质参数/标签、保存与刷新;变换只验数值输入,不代替三维 gizmo 拖动。",
"state": {
"id": "model-imported-model_mto6v5w6_09-fox-26",
"position": [
1.25,
0,
0
],
"rotation": [
0,
0.2617993877991494,
0
],
"scale": [
1,
1,
1.1
],
"customProperties": {
"resourceCode": "CLOSURE-FOX-001",
"operatingStatus": "SERVICE"
},
"customComponents": [
"扩展标记 1",
"扩展标记 2",
"扩展标记 3",
"扩展标记 4",
"扩展标记 5"
]
},
"serverVersion": 15,
"persisted": true
}
}

+ 327
- 0
reports/model-editor-closure-20260906/evidence/truck-blueprint-events.json 查看文件

@@ -0,0 +1,327 @@
{
"time": "2026-09-06T08:21:50.227Z",
"data": {
"status": "PASS",
"kind": "e2e",
"testTitle": "已保存蓝图:条件出口与目标匹配 runtime 检查,真实模型单击/双击/进入预览自动触发",
"featureIds": [
"blueprint.click",
"blueprint.double-click",
"blueprint.auto",
"view.preview"
],
"projectId": "169",
"runtimeSupplement": {
"status": "PASS",
"kind": "runtime",
"featureIds": [
"blueprint.condition"
],
"branches": {
"falseBranch": {
"result": true,
"visitedFinish": false,
"logs": [
{
"time": "16:21:41",
"message": "开始执行 · 闭环-条件判断",
"level": "run",
"nodeId": "node-mtpjlz9t-p124m"
},
{
"time": "16:21:41",
"message": "执行节点:闭环-条件判断",
"level": "run",
"nodeId": "node-mtpjlz9t-p124m"
},
{
"time": "16:21:41",
"message": "条件结果:否 / FALSE",
"level": "warning",
"nodeId": "node-mtpjlz9t-p124m"
},
{
"time": "16:21:41",
"message": "节点“闭环-条件判断”没有后续连线,流程结束",
"level": "warning",
"nodeId": "node-mtpjlz9t-p124m"
},
{
"time": "16:21:41",
"message": "蓝图执行完成 · 1 个节点",
"level": "success",
"nodeId": null
}
]
},
"trueBranch": {
"result": true,
"visitedFinish": true,
"logs": [
{
"time": "16:21:41",
"message": "开始执行 · 闭环-条件判断",
"level": "run",
"nodeId": "node-mtpjlz9t-p124m"
},
{
"time": "16:21:41",
"message": "执行节点:闭环-条件判断",
"level": "run",
"nodeId": "node-mtpjlz9t-p124m"
},
{
"time": "16:21:41",
"message": "条件结果:是 / TRUE",
"level": "success",
"nodeId": "node-mtpjlz9t-p124m"
},
{
"time": "16:21:41",
"message": "执行节点:闭环-流程完成",
"level": "run",
"nodeId": "node-mtpjlznf-cxlzk"
},
{
"time": "16:21:41",
"message": "蓝图执行完成 · 2 个节点",
"level": "success",
"nodeId": null
}
]
}
},
"mismatch": {
"result": false,
"started": false
}
},
"browserEvents": [
{
"event": "click",
"starts": 1,
"finished": true,
"source": "真实 renderer canvas 指针事件",
"logs": [
{
"time": "16:21:42",
"message": "运行状态已重置",
"level": "system",
"nodeId": null
},
{
"time": "16:21:42",
"message": "开始执行 · 闭环-点击触发",
"level": "run",
"nodeId": "node-mtpjlx7c-sgcyx"
},
{
"time": "16:21:42",
"message": "执行节点:闭环-点击触发",
"level": "run",
"nodeId": "node-mtpjlx7c-sgcyx"
},
{
"time": "16:21:42",
"message": "执行节点:闭环-播放时间轴",
"level": "run",
"nodeId": "node-mtpjlxj9-y3g3v"
},
{
"time": "16:21:42",
"message": "执行节点:闭环-等待",
"level": "run",
"nodeId": "node-mtpjlxxe-ond97"
},
{
"time": "16:21:42",
"message": "执行节点:闭环-高亮部件",
"level": "run",
"nodeId": "node-mtpjlyci-4c5oi"
},
{
"time": "16:21:42",
"message": "执行节点:闭环-操作提示",
"level": "run",
"nodeId": "node-mtpjlyuw-164xj"
},
{
"time": "16:21:43",
"message": "执行节点:闭环-条件判断",
"level": "run",
"nodeId": "node-mtpjlz9t-p124m"
},
{
"time": "16:21:43",
"message": "条件结果:是 / TRUE",
"level": "success",
"nodeId": "node-mtpjlz9t-p124m"
},
{
"time": "16:21:43",
"message": "执行节点:闭环-流程完成",
"level": "run",
"nodeId": "node-mtpjlznf-cxlzk"
},
{
"time": "16:21:43",
"message": "蓝图执行完成 · 7 个节点",
"level": "success",
"nodeId": null
}
]
},
{
"event": "double-click",
"starts": 1,
"finished": true,
"source": "真实 renderer canvas 指针事件",
"logs": [
{
"time": "16:21:43",
"message": "运行状态已重置",
"level": "system",
"nodeId": null
},
{
"time": "16:21:44",
"message": "开始执行 · 闭环-点击触发",
"level": "run",
"nodeId": "node-mtpjlx7c-sgcyx"
},
{
"time": "16:21:44",
"message": "执行节点:闭环-点击触发",
"level": "run",
"nodeId": "node-mtpjlx7c-sgcyx"
},
{
"time": "16:21:44",
"message": "执行节点:闭环-播放时间轴",
"level": "run",
"nodeId": "node-mtpjlxj9-y3g3v"
},
{
"time": "16:21:44",
"message": "执行节点:闭环-等待",
"level": "run",
"nodeId": "node-mtpjlxxe-ond97"
},
{
"time": "16:21:44",
"message": "执行节点:闭环-高亮部件",
"level": "run",
"nodeId": "node-mtpjlyci-4c5oi"
},
{
"time": "16:21:44",
"message": "执行节点:闭环-操作提示",
"level": "run",
"nodeId": "node-mtpjlyuw-164xj"
},
{
"time": "16:21:45",
"message": "执行节点:闭环-条件判断",
"level": "run",
"nodeId": "node-mtpjlz9t-p124m"
},
{
"time": "16:21:45",
"message": "条件结果:是 / TRUE",
"level": "success",
"nodeId": "node-mtpjlz9t-p124m"
},
{
"time": "16:21:45",
"message": "执行节点:闭环-流程完成",
"level": "run",
"nodeId": "node-mtpjlznf-cxlzk"
},
{
"time": "16:21:45",
"message": "蓝图执行完成 · 7 个节点",
"level": "success",
"nodeId": null
}
]
},
{
"event": "auto",
"starts": 1,
"finished": true,
"source": "真实点击进入预览",
"logs": [
{
"time": "16:21:45",
"message": "运行状态已重置",
"level": "system",
"nodeId": null
},
{
"time": "16:21:45",
"message": "开始执行 · 闭环-点击触发",
"level": "run",
"nodeId": "node-mtpjlx7c-sgcyx"
},
{
"time": "16:21:45",
"message": "执行节点:闭环-点击触发",
"level": "run",
"nodeId": "node-mtpjlx7c-sgcyx"
},
{
"time": "16:21:45",
"message": "执行节点:闭环-播放时间轴",
"level": "run",
"nodeId": "node-mtpjlxj9-y3g3v"
},
{
"time": "16:21:45",
"message": "执行节点:闭环-等待",
"level": "run",
"nodeId": "node-mtpjlxxe-ond97"
},
{
"time": "16:21:45",
"message": "执行节点:闭环-高亮部件",
"level": "run",
"nodeId": "node-mtpjlyci-4c5oi"
},
{
"time": "16:21:46",
"message": "执行节点:闭环-操作提示",
"level": "run",
"nodeId": "node-mtpjlyuw-164xj"
},
{
"time": "16:21:46",
"message": "执行节点:闭环-条件判断",
"level": "run",
"nodeId": "node-mtpjlz9t-p124m"
},
{
"time": "16:21:46",
"message": "条件结果:是 / TRUE",
"level": "success",
"nodeId": "node-mtpjlz9t-p124m"
},
{
"time": "16:21:46",
"message": "执行节点:闭环-流程完成",
"level": "run",
"nodeId": "node-mtpjlznf-cxlzk"
},
{
"time": "16:21:46",
"message": "蓝图执行完成 · 7 个节点",
"level": "success",
"nodeId": null
}
]
}
],
"persistedNodeCount": 7,
"persistedEdgeCount": 6,
"scope": "执行使用正式模型编辑器的真实模型/时间轴/高亮/提示 handler;不等同于学员端任务下发。"
}
}

+ 697
- 0
reports/model-editor-closure-20260906/evidence/truck-blueprint-tool-supplement.json 查看文件

@@ -0,0 +1,697 @@
{
"time": "2026-09-06T08:21:23.003Z",
"data": {
"status": "PASS",
"kind": "e2e+runtime-read",
"testTitle": "补充时间轴与蓝图工具:刻度/按键/记录/分量、基准匹配、节点搜索拖入与画布平移",
"featureIds": [
"timeline.seek",
"timeline.record",
"timeline.baseline",
"curve.axis",
"blueprint.palette",
"blueprint.add",
"blueprint.canvas"
],
"projectIds": [
"230",
"231"
],
"pose": {
"time": 0.9666666666666666,
"value": [
2.4166666666666665,
-0.9666666666666666,
0
],
"actual": [
2.4166666666666665,
-0.9666666666666666,
0
],
"base": [
0,
0,
0
]
},
"recorded": {
"id": "key-u60x1lh",
"time": 0.9666666666666666,
"value": [
2.4166666666666665,
-0.9666666666666666,
0
],
"easing": "easeInOut"
},
"curveAxis": {
"xAndYPathsDiffer": true,
"values": [
5,
-2,
0
]
},
"noMatchPreserved": true,
"baseline": {
"name": "闭环工具补充-基准匹配-mtpjlmiy",
"timeline": {
"version": 1,
"duration": 12,
"currentTime": 0,
"loop": true,
"zoom": 1,
"tracks": [
{
"id": "bridge-front-outrigger-drop",
"name": "前支腿下落支撑",
"targetId": "bridge-front-outrigger",
"property": "position",
"color": "#ffd166",
"muted": false,
"keyframes": [
{
"id": "bfo-k0",
"time": 0,
"value": [
0,
0,
0
],
"easing": "easeInOut"
},
{
"id": "bfo-k1",
"time": 2.4,
"value": [
0,
-0.45,
0
],
"easing": "easeInOut"
},
{
"id": "bfo-k2",
"time": 10,
"value": [
0,
-0.45,
0
],
"easing": "linear"
},
{
"id": "bfo-k3",
"time": 12,
"value": [
0,
0,
0
],
"easing": "easeInOut"
}
]
},
{
"id": "bridge-rear-outrigger-drop",
"name": "后支腿下落支撑",
"targetId": "bridge-rear-outrigger",
"property": "position",
"color": "#f4a261",
"muted": false,
"keyframes": [
{
"id": "bro-k0",
"time": 0,
"value": [
0,
0,
0
],
"easing": "easeInOut"
},
{
"id": "bro-k1",
"time": 2.2,
"value": [
0,
-0.19,
0
],
"easing": "easeInOut"
},
{
"id": "bro-k2",
"time": 10,
"value": [
0,
-0.19,
0
],
"easing": "linear"
},
{
"id": "bro-k3",
"time": 12,
"value": [
0,
0,
0
],
"easing": "easeInOut"
}
]
},
{
"id": "bridge-rear-support-drop",
"name": "后支座下落支撑",
"targetId": "bridge-rear-support",
"property": "position",
"color": "#e76f51",
"muted": false,
"keyframes": [
{
"id": "brs-k0",
"time": 0,
"value": [
0,
0,
0
],
"easing": "easeInOut"
},
{
"id": "brs-k1",
"time": 0.4,
"value": [
0,
0,
0
],
"easing": "easeInOut"
},
{
"id": "brs-k2",
"time": 2.6,
"value": [
0,
-0.25,
0
],
"easing": "easeInOut"
},
{
"id": "brs-k3",
"time": 10.2,
"value": [
0,
-0.25,
0
],
"easing": "linear"
},
{
"id": "brs-k4",
"time": 12,
"value": [
0,
0,
0
],
"easing": "easeInOut"
}
]
},
{
"id": "bridge-gantry-slew",
"name": "回转门架回转",
"targetId": "bridge-gantry",
"property": "rotation.y",
"color": "#2a9d8f",
"muted": false,
"keyframes": [
{
"id": "bgs-k0",
"time": 0,
"value": 0,
"easing": "easeInOut"
},
{
"id": "bgs-k1",
"time": 2.2,
"value": 0,
"easing": "easeInOut"
},
{
"id": "bgs-k2",
"time": 4.8,
"value": 0.24,
"easing": "easeInOut"
},
{
"id": "bgs-k3",
"time": 8.6,
"value": 0.24,
"easing": "linear"
},
{
"id": "bgs-k4",
"time": 11.4,
"value": 0,
"easing": "easeInOut"
},
{
"id": "bgs-k5",
"time": 12,
"value": 0,
"easing": "easeInOut"
}
]
},
{
"id": "bridge-gantry-upper-luffing",
"name": "门架上臂变幅",
"targetId": "bridge-gantry-upper",
"property": "rotation.x",
"color": "#8a68e8",
"muted": false,
"keyframes": [
{
"id": "bgu-k0",
"time": 0,
"value": 0,
"easing": "easeInOut"
},
{
"id": "bgu-k1",
"time": 3,
"value": 0,
"easing": "easeInOut"
},
{
"id": "bgu-k2",
"time": 5.4,
"value": -0.22,
"easing": "easeInOut"
},
{
"id": "bgu-k3",
"time": 8.8,
"value": -0.22,
"easing": "linear"
},
{
"id": "bgu-k4",
"time": 11.2,
"value": 0,
"easing": "easeInOut"
},
{
"id": "bgu-k5",
"time": 12,
"value": 0,
"easing": "easeInOut"
}
]
},
{
"id": "bridge-erection-frame-luffing",
"name": "后架设架起落(抬头 → 落桥)",
"targetId": "bridge-erection-frame",
"property": "rotation.x",
"color": "#4cc9f0",
"muted": false,
"keyframes": [
{
"id": "bef-k0",
"time": 0,
"value": 0,
"easing": "easeInOut"
},
{
"id": "bef-k1",
"time": 3.6,
"value": 0,
"easing": "easeInOut"
},
{
"id": "bef-k2",
"time": 5,
"value": -0.07,
"easing": "easeInOut"
},
{
"id": "bef-k3",
"time": 7.8,
"value": 0.2,
"easing": "easeInOut"
},
{
"id": "bef-k4",
"time": 9.8,
"value": 0.2,
"easing": "linear"
},
{
"id": "bef-k5",
"time": 11.6,
"value": 0,
"easing": "easeInOut"
},
{
"id": "bef-k6",
"time": 12,
"value": 0,
"easing": "easeInOut"
}
]
},
{
"id": "bridge-luffing-cylinder-follow",
"name": "变幅缸随动",
"targetId": "bridge-luffing-cylinder",
"property": "rotation.x",
"color": "#90be6d",
"muted": false,
"keyframes": [
{
"id": "blc-k0",
"time": 0,
"value": 0,
"easing": "easeInOut"
},
{
"id": "blc-k1",
"time": 3.6,
"value": 0,
"easing": "easeInOut"
},
{
"id": "blc-k2",
"time": 5,
"value": -0.03,
"easing": "easeInOut"
},
{
"id": "blc-k3",
"time": 7.8,
"value": 0.09,
"easing": "easeInOut"
},
{
"id": "blc-k4",
"time": 9.8,
"value": 0.09,
"easing": "linear"
},
{
"id": "blc-k5",
"time": 11.6,
"value": 0,
"easing": "easeInOut"
},
{
"id": "blc-k6",
"time": 12,
"value": 0,
"easing": "easeInOut"
}
]
},
{
"id": "bridge-carriage-travel",
"name": "移动架沿滑道后行",
"targetId": "bridge-carriage",
"property": "position",
"color": "#32b8e6",
"muted": false,
"keyframes": [
{
"id": "bct-k0",
"time": 0,
"value": [
0,
0,
0
],
"easing": "easeInOut"
},
{
"id": "bct-k1",
"time": 5.4,
"value": [
0,
0,
0
],
"easing": "easeInOut"
},
{
"id": "bct-k2",
"time": 8.4,
"value": [
0,
0,
-0.42
],
"easing": "easeInOut"
},
{
"id": "bct-k3",
"time": 10,
"value": [
0,
0,
-0.42
],
"easing": "linear"
},
{
"id": "bct-k4",
"time": 12,
"value": [
0,
0,
0
],
"easing": "easeInOut"
}
]
},
{
"id": "bridge-launch-pinion-drive",
"name": "导梁销齿轮驱动",
"targetId": "bridge-launch-pinion",
"property": "rotation.x",
"color": "#f9c74f",
"muted": false,
"keyframes": [
{
"id": "blp-k0",
"time": 0,
"value": 0,
"easing": "linear"
},
{
"id": "blp-k1",
"time": 5.4,
"value": 0,
"easing": "linear"
},
{
"id": "blp-k2",
"time": 8.4,
"value": 5.2,
"easing": "linear"
},
{
"id": "blp-k3",
"time": 10,
"value": 5.2,
"easing": "linear"
},
{
"id": "blp-k4",
"time": 12,
"value": 0,
"easing": "linear"
}
]
},
{
"id": "bridge-front-cradle-luffing",
"name": "前托架抬头",
"targetId": "bridge-front-cradle",
"property": "rotation.x",
"color": "#ff9f2f",
"muted": false,
"keyframes": [
{
"id": "bfc-k0",
"time": 0,
"value": 0,
"easing": "easeInOut"
},
{
"id": "bfc-k1",
"time": 6.8,
"value": 0,
"easing": "easeInOut"
},
{
"id": "bfc-k2",
"time": 9,
"value": 0.12,
"easing": "easeInOut"
},
{
"id": "bfc-k3",
"time": 10.4,
"value": 0.12,
"easing": "linear"
},
{
"id": "bfc-k4",
"time": 11.8,
"value": 0,
"easing": "easeInOut"
},
{
"id": "bfc-k5",
"time": 12,
"value": 0,
"easing": "easeInOut"
}
]
},
{
"id": "bridge-front-pusher-extend",
"name": "前推送装置送桥",
"targetId": "bridge-front-pusher",
"property": "position",
"color": "#ef476f",
"muted": false,
"keyframes": [
{
"id": "bfp-k0",
"time": 0,
"value": [
0,
0,
0
],
"easing": "easeInOut"
},
{
"id": "bfp-k1",
"time": 7.2,
"value": [
0,
0,
0
],
"easing": "easeInOut"
},
{
"id": "bfp-k2",
"time": 9.4,
"value": [
0,
0,
0.34
],
"easing": "easeInOut"
},
{
"id": "bfp-k3",
"time": 10.6,
"value": [
0,
0,
0.34
],
"easing": "linear"
},
{
"id": "bfp-k4",
"time": 12,
"value": [
0,
0,
0
],
"easing": "easeInOut"
}
]
},
{
"id": "bridge-feed-pinion-drive",
"name": "前推送销齿轮驱动",
"targetId": "bridge-feed-pinion",
"property": "rotation.x",
"color": "#c77dff",
"muted": false,
"keyframes": [
{
"id": "bfd-k0",
"time": 0,
"value": 0,
"easing": "linear"
},
{
"id": "bfd-k1",
"time": 7.2,
"value": 0,
"easing": "linear"
},
{
"id": "bfd-k2",
"time": 9.4,
"value": 4,
"easing": "linear"
},
{
"id": "bfd-k3",
"time": 10.6,
"value": 4,
"easing": "linear"
},
{
"id": "bfd-k4",
"time": 12,
"value": 0,
"easing": "linear"
}
]
}
]
},
"resolved": true
},
"addedNode": {
"id": "node-mtpjlj3c-n13gc",
"type": "message",
"title": "操作提示",
"x": 440,
"y": 160,
"params": {
"title": "操作提示",
"text": "请观察铲斗与动臂的联动过程",
"level": "info"
}
},
"draggedNode": {
"id": "node-mtpjlj9e-sko2s",
"type": "wait",
"title": "等待",
"x": -40,
"y": -170,
"params": {
"duration": 600
}
},
"canvasPreservedGraph": true,
"scope": "真实模型编辑参数/基准轨道生成验收,不构成装备操作或维修指导。桥梁原工程94仅GET和copy。"
}
}

+ 259
- 0
reports/model-editor-closure-20260906/evidence/truck-blueprint-ui.json 查看文件

@@ -0,0 +1,259 @@
{
"time": "2026-09-06T08:21:37.144Z",
"data": {
"status": "PASS",
"kind": "e2e+runtime-read",
"testTitle": "蓝图真实节点库与端口拖线:七种参数、内部边复制/剪切、撤销重做及保存",
"featureIds": [
"blueprint.parameters",
"blueprint.move",
"blueprint.connect",
"blueprint.delete",
"blueprint.copy",
"blueprint.run",
"blueprint.stop",
"blueprint.reset",
"blueprint.timeline",
"blueprint.wait",
"blueprint.highlight",
"blueprint.message",
"blueprint.finish",
"project.undo",
"project.redo"
],
"scope": "节点库点选添加及实际拖动/接线/执行;不把点选当成节点拖入,不把适应画布当成鼠标平移缩放全部已验。",
"projectId": "169",
"graph": {
"nodes": [
{
"id": "node-mtpjlx7c-sgcyx",
"type": "trigger-click",
"title": "闭环-点击触发",
"x": 160,
"y": -120,
"params": {
"event": "click",
"target": "model-imported-model_mto6wi6k_08-cesiummilktruck-3"
}
},
{
"id": "node-mtpjlxj9-y3g3v",
"type": "play-timeline",
"title": "闭环-播放时间轴",
"x": 420,
"y": -120,
"params": {
"clip": "牛奶卡车曲线联动",
"from": 8,
"speed": 2,
"waitForEnd": true
}
},
{
"id": "node-mtpjlxxe-ond97",
"type": "wait",
"title": "闭环-等待",
"x": 680,
"y": -120,
"params": {
"duration": 100
}
},
{
"id": "node-mtpjlyci-4c5oi",
"type": "highlight",
"title": "闭环-高亮部件",
"x": 160,
"y": 70,
"params": {
"target": "model-imported-model_mto6wi6k_08-cesiummilktruck-3",
"color": "#ff8800",
"pulse": false
}
},
{
"id": "node-mtpjlyuw-164xj",
"type": "message",
"title": "闭环-操作提示",
"x": 420,
"y": 70,
"params": {
"title": "卡车模型闭环提示",
"text": "检查真实目标高亮、时间轴完成和条件出口。",
"level": "success"
}
},
{
"id": "node-mtpjlz9t-p124m",
"type": "condition",
"title": "闭环-条件判断",
"x": 680,
"y": 70,
"params": {
"variable": "timelineComplete",
"operator": "==",
"value": true
}
},
{
"id": "node-mtpjlznf-cxlzk",
"type": "finish",
"title": "闭环-流程完成",
"x": 420,
"y": 260,
"params": {
"result": "success",
"text": "牛奶卡车蓝图验证完成"
}
}
],
"edges": [
{
"id": "edge-mtpjm04u-tt0qb",
"from": {
"node": "node-mtpjlx7c-sgcyx",
"port": "then"
},
"to": {
"node": "node-mtpjlxj9-y3g3v",
"port": "in"
}
},
{
"id": "edge-mtpjm0bc-mnf7c",
"from": {
"node": "node-mtpjlxj9-y3g3v",
"port": "then"
},
"to": {
"node": "node-mtpjlxxe-ond97",
"port": "in"
}
},
{
"id": "edge-mtpjm0gx-mu6ys",
"from": {
"node": "node-mtpjlxxe-ond97",
"port": "then"
},
"to": {
"node": "node-mtpjlyci-4c5oi",
"port": "in"
}
},
{
"id": "edge-mtpjm0nr-y06n7",
"from": {
"node": "node-mtpjlyci-4c5oi",
"port": "then"
},
"to": {
"node": "node-mtpjlyuw-164xj",
"port": "in"
}
},
{
"id": "edge-mtpjm0ts-px732",
"from": {
"node": "node-mtpjlyuw-164xj",
"port": "then"
},
"to": {
"node": "node-mtpjlz9t-p124m",
"port": "in"
}
},
{
"id": "edge-mtpjm0zf-sa3h2",
"from": {
"node": "node-mtpjlz9t-p124m",
"port": "true"
},
"to": {
"node": "node-mtpjlznf-cxlzk",
"port": "in"
}
}
],
"running": false,
"logs": [
{
"time": "16:21:35",
"message": "运行状态已重置",
"level": "system",
"nodeId": null
}
]
},
"completedLog": [
{
"time": "16:21:25",
"message": "蓝图编辑器就绪 · 7 类节点已加载",
"level": "system",
"nodeId": null
},
{
"time": "16:21:33",
"message": "开始执行 · 闭环-点击触发",
"level": "run",
"nodeId": "node-mtpjlx7c-sgcyx"
},
{
"time": "16:21:33",
"message": "执行节点:闭环-点击触发",
"level": "run",
"nodeId": "node-mtpjlx7c-sgcyx"
},
{
"time": "16:21:33",
"message": "执行节点:闭环-播放时间轴",
"level": "run",
"nodeId": "node-mtpjlxj9-y3g3v"
},
{
"time": "16:21:33",
"message": "执行节点:闭环-等待",
"level": "run",
"nodeId": "node-mtpjlxxe-ond97"
},
{
"time": "16:21:33",
"message": "执行节点:闭环-高亮部件",
"level": "run",
"nodeId": "node-mtpjlyci-4c5oi"
},
{
"time": "16:21:34",
"message": "执行节点:闭环-操作提示",
"level": "run",
"nodeId": "node-mtpjlyuw-164xj"
},
{
"time": "16:21:35",
"message": "执行节点:闭环-条件判断",
"level": "run",
"nodeId": "node-mtpjlz9t-p124m"
},
{
"time": "16:21:35",
"message": "条件结果:是 / TRUE",
"level": "success",
"nodeId": "node-mtpjlz9t-p124m"
},
{
"time": "16:21:35",
"message": "执行节点:闭环-流程完成",
"level": "run",
"nodeId": "node-mtpjlznf-cxlzk"
},
{
"time": "16:21:35",
"message": "蓝图执行完成 · 7 个节点",
"level": "success",
"nodeId": null
}
],
"actions": "真实节点库/参数控件/端口拖线/复制剪切粘贴/删除/撤销重做/运行停止重置/保存",
"boundaries": "200 步循环保护由独立 Node 回归覆盖;本浏览器流程不注入假图或替换执行 handler。"
}
}

+ 81
- 0
reports/model-editor-closure-20260906/evidence/truck-timeline-curve.json 查看文件

@@ -0,0 +1,81 @@
{
"time": "2026-09-06T08:21:02.898Z",
"data": {
"status": "PASS",
"kind": "e2e+runtime-read",
"testTitle": "时间轴真实控件:轨道/关键帧/播放与曲线 5 插值,保存后重新加载一致",
"featureIds": [
"timeline.play",
"timeline.stop",
"timeline.loop",
"timeline.key-nav",
"timeline.add-track",
"timeline.remove-track",
"timeline.target",
"timeline.property",
"timeline.mute",
"timeline.add-key",
"timeline.delete-key",
"timeline.drag-key",
"timeline.zoom",
"timeline.curve",
"curve.time",
"curve.value",
"curve.easing"
],
"scope": "真实控件和指针操作,运行时读取数值校验;curve.axis仅切换无数值独立断言,timeline.seek播放头与Alt吸附未在本例覆盖。",
"projectId": "169",
"actions": "真实 DOM 轨道/帧增删、关键帧指针拖移、播放控件、曲线输入和保存重开",
"restored": {
"id": "track-0-che4ljm",
"name": "新轨道 6",
"targetId": "interaction-5f7e4bee",
"property": "position",
"color": "#ffb22e",
"muted": false,
"keyframes": [
{
"id": "key-0-0-mi1ztwf",
"time": 0,
"value": [
0,
0,
0
],
"easing": "easeInOut"
},
{
"id": "key-zi8i3f7",
"time": 2,
"value": [
5,
0,
0
],
"easing": "easeInOut"
},
{
"id": "key-0-1-2lnk2wi",
"time": 8,
"value": [
0,
0,
0
],
"easing": "easeInOut"
}
]
},
"interpolationSamples": {
"linear": 1.25,
"easeInOut": 0.625,
"easeIn": 0.3125,
"easeOut": 2.1875,
"step": 0
},
"excluded": [
"未新增 solo 能力",
"未将原生 GLB 动画片段当成多条编辑时间轴"
]
}
}

+ 26
- 0
reports/model-editor-closure-20260906/evidence/viewport.json 查看文件

@@ -0,0 +1,26 @@
{
"time": "2026-09-06T08:22:14.169Z",
"data": {
"status": "PASS",
"kind": "e2e",
"testTitle": "场景树搜索、可见性、选择、视口工具、原生动画与截图",
"featureIds": [
"tree.search",
"tree.visibility",
"selection.sync",
"view.grid",
"view.pbr",
"view.wireframe",
"view.outline",
"view.perspective",
"view.preview",
"view.snapshot",
"timeline.native"
],
"scope": "树搜索、对象隐藏刷新、轮廓及视图开关、原生动画和PNG下载。移动/旋转/缩放只切换模式,真实gizmo拖动仍需补验;聚焦未做几何断言。",
"clips": 3,
"nativeClipPersisted": true,
"hiddenObjectPersisted": true,
"snapshot": "装备模型编辑工具_1788682931740.png"
}
}

+ 1447
- 0
reports/model-editor-closure-20260906/feature-catalog.json
文件差异内容过多而无法显示
查看文件


+ 2624
- 0
reports/model-editor-closure-20260906/index.html
文件差异内容过多而无法显示
查看文件


二进制
查看文件


二进制
查看文件


二进制
查看文件


二进制
查看文件


二进制
查看文件


二进制
查看文件


二进制
查看文件


二进制
查看文件


二进制
查看文件


二进制
查看文件


二进制
查看文件


二进制
查看文件


二进制
查看文件


二进制
查看文件


二进制
查看文件


二进制
查看文件


二进制
查看文件


二进制
查看文件


二进制
查看文件


二进制
查看文件


二进制
查看文件


二进制
查看文件


二进制
查看文件


二进制
查看文件


二进制
查看文件


二进制
查看文件


二进制
查看文件


二进制
查看文件


二进制
查看文件


二进制
查看文件


二进制
查看文件


二进制
查看文件


二进制
查看文件


二进制
查看文件


二进制
查看文件


二进制
查看文件


二进制
查看文件


二进制
查看文件


二进制
查看文件


二进制
查看文件


+ 76
- 0
reports/model-editor-closure-20260906/playwright/index.html
文件差异内容过多而无法显示
查看文件


+ 1473
- 0
reports/model-editor-closure-20260906/results.json
文件差异内容过多而无法显示
查看文件


+ 100
- 0
reports/model-editor-closure-20260906/run-history.json 查看文件

@@ -0,0 +1,100 @@
{
"time": "2026-09-06T08:13:36.256Z",
"kind": "historical-runs",
"scope": "仅保留安全的次数、名称、时间及源文件哈希;不复制请求正文、会话、错误上下文或私有运行日志。历史轮次不替代当前 results.json,定向2/2不等同全量19/19。",
"runs": [
{
"name": "全量首轮",
"outcome": "FAIL",
"startedAt": "2026-09-06T07:23:31.420Z",
"tests": 19,
"passed": 17,
"failed": 2,
"skipped": 0,
"sourceSha256": "21e9e8a824ba988682ee2eb5edcbb35f2b3a97be4f86ad63353c535922aac22b",
"sourceDescription": "私有归档的首轮 Playwright JSON",
"cases": [
{
"title": "未保存离开:关闭确认保留工作、保存失败留在原页、重试保存后离开",
"outcome": "FAIL",
"startTime": "2026-09-06T07:27:01.902Z",
"httpStatus": 503,
"sourceLocation": {
"file": "tests/model-editor-interaction-closure.spec.ts",
"line": 114,
"column": 41
},
"request": {
"method": "GET",
"route": "/api/tran/v1/content/projects/{id}"
},
"stage": "保存完成并返回模型列表后,由测试辅助函数读取项目详情核验",
"note": "界面已返回列表;失败发生于末尾GET详情的状态码断言,不是进入用例登录失败,也不是测试有意注入的保存503。"
},
{
"title": "补充环境与树:内置三环境保存重开、节点计数与折叠展开",
"outcome": "FAIL",
"startTime": "2026-09-06T07:27:31.096Z",
"httpStatus": 503,
"sourceLocation": {
"file": "tests/model-editor-navigation-closure.spec.ts",
"line": 142,
"column": 49
},
"request": {
"method": "GET",
"route": "/api/tran/v1/content/projects/{id}"
},
"stage": "保存完成并返回模型列表后,由测试辅助函数读取项目详情核验",
"note": "界面已返回列表;失败发生于末尾GET详情的状态码断言,不是进入用例登录失败,也不是测试有意注入的保存503。"
}
],
"note": "两例均已完成保存并返回列表,末尾测试辅助GET项目详情返回503;分别定位 interaction:114 与 navigation:142。"
},
{
"name": "首次鉴权诊断定向重跑",
"outcome": "FAIL",
"tests": 2,
"passed": 0,
"failed": 2,
"sourceSha256": "2c66d00995fa4c69ad12b7fb2e3f367b9d7216eb4a2f283e883c560ac38fc573",
"sourceDescription": "私有定向运行日志,仅提取计数及调用阶段",
"stage": "测试signIn→login请求达到30秒超时",
"note": "此轮才在登录阶段超时,业务操作未开始;不与首轮末尾GET详情503混为同一发生阶段。"
},
{
"name": "后续定向重跑",
"outcome": "PASS",
"tests": 2,
"passed": 2,
"failed": 0,
"sourceSha256": "58711f5c450de4fd85845ec7e2a698fbb5faf01ad3258654ca74964b9e0462b1",
"sourceDescription": "私有定向运行日志,匹配原两个失败标题",
"cases": [
{
"title": "未保存离开:关闭确认保留工作、保存失败留在原页、重试保存后离开",
"outcome": "PASS"
},
{
"title": "补充环境与树:内置三环境保存重开、节点计数与折叠展开",
"outcome": "PASS"
}
],
"note": "只证明这两条在此次运行通过,不能把首轮17/19改写为19/19。"
},
{
"name": "修复与曲线配色更新后的最终完整轮",
"outcome": "PASS",
"startedAt": "2026-09-06T08:20:11.525Z",
"tests": 19,
"passed": 19,
"failed": 0,
"skipped": 0,
"durationMs": 246742.013,
"sourceSha256": "f37013658c8c38a5ec5993e636a30ad57eee9d3bcc119650c929952de8d556e9",
"sourceDescription": "当前完整 Playwright JSON;重试次数0,未拼接定向结果"
}
],
"investigation": "已修复 Auth/Tran 数据库连接健康检查可能无界阻塞的问题,并完成实际 Kingbase 驱动隔离黑洞探针(约2010ms释放关闭);最终双模块构建和完整E2E另行记录。该探针不能证明历史每一次503均已逐条与该原因建立因果关联。",
"finalAcceptance": "完成修复后另跑完整19条,使用新的完整results.json、对应时段证据/附件、最终validation及artifact检查;旧失败保留在本历史记录。"
}

+ 43
- 0
reports/model-editor-closure-20260906/screenshot-captions.json 查看文件

@@ -0,0 +1,43 @@
{
"01-components-saved": { "title": "对象属性与扩展标记保存", "description": "通过真实属性控件编辑并保存;新增内容是可持久化的名称标记,不代表组件运行行为已经实现。" },
"02-properties-reopened": { "title": "刷新后的模型属性", "description": "重新加载服务端工程后核对对象名称、变换、首个材质槽、自定义字段和扩展标记;不是仅核对保存提示。" },
"03-fox-preview": { "title": "狐狸模型运行预览", "description": "真实狐狸模型在编辑器预览视口显示。临时网格、线框、透视等视图选项与模型数据保存分开验收。" },
"04-new-retry-dialog": { "title": "新建失败后的重试界面", "description": "定向注入创建请求失败,核对原工程保留及新建表单可重试;该画面不表示开发服务自然发生故障。" },
"05-new-separate-project": { "title": "新建独立模型工程", "description": "新建走真实创建接口并进入新项目 ID,原模型工程没有被清空覆盖。" },
"06-readonly-permissions": { "title": "只读模型入口", "description": "使用本轮实际权限会话检查只读控件及接口拒绝;平台角色名称本身不授予内容写权限。" },
"21-truck-timeline-controls": { "title": "卡车时间轴与部件轨道", "description": "真实轨道增删、目标绑定、播放停止、静音和关键帧操作。当前截图停在零秒;它不表示原生 GLB 动画已经变成多条可编辑时间轴。" },
"22-truck-curve-value-five": { "title": "曲线编辑:部件 X=5 的测试姿态", "description": "将卡车车身部件关键帧 X 改为 5 验证曲线与真实视口联动,因此车身与轮子暂时分离;这是测试姿态,不是模型加载丢失。" },
"23-truck-blueprint-seven-nodes": { "title": "七种蓝图节点与真实端口连线", "description": "节点通过节点库创建,参数使用实际控件编辑,端口通过指针拖线连接;蓝图图数据随后保存重开核对。" },
"24-truck-blueprint-real-message": { "title": "蓝图执行到操作提示", "description": "编辑器真实 handler 驱动时间轴、等待、高亮与提示节点;不是替换 handler 的演示截图。" },
"25-truck-blueprint-completed-log": { "title": "蓝图完成与本次运行日志", "description": "用例检查节点顺序、条件出口和完成事件;右侧日志只记录当前运行,不等同服务端审计或教学成绩。" },
"26-truck-condition-branches-runtime": { "title": "条件真假出口的运行时补充检查", "description": "对已由 UI 创建的图调用运行时接口检查 true/false 与不匹配目标;这张图标记为运行时证据,不能当成纯鼠标 UI 覆盖。" },
"27-truck-preview-click": { "title": "真实单击卡车触发蓝图", "description": "在真实可见网格像素上单击,校验只启动一次且流程完成;没有伪造 trigger 事件。" },
"27-truck-preview-double-click": { "title": "真实双击卡车触发蓝图", "description": "通过 renderer canvas 双击命中真实模型,校验事件匹配与单次执行;避免单击误启动双击/自动触发器。" },
"27-truck-preview-auto": { "title": "进入预览自动触发蓝图", "description": "真实点击进入预览后派发 auto,校验只启动一次;不代表下游场景或训练会自动运行模型蓝图。" },
"28-curve-axis-y-negative": { "title": "曲线分量切换与负值", "description": "在独立卡车副本中设置关键帧 X=5、Y=-2,切换曲线显示分量并比较曲线路径,确认切换视图不修改关键帧数据。车身偏移是特意设置的测试姿态。" },
"29-timeline-seek-record": { "title": "真实刻度定位、方向键与关键帧记录", "description": "通过时间刻度点击/拖动、左右与 Shift 按键定位时间,再用实际关键帧按钮记录当前偏移,核对时间码、关键帧和持久化内容。" },
"30-blueprint-palette-canvas": { "title": "蓝图库搜索、真实拖入与画布操作", "description": "搜索并清空节点库,通过 HTML5 拖放添加节点,核对工具栏默认添加、画布滚轮缩放/平移/适应操作没有意外改变节点图。" },
"31-bridge-baseline-reopened": { "title": "匹配模型的基准时间轴保存重开", "description": "在独立匹配装备副本载入基准动作,核对轨道目标存在、项目名称保留、保存刷新后时间轴一致;不匹配卡车分支另外验证原时间轴未被覆盖。仅验证通用编辑数据,不制作实际维修流程。" },
"30-assets-environment-reopened": { "title": "主狐狸与外部方盒环境同时重开", "description": "狐狸是主模型,旁边方盒是轻量环境 GLB;两者使用独立受控资产引用,刷新后均有真实网格。当前镜头较远,资产身份以随附 API 断言核对。" },
"31-invalid-import-keeps-model": { "title": "无效工程导入保留原模型", "description": "非法 JSON 或无有效受控引用的导入被拒绝;核对原模型与工程内容仍在,没有以默认模型静默替换。" },
"32-save-conflict-keeps-recovery": { "title": "版本冲突阻断保存并保留恢复稿", "description": "通过定向注入 409 验证保存失败分支及恢复数据,不将失败提示本身当成成功保存。" },
"33-save-retry-success": { "title": "保存失败后再次保存成功", "description": "恢复正常请求后点击真实保存。右上红色 409 提示来自上一故障注入步骤,截图时尚在自动消退周期内;本次重试成功由当前 PUT 响应和保存后的刷新断言确认。失败后的旧上传票据不得被误复用。" },
"34-published-current-cover": { "title": "发布版本与当前视口封面", "description": "发布接口、保存版本和受控封面资产一起核对;封面来自当前三维视口。下载后的下游资源验证不等于下游自动执行蓝图。" },
"35-offline-step-demo-actual-file": { "title": "实际下载的步骤演示 HTML", "description": "打开真实导出文件检查步骤演示内容。此文件不含完整三维模型和资源,完整三维离线包列为待确认范围。" },
"41-resource-search-restored": { "title": "资源搜索清空后恢复卡片", "description": "输入命中关键字、无匹配关键字,再清空搜索,断言卡片数量与空结果状态;仅搜索当前目录。" },
"42-resource-card-switch-reopened": { "title": "真实资源卡片切换后刷新", "description": "在独立副本导入小方盒,再点回原狐狸卡片;保存刷新后核对原资产 ID、code 与真实网格,不改原模型数据。" },
"43-builtin-workshop-reopened": { "title": "内置车间环境保存重开", "description": "真实切换内置车间、保存和刷新后核对环境类型与网格;树计数、折叠和展开同时验证。" },
"44-builtin-outdoor-reopened": { "title": "内置野外环境保存重开", "description": "真实切换内置野外、保存和刷新后核对环境类型与网格;程序化环境不冒称外部 GLB。" },
"45-builtin-depot-reopened": { "title": "内置装备车库保存重开", "description": "真实加载随包车库 GLB,保存刷新后检查 builtin-gltf 来源与网格;树总数与当前展开行数分开统计。" },
"46-preview-navigation": { "title": "预览前后步与退出", "description": "通过真实按钮验证下一步推进两秒、上一步回零,并用 Escape 返回编辑;预览步进不是创建新的业务步骤。" },
"47-navigation-autosave-log": { "title": "等待自动保存后刷新核对字段", "description": "自定义编码修改后没有点击保存,等待实际 30 秒自动 PUT;刷新确认名称与编码保留。下方日志为本次加载运行日志,FPS 与显存只作状态展示。" },
"51-transform-gizmos": { "title": "真实手柄操作的旋转与单轴缩放测试姿态", "description": "为了验证真实平移、旋转与缩放手柄,特意把狐狸旋转至侧立并缩小 X 轴;画面中的侧立和压扁属于测试姿态,不是加载变形。定位只读投影,没有脚本写姿态;随后撤销/重做、保存刷新核对。" },
"52-leave-save-failure": { "title": "未保存离开遇到保存失败", "description": "关闭确认框保留修改;定向注入保存 503 后仍留在原页,解除异常后重试保存才离开,最终 API 核对数据。" },
"60-same-version-real-recovery": { "title": "真实未保存修改触发同版本恢复", "description": "先在实际属性控件修改,再刷新触发 beforeunload 恢复稿;没有预先注入 localStorage 假快照。此时服务端版本未变化。" },
"61-recovered-draft-explicitly-saved": { "title": "恢复稿经显式保存后落库", "description": "点击恢复后编辑器保留需显式保存状态;实际点击保存才更新服务端版本,恢复名称与原受控模型一致。" },
"62-stale-version-recovery-protection": { "title": "旧版本恢复稿只下载与隔离", "description": "在独立副本模拟另一个编辑器保存;旧稿不显示覆盖恢复按钮,只下载并隔离保留,服务端较新内容未被覆盖。" },
"63-controlled-glb-download-failed": { "title": "受控模型下载失败时禁止编辑", "description": "定向注入资源下载 503,中性加载失败界面保留重试入口,保存与发布均禁用;空白视口不作为模型加载成功。" },
"64-controlled-glb-retry-loaded": { "title": "解除资源故障后实际重试成功", "description": "解除下载故障后点击宿主重试,iframe 重新载入并出现真实模型网格;没有以默认占位模型绕过失败。" },
"65-publish-preflight-readonly": { "title": "发布预检清单与只读开关行为", "description": "打开和关闭预检面板不会写入项目;错误受控资产引用的 JSON 在替换模型前被拒绝。面板绿标不能替代服务端发布校验。" },
"66-depot-saved-return-list": { "title": "车库保存后正常返回列表", "description": "车库环境保存后使用正式宿主导航返回列表,确认不会因旧版规范化器把 depot 误改成 outdoor 而产生虚假的未保存提示;实际修改仍受离开保护。" }
}

+ 498
- 0
reports/model-editor-closure-20260906/screenshot-verification.json 查看文件

@@ -0,0 +1,498 @@
{
"time": "2026-09-06T08:34:35.457Z",
"scope": "截图与当前 results.json 的附件逐字节 SHA256 一致性;同名预跑或重拍不自动计本轮通过。",
"screenshots": [
{
"file": "screenshots/01-components-saved.png",
"title": "对象属性与扩展标记保存",
"status": "PASS",
"associations": [
{
"title": "对象名称、变换、PBR、属性与扩展标记保存重开;撤销重做",
"status": "PASS",
"hashMatches": true
}
]
},
{
"file": "screenshots/02-properties-reopened.png",
"title": "刷新后的模型属性",
"status": "PASS",
"associations": [
{
"title": "对象名称、变换、PBR、属性与扩展标记保存重开;撤销重做",
"status": "PASS",
"hashMatches": true
}
]
},
{
"file": "screenshots/03-fox-preview.png",
"title": "狐狸模型运行预览",
"status": "PASS",
"associations": [
{
"title": "场景树搜索、可见性、选择、视口工具、原生动画与截图",
"status": "PASS",
"hashMatches": true
}
]
},
{
"file": "screenshots/04-new-retry-dialog.png",
"title": "新建失败后的重试界面",
"status": "PASS",
"associations": [
{
"title": "新建工程取消及失败保留输入;成功创建新ID且不覆盖当前模型",
"status": "PASS",
"hashMatches": true
}
]
},
{
"file": "screenshots/05-new-separate-project.png",
"title": "新建独立模型工程",
"status": "PASS",
"associations": [
{
"title": "新建工程取消及失败保留输入;成功创建新ID且不覆盖当前模型",
"status": "PASS",
"hashMatches": true
}
]
},
{
"file": "screenshots/06-readonly-permissions.png",
"title": "只读模型入口",
"status": "PASS",
"associations": [
{
"title": "管理员只读权限:编辑、新建、导入、保存发布均不可越权",
"status": "PASS",
"hashMatches": true
}
]
},
{
"file": "screenshots/21-truck-timeline-controls.png",
"title": "卡车时间轴与部件轨道",
"status": "PASS",
"associations": [
{
"title": "时间轴真实控件:轨道/关键帧/播放与曲线 5 插值,保存后重新加载一致",
"status": "PASS",
"hashMatches": true
}
]
},
{
"file": "screenshots/22-truck-curve-value-five.png",
"title": "曲线编辑:部件 X=5 的测试姿态",
"status": "PASS",
"associations": [
{
"title": "时间轴真实控件:轨道/关键帧/播放与曲线 5 插值,保存后重新加载一致",
"status": "PASS",
"hashMatches": true
}
]
},
{
"file": "screenshots/23-truck-blueprint-seven-nodes.png",
"title": "七种蓝图节点与真实端口连线",
"status": "PASS",
"associations": [
{
"title": "蓝图真实节点库与端口拖线:七种参数、内部边复制/剪切、撤销重做及保存",
"status": "PASS",
"hashMatches": true
}
]
},
{
"file": "screenshots/24-truck-blueprint-real-message.png",
"title": "蓝图执行到操作提示",
"status": "PASS",
"associations": [
{
"title": "蓝图真实节点库与端口拖线:七种参数、内部边复制/剪切、撤销重做及保存",
"status": "PASS",
"hashMatches": true
}
]
},
{
"file": "screenshots/25-truck-blueprint-completed-log.png",
"title": "蓝图完成与本次运行日志",
"status": "PASS",
"associations": [
{
"title": "蓝图真实节点库与端口拖线:七种参数、内部边复制/剪切、撤销重做及保存",
"status": "PASS",
"hashMatches": true
}
]
},
{
"file": "screenshots/26-truck-condition-branches-runtime.png",
"title": "条件真假出口的运行时补充检查",
"status": "PASS",
"associations": [
{
"title": "已保存蓝图:条件出口与目标匹配 runtime 检查,真实模型单击/双击/进入预览自动触发",
"status": "PASS",
"hashMatches": true
}
]
},
{
"file": "screenshots/27-truck-preview-auto.png",
"title": "进入预览自动触发蓝图",
"status": "PASS",
"associations": [
{
"title": "已保存蓝图:条件出口与目标匹配 runtime 检查,真实模型单击/双击/进入预览自动触发",
"status": "PASS",
"hashMatches": true
}
]
},
{
"file": "screenshots/27-truck-preview-click.png",
"title": "真实单击卡车触发蓝图",
"status": "PASS",
"associations": [
{
"title": "已保存蓝图:条件出口与目标匹配 runtime 检查,真实模型单击/双击/进入预览自动触发",
"status": "PASS",
"hashMatches": true
}
]
},
{
"file": "screenshots/27-truck-preview-double-click.png",
"title": "真实双击卡车触发蓝图",
"status": "PASS",
"associations": [
{
"title": "已保存蓝图:条件出口与目标匹配 runtime 检查,真实模型单击/双击/进入预览自动触发",
"status": "PASS",
"hashMatches": true
}
]
},
{
"file": "screenshots/28-curve-axis-y-negative.png",
"title": "曲线分量切换与负值",
"status": "PASS",
"associations": [
{
"title": "补充时间轴与蓝图工具:刻度/按键/记录/分量、基准匹配、节点搜索拖入与画布平移",
"status": "PASS",
"hashMatches": true
}
]
},
{
"file": "screenshots/29-timeline-seek-record.png",
"title": "真实刻度定位、方向键与关键帧记录",
"status": "PASS",
"associations": [
{
"title": "补充时间轴与蓝图工具:刻度/按键/记录/分量、基准匹配、节点搜索拖入与画布平移",
"status": "PASS",
"hashMatches": true
}
]
},
{
"file": "screenshots/30-assets-environment-reopened.png",
"title": "主狐狸与外部方盒环境同时重开",
"status": "PASS",
"associations": [
{
"title": "受控模型与外部环境 GLB 上传、JSON 往返和刷新重开",
"status": "PASS",
"hashMatches": true
}
]
},
{
"file": "screenshots/30-blueprint-palette-canvas.png",
"title": "蓝图库搜索、真实拖入与画布操作",
"status": "PASS",
"associations": [
{
"title": "补充时间轴与蓝图工具:刻度/按键/记录/分量、基准匹配、节点搜索拖入与画布平移",
"status": "PASS",
"hashMatches": true
}
]
},
{
"file": "screenshots/31-bridge-baseline-reopened.png",
"title": "匹配模型的基准时间轴保存重开",
"status": "PASS",
"associations": [
{
"title": "补充时间轴与蓝图工具:刻度/按键/记录/分量、基准匹配、节点搜索拖入与画布平移",
"status": "PASS",
"hashMatches": true
}
]
},
{
"file": "screenshots/31-invalid-import-keeps-model.png",
"title": "无效工程导入保留原模型",
"status": "PASS",
"associations": [
{
"title": "非法 JSON 与未登记 blob 引用导入失败时保留当前文档",
"status": "PASS",
"hashMatches": true
}
]
},
{
"file": "screenshots/32-save-conflict-keeps-recovery.png",
"title": "版本冲突阻断保存并保留恢复稿",
"status": "PASS",
"associations": [
{
"title": "保存请求超时和 409 保留恢复副本,解除故障后可重试",
"status": "PASS",
"hashMatches": true
}
]
},
{
"file": "screenshots/33-save-retry-success.png",
"title": "保存失败后再次保存成功",
"status": "PASS",
"associations": [
{
"title": "保存请求超时和 409 保留恢复副本,解除故障后可重试",
"status": "PASS",
"hashMatches": true
}
]
},
{
"file": "screenshots/34-published-current-cover.png",
"title": "发布版本与当前视口封面",
"status": "PASS",
"associations": [
{
"title": "直接发布同步截图封面、固定版本目录与真实离线步骤 HTML",
"status": "PASS",
"hashMatches": true
}
]
},
{
"file": "screenshots/35-offline-step-demo-actual-file.png",
"title": "实际下载的步骤演示 HTML",
"status": "PASS",
"associations": [
{
"title": "直接发布同步截图封面、固定版本目录与真实离线步骤 HTML",
"status": "PASS",
"hashMatches": true
}
]
},
{
"file": "screenshots/41-resource-search-restored.png",
"title": "资源搜索清空后恢复卡片",
"status": "PASS",
"associations": [
{
"title": "补充资源库:搜索清空、真实卡片切换与刷新保留",
"status": "PASS",
"hashMatches": true
}
]
},
{
"file": "screenshots/42-resource-card-switch-reopened.png",
"title": "真实资源卡片切换后刷新",
"status": "PASS",
"associations": [
{
"title": "补充资源库:搜索清空、真实卡片切换与刷新保留",
"status": "PASS",
"hashMatches": true
}
]
},
{
"file": "screenshots/43-builtin-workshop-reopened.png",
"title": "内置车间环境保存重开",
"status": "PASS",
"associations": [
{
"title": "补充环境与树:内置三环境保存重开、节点计数与折叠展开",
"status": "PASS",
"hashMatches": true
}
]
},
{
"file": "screenshots/44-builtin-outdoor-reopened.png",
"title": "内置野外环境保存重开",
"status": "PASS",
"associations": [
{
"title": "补充环境与树:内置三环境保存重开、节点计数与折叠展开",
"status": "PASS",
"hashMatches": true
}
]
},
{
"file": "screenshots/45-builtin-depot-reopened.png",
"title": "内置装备车库保存重开",
"status": "PASS",
"associations": [
{
"title": "补充环境与树:内置三环境保存重开、节点计数与折叠展开",
"status": "PASS",
"hashMatches": true
}
]
},
{
"file": "screenshots/46-preview-navigation.png",
"title": "预览前后步与退出",
"status": "PASS",
"associations": [
{
"title": "补充视口与工作区:鼠标镜头、聚焦、面板、预览导航、日志与自动保存",
"status": "PASS",
"hashMatches": true
}
]
},
{
"file": "screenshots/47-navigation-autosave-log.png",
"title": "等待自动保存后刷新核对字段",
"status": "PASS",
"associations": [
{
"title": "补充视口与工作区:鼠标镜头、聚焦、面板、预览导航、日志与自动保存",
"status": "PASS",
"hashMatches": true
}
]
},
{
"file": "screenshots/51-transform-gizmos.png",
"title": "真实手柄操作的旋转与单轴缩放测试姿态",
"status": "PASS",
"associations": [
{
"title": "真实三维移动、旋转、缩放手柄拖动及撤销重做保存重开",
"status": "PASS",
"hashMatches": true
}
]
},
{
"file": "screenshots/52-leave-save-failure.png",
"title": "未保存离开遇到保存失败",
"status": "PASS",
"associations": [
{
"title": "未保存离开:关闭确认保留工作、保存失败留在原页、重试保存后离开",
"status": "PASS",
"hashMatches": true
}
]
},
{
"file": "screenshots/60-same-version-real-recovery.png",
"title": "真实未保存修改触发同版本恢复",
"status": "PASS",
"associations": [
{
"title": "真实未保存稿同版本恢复并显式保存;旧版本恢复稿下载隔离保留",
"status": "PASS",
"hashMatches": true
}
]
},
{
"file": "screenshots/61-recovered-draft-explicitly-saved.png",
"title": "恢复稿经显式保存后落库",
"status": "PASS",
"associations": [
{
"title": "真实未保存稿同版本恢复并显式保存;旧版本恢复稿下载隔离保留",
"status": "PASS",
"hashMatches": true
}
]
},
{
"file": "screenshots/62-stale-version-recovery-protection.png",
"title": "旧版本恢复稿只下载与隔离",
"status": "PASS",
"associations": [
{
"title": "真实未保存稿同版本恢复并显式保存;旧版本恢复稿下载隔离保留",
"status": "PASS",
"hashMatches": true
}
]
},
{
"file": "screenshots/63-controlled-glb-download-failed.png",
"title": "受控模型下载失败时禁止编辑",
"status": "PASS",
"associations": [
{
"title": "受控 GLB 下载失败阻止编辑,重试成功;发布预检开关无写入且拒绝错误资源 JSON",
"status": "PASS",
"hashMatches": true
}
]
},
{
"file": "screenshots/64-controlled-glb-retry-loaded.png",
"title": "解除资源故障后实际重试成功",
"status": "PASS",
"associations": [
{
"title": "受控 GLB 下载失败阻止编辑,重试成功;发布预检开关无写入且拒绝错误资源 JSON",
"status": "PASS",
"hashMatches": true
}
]
},
{
"file": "screenshots/65-publish-preflight-readonly.png",
"title": "发布预检清单与只读开关行为",
"status": "PASS",
"associations": [
{
"title": "受控 GLB 下载失败阻止编辑,重试成功;发布预检开关无写入且拒绝错误资源 JSON",
"status": "PASS",
"hashMatches": true
}
]
},
{
"file": "screenshots/66-depot-saved-return-list.png",
"title": "车库保存后正常返回列表",
"status": "PASS",
"associations": [
{
"title": "补充环境与树:内置三环境保存重开、节点计数与折叠展开",
"status": "PASS",
"hashMatches": true
}
]
}
]
}

二进制
查看文件


二进制
查看文件


二进制
查看文件


二进制
查看文件


二进制
查看文件


二进制
查看文件


二进制
查看文件


二进制
查看文件


二进制
查看文件


二进制
查看文件


二进制
查看文件


部分文件因为文件数量过多而无法显示

正在加载...
取消
保存