Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.
 
 
 
 

100 wiersze
12 KiB

  1. <!doctype html><html lang="zh-CN"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>frontend-review · Code Review</title><style>*{box-sizing:border-box}body{margin:0;background:#edf2f7;color:#203248;font:16px/1.75 "Microsoft YaHei","Segoe UI",sans-serif}header{background:#0c2b47;color:white;padding:22px max(24px,calc((100vw - 1160px)/2))}header a{color:#c1e6ff;margin-right:24px}main{max-width:1200px;margin:24px auto 60px;padding:36px;background:white;border-radius:12px;box-shadow:0 6px 24px #1028400c}h1{font-size:30px;line-height:1.4;margin-top:0}h2{font-size:22px;margin:36px 0 14px;border-bottom:2px solid #dbe8f2;padding-bottom:8px}h3{font-size:18px}p{margin:13px 0}a{color:#126fba;text-decoration:none}a:hover{text-decoration:underline}table{border-collapse:collapse;width:100%;margin:18px 0;font-size:14px;table-layout:auto}th,td{padding:11px 13px;border:1px solid #dce5ed;text-align:left;vertical-align:top;overflow-wrap:anywhere}th{background:#edf5fc}tr:nth-child(even){background:#f9fbfd}code{font:13px/1.5 Consolas,monospace;background:#edf2f7;padding:2px 5px;border-radius:4px;overflow-wrap:anywhere}pre{padding:18px;overflow:auto;background:#edf2f7;border-radius:8px}pre code{padding:0}img{max-width:100%;height:auto}details{padding:12px;background:#f7f9fc;margin:12px 0}.gallery{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:20px}figure{margin:0;border:1px solid #dce5ed;border-radius:8px;overflow:hidden;background:#f8fafc}figure img{display:block;width:100%;height:300px;object-fit:contain;background:#e8eef3}figcaption{padding:12px;font-size:14px;color:#37526b}footer{color:#657c91;font-size:13px;margin-top:36px}li{margin:8px 0}@media(max-width:760px){main{margin:0;padding:20px;border-radius:0}.gallery{grid-template-columns:1fr}table{display:block;overflow:auto}h1{font-size:25px}header{padding:16px}}@media print{body{background:white}main{margin:0;box-shadow:none;max-width:none}header{display:none}figure{break-inside:avoid}h2{break-after:avoid}}</style></head><body><header><a href="index.html">审查总报告</a><a href="live/html/index.html">真实 E2E</a><a href="frontend-e2e/html/index.html">模拟接口回归</a></header><main><h1 id="前端增量-code-review">前端增量 Code Review</h1>
  2. <p>范围:<code>unreal_tran_web</code> 的 <code>0aac918..1576728</code>,以及新增正式入口所依赖的运行页与通用内容编辑器。按资料、产品原型、设计、开发、测试核对;审查完成后按用户授权提交为 <code>3c7f295</code>。</p>
  3. <h2 id="资料与产品原型">资料与产品原型</h2>
  4. <ul>
  5. <li>原始资料与确认原型的详细比对由本次资料审查分工提供,见同目录汇总报告。本分工未独立宣称核读全部 PDF。</li>
  6. <li>已完整阅读前端 <code>AGENTS.md</code>:正式教学页面必须消费 API;训练编排复用已发布场景目标;工程修改须保持教员身份门槛;保留原型工作台与接口工作台已有入口。</li>
  7. <li>保留既有功能与页面结构,只修复排序、保存兼容和错误遮罩。实装默认离线回放、正式虚拟训练与原型交互能力的差异属于汇总报告中的功能确认事项,本分工未改路由或扩建交互。</li>
  8. </ul>
  9. <h2 id="设计合同">设计合同</h2>
  10. <ul>
  11. <li><code>unreal_tran_api/wiki/19-训练定义渠道合同.md</code>:一份公共步骤、多渠道差异配置;默认渠道必须启用;<code>modeConfig</code> 与默认渠道 profile 一致。</li>
  12. <li><code>unreal_tran_api/wiki/20-教学命令幂等.md</code>:四类命令 body/header 使用同一 commandId;结果未知时复用原命令号与冻结载荷。</li>
  13. <li><code>unreal_tran_api/wiki/21-教学步骤运行事实.md</code>:新运行展示服务端步骤状态;空列表仅兼容历史运行;全部步骤完成方可提交。</li>
  14. <li>后端 <code>TeachingAssignmentService.validateRuntimeDefinition</code> 明确要求实装步骤进度按顺序严格递增,末步 100%。</li>
  15. </ul>
  16. <h2 id="已修复问题">已修复问题</h2>
  17. <table>
  18. <thead>
  19. <tr>
  20. <th>编号</th>
  21. <th>问题与影响</th>
  22. <th>根因</th>
  23. <th>最小修复</th>
  24. </tr>
  25. </thead>
  26. <tbody>
  27. <tr>
  28. <td>WEB-01</td>
  29. <td>实装步骤倒序、删除或复制后,保存保留旧序号和旧进度,导致排序事实不一致、发布被拒。多渠道工程同样受影响。</td>
  30. <td>新 <code>resequenceSteps</code> 直接调用归一化函数,而归一化优先保留已有 <code>order/progressPercent</code>。例如三步反转产生序号 <code>3,2,1</code> 与进度 <code>100,67,33</code>。</td>
  31. <td>按编辑后的数组重算连续序号、实装严格递增进度;保留稳定 stepCode 及已有事件规则扩展字段。</td>
  32. </tr>
  33. <tr>
  34. <td>WEB-02</td>
  35. <td>通用编辑器修改默认配置后仅更新旧 <code>modeConfig</code>,与已有 <code>channelProfiles</code> 冲突;在接口编排器重开后新值被旧 profile 覆盖。切换默认渠道也未同步正式字段。</td>
  36. <td>通用编辑器未跟进新渠道合同,只读写单个旧配置对象;对抗时长仍只写旧字段。</td>
  37. <td>各渠道按对应 profile 回填;保存同步默认渠道、启用渠道、profile 和兼容镜像;保留其他渠道。对抗时长新旧字段同步,兼容历史 <code>roundDuration</code>,避免 45 分钟被默认 30 分钟替代。</td>
  38. </tr>
  39. <tr>
  40. <td>WEB-03</td>
  41. <td>普通虚拟训练、实装、对抗以及执行中的正式考核,可能错误显示“正式考核执行场景已关闭”。该问题在正式虚拟页面成为默认入口后更容易暴露。</td>
  42. <td>遮罩的 <code>v-else</code> 实际绑定紧邻的“虚拟拆卸存放区”条件,而非正式考核生命周期。</td>
  43. <td>改为显式判断“正式考核且运行不在 IN_PROGRESS”,其他训练与执行中的考核不显示关闭遮罩。</td>
  44. </tr>
  45. <tr>
  46. <td>WEB-04</td>
  47. <td>当前步骤失败后聚合运行仍为 IN_PROGRESS,页面没有可进入正式重试状态的入口。</td>
  48. <td>原“开始训练”仅在 ACCEPTED 显示,未覆盖新步骤事实的 FAILED→IN_PROGRESS 重试合同。</td>
  49. <td>仅当学员的运行仍在 IN_PROGRESS 且当前步骤事实为 FAILED 时显示“重试当前步骤”,复用原 start 命令及幂等 tracker;已提交、归档和已完成步骤不显示。</td>
  50. </tr>
  51. <tr>
  52. <td>WEB-05</td>
  53. <td>真实 E2E 截图显示场景只占视口上方约 315px,其下安全确认区在深色场景底色上显示深色文字,难以阅读。</td>
  54. <td>场景组件 scoped <code>position: relative</code> 覆盖全局绝对定位,运行页缺少预览页已有的填充规则;<code>runtime-safety-gate</code> 没有任何对应样式。</td>
  55. <td>仅在运行视口下补场景 absolute/inset 定位;安全区使用已有主题 surface/text 颜色,补齐卡片间距、14px 复选框文字和底部定位,不修改安全规则或推进逻辑。</td>
  56. </tr>
  57. <tr>
  58. <td>WEB-06</td>
  59. <td>离线回放默认视频被替换成约 32 秒的新片,但候选与抓拍仍对应约 45 秒已验收片;34 秒与 45.2 秒两个候选不可达。</td>
  60. <td>当前默认文件实际 31.973991 秒;旧 12 候选时间轴不按 metadata 缩放,视频结束却会把五阶段标记为已回放。既有视频 SHA 契约实际失败。</td>
  61. <td>默认引用改为仓库保留的 <code>pose1.mp4</code>,该文件 42,865,492 字节、SHA-256 为 <code>B588101115196061E0D2BCE4B0BD0CB1B01CAEB7561B31D0F26F5C0E980696D4</code>,与既有已验收视频契约完全一致,实际 45.422 秒。新 32 秒文件原样保留,是否换用新片及重标候选/抓拍列 F5 待确认,不猜测新时间轴。</td>
  62. </tr>
  63. </tbody>
  64. </table>
  65. <p>修改文件:</p>
  66. <ul>
  67. <li><code>unreal_tran_web/src/features/training/trainingDocument.ts</code></li>
  68. <li><code>unreal_tran_web/src/views/content/ContentEditorView.vue</code></li>
  69. <li><code>unreal_tran_web/src/views/teaching/TeachingRunView.vue</code></li>
  70. <li><code>unreal_tran_web/src/styles/teaching-run-workspaces.scss</code></li>
  71. <li><code>unreal_tran_web/src/features/physical-legacy/runtime.ts</code></li>
  72. <li><code>unreal_tran_web/scripts/physical-offline-replay.contract.test.mjs</code></li>
  73. <li><code>unreal_tran_web/scripts/training-channel-profiles.contract.test.mjs</code></li>
  74. <li><code>unreal_tran_web/scripts/teaching-step-run.contract.test.mjs</code></li>
  75. </ul>
  76. <h2 id="验证">验证</h2>
  77. <p>先加入已保存步骤排序回归:修改前 8 项测试中 2 项失败,实际观察到序号 <code>[3,2,1]</code> 与 <code>[2,1]</code>,确认不是推测问题。</p>
  78. <p>修复后的命令:</p>
  79. <pre><code class="language-text">node --experimental-strip-types --test scripts/physical-offline-replay.contract.test.mjs scripts/training-channel-profiles.contract.test.mjs scripts/teaching-step-run.contract.test.mjs scripts/teaching-command-idempotency.contract.test.mjs scripts/core-role-contract.test.mjs scripts/virtual-training-formal-route.contract.test.mjs scripts/training-scene-grounding.test.mjs
  80. pnpm run build
  81. git diff --check
  82. </code></pre>
  83. <ul>
  84. <li>Node 回归:25/25 通过,详见 <a href="frontend-contract-tests.log">frontend-contract-tests.log</a>。其中包含实际执行的渠道转换、已保存步骤重排、旧文档迁移、配置保存再打开、冻结命令载荷、失败步骤重试资格矩阵及离线视频 SHA/12 候选/抓拍资源等断言;路由与模板条件部分属于静态契约检查。</li>
  85. <li>最后一轮构建通过(退出码 0):包含 <code>vue-tsc --noEmit</code>、Vite 打包与旧模型 iframe 校验,详见 <a href="frontend-build.log">frontend-build.log</a>。已有资源 URL、包体大小告警不按构建失败统计。</li>
  86. <li><code>git diff --check</code> 未发现空白错误;工作区 Git 的 LF/CRLF 提醒属于换行提示。</li>
  87. <li>浏览器 API mock 回归 15/15 通过,详见 <a href="frontend-e2e/README.html">frontend-e2e/README.md</a>。其中军工绿/暗色两套视觉用例确认场景和 host 同为 630×583.72px;安全区标题及复选框文本对比分别为 12.00/15.30,17 张截图均保留。真实 API E2E 另见同目录汇总,不能以 mock 或 Node 检查替代。</li>
  88. <li>视频兼容性单独核实:静态服务 HEAD 200、Range 206、<code>video/mp4</code>;ffprobe 显示 H.264 Main/yuv420p + AAC LC。bundled Chromium 对新旧 H.264 都返回不支持并触发 <code>DEMUXER_ERROR_NO_SUPPORTED_STREAMS</code>,不属于该视频的产品解码缺陷;根代理使用本机 Edge 验证 H.264 可播放,真实离线回放使用 Edge 完成。</li>
  89. </ul>
  90. <h2 id="交给-e2e-的验证点">交给 E2E 的验证点</h2>
  91. <ol>
  92. <li>在接口编排器重排已保存的实装/多渠道步骤,保存后检查序号与实装进度;删除末步后新末步为 100%。</li>
  93. <li>通用编辑器修改默认配置并保存,再进接口编排器,确认新值未丢失,未修改渠道原配置保留;切默认渠道后合同字段一致。</li>
  94. <li>普通三渠道运行以及执行中的正式考核不出现考核关闭遮罩;未开始/提交后的正式考核显示关闭态。</li>
  95. <li>正式虚拟主入口、旧 <code>/api</code> 重定向、命令丢响应后的重放、步骤事实失败与重试、教员/管理员身份边界继续验证。</li>
  96. <li>失败步骤显示“重试当前步骤”;点击后通过 start 端点进入执行中、尝试次数增加、失败次数保持,重试按钮消失。</li>
  97. <li>等待 <code>.teaching-three-scene</code> 的 <code>aria-label</code>/<code>.teaching-scene-status</code> 成为“已加载发布训练场景 · N 个对象”且无资产失败提示,再检查真实资产下载响应与截图。canvas 存在不等于 GLB 就绪。场景 host 应填满运行视口;明暗主题下安全确认区均应可读。</li>
  98. <li>本机 Edge 播放离线素材,3 秒出现首条候选,跳转至 <code>video.duration - 0.03</code> 后 <code>[data-event-timeline] [data-physical-event][data-offline-replay="true"]</code> 应为 12 条,包含 <code>offline-replay:replay-complete</code>;候选仍只供教员复核,不写正式运行进度。</li>
  99. </ol>
  100. <p>本分工没有数据库变更、依赖版本变更或新增产品功能。所有待确认功能范围统一列入总报告,避免分散审批。</p><footer>2026-09-05 · 开发环境审查 · 图片可点击查看原尺寸</footer></main></body></html>