import fs from 'node:fs';
import assert from 'node:assert/strict';
const dir='reports/bridge-final-acceptance-20260924';
fs.mkdirSync(dir,{recursive:true});
const names={'005':'液压泵应急切换','006':'液压泵应急替代','007':'前泵换件修复','008':'平衡阀拆拼互换'};
const records=Object.entries(names).map(([code,name])=>{
const folder=`bridge-final-acceptance-20260924-${code}`;
const result=JSON.parse(fs.readFileSync(`reports/${folder}/result.json`,'utf8'));
const audit=JSON.parse(fs.readFileSync(`reports/${folder}/acceptance.json`,'utf8'));
assert.equal(result.pass,true,code);assert.equal(audit.tasks.length,1);
const task=audit.tasks[0];assert.equal(task.finished,true,code);
const introductions=result.checks.filter(c=>c.introduction).length;
const operations=result.checks.filter(c=>c.target).length;assert.equal(operations,task.operations);
assert.equal(audit.learnerResultsCreated,false);assert.deepEqual(audit.premature,[]);
return {code,name,folder,...task,introductions,environment:audit.environment,checks:result.checks,requests:audit.writes.length};
});
const total=key=>records.reduce((n,r)=>n+r[key],0);
assert.equal(total('introductions'),11);assert.equal(total('steps'),38);assert.equal(total('operations'),98);
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));
const e=value=>String(value??'').replace(/[&<>"']/g,c=>({'&':'&','<':'<','>':'>','"':'"',"'":'''}[c]));
fs.writeFileSync(dir+'/index.html',`
005–008 全流程验收
四个流程通过 · 2026-09-24
背景讲解 → 工具操作 → 零件暂存 → 完成训练
11 页背景/讲解、38 个步骤、98 个子操作。本轮从打开任务开始,在同一训练会话中用鼠标操作到完成弹窗;各步经过实际预览校验接口。保留原发布任务和固定版本,没有创建学员成绩。
结果
| 脚本 | 讲解页 | 步骤 / 子操作 | 固定版本 | 证据 |
${records.map(r=>`| ${r.code} ${e(r.name)} | ${r.introductions} | ${r.steps} / ${r.operations} | ${e(r.contentVersionId)} | 操作记录 · 接口与完成记录 |
`).join('')}
本轮检查
- 每一页播放、暂停、重播、下一步及停止旧视频;加载阶段没有抢先播放。
- 005 盒盖打开后、006 软管连接中、007 螺栓拆到一半、008 大腔管路拆开并封口后返回背景,再跳过讲解。步骤、已完成子操作、零件姿态、暂存状态保持不变。
- 实际拖动工具、错误工具拦截、Esc 取消、螺栓遮挡处理、暂存位置与回装;007 保存失败后重新操作并通过服务端校验。
- 场景半透明与恢复、爆炸展开与归零、部件与相机地形边界。保障车参与半透明。
- 逐个点击“完成训练”,确认显示“预览校验完成”,全部媒体停播。006 完成页说明可恢复正常作业,不增加第七操作步。
- 1366×768 笔记本;008 通过局域网入口。所有训练写请求仅为预览校验,任务响应除时钟外前后完整一致。
${records.map(r=>`${r.code} ${e(r.name)}
${r.environment.width}×${r.environment.height} · ${e(r.environment.baseUrl)} · ${r.requests} 次校验请求${r.requests>r.steps?'(含一次模拟失败与重试)':''}
${r.steps} 步 / ${r.operations} 子操作通过。${r.id==='88'?'暂存台最终保留旧泵。':r.id==='89'?'所有零件完成回装,暂存台清空。':''}`).join('')}
工具和零件暂存
007:拖入工具后自动拆卸,数字教员保持显示。
008:拆卸后检查 10 件实际零件的编号存放位置。查看回装后的空台。
验收范围与后续
六项交互改造、制作链工具参数、三维暂存台、背景数字人讲解以及本轮整体复验均已完成。没有改动已发布任务、创建学员成绩、提交 Git、推送或部署。
本轮通过的是教员预览全流程,不能替代学员成绩提交、并发或目标服务器性能测试。数字人听感、专业词读音和逐帧口型仍需人工试听确认;自动音轨与 ASR 检查见讲解报告。
测试账号:内部维护账号,教员预览。不包含账号凭据。`);
console.log(dir+'/index.html');