forked from harmony_car/subject-two
849 lines
27 KiB
TypeScript
849 lines
27 KiB
TypeScript
import systemTime from '@ohos.systemDateTime';
|
||
import router from '@ohos.router';
|
||
import util from '@ohos.util';
|
||
import buffer from '@ohos.buffer';
|
||
import {testMarkRules,testKm2Items} from './dataTest/index'
|
||
import VoiceAnnounce from './utils/voice-announcements'
|
||
import FileModel from './utils/file-model'
|
||
import FilePhoto from './utils/file-photo'
|
||
import JudgeTask from './utils/judge-task'
|
||
import FileUtil from '../../common/utils/File'
|
||
import { judgeConfig } from './utils/judge-config'
|
||
import {writeObjectOut,uploadExamProgressData} from '../../api/judge'
|
||
import {deepClone,getCurrentTime,stringToASC,string2Bytes,fillZero,Array2Byte,convertGpsCoord2} from '../../common/utils/tools'
|
||
import {getTranslateSignals,getCarStatus,getCarStatusType,getCenterProjectStatus,plcStrToJson,plcStrToWXJson,promptWxCode} from './utils//judge-common'
|
||
import {examJudgeSetLogCallback,examJudgeBeginExam,examJudgeInit,examJudgeRealExam,examJudgeSetRealExamCallback,examJudgeSetPerformCallback,examJudgeEndExam} from './api/index'
|
||
|
||
const judgeTag = 'SURENJUN_JUDGE'
|
||
|
||
export default class Judge{
|
||
|
||
constructor(judgeUI,fileLog) {
|
||
this.serialIndex = 1;
|
||
this.judgeUI = judgeUI
|
||
this.fileLog = fileLog;
|
||
//语音播放工具
|
||
this.avPlayer = new VoiceAnnounce();
|
||
//模型工具
|
||
this.fileModel = new FileModel(judgeUI.context);
|
||
//文件工具
|
||
this.fileUtil = new FileUtil(judgeUI.context)
|
||
this.judgeTask = new JudgeTask()
|
||
const mediaTest= new FilePhoto(judgeUI.context);
|
||
this.filePhoto = mediaTest
|
||
this.kfArr = judgeUI.kfArr
|
||
this.xmmcStr = '';this.xmmcCode = '';this.carztStr = '';
|
||
this.allKm2ItemsObj = {};
|
||
|
||
// 考试回放配置
|
||
const {isTrajectoryOpen,modelPath,trajectoryPath} = judgeConfig
|
||
this.isTrajectoryOpen = isTrajectoryOpen;
|
||
this.modelPath = modelPath;
|
||
this.trajectoryPath = trajectoryPath;
|
||
|
||
this.isExam = !globalThis.singlePlay;
|
||
const {projectsCenterObj} = judgeUI
|
||
|
||
//科目三待修改
|
||
testKm2Items.forEach(item => {
|
||
this.allKm2ItemsObj[item.code] = item;
|
||
//考试项目存在
|
||
if(projectsCenterObj[item.code]){
|
||
this.allKm2ItemsObj[item.code] = {code:item.code,status:1}
|
||
}
|
||
})
|
||
this.isEnd = false;
|
||
}
|
||
|
||
//开始评判
|
||
private async judging(callBack:Function){
|
||
const {getJudgeBeginData,getPlcData,fileLog,fileUtil,isTrajectoryOpen,trajectoryPath,avPlayer} = this;
|
||
const isJudgeInitBool = globalThis.isJudgeInitBool;
|
||
let strArr = [];
|
||
if(isTrajectoryOpen){
|
||
const folderPath = await this.fileUtil.initFolder(trajectoryPath);
|
||
const str = await fileUtil.readFile(folderPath)
|
||
strArr = str.split('\n')
|
||
}
|
||
//日志回调
|
||
console.info(judgeTag,'1.进入评判入口')
|
||
await examJudgeSetLogCallback(3, async (level, info,len)=>{
|
||
console.log('评判日志:' + info)
|
||
await fileLog.setExamJudgeLogData(info);
|
||
})
|
||
|
||
console.info(judgeTag,'2.注册日志回调完成')
|
||
|
||
let initInfo:any = ''
|
||
if(isTrajectoryOpen){
|
||
initInfo = JSON.parse(strArr[0])
|
||
}else{
|
||
initInfo = await this.getJudgeInitData();
|
||
}
|
||
|
||
//相关评判初始化只做一次
|
||
if(!isJudgeInitBool){
|
||
await fileLog.setExamJudgeData(initInfo)
|
||
const tempJudge = await examJudgeInit(initInfo);
|
||
globalThis.isJudgeInitBool = true
|
||
console.info(judgeTag,'4.评判初始化完成')
|
||
}else{
|
||
await fileLog.setExamJudgeData(initInfo)
|
||
}
|
||
|
||
globalThis.isJudge = true
|
||
// 2.评判过程回调
|
||
await examJudgeSetRealExamCallback(async (strData,len)=>{
|
||
await fileLog.setExamJudgeCallbackData(strData)
|
||
console.info('评判回调数据',strData)
|
||
this.handleRealExam(strData,callBack)
|
||
})
|
||
|
||
await examJudgeSetPerformCallback(async (info)=>{
|
||
console.info('评判实时数据',info)
|
||
this.performInfo = info
|
||
})
|
||
|
||
// 3.开始考试
|
||
let beginExamInfo
|
||
if(isTrajectoryOpen){
|
||
beginExamInfo = JSON.parse(strArr[1])
|
||
}else{
|
||
//获取开始考试数据
|
||
beginExamInfo = await getJudgeBeginData()
|
||
}
|
||
await fileLog.setExamJudgeData(beginExamInfo)
|
||
await examJudgeBeginExam(beginExamInfo);
|
||
console.info(judgeTag,'6.开始考试注册完成')
|
||
|
||
//实时plc数据信号
|
||
if(isTrajectoryOpen){
|
||
let num = 2;
|
||
const judgeTimer = setInterval(async ()=>{
|
||
const msg = JSON.parse(strArr[num]);
|
||
await fileLog.setExamJudgeData(msg)
|
||
if(!msg){
|
||
console.info(judgeTag,'模拟数据考试结束')
|
||
examJudgeEndExam();
|
||
globalThis.windowClass.setWindowSystemBarEnable(['navigation'])
|
||
clearInterval(judgeTimer)
|
||
return
|
||
}
|
||
// 4.过程数据
|
||
this.tempData = msg
|
||
this.plcData= msg
|
||
globalThis.msgStr= ''
|
||
await examJudgeRealExam(msg)
|
||
num++
|
||
},100)
|
||
globalThis.judgeTimer = judgeTimer;
|
||
return
|
||
}
|
||
|
||
globalThis.udpClient.onMessage(async (msg) => {
|
||
console.info('plc信号',msg)
|
||
const stachArr= msg.split(',')
|
||
const {isEnd} = this;
|
||
if (stachArr[0] != '#DN_GD' || isEnd) {
|
||
return
|
||
}
|
||
const plcData = await getPlcData(msg);
|
||
// 4.过程数据
|
||
await fileLog.setExamJudgeData(plcData)
|
||
await examJudgeRealExam(plcData)
|
||
const udpIndex = globalThis.udpIndex;
|
||
if(udpIndex % 5 === 0){
|
||
const judgeUdp = globalThis.judgeUdp
|
||
//平台实时轨迹心跳
|
||
const bytes= await this.getMessageHeartbeat();
|
||
judgeUdp.send(bytes)
|
||
}
|
||
globalThis.udpIndex+=1
|
||
})
|
||
|
||
avPlayer.playAudio(['km2/ksks.WAV'],true)
|
||
}
|
||
|
||
public async onJudgeFn(fn:Function){
|
||
await this.judging(fn)
|
||
}
|
||
|
||
//处理评判过程回调
|
||
handleRealExam = async (strData,callBack) => {
|
||
// console.log('过程数据:' + strData);
|
||
let examData = JSON.parse(strData);
|
||
const {getDqxmStr,getKfStr,judgeUI} = this;
|
||
const {carzt,xmks,kf,event,xmjs,ksjs} = examData
|
||
|
||
//获取项目结束、项目开始代码
|
||
const xmdm = event == 2 ? xmjs.xmdm : xmks.xmdm
|
||
const xmxh = event == 2 ? xmjs.xmxh : xmks.xmxh;
|
||
|
||
switch (event){
|
||
//项目开始
|
||
case 1:
|
||
judgeUI.projectsObj[xmdm].type = '2';
|
||
const xmmcStr = judgeUI.projectsObj[xmdm].name;
|
||
const xmmcCode = judgeUI.projectsObj[xmdm].projectCodeCenter;
|
||
const xmmcSingleCode = judgeUI.projectsObj[xmdm].projectCode;
|
||
this.allKm2ItemsObj[xmmcCode].status = 2;
|
||
this.xmmcStr = xmmcStr;
|
||
this.xmmcCode = xmmcCode;
|
||
this.xmmcSingleCode = xmmcSingleCode
|
||
this.xmdm = xmdm;
|
||
this.xmxh = xmxh;
|
||
break;
|
||
|
||
//项目结束
|
||
case 2:
|
||
judgeUI.projectsObj[xmdm].type = (xmjs.xmhg === 0 ? '4' : '3');
|
||
this.xmmcStr = '无';
|
||
this.xmmcCode = '';
|
||
this.xmmcSingleCode = 0;
|
||
this.xmdm = '';
|
||
break;
|
||
|
||
//扣分
|
||
case 3:
|
||
const thisKf = getKfStr(`${kf.xmdm}_${kf.kfdm}`)
|
||
//扣分信息
|
||
this.kfArr.push({
|
||
//扣分项目名称
|
||
xmmcStr:getDqxmStr(kf.xmdm),
|
||
xmdm:kf.xmdm,
|
||
//扣分描述
|
||
desc:thisKf.desc,
|
||
//扣分分数
|
||
score:thisKf.score,
|
||
// 扣分无锡所代码
|
||
markcatalog:thisKf.markcatalog,
|
||
markserial:thisKf.markserial,
|
||
kfxh:thisKf.kfxh
|
||
})
|
||
this.judgeUI.totalScore += thisKf.score*1;
|
||
break;
|
||
|
||
//考车状态
|
||
case 4: this.carztStr = getCarStatus(carzt);break;
|
||
|
||
//考试结束
|
||
case 5: this.ksjs = ksjs;break;
|
||
default:;break;
|
||
}
|
||
const {xmmcStr,carztStr,kfArr} = this;
|
||
await callBack({
|
||
//项目名称 考车状态 扣分arr
|
||
xmmcStr, carztStr, kfArr
|
||
});
|
||
const copyProjectsObj = this.judgeUI.projectsObj;
|
||
|
||
//语音播报
|
||
this.goVoiceAnnounce(event,xmdm, this.kfArr,xmjs)
|
||
judgeUI.projectsObj = deepClone(copyProjectsObj)
|
||
}
|
||
|
||
//更改考试状态
|
||
goVoiceAnnounce = async (event,xmdm,kf,xmjs) => {
|
||
const projectsObj = this.judgeUI.projectsObj;
|
||
const {beginProject,pointsDedute,endProject,avPlayer,uploadProgressPhoto,judgeTask,handEndExam} = this;
|
||
const xmhg = xmjs.xmhg
|
||
const kfLen = kf.length
|
||
switch (event){
|
||
|
||
// 项目开始
|
||
case 1:
|
||
avPlayer.playAudio([`km2/${projectsObj[xmdm].projectCodeCenter}.mp3`],true)
|
||
//项目开始同步接口
|
||
await judgeTask.addTask(async ()=>{
|
||
console.info(judgeTag,'项目开始 start')
|
||
await beginProject(xmdm)
|
||
console.info(judgeTag,'上传照片 start')
|
||
await uploadProgressPhoto(xmdm)
|
||
})
|
||
break;
|
||
|
||
// 项目结束
|
||
case 2:
|
||
await judgeTask.addTask(async ()=>{
|
||
console.info(judgeTag,'项目结束 start')
|
||
await endProject(xmdm)
|
||
})
|
||
break;
|
||
|
||
// 扣分
|
||
case 3:
|
||
console.info(judgeTag ,kf[kfLen -1].markcatalog);
|
||
avPlayer.playAudio([`km2/${kf[kfLen -1].markcatalog}.mp3`])
|
||
await judgeTask.addTask(async ()=>{
|
||
console.info(judgeTag,'项目扣分 start')
|
||
await pointsDedute(kf[kfLen -1].xmdm,kf[kfLen -1])
|
||
})
|
||
break;
|
||
|
||
// 考车状态
|
||
case 4:break
|
||
|
||
// 考试结束
|
||
case 5:
|
||
clearInterval(globalThis.judgeTimer)
|
||
await judgeTask.addTask(async ()=>{
|
||
console.info(judgeTag,'考试结束 start')
|
||
await handEndExam()
|
||
})
|
||
break
|
||
default:break
|
||
}
|
||
}
|
||
|
||
//处理考试结束
|
||
public handEndExam = async ()=>{
|
||
const {endExam,avPlayer} = this;
|
||
avPlayer.playAudio(['km2/exam_waiting.mp3'],true)
|
||
this.isEnd = true
|
||
// 获取最后一次心跳
|
||
const bytes = await this.getMessageHeartbeat(true);
|
||
const singlePlay = globalThis.singlePlay
|
||
singlePlay || globalThis.judgeUdp.send(bytes)
|
||
// c++调用考试结束
|
||
await examJudgeEndExam();
|
||
globalThis.isJudge = false
|
||
await endExam()
|
||
}
|
||
|
||
// 过程照片拍照
|
||
getPhoto = async (empty?:boolean) => {
|
||
const singlePlay = globalThis.singlePlay
|
||
//单机模式返回空照片
|
||
if(singlePlay){
|
||
return ''
|
||
}else{
|
||
const {filePhoto} = this;
|
||
const photoBase64 = await filePhoto.getPhoto();
|
||
console.info(judgeTag,'拍照完成')
|
||
return photoBase64
|
||
}
|
||
}
|
||
|
||
// 当前项目转换
|
||
getDqxmStr = (type) => {
|
||
const projectsObj = this.judgeUI.projectsObj
|
||
return projectsObj[type]?.abbreviation || '通用评判'
|
||
}
|
||
|
||
// 扣分项目转换
|
||
getKfStr = (code) => {
|
||
const markRuleListObj = this.judgeUI.markRuleListObj;
|
||
const thisMark = markRuleListObj[code]
|
||
return {
|
||
//扣分描述
|
||
desc: thisMark.markshow,
|
||
//扣分分数
|
||
score: thisMark.markreal,
|
||
markcatalog: thisMark.markcatalog,
|
||
// 扣分编码
|
||
markserial:thisMark.markserial,
|
||
// 扣分序号
|
||
kfxh:thisMark.kfxh
|
||
}
|
||
}
|
||
|
||
// 项目开始接口同步
|
||
beginProject = async(ksxm) => {
|
||
const carInfo = globalThis.carInfo;
|
||
const { examSubject,plateNo } = carInfo;
|
||
const {judgeUI,fileLog,getSbbm,xmxh} = this;
|
||
const {lsh,idCard,serialNumber,projectsObj,ksdd,kslx} = judgeUI
|
||
const time = await getCurrentTime();
|
||
const project = projectsObj[ksxm]
|
||
const sbxh = getSbbm(ksxm,xmxh)
|
||
const data = {
|
||
//系统类别 接口序列号 接口标识
|
||
xtlb:'17', jkxlh:serialNumber, jkid:'17C52',
|
||
drvexam:{
|
||
// 考试科目 身份证号码
|
||
lsh, kskm:examSubject, sfzmhm:idCard, ksxm:project.projectCodeCenter,sbxh, kchp:encodeURI(plateNo),
|
||
// 开始时间
|
||
ksdd:encodeURI(ksdd), ksxl:encodeURI(kslx) || '', kssj:time
|
||
}
|
||
}
|
||
const code = await writeObjectOut(data)
|
||
console.info(judgeTag,'项目开始 end')
|
||
if(code === 2300007){this.isJudgeDisConnect = true;}
|
||
const isJudgeDisConnect = this.isJudgeDisConnect
|
||
isJudgeDisConnect ? fileLog.setExamJudgeDisWuxiProgressData(data) : fileLog.setExamJudgeWuxiData(data)
|
||
promptWxCode('17C52',code)
|
||
}
|
||
|
||
// 项目结束接口同步
|
||
endProject = async(ksxm) =>{
|
||
const carInfo = globalThis.carInfo;
|
||
const deviceNo = globalThis.deviceNo;
|
||
const { examSubject,plateNo,carNo } = carInfo;
|
||
const {judgeUI,fileLog,getSbxh,xmxh,getSbbm} = this;
|
||
const {lsh,idCard,serialNumber,projectsObj,cdsbInfoObj,ksdd,kslx} = judgeUI
|
||
const time = await getCurrentTime();
|
||
const project = projectsObj[ksxm]
|
||
const sbxh = getSbbm(ksxm,xmxh)
|
||
|
||
const data = {
|
||
xtlb:'17',jkxlh:serialNumber,jkid:'17C55',
|
||
drvexam:{
|
||
lsh,kskm:examSubject,sfzmhm:idCard,
|
||
ksxm:project.projectCodeCenter,
|
||
sbxh,
|
||
//操作类型 1:正常 0:撤销该考试记录
|
||
czlx:'1',
|
||
kchp:encodeURI(plateNo),ksdd:encodeURI(ksdd),ksxl:encodeURI(kslx) || '',
|
||
jssj:time
|
||
}
|
||
}
|
||
const code = await writeObjectOut(data)
|
||
if(code === 2300007){this.isJudgeDisConnect = true;}
|
||
const isJudgeDisConnect = this.isJudgeDisConnect
|
||
isJudgeDisConnect ? fileLog.setExamJudgeDisWuxiProgressData(data) : fileLog.setExamJudgeWuxiData(data)
|
||
console.info(judgeTag,'项目结束 end')
|
||
promptWxCode('17C55',code)
|
||
}
|
||
|
||
// 考试扣分
|
||
pointsDedute= async (ksxm,kf) => {
|
||
const carInfo = globalThis.carInfo;
|
||
const deviceNo = globalThis.deviceNo;
|
||
const { examSubject,plateNo,carNo } = carInfo;
|
||
const {judgeUI,getProjectInfo,fileLog} = this;
|
||
const {lsh,idCard,serialNumber,ksdd} = judgeUI
|
||
const time = await getCurrentTime();
|
||
const project = getProjectInfo(ksxm);
|
||
const data = {
|
||
xtlb:'17',jkxlh:serialNumber,jkid:'17C53',
|
||
drvexam:{
|
||
lsh,kskm:examSubject,
|
||
//TODO 通用评判科二10000,科三30000
|
||
ksxm:project?project.projectCodeCenter:10000,
|
||
kfxm:kf.markcatalog,
|
||
kfxmmx:`${ksxm},${kf.markserial}`,
|
||
sfzmhm:idCard, kchp:encodeURI(carInfo.plateNo),
|
||
//1:自动 2:人工
|
||
kffs:1,
|
||
ksdd:encodeURI(ksdd), kfsj:time
|
||
}
|
||
}
|
||
const code = await writeObjectOut(data);
|
||
if(code === 2300007){this.isJudgeDisConnect = true}
|
||
const isJudgeDisConnect = this.isJudgeDisConnect
|
||
isJudgeDisConnect ? fileLog.setExamJudgeDisWuxiProgressData(data) : fileLog.setExamJudgeWuxiData(data)
|
||
console.info(judgeTag,'项目扣分 end')
|
||
promptWxCode('17C53',code)
|
||
}
|
||
|
||
// 考试过程照片
|
||
uploadProgressPhoto = async (ksxm) => {
|
||
const time = await getCurrentTime();
|
||
const {judgeUI,plcData,getPhoto,fileLog} = this;
|
||
const photoBase64 = await getPhoto();
|
||
const carInfo = globalThis.carInfo;
|
||
const { examSubject,plateNo,carNo } = carInfo;
|
||
const {lsh,idCard,serialNumber,projectsObj,ksdd} = judgeUI;
|
||
const {sensor,gps} = plcData
|
||
const project = projectsObj[ksxm]
|
||
|
||
const data = {
|
||
xtlb:'17',jkxlh:serialNumber,jkid:'17C54',
|
||
drvexam:{
|
||
lsh,kskm:examSubject,ksxm:project.projectCodeCenter,
|
||
sfzmhm:idCard,kchp:encodeURI(plateNo),zpsj:time,
|
||
//@ts-ignore
|
||
zp:encodeURIComponent(photoBase64),
|
||
cs:Math.ceil(gps.sd * 1.852),
|
||
ksdd:encodeURI(ksdd)
|
||
}
|
||
};
|
||
const code = await writeObjectOut(data);
|
||
if(code === 2300007){this.isJudgeDisConnect = true}
|
||
promptWxCode('17C54',code)
|
||
fileLog.setExamJudgeWuxiData(data)
|
||
console.info(judgeTag,'上传照片 end')
|
||
}
|
||
|
||
// 考试结束
|
||
public endExam = async (isManual?:Boolean) => {
|
||
const carInfo = globalThis.carInfo;
|
||
const deviceNo = globalThis.deviceNo;
|
||
const { examSubject ,plateNo} = carInfo;
|
||
const {judgeUI,fileLog,ksjs,getPhoto,uploadProgressData,uploadDisConnectData,avPlayer} = this;
|
||
const {lsh,idCard,serialNumber,kssycs,totalScore} = judgeUI
|
||
await uploadDisConnectData();
|
||
const time = await getCurrentTime();
|
||
const photoBase64 = await getPhoto();
|
||
const data = {
|
||
xtlb:'17',jkxlh:serialNumber,jkid:'17C56',
|
||
drvexam:{
|
||
lsh,kchp:encodeURI(plateNo),kskm:examSubject,sfzmhm:idCard,
|
||
//@ts-ignore
|
||
zp:encodeURIComponent(photoBase64),jssj:time,
|
||
kscj:(totalScore*1) > 0 ? totalScore : 0,
|
||
kslc:(ksjs?.qjjl + ksjs?.dcjl) || 0,
|
||
dwlc:'',
|
||
}
|
||
}
|
||
const code = await writeObjectOut(data);
|
||
promptWxCode('17C56',code)
|
||
console.info(judgeTag,'考试结束 end')
|
||
if(!isManual){
|
||
if(totalScore < 80){
|
||
judgeUI.loadingPopupVisible = true
|
||
//考试次数为1次
|
||
if(kssycs == 1){
|
||
avPlayer.playAudio(['km2/unqualified_one.wav'],true)
|
||
}else{
|
||
avPlayer.playAudio(['km2/unqualified_two.wav'],true)
|
||
}
|
||
}else{
|
||
avPlayer.playAudio(['km2/qualified.mp3'],true)
|
||
}
|
||
}
|
||
console.info(judgeTag,`考试成绩:${totalScore}`)
|
||
fileLog.setExamJudgeWuxiData(data)
|
||
await uploadProgressData();
|
||
setTimeout(()=>{
|
||
router.back();
|
||
},3000)
|
||
|
||
}
|
||
|
||
// 断网数据补传
|
||
uploadDisConnectData = async () => {
|
||
const {isJudgeDisConnect,fileLog,fileUtil} = this;
|
||
if(!isJudgeDisConnect){
|
||
return
|
||
}
|
||
const folderPath = fileLog.folderPath
|
||
const examDataStr = await fileUtil.readFile(`${folderPath}/wuxi_dis_progress_data.txt`);
|
||
const examDataArr = examDataStr.split('\n');
|
||
for(let examDataStr of examDataArr){
|
||
const examData = JSON.parse(examDataStr)
|
||
const code = await writeObjectOut(examData);
|
||
}
|
||
}
|
||
|
||
//上传无锡所过程数据
|
||
uploadProgressData = async () => {
|
||
const {judgeUI,fileUtil,fileLog} = this;
|
||
const {idCard,startFullTime} = judgeUI
|
||
const carInfo = globalThis.carInfo;
|
||
const {carId,examinationRoomId} = carInfo
|
||
const folderPath = fileLog.folderPath
|
||
const base64 = new util.Base64();
|
||
const time = await getCurrentTime();
|
||
const endTime = await getCurrentTime(1)
|
||
let examDataBase64
|
||
//@ts-ignore
|
||
//TODO try catch报错待优化
|
||
const examDataStr:string = await fileUtil.readFile(`${folderPath}/wuxi_progress_data.txt`);
|
||
try {
|
||
let tempBuff = buffer.alloc(examDataStr.length, examDataStr)
|
||
let examData:Uint8Array = new Uint8Array(tempBuff.buffer)
|
||
examDataBase64 = base64.encodeToStringSync(examData)
|
||
}catch (e){
|
||
console.info(judgeTag,JSON.stringify(e))
|
||
}
|
||
console.info(judgeTag,'过程数据文件上传 start')
|
||
await uploadExamProgressData({
|
||
time,
|
||
carId,
|
||
examinationRoomId,
|
||
examData:examDataBase64,
|
||
type:1,
|
||
cardNo:idCard,
|
||
examStartTime:startFullTime,
|
||
examEndTime:endTime,
|
||
})
|
||
console.info(judgeTag,'过程数据文件上传 end')
|
||
}
|
||
|
||
// 获取评判初始化数据
|
||
getJudgeInitData = async () => {
|
||
const {getModelData} = this
|
||
const carInfo = globalThis.carInfo;
|
||
const { examSubject,plateNo,carNo } = carInfo;
|
||
const {fileLog} = this
|
||
const judgeUI = this.judgeUI
|
||
const {projectsObj,cdsbInfoObj,markRuleListObj,carType,carName} = judgeUI
|
||
const initInfo = {
|
||
kskm:examSubject*1,
|
||
kchp:plateNo,
|
||
kchm:carNo*1,
|
||
kscx:carType,
|
||
cxcode:'1',
|
||
name:carName,
|
||
carmodel:getModelData(`${carType}.txt`),
|
||
allitems:Reflect.ownKeys(cdsbInfoObj).map(cdsbKey=>{
|
||
const cdsb = cdsbInfoObj[cdsbKey];
|
||
const {xmdm,xmxh,modelKey} = cdsb
|
||
return {
|
||
xmdm,xmxh,model:getModelData(`${modelKey}.txt`)
|
||
}
|
||
}),
|
||
mark:Reflect.ownKeys(markRuleListObj).map(ruleKey=>(markRuleListObj[ruleKey])) || testMarkRules,
|
||
sysset:judgeUI.judgeConfig,
|
||
};
|
||
console.info(judgeTag,'3.获取评判初始化数据完成')
|
||
return initInfo
|
||
}
|
||
|
||
// 消息心跳发送
|
||
getMessageHeartbeat = async (isEnd?:Boolean) => {
|
||
const carInfo = globalThis.carInfo;
|
||
const { examSubject,plateNo,ksyh } = carInfo;
|
||
const {judgeUI,isExam,serialIndex,tempData,xmmcCode,xmxh,xmmcSingleCode,xmdm,performInfo,kfArr,getTranslateProject,getSbxh} = this;
|
||
const {lsh,startHourTime,totalScore} = judgeUI;
|
||
const examType = isExam?examSubject:0;
|
||
const {sensor,gps} = tempData;
|
||
const {zfxd,yfxd,shtd,ygd,jgd,skd,dh1,dh2,lhq,jsc,ssc,fsc,lb,mkg,aqd,ygq,cs,fdjzs} = sensor
|
||
const {jd,wd, hxj, fyj, hbg,} = gps
|
||
const translateProject = getTranslateProject();
|
||
const sbxh = getSbxh(xmdm,xmxh)
|
||
const {carzt,dcjl,qjjl,dxjl,bxjl} = JSON.parse(performInfo);
|
||
|
||
const asclshArr = stringToASC(lsh);
|
||
//13不足要补0
|
||
const ascksyhArr = stringToASC(fillZero(ksyh || 0,13))
|
||
const ascsbxhArr = stringToASC(sbxh)
|
||
const translateSignals = getTranslateSignals(
|
||
[zfxd, yfxd, shtd, ygd, jgd, skd, dh1, dh2, lhq, jsc,ssc,fsc, lb, mkg, aqd, 0,0,0,0 ].concat(getCarStatusType(carzt)).concat([ ygq, sensor.wd, 0 ])
|
||
)
|
||
|
||
//@ts-ignore
|
||
const translateJd = convertGpsCoord2(wd).toFixed(7) * Math.pow(10,7)
|
||
//@ts-ignore
|
||
const translateWd = convertGpsCoord2(jd).toFixed(7) * Math.pow(10,7)
|
||
//@ts-ignore
|
||
const translateProjects= translateProject.map(num => string2Bytes(num,8)[0])
|
||
const arr = [
|
||
//考生号 TODO 考试员号
|
||
asclshArr.map(lsh => string2Bytes(lsh,8)[0]), ascksyhArr.map(ksyh => string2Bytes(ksyh,8)[0]),
|
||
//科目类型(0:未考试 1:科目二 2:科目三) + 考试开始时间
|
||
string2Bytes(`${examType}${startHourTime}`,4 * 8),
|
||
// TODO 消息序号从1开始,0结束
|
||
string2Bytes(isEnd ? 0 : serialIndex,2 * 8),
|
||
/*左向灯 右向灯 双跳灯 远光灯 近光灯 视宽灯 点火1 点火2 离合器 脚刹 手刹 副刹 喇叭 门开关 安全带 档位 车辆状态 雨刮器 雾灯 0*/
|
||
translateSignals,
|
||
//速度 发动机转速 GPS纬度 GPS经度 主天线位置
|
||
//@ts-ignore
|
||
string2Bytes(cs,2 * 8), string2Bytes(fdjzs / 60,8), string2Bytes(translateJd,4*8), string2Bytes(translateWd,4*8), string2Bytes(1,8),
|
||
//GPS东向距离
|
||
string2Bytes(dxjl < 0 ? (dxjl+4294967296) : dxjl,4*8),
|
||
//GPS北向距离
|
||
string2Bytes(bxjl < 0 ? (bxjl+4294967296) : bxjl,4*8),
|
||
//航向角 俯仰角 高程(海拔)
|
||
string2Bytes((hxj+90) * 100,2*8), string2Bytes(fyj*100,2*8), string2Bytes(hbg*100,4*8),
|
||
//项目状态 parseInt('01010010',2) 二进制转成10进制
|
||
translateProjects,
|
||
//当前项目编号
|
||
string2Bytes(xmmcSingleCode ? (xmmcSingleCode*1 + 1) : 0,8),
|
||
//场地设备编号
|
||
ascsbxhArr.map(sbxh => string2Bytes(sbxh,8)[0]),
|
||
//本次考试行驶距离
|
||
string2Bytes(Math.floor((dcjl + qjjl)/100),2*8),
|
||
//扣分
|
||
string2Bytes(100 - Math.abs(totalScore),2*8),
|
||
//扣分项数量
|
||
string2Bytes(kfArr.length,8),
|
||
//n个扣分序号
|
||
kfArr.map(kf => string2Bytes(kf.kfxh,8)[0])
|
||
]
|
||
|
||
let tempArr = [];
|
||
arr.forEach(itemArr =>{ tempArr = tempArr.concat(itemArr)})
|
||
this.serialIndex += 1;
|
||
return Array2Byte(tempArr)
|
||
}
|
||
|
||
// 获取开始考试数据
|
||
getJudgeBeginData = async () => {
|
||
const {code,name:examinerName} = globalThis.examinerInfo;
|
||
const {isExam} = this;
|
||
const judgeUI = this.judgeUI
|
||
const {projects,carType,isDdxk,ddxkTime,projectsCenterObj,ddxkKsxmArr,ddxkKfArr} = judgeUI;
|
||
const beginInfo = {
|
||
ic:'',
|
||
kgid:'012',
|
||
kgxm:decodeURI(examinerName),
|
||
exam:isExam?1:0,
|
||
//生成的轨迹文件
|
||
track:'',
|
||
xm:judgeUI.name,
|
||
sex:0,
|
||
kslsh:judgeUI.lsh,
|
||
sfzmhm:judgeUI.idCard,
|
||
ksyy:'',
|
||
kscx:carType,
|
||
kkcs:1,
|
||
sfyk:0,
|
||
ykkkcs:1,
|
||
wayno:0,
|
||
czlx:0,
|
||
kskssj:await systemTime.getCurrentTime(),
|
||
ksxm:projects.map(project=>{
|
||
return {
|
||
xmdm:project.projectCode*1,
|
||
xmxh:'',
|
||
}
|
||
}),
|
||
//断点续考
|
||
ddxk:isDdxk ? 1 : 0,
|
||
ddkssj:ddxkTime,
|
||
ykxm:isDdxk?(ddxkKsxmArr?.map(projectCenterCode => (projectsCenterObj[projectCenterCode]?.projectCode)*1)):[],
|
||
kfxm:isDdxk?(ddxkKfArr?.map(kf => {
|
||
const [xmdm,kfdm] = kf.split(',')
|
||
return {
|
||
xmdm:xmdm*1,
|
||
kfdm
|
||
}
|
||
})):[],
|
||
yklc:0,
|
||
special:[]
|
||
}
|
||
console.info(judgeTag,'5.获取开始考试数据完成')
|
||
return beginInfo
|
||
}
|
||
|
||
// 获取plc数据
|
||
getPlcData = async (plc:string) => {
|
||
const {fileLog} = this;
|
||
await fileLog.setPlcProgressData(plc)
|
||
//plc字符串转化成评判初始化数据
|
||
const tempData = await plcStrToJson(plc);
|
||
//plc字符串转化成无锡所过程数据
|
||
const wuXiDataStr = await plcStrToWXJson(plc)
|
||
this.plcData= tempData
|
||
await fileLog.setExamJudgeWuxiProgressData(wuXiDataStr)
|
||
this.tempData = tempData
|
||
this.plcStr = plc;
|
||
globalThis.msgStr= plc
|
||
return tempData
|
||
}
|
||
|
||
//获取场地序号
|
||
getSbxh = (ksxm,xmxh) => {
|
||
const {judgeUI} = this;
|
||
const {cdsbInfoObj,projectsObj} = judgeUI;
|
||
const project = projectsObj[ksxm]
|
||
if(project === undefined){
|
||
return '0000000000'
|
||
}
|
||
const projectType = project.sbxh;
|
||
const projectKey = `${ksxm}_${xmxh}`;
|
||
const currentCdsb = cdsbInfoObj[projectKey] || {};
|
||
const sbxh = currentCdsb.sbbh || '0000000000'
|
||
return sbxh
|
||
}
|
||
|
||
//获取场地设备编码
|
||
getSbbm = (ksxm,xmxh) => {
|
||
const {judgeUI} = this;
|
||
const {cdsbInfoObj,projectsObj} = judgeUI;
|
||
const project = projectsObj[ksxm]
|
||
if(project === undefined){
|
||
return '00000000'
|
||
}
|
||
const projectKey = `${ksxm}_${xmxh}`;
|
||
const currentCdsb = cdsbInfoObj[projectKey] || {};
|
||
const sbxh = currentCdsb.sbbm || '00000000'
|
||
return sbxh
|
||
}
|
||
|
||
// 中心所有项目转换
|
||
getTranslateProject = () => {
|
||
const {allKm2ItemsObj} = this;
|
||
const tempItems = testKm2Items.map(item=>{
|
||
const current = allKm2ItemsObj[item.code];
|
||
return {
|
||
code:item.code,
|
||
status:getCenterProjectStatus(current.status)
|
||
}
|
||
})
|
||
const len = Math.floor(tempItems.length / 4);
|
||
const arr = [];
|
||
for(let i = 0;i <= len;i++){
|
||
const temp = tempItems.slice( i*4 , (i+1)*4 );
|
||
let tempArr = temp.map(item => item.status)
|
||
if(i === 4){
|
||
tempArr = tempArr.concat(['00','00'])
|
||
}
|
||
arr.push(tempArr.join(''));
|
||
}
|
||
return arr.map(numStr => parseInt(numStr,2));
|
||
}
|
||
|
||
// 获取考试项目详情
|
||
getProjectInfo = (projectCode) => {
|
||
const judgeUI = this.judgeUI;
|
||
return judgeUI.projectsObj[projectCode]
|
||
}
|
||
|
||
// 获取模型数据
|
||
getModelData = (modelName) => {
|
||
const modelPath = this.modelPath
|
||
const fileModel = this.fileModel;
|
||
const modelData = fileModel.getModelContent(modelPath,modelName);
|
||
return modelData
|
||
}
|
||
|
||
private judgeUI
|
||
private fileLog
|
||
private totalScore:number
|
||
private folderPath:string
|
||
private modelPath:string
|
||
private avPlayer
|
||
private carztStr:string
|
||
private xmmcStr:string
|
||
private xmmcCode:string
|
||
private xmmcSingleCode:number
|
||
private xmdm:string
|
||
private xmxh:string
|
||
private fileModel:FileModel
|
||
private filePhoto:FilePhoto
|
||
//是否是考试模式
|
||
private isExam:boolean
|
||
//考试是否结束了
|
||
private isEnd:boolean
|
||
//UDP服务序列号
|
||
private serialIndex:number
|
||
private fileUtil:FileUtil
|
||
private judgeTask:JudgeTask
|
||
private tempData:any
|
||
public plcStr:string
|
||
private performInfo:any
|
||
private ksjs:{
|
||
// 累计前进距离
|
||
qjjl:number,
|
||
// 累计倒车距离
|
||
dcjl:number
|
||
}
|
||
private kfArr:{
|
||
//项目名称
|
||
xmmcStr:string,
|
||
xmdm:string,
|
||
//扣分描述
|
||
desc:string,
|
||
//扣分
|
||
score:string
|
||
//无锡所扣分代码
|
||
markcatalog:string
|
||
markserial:string
|
||
kfxh:string
|
||
}[]
|
||
private plcData:any
|
||
private km2ItemsStatus:any[]
|
||
|
||
//所有的科目二考试项目(大车&小车)
|
||
private allKm2ItemsObj:any
|
||
//当前科目二的考试项目
|
||
private currentKm2ItemsObj:any
|
||
//本地轨迹回放地址
|
||
private trajectoryPath:string
|
||
private isTrajectoryOpen:boolean;
|
||
// 调代理接口是否断网了
|
||
private isJudgeDisConnect:boolean;
|
||
} |