import fs from 'node:fs';
import path from 'node:path';
import assert from 'node:assert/strict';
const root=path.resolve('reports/animation-capabilities-20260912');
const sections=[['model','模型编辑与发布'],['guide','指导书在线使用与交付'],['offline','离线播放'],['teaching','正式教学视口'],['training-editor','训练编辑器绑定']];
const escape=value=>String(value??'').replace(/[&<>"']/g,c=>({'&':'&','<':'<','>':'>','"':'"',"'":'''}[c]));
const results=sections.map(([key,name])=>({key,name,...JSON.parse(fs.readFileSync(path.join(root,key+'-checks.json'),'utf8'))}));
for(const result of results){assert.ok(result.checks.every(c=>c.pass),result.key);assert.equal(result.errors.length,0,result.key);}
const f=JSON.parse(fs.readFileSync(path.join(root,'fixture.json'),'utf8'));
const shots=[['01-animation-settings','动作与轨道设置:范围、结束处理、路径和阀门联动'],['02-editor-end-pose','模型编辑器中的组合动作'],['03-model-reopened','刷新重开后恢复动画配置'],['05-guide-model-animation','正式指导书模型视口'],['07-offline-before','离线包加载模型'],['08-offline-animation','离线片段播放及暂停'],['09-teaching-animation','教学步骤:保持末帧、清洁状态和流向开通'],['10-teaching-reset','教学步骤:播放结束复位并关闭流向'],['11-training-action-library','训练编辑器读取正式动作目录'],['12-training-action-bound','通过页面绑定并保存动作']];
const total=results.reduce((n,r)=>n+r.checks.length,0);
const html=`
动画能力实施与测试报告 · 2026-09-12
数字车间 · 功能实施 / 真实接口 / 浏览器端到端
模型动画能力实施与测试报告
2026-09-12 · ${total} 项端到端检查通过
按已确认范围补齐命名动作、组合运动、材质状态、流向讲解和跨模块复用。使用独立的牛奶卡车测试工程验证,不修改原始模型和既有业务任务。
已实施能力
| 能力 | 实现与使用 |
| 动作片段与机械组合运动 | 时间轴设置命名起止范围;旋转中心使用部件局部坐标;位移与 XYZ 旋转叠加,关键帧错开形成顺序动作;支持保持末帧和回到起点。蓝图按名称播放片段。 |
| 状态与材质 | 新增缩放、显隐、不透明度、颜色、材质状态轨道;材质副本隔离,不污染其他实例。录制与保存保留中性基准,旋转中心偏移不会被重复写入位移关键帧。 |
| 回路流向 | 配置路径点、颜色、速度、流点数量、正向/反向/停止;可关联标量轨道控制开通。用于工作原理讲解。 |
| 跨模块复用 | 训练编辑器从正式目录选动作,保存步骤绑定;教学任务固定模型/场景/训练版本;指导书在线模型与离线 ZIP 使用同一动画求值规则。原生 GLB 动画仍可选择。 |
实测结果
${results.map(r=>`${escape(r.name)}
| 检查 | 结果 |
${r.checks.map(c=>`| ${escape(c.name)} | 通过 |
`).join('')}
查看原始检查记录 · 浏览器脚本异常 ${r.errors.length} 条
`).join('')}
补充验证:前端类型检查及生产构建通过;生成的模型编辑器 public/dist 文件哈希一致。后端 18 条校验、快照与考试提示隔离用例通过;原型 5 项合同测试、Web 4 项场景/缓存/落地测试通过。构建仅有现有的大分块提示。
测试采用真实登录、GLB、保存/发布/下载接口。部分配置和视口内部状态由 Playwright 调用页面模块核对;教学原生 GLB 切换为浏览器运行时兼容检查。离线用例阻断业务接口及公网请求,外部请求数为 0。
可继续使用的测试数据
| 数据 | 标识 | 入口 |
| 组合动作模型 | ${f.modelId} · 固定模型版本 ${f.modelVersionId} | 打开模型编辑器 |
| 测试场景 | ${f.animationSceneId} · 版本 ${f.animationSceneVersionId} | 打开场景 |
| 两步骤测试训练 | ${f.animationTrainingId} | 打开训练编排 |
| 固定快照教学任务 | ${f.animationAssignmentId} · 训练版本 482 | 打开教学预览 |
| 动画指导书 | ${f.guideId} | 打开指导书 · 下载实测离线包 |
训练当前保留实测保存的草稿;已有任务仍使用旧发布快照,这正是版本隔离测试验证的行为。试验性教学任务未产生学员成绩。
使用顺序与边界
- 模型编辑器时间轴添加轨道,选择部件、属性及关键帧;进入「动作与轨道设置」配置片段、枢轴、材质状态或流向。
- 保存并发布模型,在场景选择固定版本;训练的「步骤动画」选择正式动作并保存。
- 发布训练、下发新任务后在教学端使用;指导书关联模型片段后可在线播放或导出离线 ZIP。
本次没有数据库表改动。未加入新的密钥文件、独立服务或认证方式。代码尚未提交 Git。
污渍/清洁通过颜色和粗糙度等 PBR 参数表达;贴图擦除、软管/密封圈弹性变形、真实流体压力计算、整片视频导出不在本次实施范围。表格中的具体装备动作仍需配置部件、路径和时序,本报告不代表已经制作完成全部动画素材。
浏览器截图
点击图片查看原图。
${shots.map(([file,title])=>`
${escape(title)}`).join('')}
`;
fs.writeFileSync(path.join(root,'index.html'),html);
fs.writeFileSync(path.join(root,'summary.json'),JSON.stringify({date:'2026-09-12',passed:total,failed:0,backendTests:18,prototypeContractTests:5,webTests:4,build:'passed',ddlChanges:false},null,2));
console.log(`Report generated: ${total} checks passed`);