25'ten fazla konu seçemezsiniz Konular bir harf veya rakamla başlamalı, kısa çizgiler ('-') içerebilir ve en fazla 35 karakter uzunluğunda olabilir.
 
 
 
 

40 satır
3.6 KiB

  1. import fs from 'node:fs';
  2. import assert from 'node:assert/strict';
  3. import {login,call} from './role-permissions-live.mjs';
  4. import {scripts,scriptDefinition} from '../../unreal_tran_web/src/features/virtual-training-scripts/definition.js';
  5. const dir='reports/bridge-new-models-006-008-20260917';fs.mkdirSync(dir,{recursive:true});
  6. const signed=await login('root');
  7. const api=async(endpoint,body,method)=>{const r=await call('tran/v1/'+endpoint,signed.accessToken,body,method);assert.equal(r.status,200,endpoint+': '+r.message);return r.data;};
  8. const backup=(name,value)=>{const p=dir+'/'+name+'.json';if(!fs.existsSync(p))fs.writeFileSync(p,JSON.stringify(value,null,2));};
  9. for(const id of [86,116])backup('unchanged-'+id,await api('teaching/assignments/'+id));
  10. const migrated=[];
  11. for(const [id,code]of [[87,'TASK-VIRTUAL-006'],[88,'TASK-VIRTUAL-007'],[89,'TASK-VIRTUAL-008']]){
  12. let task=await api('teaching/assignments/'+id),detail=await api('content/projects/'+task.contentProjectId);
  13. assert.equal(task.code,code);const script=scripts.find(s=>s.code===code);assert.equal(task.definitionSnapshot.runtime.scriptId,script.id);
  14. backup('before-task-'+id,task);backup('before-project-'+task.contentProjectId,detail);
  15. if(task.definitionSnapshot.runtime.scriptVersion==='4'){migrated.push({id,code,versionId:task.contentVersionId});continue;}
  16. const content=structuredClone(detail.currentVersion.content),next=scriptDefinition(script);
  17. // Retain all scoring, speech assets, step codes, observations and task membership.
  18. content.scenario=next.scenario;content.runtime={...content.runtime,scriptVersion:'4'};
  19. if(code==='TASK-VIRTUAL-006'){
  20. const current=content.steps[4],replacement=next.steps[4];
  21. current.action=replacement.action;current.targetId=replacement.targetId;current.targetName='滤油器出口球阀 1';
  22. }
  23. if(detail.currentVersion.content.runtime.scriptVersion!=='4'){
  24. detail=await api('content/projects/'+detail.project.id,{...detail.project,content,assets:detail.currentVersion.assets,dependencies:detail.currentVersion.dependencies,version:detail.project.version,changeSummary:'换用0916整车及配套零件,原位操作;保留步骤编码、讲解与成绩规则'},'PUT');
  25. }
  26. if(detail.project.publishedVersionId!==detail.currentVersion.id)detail=await api('content/projects/'+detail.project.id+'/publish',{version:detail.project.version});
  27. if(id!==87 && task.status==='PUBLISHED'){
  28. task=await api('teaching/assignments/'+id+'/model-version',{contentVersionId:detail.project.publishedVersionId,version:task.version,reason:'只更新模型,保留步骤、操作、讲解、成绩及已有训练记录'},'PUT');
  29. }else{
  30. if(task.status==='PUBLISHED')task=await api('teaching/assignments/'+id+'/withdraw',{version:task.version,reason:'更新为已核验的0916模型版本,保留原任务与历史训练记录'});
  31. assert.ok(['DRAFT','WITHDRAWN'].includes(task.status));
  32. task=await api('teaching/assignments/'+id,{...task,contentVersionId:detail.project.publishedVersionId,version:task.version},'PUT');
  33. task=await api('teaching/assignments/'+id+'/publish',{version:task.version});
  34. }
  35. assert.equal(task.status,'PUBLISHED');assert.equal(task.definitionSnapshot.runtime.scriptVersion,'4');
  36. migrated.push({id,code,projectId:task.contentProjectId,versionId:task.contentVersionId,steps:task.definitionSnapshot.steps.length});console.log(migrated.at(-1));
  37. }
  38. for(const id of [86,116]){const before=JSON.parse(fs.readFileSync(dir+'/unchanged-'+id+'.json')),after=await api('teaching/assignments/'+id);delete before.serverNow;delete after.serverNow;assert.deepEqual(after,before);}
  39. fs.writeFileSync(dir+'/migration.json',JSON.stringify({pass:true,migrated,unchanged:[86,116]},null,2));