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=>``).join('')}
任务聚焦前聚焦后自动隐藏
${titles[c.id]}${c.before}${c.after}${c.automaticHidden}

旋转视角后的实际画面

${Object.entries(titles).map(([id,title])=>``).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')}));