${esc(r.title)}
${esc(r.note)}
${r.source} · 已验证 ${r.verifiedOperations}/${r.expectedOperations} 项交互查看原稿和动作目标
${esc(r.original)}
${esc(r.operations.map(o=>o.targetId+' · '+o.kind).join('\n'))}import fs from 'node:fs';
import path from 'node:path';
import crypto from 'node:crypto';
const dir=path.resolve('reports/bridge-model-acceptance-20260921');
const tasks=JSON.parse(fs.readFileSync(path.join(dir,'current-tasks.json'),'utf8'));
const models=JSON.parse(fs.readFileSync(path.join(dir,'source-models.json'),'utf8'));
const source=JSON.parse(fs.readFileSync(path.join(dir,'source.json'),'utf8'));
const runtime=JSON.parse(fs.readFileSync(path.join(dir,'new-model-runtime.json'),'utf8'));
const originalPath=path.join(dir,'original-005-runtime.json');
const originalRuntime=fs.existsSync(originalPath)?JSON.parse(fs.readFileSync(originalPath,'utf8')):null;
const data={
'005':[
[30,'简化实现','真实前泵可点选确认;故障由脚本预设,没有两个泵之间的诊断分支。'],
[31,'基本对应','真实取力器开关可旋转断开;模型命名及原稿均提示该开关实物准确性仍需确认。'],
[32,'基本对应','真实球阀手柄旋转;已验证交互,最终与管轴平行关系仍需实装确认。'],
[33,'基本对应','同一取力器开关反向旋转复位,接通动作可完成。'],
[34,'基本对应','真实盒盖与互救开关分两次操作;盒盖铰链、手柄固定端转轴已有。单泵驱动整车的结果动画未接入。'],
],
'006':[
[39,'简化实现','发动机以颜色表示运行,取力器开关可断开;无发动机/液压动力联动。'],
[40,'简化实现','双车、接口盖和两条真实软管存在;移动盖子后显示预成形软管,没有快接插入与锁紧动作。'],
[41,'基本对应','使用保障车独立回油截止阀节点,可旋转打开;实装位置待专业确认。'],
[42,'基本对应','使用真实盒盖和互救开关;与005是否同一开关,原表列为待澄清项。'],
[43,'基本对应','两个独立滤油器出口球阀均绑定,必须分别完成操作。'],
[44,'简化实现','保障车GLB只有整车、玻璃、接口盖、回油阀四个网格;取力器开关是代码补充件,供油靠软管变色表示。'],
[45,'关键内容缺失','可移动示意手柄结束步骤,但没有“按正常步骤操作架桥车”的整机作业动作。不能据此验收正常作业已完成。'],
],
'007':[
[47,'简化实现','停机着色及牛皮纸缩放已实现;未用裁剪工具沿真实结合面轮廓裁切。'],
[48,'待资料确认','绑定2_07球阀开关02和3-02球阀开关,能关闭;是否对应“1号球阀”须确认编号。'],
[49,'简化实现','进出油接头与两封口袋可独立操作;接头只有位移,缺大活动扳手旋松及包扎动作。'],
[50,'简化实现','两组源网格拆成四颗真实螺栓,逐颗旋转拆下;无开口扳手动作,旋转行程为示意。'],
[51,'基本对应','原位旧前泵可取下,安装位置保留。'],
[52,'简化实现','从初裁纸切换为精裁纸垫几何;没有实际轮廓裁切过程。'],
[53,'简化实现','纸垫可移动到取力器接口;贴合位置按偏移估算,尚缺结合面形状尺寸验收依据。'],
[54,'基本对应','新泵归位并安装四颗螺栓;新旧泵复用同一源几何。不能据此验收扭矩或装配尺寸。'],
[55,'简化实现','真实加油口盖随新泵移动,可打开;加油壶与油流是补充件,无油量计算及关盖动作。'],
[56,'简化实现','取袋和接头归位可完成;没有“拧紧”的接头旋转及扳手动作。'],
[57,'关键内容缺失','发动机变色、示意试验手柄可操作;没有整机试车工况、泄漏检查、压力响应与合格判据。'],
],
'008':[
[59,'简化实现','补充布块移动和阀体变色;没有清洗剂、油污到洁净的材质变化及各管接头擦拭。'],
[60,'简化实现','真实管接头移开、封口袋就位;无19号开口扳手及旋松过程。'],
[61,'简化实现','四颗真实安装螺栓分别拆除并取阀;无8号内六角工具。'],
[62,'简化实现','两个真实油堵分别封堵;擦净结合面仅为示意阀座平面变色。'],
[64,'简化实现','同小腔,补充布块移动、阀体变色;缺去污材质和管接头清洗。'],
[65,'简化实现','真实大腔接头和封口袋可操作;无19号扳手和接头旋松。'],
[66,'简化实现','四颗真实安装螺栓与大腔阀体可拆除;无8号内六角工具。'],
[67,'简化实现','两个真实油堵可封堵;阀座接触面仍是代码补充平面。'],
[69,'简化实现','示意阀座变色及两个油堵移开;缺阀体、阀座双方的擦拭动作。'],
[70,'简化实现','小腔来源阀换装到大腔位置,按四螺栓安装面换算朝向;可安装四颗螺栓,缺内六角工具。'],
[71,'待资料确认','原表同时写连接拧紧与拆开包扎。当前执行取袋接管并要求记录依据,交教员核对;不能自动判为正确装配。'],
[72,'待资料确认','复用第10步同一组四颗螺栓再次旋转。若固定螺栓和阀体连接螺栓是两组,当前缺第二组。'],
[74,'简化实现','示意阀座变色及两个油堵移开;缺阀体和阀座双面擦拭。'],
[75,'简化实现','大腔来源阀换装到小腔位置并调整朝向;四颗真实螺栓可装,缺内六角工具。'],
[76,'待资料确认','与第11步相同的装/拆原文矛盾;保留人工依据与教员核对,不能当作已澄清。'],
[77,'待资料确认','复用第14步四颗螺栓。是否另有一组四颗阀体连接螺栓仍待确认。'],
]};
const taskIds={'005':116,'006':87,'007':88,'008':89};
const rows=[];
for(const [code,notes] of Object.entries(data)){
const task=tasks.find(t=>String(t.id)===String(taskIds[code]));
if(notes.length!==task.definitionSnapshot.steps.length)throw Error('Step coverage mismatch '+code);
for(const [i,[row,grade,note]]of notes.entries()){
const step=task.definitionSnapshot.steps[i],ops=step.action.mechanism.steps;
const matches=runtime.checks.filter(c=>c.name.startsWith(`task ${taskIds[code]} step ${i+1} operation `));
const sourceRow=source[0].rows.find(r=>r['B'+row]);
rows.push({code,number:i+1,title:step.title,grade,note,source:`1-动画!B${row}:D${row}`,original:sourceRow?.['C'+row],
operations:ops.map(o=>({targetId:o.targetId,kind:o.kind,effects:o.effects})),
expectedOperations:ops.length,verifiedOperations:matches.length,
runtimeComplete:matches.length===ops.length,screenshot:`task-${taskIds[code]}-step-${i+1}.png`});
}
}
const counts=Object.fromEntries(['基本对应','简化实现','待资料确认','关键内容缺失'].map(s=>[s,rows.filter(r=>r.grade===s).length]));
const copiedModels=[];
for(const task of tasks.filter(t=>t.id!=='86'))for(const o of task.definitionSnapshot.scenario.sceneResource.snapshot.objects){
const supplied=models.find(m=>m.name===o.sourceName);if(!supplied)continue;
const file=path.resolve('../unreal_tran_web/public'+o.resourceUrl);
const sha256=crypto.createHash('sha256').update(fs.readFileSync(file)).digest('hex');
if(sha256!==supplied.sha256)throw Error('Source model changed '+o.sourceName);
if(!copiedModels.some(m=>m.source===o.sourceName))copiedModels.push({source:o.sourceName,file:o.resourceUrl,sha256});
}
const report={date:'2026-09-21',counts,verifiedSteps:rows.filter(r=>r.runtimeComplete).length,totalSteps:39,
verifiedOperations:rows.reduce((n,r)=>n+r.verifiedOperations,0),original005RuntimePass:originalRuntime?.pass===true,
runtimePass:runtime.pass,copiedModels,rows,
limitation:'仅教员预览真实点击/拖拽、准备与服务端步骤校验;不写学员成绩,不等同实装质量、工具尺寸、扭矩、压力和安全流程验收。'};
fs.writeFileSync(path.join(dir,'assessment.json'),JSON.stringify(report,null,2));
const summary=`# 四套脚本新模型逐步验收(2026-09-21)\n\n对照原始工作簿,检查当前接口任务定义、GLB节点与运行时代码,并用真实浏览器逐项操作。工作簿内容与2026-09-17提取件一致,本次重新读取并记录SHA-256。\n\n## 结论\n\n- 新模型39步:${report.verifiedSteps}/39步完成全部配置操作;浏览器总结果:${runtime.pass?'通过':'存在失败,见JSON'}。\n- 内容匹配:${Object.entries(counts).map(([k,v])=>k+' '+v+'步').join(';')}。这些是内容判断,不能用交互通关替代。\n- 005正式任务86仍使用旧“步骤模型.glb”;新模型005在验证任务116。006~008正式任务87~89已使用0916新模型。本次没有擅自更换任务版本。\n- 006第7步的整机正常作业、007第11步的试车验证,目前只有示意手柄,不能按原要求完成。\n- 008第11/15步装拆方向、12/16步是否两组螺栓、007第2步球阀编号,仍需专业资料确认。\n- 所有新GLB均无内嵌动画;局部机构动画由运行代码实现。提供的“开口扳手.glb”未接入当前场景,工具操作并非模型里自动具备。\n\n## 每一步\n\n|流程|步|步骤|内容匹配|操作验证|缺口/边界|原表|\n|---|---:|---|---|---|---|---|\n`;
const table=rows.map(r=>`|${r.code}|${r.number}|${r.title}|${r.grade}|${r.verifiedOperations}/${r.expectedOperations}|${r.note}|${r.source}|`).join('\n');
const tail=`\n\n## 优先补齐\n\n1. 006最后一步、007试车:需明确整机作业内容及试车合格判据,再绑定真实机构联动,不能仅移动示意开关。\n2. 008两组螺栓及装拆矛盾、007球阀编号:请模型/业务人员确认后才能据此更改评分或动作。\n3. 接入已有开口扳手,补充内六角工具、接头旋紧动作;工具规格与接触点需要核验。\n4. 补齐纸垫真实结合面尺寸、清洗去污、加油口关闭;005补充独立后泵定位及单泵工作结果演示。\n5. 005从验证入口切换正式任务另走内容发布与模型换版,避免影响已有运行。\n\n## 讲解与背景范围\n\n背景和讲解页已存在,不能继续沿用旧报告“没有导入页面”的结论。但文字/背景图不等于液压原理图和动态供油回路;原表要求的液压原理图、三类环境素材及整机作业演示仍需单独验收。本次新数字人资源覆盖39个操作步骤。\n\n## 验证边界\n\n${report.limitation}\n\n新模型文件已逐项与用户提供原文件核对SHA-256。步骤截图、接口快照、原表提取、模型节点清单与实时操作结果都保存在本报告目录。\n`;
fs.writeFileSync(path.join(dir,'验收报告.md'),summary+table+tail);
const esc=s=>String(s??'').replaceAll('&','&').replaceAll('<','<').replaceAll('>','>').replaceAll('"','"');
const cards=rows.map(r=>` ${esc(r.note)} ${esc(r.original)}${esc(r.title)}
查看原稿和动作目标
${esc(r.operations.map(o=>o.targetId+' · '+o.kind).join('\n'))}
${Object.entries(counts).map(([k,v])=>k+' '+v+'步').join(' · ')}
005 正式任务86仍是旧模型;新模型验证入口为116。006~008正式任务已用新模型。
主要缺口:006整机正常作业、007试车;008装拆方向与螺栓分组待确认。交互通关不等同于实装检修合格。
完整 Markdown 报告 · 逐项证据