import fs from 'node:fs/promises';
import path from 'node:path';
import assert from 'node:assert/strict';
import {pathToFileURL} from 'node:url';
import {chromium} from '@playwright/test';
const folder=path.resolve('reports/bridge-solid-view-20260915');
const read=async file=>JSON.parse(await fs.readFile(path.join(folder,file),'utf8'));
const before=await read('../bridge-solid-view-before-20260915/result.json');
const after=await read('result.json'),lan=await read('../bridge-solid-view-lan-20260915/result.json');
assert.equal(before.pass,false);assert.equal(after.pass,true);assert.equal(lan.pass,true);
const flowFiles=['task-86.json','tasks-87-88.json','task-89.json'];
const flows=[];
for(const file of flowFiles){const result=await read('../bridge-solid-view-flow-20260915/'+file);assert.equal(result.pass,true);flows.push(result);}
const summary={pass:true,generatedAt:new Date().toISOString(),
rootCause:'聚焦/旋转视角时自动将遮挡网格 visible 设为 false。实际 GLB 的一块网格可能涵盖大片车身或地形,DoubleSide 无法显示已被隐藏的网格。',
changes:['删除自动遮挡隐藏及其恢复/逐帧射线逻辑','保留物理材质 DoubleSide','校准液压泵和球阀的可见观察面','只允许步骤动画及主动查看工具改变显隐'],
visibility:after.checks,lan:lan.checks,
operations:flows.reduce((n,r)=>n+r.checks.filter(c=>c.target).length,0),
serverValidations:flows.reduce((n,r)=>n+r.writes.length,0),
explicitTools:flows.flatMap(r=>r.checks.filter(c=>c.targetId)),
commands:[{command:'pnpm run build',pass:true},{command:'node scripts/virtual-training-formal-route.contract.test.mjs',pass:true},{command:'git diff --check',pass:true}],
environment:['http://127.0.0.1:6180','http://192.168.31.168:6180'],
account:'管理员 / 教员预览',data:'未新增任务、未写学员成绩;操作回归只使用现有任务的 preview/validate。',
};
assert.equal(summary.operations,94);assert.equal(summary.serverValidations,39);
await fs.writeFile(path.join(folder,'summary.json'),JSON.stringify(summary,null,2));
const titles={86:'005 液压泵应急切换',87:'006 液压泵应急替代',88:'007 前泵换件修复',89:'008 平衡阀拆拼互换'};
const html=`
双面材质与视角镂空修复
双面材质与视角镂空修复
2026-09-15 · 四套正式桥梁脚本 · 管理员 / 教员预览
结论:双面材质已生效,镂空来自自动隐藏网格。${summary.rootCause}
现已删除该逻辑。聚焦、旋转、增强辉光均不改变完整网格集合;显隐仅由实际步骤动画或用户主动操作控制。
复现与回归证据
修复前 005 聚焦后可见网格由 ${before.checks[0].before} 块变成 ${before.checks[0].after} 块。修复后四个场景均保持数量和网格标识完全一致,检查双面材质、三个方向旋转、辉光切换、半透明、隐藏其他及恢复。
| 任务 | 聚焦前 | 聚焦后 | 自动隐藏 |
${after.checks.filter(c=>c.before!=null).map(c=>`| ${titles[c.id]} | ${c.before} | ${c.after} | ${c.automaticHidden} |
`).join('')}
旋转视角后的实际画面
${Object.entries(titles).map(([id,title])=>`
${title}
方向 2 · 方向 3 · 工具恢复后
`).join('')}
实际操作回归
39 个步骤、94 次真实模型点击/拖动、39 次服务端预览校验通过。液压泵与球阀的可见观察方向已重新校准。
取力器等位于车体内部的部件,按用户操作打开“其他半透明”后查看和操作;重叠的流程零件可主动使用“隐藏其他”隔离查看。测试记录这些工具使用,不再靠自动移除车身保证命中。
${flowFiles.map(f=>`${f}`).join(' · ')}
环境:本机与局域网,经 6100 Gateway。${summary.data}
构建(含类型检查及模型发布包校验)、正式路由契约、Git 差异检查通过。
四场景显隐回归 · 局域网记录 · 修复前复现 · 汇总记录
`;
await fs.writeFile(path.join(folder,'index.html'),html);
const browser=await chromium.launch({channel:'msedge',headless:true});
try{const page=await browser.newPage({viewport:{width:1400,height:1000}});await page.goto(pathToFileURL(path.join(folder,'index.html')).href);assert.ok(await page.locator('img').evaluateAll(imgs=>imgs.every(i=>i.complete&&i.naturalWidth>0)));await page.screenshot({path:path.join(folder,'report-overview.png')});}finally{await browser.close();}
console.log(JSON.stringify({pass:true,operations:summary.operations,report:path.join(folder,'index.html')}));