Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.
 
 
 
 

30 строки
4.8 KiB

  1. import fs from 'node:fs';
  2. import assert from 'node:assert/strict';
  3. import {createHash} from 'node:crypto';
  4. import {login,call} from './role-permissions-live.mjs';
  5. const dir='reports/bridge-new-models-006-008-20260917',read=name=>JSON.parse(fs.readFileSync(dir+'/'+name+'.json','utf8'));
  6. assert.equal(read('list').pass,true,'local and LAN task covers');
  7. assert.equal(read('lan-media-and-005').pass,true,'LAN media playback and unchanged 005 entries');
  8. const session=await login('root');
  9. const api=async url=>{const r=await call('tran/v1/'+url,session.accessToken);assert.equal(r.status,200,r.message);return r.data;};
  10. const tasks=[];
  11. for(const [id,code]of [[87,'006'],[88,'007'],[89,'008']]){
  12. const task=await api('teaching/assignments/'+id),before=read('before-task-'+id),live=read('task-'+code+'-live');
  13. assert.equal(live.pass,true,code+' browser regression');assert.equal(task.status,'PUBLISHED');assert.equal(task.definitionSnapshot.runtime.scriptVersion,'4');
  14. assert.equal(task.code,before.code);assert.equal(task.runCount,before.runCount);assert.deepEqual(task.members,before.members);
  15. if(id!==87)assert.deepEqual(task.definitionSnapshot.steps,before.definitionSnapshot.steps,'existing operations and scoring unchanged');
  16. const runs=await api('teaching/runs?assignmentId='+id+'&size=100');
  17. tasks.push({id,code:task.code,name:task.name,versionId:task.contentVersionId,steps:task.definitionSnapshot.steps.length,operations:live.checks.filter(c=>/ step \d+ operation /.test(c.name)).length,members:task.members.length,runCount:task.runCount,runs:runs.records.map(r=>({id:r.id,status:r.status})),preview:'/teaching/virtual-training/preview/'+id});
  18. }
  19. for(const id of [86,116]){const before=read('unchanged-'+id),after=await api('teaching/assignments/'+id);delete before.serverNow;delete after.serverNow;assert.deepEqual(after,before);}
  20. const models=[];
  21. for(const [source,file]of [['0916架桥车.glb','bridge-erector-20260916.glb'],['0916保障车.glb','bridge-support-20260916.glb'],['双车连接油管.glb','bridge-rescue-hoses-20260916.glb'],['3封口袋.glb','bridge-pump-bags-20260916.glb'],['4封口袋.glb','bridge-valve-bags-20260916.glb'],['牛皮纸.glb','bridge-paper-20260916.glb']]){
  22. const a=fs.readFileSync('../../模型/'+source),b=fs.readFileSync('../unreal_tran_web/public/models/'+file);assert.deepEqual(a,b);models.push({source,url:'/models/'+file,bytes:b.length,sha256:createHash('sha256').update(b).digest('hex')});
  23. }
  24. const audit={pass:true,time:new Date().toISOString(),environment:'127.0.0.1:6180 / 192.168.31.168:6180 through Gateway',role:'管理员教员预览',tasks,unchanged:[86,116],models};
  25. fs.writeFileSync(dir+'/audit.json',JSON.stringify(audit,null,2));
  26. const rows=tasks.map(t=>`<tr><td>${t.code}</td><td>${t.name}</td><td>${t.steps}</td><td>${t.operations}</td><td>${t.versionId}</td><td>通过</td></tr>`).join('');
  27. const sections=tasks.map(t=>`<h2>${t.code} · ${t.name}</h2><p><a href="http://127.0.0.1:6180${t.preview}">打开现有任务预览</a> · <a href="task-${t.code.slice(-3)}-live.json">逐项动作检查</a></p><img src="covers/${t.code}-scene.jpg" alt="新模型场景封面"><img src="task-${t.id}-step-${t.steps}.png" alt="最终步骤完成">`).join('');
  28. fs.writeFileSync(dir+'/index.html',`<!doctype html><html lang="zh-CN"><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>006~008 新模型验收</title><style>body{font:16px/1.7 system-ui;max-width:1100px;margin:32px auto;padding:0 20px;color:#153b37}table{width:100%;border-collapse:collapse}td,th{border:1px solid #bdd8d1;padding:8px}img{max-width:100%;margin:8px 0;border:1px solid #bdd8d1}a{color:#087d69}</style><h1>006~008 新模型验收</h1><p>更新现有任务;005 两个入口未变。新模型来自用户提供文件,保留原始字节;旧内容版本及 v3 定义保留。现有成员、运行记录和成绩规则没有删除或重建。</p><table><tr><th>任务</th><th>名称</th><th>步骤</th><th>真实交互</th><th>内容版本</th><th>结果</th></tr>${rows}</table><p>以管理员教员预览通过真实鼠标点击/拖拽、逐步服务端校验完成;预览不写入学员成绩。006 分别操作两个出口球阀,007 拆装四颗真实螺栓,008 完成两侧阀体互换。数字人视频与语音保留。</p><p>保障车取力器开关、试验手柄、清洗布、阀座结合面等没有独立精确模型的项目仍标明操作示意。</p><p>校验命令:node --test scripts/bridge-new-models.test.mjs;node scripts/virtual-training-formal-route.contract.test.mjs;pnpm run build;mvn -pl ut_tran -Dtest=ScriptedTrainingContractTest,ScriptModelRevisionTest test。<a href="audit.json">数据与文件校验</a> · <a href="migration.json">版本迁移</a>。测试没有新增教学任务。</p>${sections}</html>`);
  29. console.log(JSON.stringify(tasks));