No puede seleccionar más de 25 temas Los temas deben comenzar con una letra o número, pueden incluir guiones ('-') y pueden tener hasta 35 caracteres de largo.
 
 
 
 

30 líneas
6.8 KiB

  1. import fs from 'node:fs';
  2. import assert from 'node:assert/strict';
  3. const dir='reports/bridge-final-acceptance-20260924';
  4. fs.mkdirSync(dir,{recursive:true});
  5. const names={'005':'液压泵应急切换','006':'液压泵应急替代','007':'前泵换件修复','008':'平衡阀拆拼互换'};
  6. const records=Object.entries(names).map(([code,name])=>{
  7. const folder=`bridge-final-acceptance-20260924-${code}`;
  8. const result=JSON.parse(fs.readFileSync(`reports/${folder}/result.json`,'utf8'));
  9. const audit=JSON.parse(fs.readFileSync(`reports/${folder}/acceptance.json`,'utf8'));
  10. assert.equal(result.pass,true,code);assert.equal(audit.tasks.length,1);
  11. const task=audit.tasks[0];assert.equal(task.finished,true,code);
  12. const introductions=result.checks.filter(c=>c.introduction).length;
  13. const operations=result.checks.filter(c=>c.target).length;assert.equal(operations,task.operations);
  14. assert.equal(audit.learnerResultsCreated,false);assert.deepEqual(audit.premature,[]);
  15. return {code,name,folder,...task,introductions,environment:audit.environment,checks:result.checks,requests:audit.writes.length};
  16. });
  17. const total=key=>records.reduce((n,r)=>n+r[key],0);
  18. assert.equal(total('introductions'),11);assert.equal(total('steps'),38);assert.equal(total('operations'),98);
  19. fs.writeFileSync(dir+'/summary.json',JSON.stringify({pass:true,records,totals:{introductions:11,steps:38,operations:98},learnerResultsCreated:false,limits:['教员预览使用服务端逐步校验,本轮没有新建学员运行或提交学员成绩。','每段讲解验证播放控制及切换;音轨/ASR 完整检查见阶段 4B,听感与逐帧口型仍需人工确认。'],createdAt:new Date().toISOString()},null,2));
  20. const e=value=>String(value??'').replace(/[&<>"']/g,c=>({'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#39;'}[c]));
  21. fs.writeFileSync(dir+'/index.html',`<!doctype html><html lang="zh-CN"><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>005–008 全流程验收</title>
  22. <style>body{margin:0;background:#eef5f2;color:#193d35;font:16px/1.7 system-ui,"Microsoft YaHei",sans-serif}main{max-width:1180px;padding:32px 24px;margin:auto}section,figure{background:white;border:1px solid #cdded7;border-radius:12px;padding:24px;margin:20px 0}h1{font-size:30px}h2{font-size:23px}a{color:#087a60}table{width:100%;border-collapse:collapse}td,th{text-align:left;padding:12px;border-bottom:1px solid #dce9e2}img{width:100%;border-radius:6px}figcaption{margin-top:10px}.ok{color:#087a60;font-weight:700}.note{background:#fff9ed}.links{display:flex;gap:16px;flex-wrap:wrap}small{color:#607b70}@media(max-width:700px){main{padding:16px}section,figure{padding:16px}table{font-size:13px}td,th{padding:6px}}</style>
  23. <main><p class="ok">四个流程通过 · 2026-09-24</p><h1>背景讲解 → 工具操作 → 零件暂存 → 完成训练</h1><p>11 页背景/讲解、38 个步骤、98 个子操作。本轮从打开任务开始,在同一训练会话中用鼠标操作到完成弹窗;各步经过实际预览校验接口。保留原发布任务和固定版本,没有创建学员成绩。</p>
  24. <section><h2>结果</h2><table><thead><tr><th>脚本</th><th>讲解页</th><th>步骤 / 子操作</th><th>固定版本</th><th>证据</th></tr></thead><tbody>${records.map(r=>`<tr><td>${r.code} ${e(r.name)}</td><td>${r.introductions}</td><td>${r.steps} / ${r.operations}</td><td>${e(r.contentVersionId)}</td><td><a href="../${r.folder}/result.json">操作记录</a> · <a href="../${r.folder}/acceptance.json">接口与完成记录</a></td></tr>`).join('')}</tbody></table></section>
  25. <section><h2>本轮检查</h2><ul><li>每一页播放、暂停、重播、下一步及停止旧视频;加载阶段没有抢先播放。</li><li>005 盒盖打开后、006 软管连接中、007 螺栓拆到一半、008 大腔管路拆开并封口后返回背景,再跳过讲解。步骤、已完成子操作、零件姿态、暂存状态保持不变。</li><li>实际拖动工具、错误工具拦截、Esc 取消、螺栓遮挡处理、暂存位置与回装;007 保存失败后重新操作并通过服务端校验。</li><li>场景半透明与恢复、爆炸展开与归零、部件与相机地形边界。保障车参与半透明。</li><li>逐个点击“完成训练”,确认显示“预览校验完成”,全部媒体停播。006 完成页说明可恢复正常作业,不增加第七操作步。</li><li>1366×768 笔记本;008 通过局域网入口。所有训练写请求仅为预览校验,任务响应除时钟外前后完整一致。</li></ul></section>
  26. ${records.map(r=>`<section><h2>${r.code} ${e(r.name)}</h2><p>${r.environment.width}×${r.environment.height} · ${e(r.environment.baseUrl)} · ${r.requests} 次校验请求${r.requests>r.steps?'(含一次模拟失败与重试)':''}</p><div class="links"><a href="../${r.folder}/task-${r.id}-intro-0.png">背景讲解</a><a href="../${r.folder}/task-${r.id}-mid-operation-intro.png">操作中回看讲解</a><a href="../${r.folder}/task-${r.id}-overview.png">操作区</a></div><figure><img src="../${r.folder}/task-${r.id}-complete.png" alt="${r.code} 实际操作完成弹窗"><figcaption>${r.steps} 步 / ${r.operations} 子操作通过。${r.id==='88'?'暂存台最终保留旧泵。':r.id==='89'?'所有零件完成回装,暂存台清空。':''}</figcaption></figure></section>`).join('')}
  27. <section><h2>工具和零件暂存</h2><figure><img src="../bridge-final-acceptance-20260924-007/task-88-tool-step-4.png" alt="007 工具驱动螺栓拆卸"><figcaption>007:拖入工具后自动拆卸,数字教员保持显示。</figcaption></figure><figure><img src="../bridge-final-acceptance-20260924-008/task-89-tray-step-7.png" alt="008 八颗螺栓与两只平衡阀暂存"><figcaption>008:拆卸后检查 10 件实际零件的编号存放位置。<a href="../bridge-final-acceptance-20260924-008/task-89-tray-step-14.png">查看回装后的空台</a>。</figcaption></figure></section>
  28. <section class="note"><h2>验收范围与后续</h2><p>六项交互改造、制作链工具参数、三维暂存台、背景数字人讲解以及本轮整体复验均已完成。没有改动已发布任务、创建学员成绩、提交 Git、推送或部署。</p><p>本轮通过的是教员预览全流程,不能替代学员成绩提交、并发或目标服务器性能测试。数字人听感、专业词读音和逐帧口型仍需人工试听确认;自动音轨与 ASR 检查见讲解报告。</p><div class="links"><a href="../bridge-introduction-narration-20260924/index.html">全部讲解试听</a><a href="../bridge-parts-workbench-20260924/index.html">暂存台报告</a><a href="../bridge-training-improvements-20260924/index.html">全部改造记录</a><a href="summary.json">验收汇总 JSON</a></div></section><small>测试账号:内部维护账号,教员预览。不包含账号凭据。</small></main></html>`);
  29. console.log(dir+'/index.html');