1841 lines
59 KiB
Plaintext
Raw Normal View History

2025-01-14 15:34:13 +08:00
import systemTime from '@ohos.systemDateTime';
import router from '@ohos.router';
import util from '@ohos.util';
import buffer from '@ohos.buffer';
2025-01-20 08:50:40 +08:00
import { testKm2Items, testKm3Items, testMarkRules } from './dataTest/index';
import { EXAMDATA, KSJS, SOUND } from './api/judgeSDK';
2025-01-14 15:34:13 +08:00
import VoiceAnnounce from './utils/voiceAnnouncements';
import FileModel from './utils/fileModel';
import FilePhoto from './utils/filePhoto';
2025-03-26 13:43:47 +08:00
2025-01-14 15:34:13 +08:00
import FileLog from './utils/fileLog';
import JudgeTask from './utils/judgeTask';
import { judgeConfig } from './utils/judgeConfig';
2025-01-20 08:50:40 +08:00
import { KF, LANE } from '../judgeSDK/api/judgeSDK.d';
2025-01-14 15:34:13 +08:00
import {
getCarStatus,
getCarStatusType,
getCenterProjectStatus,
2025-01-20 08:50:40 +08:00
getDwStatusType,
getKmProjectCancelVoice,
2025-01-14 15:34:13 +08:00
getKmProjectVoice,
getTranslateSignals,
plcStrToJson,
plcStrToWXJson,
promptWxCode,
2025-01-20 08:50:40 +08:00
senorToWXDataStr
2025-01-14 15:34:13 +08:00
} from './utils/judgeCommon';
import {
2025-01-20 08:50:40 +08:00
examCalcGpsDistance,
2025-01-14 15:34:13 +08:00
examJudgeArtificialItem,
examJudgeArtificialMark,
examJudgeBeginExam,
examJudgeEndExam,
examJudgeInit,
examJudgeRealExam,
examJudgeSetLogCallback,
examJudgeSetPerformCallback,
examJudgeSetRealExamCallback,
2025-01-20 08:50:40 +08:00
examJudgeSoundEnd,
2025-01-14 15:34:13 +08:00
examJudgeVersion
} from './api/index';
import { writeObjectOut } from '../../api/judge';
import { saveStartRecordVideo } from '../../utils/Video';
import common from '@ohos.app.ability.common';
import { Array2Byte, convertGpsCoord2, deepClone, fillZero, string2Bytes } from './utils/Common';
import { GetCurrentTime, StringToASCII } from '../../utils/Common';
import UsbService from '../../utils/USB';
2025-03-26 13:43:47 +08:00
import FileUtils from '../../utils/FileUtils';
2025-01-14 15:34:13 +08:00
2025-01-20 08:50:40 +08:00
const judgeTag = 'SURENJUN_JUDGE'
2025-01-14 15:34:13 +08:00
2025-01-20 08:50:40 +08:00
export default class Judge {
// 断网数据补传
uploadDisConnectData = async () => {
2025-02-11 09:18:16 +08:00
const { isJudgeDisConnect, fileLog, fileUtil } = this;
2025-01-20 08:50:40 +08:00
if (!isJudgeDisConnect) {
return
2024-07-31 13:47:40 +08:00
}
2025-01-20 08:50:40 +08:00
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);
2025-01-14 15:34:13 +08:00
}
2025-01-20 08:50:40 +08:00
}
//上传无锡所过程数据
uploadProgressData = async () => {
const carInfo = AppStorage.get('carInfo')
2025-02-11 09:18:16 +08:00
const { judgeUI, fileUtil, fileLog } = this;
const { idCard, startFullTime } = judgeUI
const { carId, examinationRoomId } = carInfo
2025-01-20 08:50:40 +08:00
const folderPath = fileLog.folderPath
const base64 = new util.Base64();
const time = await GetCurrentTime();
const endTime = await GetCurrentTime(1)
2025-01-20 08:50:40 +08:00
let examDataBase64
//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))
2025-01-14 15:34:13 +08:00
}
2025-01-20 08:50:40 +08:00
console.info(judgeTag, '过程数据文件上传 start')
2025-01-14 15:34:13 +08:00
2025-01-20 08:50:40 +08:00
try {
await uploadExamProgressData({
time,
carId,
examinationRoomId,
examData: examDataBase64,
type: 1,
cardNo: idCard,
examStartTime: startFullTime,
examEndTime: endTime,
})
} catch (e) {
console.info(judgeTag, '过程数据文件上传失败:' + JSON.stringify(e))
}
console.info(judgeTag, '过程数据文件上传 end')
}
//获取科目三的评判初始化配置
getKm3JudgeInitConfig = async () => {
2025-02-11 09:18:16 +08:00
const { judgeUI, getModelData } = this;
const { mapPointArr, mapPointItemArr } = judgeUI;
2025-01-20 08:50:40 +08:00
return {
map_point: mapPointArr,
map_point_item: mapPointItemArr,
//科目三暂时为空
iteminfo: [],
roads: getModelData('km3/Roads.txt'),
sharps: getModelData('km3/Sharps.txt')
}
}
// 处理特殊参数配置
handleSEP = async (code: number) => {
const carInfo = AppStorage.get('carInfo')
2025-02-11 09:18:16 +08:00
const {
judgeUI:{
judgeConfigObj
}, avPlayer
} = this;
2025-02-13 15:30:48 +08:00
const { examSubject } = carInfo;
2025-01-14 15:34:13 +08:00
2025-01-20 08:50:40 +08:00
switch (code) {
//结束考试方式
case 306:
if (judgeConfigObj[code] == 5) {
//靠边停车
avPlayer.playAudio(['voice/406001.mp3'])
}
break;
2024-07-05 09:08:17 +08:00
}
2025-01-20 08:50:40 +08:00
}
public plcStr: string
private context: common.UIAbilityContext
2025-01-20 08:50:40 +08:00
private judgeUI
// 检测扣分、结束项目时该项目是否开始
checkProjectIsStart = async (xmdm, currentType: 1 | 2, kf?: KF) => {
if (xmdm == 20) {
return true
}
2025-02-11 09:18:16 +08:00
const { judgeTask, beginProject, pointsDedute, uploadProgressPhoto, endProject, checkExamIsEnd, totalScore } = this;
const { projectsObj, passingScore:passingGrade } = this.judgeUI
const { isUpload } = projectsObj[xmdm];
2025-01-20 08:50:40 +08:00
//如果项目没有开始
console.info('surenjun isUpload=>', isUpload)
if (!isUpload) {
console.info(judgeTag, '项目补传开始')
//项目开始补传
judgeTask.addTask(async () => {
await beginProject(xmdm)
}, {
isDelay: true
})
judgeTask.addTask(async () => {
await uploadProgressPhoto(xmdm)
}, {
isDelay: true
})
this.judgeUI.projectsObj[xmdm].isUpload = true;
//扣分补传
if (currentType == 2) {
judgeTask.addTask(async () => {
await pointsDedute(xmdm, kf)
}, {
isDelay: true
})
2025-01-14 15:34:13 +08:00
}
2025-01-20 08:50:40 +08:00
//扣分补传判断是否合格 不合格补传项目结束
if (currentType == 1 || (currentType == 2 && totalScore < passingGrade)) {
judgeTask.addTask(async () => {
await endProject(xmdm)
}, {
isDelay: true
})
this.judgeUI.projectsObj[xmdm].isEnd = true;
}
judgeTask.addTask(async () => {
checkExamIsEnd()
})
return false;
} else {
return true
}
}
private fileLog
//人工扣分
public setJudgeMark = async (itemno, serial, type = 1) => {
await examJudgeArtificialMark(itemno * 1, serial, type);
console.info(judgeTag, `进入人工扣分-${itemno}-${serial}`)
await this.fileLog.setExamJudgeData({
method: 'examJudgeArtificialMark',
itemno: itemno * 1,
serial,
type
})
console.info(judgeTag, `人工扣分-${itemno}-${serial}`)
}
//人工操作项目
public setJudgeItem = async (itemno: number, type: 1 | 2) => {
// const { fileLog } = this;
await examJudgeArtificialItem(itemno * 1, type);
await this.fileLog.setExamJudgeData({
method: 'examJudgeArtificialItem',
itemno: itemno * 1,
type
})
console.info(judgeTag, `人工评判${type == 1 ? '进入' : '取消'}项目-${itemno}`)
}
private filePath: string
2025-01-20 08:50:40 +08:00
private totalScore: number
private prevJd: number = 0
private prevWd: number = 0
private dwztNum: number = 0
private folderPath: string
private modelPath: string
private avPlayer: VoiceAnnounce
2025-01-20 08:50:40 +08:00
private carztStr: string
private rmndg: 0 | 1
private mndgStr: string | undefined
// 模拟灯光
setMndg = async (mndgStr: string) => {
this.mndgStr = mndgStr
}
private xmmcStr: string
private xmmcCode: string
private xmmcSingleCode: number
private xmmcEndCode?: number
private xmdm: string | number
private xmxh: string
private fileModel: FileModel
private filePhoto: FilePhoto
// 过程照片拍照
getPhoto = async (empty?: boolean) => {
const singlePlay: boolean = AppStorage.get('singlePlay')
//单机模式返回空照片
if (singlePlay) {
return ''
} else {
const photoBase64 = await this.filePhoto.getPhoto();
console.info(judgeTag, '拍照完成')
return photoBase64
}
}
2025-01-20 08:50:40 +08:00
private usbService: UsbService
//是否是考试模式
private isExam: boolean
//考试是否结束了
private isExamEnd: boolean
// 是否发送udp
private isUdpEnd: boolean = false
//是否手动结束考试
private isManual: boolean
//UDP服务序列号
private serialIndex: number
2025-03-26 13:43:47 +08:00
private fileUtil: FileUtils
2025-01-20 08:50:40 +08:00
private judgeTask: JudgeTask
private tempData: any
//实时计算gps经纬度距离
handDistance = async () => {
2025-02-11 09:18:16 +08:00
const { jd, wd, hxj, dwzt, jdzt } = this.tempData.gps;
2025-01-20 08:50:40 +08:00
const tJD = convertGpsCoord2(jd)
const tWD = convertGpsCoord2(wd)
2025-02-11 09:18:16 +08:00
const { prevJd, prevWd } = this
2025-01-20 08:50:40 +08:00
if (prevJd && dwzt == 4 && jdzt == 3) {
const distance = await examCalcGpsDistance({
jd1: prevJd,
wd1: prevWd,
jd2: tJD,
wd2: tWD,
h: hxj || 1,
})
const distanceClass = AppStorage.get('distanceClass')
2025-02-13 15:30:48 +08:00
distanceClass?.setTimeData(((distance / 100).toFixed(2)) * 1)
2025-01-20 08:50:40 +08:00
}
this.prevJd = tJD;
this.prevWd = tWD;
}
private performInfo: any
private isEndTip: boolean = false;
private deductedPopShowTimer: number = 0;
// 校验考试是否结束
checkExamIsEnd =
async (isManual?: boolean) => {
2025-02-11 09:18:16 +08:00
const { judgeUI, avPlayer, isExamEnd, isEndTip, ksjs } = this;
const { isAllProjectsEnd, examSubject, singlePlay, totalScore, judgeConfigObj, passingScore, examMileage, jl } =
judgeUI;
2025-01-14 15:34:13 +08:00
2025-01-20 08:50:40 +08:00
if (isExamEnd) {
return
}
//及格分
let passingGrade = passingScore
if (isManual) {
// 考试不合格
await examJudgeEndExam()
this.isExamEnd = true
this.isManual = true
} else {
const param302 = judgeConfigObj['302'];
const param342 = judgeConfigObj['342'];
const param512 = (judgeConfigObj['512'] || '').split(',');
2025-01-14 15:34:13 +08:00
2025-01-20 08:50:40 +08:00
//单机模式
if (singlePlay) {
console.info(judgeTag + ' isAllProjectsEnd => ', isAllProjectsEnd)
if (isAllProjectsEnd && jl >= examMileage) {
//成绩合格
if (totalScore >= passingGrade && !isEndTip) {
2025-02-11 09:18:16 +08:00
if (examSubject == 3 && (param342 == 0 || param342 == 2) &&
(param302 != 6 || param302 != 7 || param302 != 8)) {
2025-01-20 08:50:40 +08:00
if (param512[7] != 0) {
clearTimeout(this.deductedPopShowTimer)
avPlayer.playAudio(['voice/综合评判.mp3'])
this.judgeUI.isDeductedPopShow = true
this.judgeUI.defaultTabIndex = 1
this.isEndTip = true
return
}
} else {
await examJudgeEndExam()
this.isExamEnd = true
return
}
} else {
if (examSubject == 3 && (param302 == 4 || param302 == 5 || param302 == 7 || param302 == 8)) {
await examJudgeEndExam()
this.isExamEnd = true
return
}
}
await examJudgeEndExam()
this.isExamEnd = true
}
} else {
//成绩不合格
if (totalScore < passingGrade) {
//科目三不合格报靠边停车
if (examSubject == 3 && param302 == 1) {
avPlayer.playAudio([`voice/考试结束.mp3`]);
return
}
await examJudgeEndExam()
this.isExamEnd = true
return
}
2025-01-14 15:34:13 +08:00
2025-01-20 08:50:40 +08:00
//成绩合格
if (isAllProjectsEnd && totalScore >= passingGrade && !isEndTip) {
if (examSubject == 2) {
await examJudgeEndExam()
this.isExamEnd = true
return
}
//考试里程判断
if (examSubject == 3 && jl < examMileage) {
return
}
//考试合格自动退出
if (examSubject == 3 && (param302 == 4 || param302 == 7) || param302 == 8) {
await examJudgeEndExam()
this.isExamEnd = true
return
}
2025-02-11 09:18:16 +08:00
if (examSubject == 3 && (param342 == 0 || param342 == 2) &&
(param302 != 6 || param302 != 7 || param302 != 8)) {
2025-01-20 08:50:40 +08:00
if (param512[7] != 0) {
clearTimeout(this.deductedPopShowTimer)
this.judgeUI.isDeductedPopShow = false
avPlayer.playAudio(['voice/综合评判.mp3'])
this.judgeUI.isDeductedPopShow = true
this.judgeUI.defaultTabIndex = 1
this.isEndTip = true
}
} else {
await examJudgeEndExam()
this.isExamEnd = true
}
}
}
}
}
private ksjs: {
// 累计前进距离
qjjl: number,
// 累计倒车距离
dcjl: number
d1: number
d2: number
d3: number
d4: number
d5: number
d6: number
}
private kfArr: {
//项目名称
xmmcStr: string,
xmdm: string | number,
//扣分描述
desc: string,
//扣分
score: string
//无锡所扣分代码
markcatalog: string
markserial: string
kfxh: string
type: 0 | 1 | 2
}[]
private km2ItemsStatus: any[]
//所有的科目考试项目(大车&小车)
private testKmItems: any
private plcData: any
// 获取plc数据
getPlcData = async (plc: string) => {
2025-02-11 09:18:16 +08:00
const { fileLog, mndgStr, rmndg } = this;
2025-01-20 08:50:40 +08:00
await fileLog.setPlcProgressData(plc)
//plc字符串转化成评判初始化数据
const tempData = await plcStrToJson(plc);
//模拟灯光回放时刻
tempData.sensor.rmndg = rmndg;
//模拟灯灯光灯光项目
tempData.sensor.mndg = mndgStr;
//plc字符串转化成无锡所过程数据
const wuXiDataStr = await plcStrToWXJson(plc)
this.plcData = tempData
await fileLog.setExamJudgeWuxiProgressData(wuXiDataStr)
this.tempData = tempData
this.plcStr = plc;
this.mndgStr = '';
this.rmndg = 0;
AppStorage.setOrCreate('msgStr', plc)
2025-01-20 08:50:40 +08:00
return tempData
}
// 处理udp plc信号
handleUdp = async (msg) => {
console.info('plc信号', msg)
// const { fileLog, getPlcData, usbService, isUdpEnd, isExamEnd, judgeUI } = this
const stachArr = msg.split(',')
if (stachArr[0] != '#DN_GD' || this.isUdpEnd) {
return
}
const plcData = await this.getPlcData(msg);
// 4.过程数据
await this.fileLog.setExamJudgeData(plcData)
//检测到有无锡所设备接入,需要发送特定的数据,供检测
if (this.usbService.isWXUSBDevice) {
const str = await senorToWXDataStr(msg);
this.usbService.sendUSB(str)
}
const param350 = this.judgeUI.judgeConfigObj['350']
this.judgeUI.sd = ((param350 == 0 ? plcData.gps.sd : plcData.sensor.cs) as number * 1.852).toFixed(0) + ''
this.judgeUI.dw = (Math.floor(plcData.sensor.dw as number) || 0) + ''
//TODO 暂时关闭差分检测异常
// await this.checkDwzt(plcData.gps.dwzt,plcData.gps.jdzt);
if (!this.isExamEnd) {
await examJudgeRealExam(plcData)
}
let udpIndex = AppStorage.get('udpIndex') as number;
let [prevJd, preWd] = [0, 0]
if (udpIndex % 5 === 0 && !this.isUdpEnd) {
// TODO UPD缺失
// const judgeUdp = globalThis.judgeUdp
// const bytes = await this.getMessageHeartbeat(this.isExamEnd);
// judgeUdp.send(bytes)
}
AppStorage.setOrCreate('udpIndex', udpIndex++)
}
2025-01-20 08:50:40 +08:00
// 处理轨迹plc信号
handleTrajectoryUdp = async (strArr) => {
// const { fileLog, setJudgeItem, setJudgeMark, endExam } = this;
2025-01-20 08:50:40 +08:00
let num = 2;
const judgeTimer = setInterval(async () => {
const msgStr = strArr[num];
if (msgStr == '') {
console.info(judgeTag, '模拟数据考试结束')
clearInterval(judgeTimer)
this.checkExamIsEnd(true)
return
}
const msg = JSON.parse(strArr[num]);
num++
// 4.过程数据
this.tempData = msg
this.judgeUI.isDwztRight = (msg?.gps?.dwzt == 4 && msg?.gps?.jdzt == 3);
this.judgeUI.sd = Math.floor(msg?.gps?.sd * 1.852) + '';
this.judgeUI.dw = Math.floor(msg?.sensor?.dw) + ''
this.plcData = msg
// this.judgeUI.isDwztRight = msg.gps.dwzt == 4;
AppStorage.setOrCreate('msgStr', '')
2025-01-20 08:50:40 +08:00
if (msg.method === 'examJudgeArtificialItem') {
this.setJudgeItem(msg.itemno, msg.type)
2025-01-20 08:50:40 +08:00
}
if (msg.method === 'examJudgeArtificialMark') {
this.setJudgeItem(msg.itemno, msg.serial)
2025-01-20 08:50:40 +08:00
}
await examJudgeRealExam(msg)
// const bytes = await this.getMessageHeartbeat();
// bytes && globalThis.judgeUdp.send(bytes)
2025-01-20 08:50:40 +08:00
}, 200)
// TODO 定时器缺失
// globalThis.judgeTimer = judgeTimer;
2025-01-20 08:50:40 +08:00
}
//当前科目二的考试项目
private currentKm2ItemsObj: any
//本地轨迹回放地址
private trajectoryPath: string
private isTrajectoryOpen: boolean;
// 调代理接口是否断网了
private isJudgeDisConnect: boolean;
// 项目开始接口同步
beginProject = async (ksxm) => {
2025-02-13 15:30:48 +08:00
const carInfo = AppStorage.get('carInfo');
2025-02-11 09:18:16 +08:00
const { examSubject, plateNo } = carInfo;
const { judgeUI, fileLog, getSbbm, xmxh, filePath } = this;
const { lsh, idCard, serialNumber, projectsObj, ksdd, kslx, xldm } = judgeUI
const time = await GetCurrentTime();
2025-01-20 08:50:40 +08:00
const project = projectsObj[ksxm]
const sbxh = getSbbm(ksxm, xmxh)
const data = {
//系统类别 接口序列号 接口标识
2025-02-11 09:18:16 +08:00
xtlb: '17',
jkxlh: serialNumber,
jkid: '17C52',
2025-01-20 08:50:40 +08:00
drvexam: {
// 考试科目 身份证号码
lsh,
kskm: examSubject,
sfzmhm: idCard,
ksxm: project.projectCodeCenter,
sbxh,
ksxl: xldm,
kchp: encodeURI(plateNo),
// 开始时间
ksdd: encodeURI(ksdd),
kslx: encodeURI(kslx) || '',
kssj: time
}
}
2025-02-11 09:18:16 +08:00
const { code } = await this.sendWriteObjectOut(data, filePath)
2025-01-20 08:50:40 +08:00
console.info(judgeTag, '项目开始 end')
if (code === 2300007) {
this.isJudgeDisConnect = true;
}
promptWxCode('17C52', code)
}
// 项目结束接口同步
endProject = async (ksxm) => {
2025-02-13 15:30:48 +08:00
const carInfo = AppStorage.get('carInfo');
2025-02-11 09:18:16 +08:00
const { examSubject, plateNo, carNo } = carInfo;
const { judgeUI, fileLog, getSbxh, xmxh, getSbbm, filePath } = this;
const { lsh, idCard, serialNumber, projectsObj, cdsbInfoObj, ksdd, kslx, xldm, } = judgeUI
const time = await GetCurrentTime();
2025-01-20 08:50:40 +08:00
const project = projectsObj[ksxm]
const sbxh = examSubject == 3 ? undefined : getSbbm(ksxm, xmxh)
const data = {
2025-02-11 09:18:16 +08:00
xtlb: '17',
jkxlh: serialNumber,
jkid: '17C55',
2025-01-20 08:50:40 +08:00
drvexam: {
lsh,
kskm: examSubject,
sfzmhm: idCard,
ksxm: project.projectCodeCenter,
sbxh,
//TODO 操作类型 1:正常 0:撤销该考试记录
czlx: '1',
ksxl: xldm,
kchp: encodeURI(plateNo),
ksdd: encodeURI(ksdd),
kslx: encodeURI(kslx) || '',
jssj: time
}
}
2025-02-11 09:18:16 +08:00
const { code } = await this.sendWriteObjectOut(data, filePath)
2025-01-20 08:50:40 +08:00
if (code === 2300007) {
this.isJudgeDisConnect = true;
}
console.info(judgeTag, '项目结束 end')
promptWxCode('17C55', code)
}
private artSubject3ProjectsCodesArr: number[] = [3, 9, 4, 10, 12, 11]
private lane: LANE = {
road: '', num: 0, count: 0
}
private videoData: any
private disConnectNum: number = 0;
//调用监管接口
sendWriteObjectOut = async (data, filePath) => {
const temp = await writeObjectOut(data, filePath);
console.log("wzj", JSON.stringify(temp))
//断网&网络超时次数计算
if (temp.code == 2300007 || temp.code == 2300028) {
this.disConnectNum += 1;
if (this.disConnectNum < 5) {
return await this.sendWriteObjectOut(data, filePath)
}
}
if (this.disConnectNum >= 5) {
console.info('surenjun', '123')
this.judgeUI.errorMsg = '当前的考试过程信息网络传输异常,程序点击确认将重启!';
this.judgeUI.disConnectErrorOpen = true
}
this.disConnectNum = 0
return temp
}
// 考试过程照片
uploadProgressPhoto = async (ksxm) => {
const time = await GetCurrentTime();
const { judgeUI, plcData, getPhoto, fileLog, filePath } = this;
const photoBase64 = await getPhoto();
const carInfo = AppStorage.get('carInfo');
const { examSubject, plateNo, carNo } = carInfo;
const { lsh, idCard, serialNumber, projectsObj, ksdd, judgeConfigObj } = 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,
zp: photoBase64,
cs: Math.floor((judgeConfigObj['350'] == 0 ? gps.sd : sensor.cs) * 1.852),
ksdd: encodeURI(ksdd)
}
};
const { code } = await this.sendWriteObjectOut(data, filePath);
if (code === 2300007) {
this.isJudgeDisConnect = true
}
promptWxCode('17C54', code)
console.info(judgeTag, '上传照片 end')
}
2025-01-20 08:50:40 +08:00
constructor(judgeUI) {
this.serialIndex = 1;
this.judgeUI = judgeUI
//语音播放工具
this.avPlayer = new VoiceAnnounce();
//模型工具
this.fileModel = new FileModel(judgeUI.context);
//文件工具
2025-03-26 13:43:47 +08:00
this.fileUtil = new FileUtils(judgeUI.context)
2025-01-20 08:50:40 +08:00
this.judgeTask = new JudgeTask()
this.usbService = new UsbService();
this.filePhoto = new FilePhoto(judgeUI.context);
this.kfArr = judgeUI.kfArr
this.xmmcStr = '';
this.xmmcCode = '';
this.xmmcEndCode = undefined;
this.carztStr = '';
this.testKmItems = {};
// 考试回放配置
2025-02-11 09:18:16 +08:00
const { isTrajectoryOpen, modelPath, trajectoryPath } = judgeConfig
2025-01-20 08:50:40 +08:00
this.isTrajectoryOpen = isTrajectoryOpen;
this.modelPath = modelPath;
this.trajectoryPath = trajectoryPath;
this.isExam = !this.judgeUI.singlePlay;
2025-02-11 09:18:16 +08:00
const { projectsCenterObj, examSubject } = judgeUI;
2025-01-20 08:50:40 +08:00
(examSubject == 2 ? testKm2Items : testKm3Items).forEach(item => {
const projectCenterObj = projectsCenterObj[item.code]
this.testKmItems[item.code] = item;
//考试项目存在
this.testKmItems[item.code] = {
code: item.code,
status: projectCenterObj === undefined
? 0
: (projectCenterObj.isEnd ? 3 : 1)
}
2025-01-14 15:34:13 +08:00
})
2025-01-20 08:50:40 +08:00
console.info(judgeTag + 'testKmItems', JSON.stringify(this.testKmItems))
this.isExamEnd = false;
2024-07-05 09:08:17 +08:00
}
2025-01-20 08:50:40 +08:00
public async onJudgeFn(fn: Function) {
await this.judging(fn)
2025-01-14 15:34:13 +08:00
}
// 获取评判初始化数据
getJudgeInitData = async () => {
2025-02-11 09:18:16 +08:00
const { getModelData, getKm3JudgeInitConfig } = this
2025-02-13 15:30:48 +08:00
const carInfo = AppStorage.get('carInfo');
2025-02-11 09:18:16 +08:00
const { examSubject, plateNo, carId } = carInfo;
2025-01-14 15:34:13 +08:00
const judgeUI = this.judgeUI
2025-02-11 09:18:16 +08:00
const { projectsObj, itemInfoObj, markRuleListObj, carType, carName, systemparmArr, carinfoArr } = judgeUI
2025-01-14 15:34:13 +08:00
const examType = examSubject == 2 ? 'km2' : 'km3'
let allitems = [];
if (examSubject == 2) {
allitems = Reflect.ownKeys(itemInfoObj).map(cdsbKey => {
const cdsb = itemInfoObj[cdsbKey];
2025-02-11 09:18:16 +08:00
const { xmdm, xmxh, modelKey } = cdsb
2025-01-14 15:34:13 +08:00
return {
xmdm, xmxh, model: getModelData(`${examType}/${modelKey}.txt`)
}
})
}
//获取版本号
const sdkver = await examJudgeVersion();
const initInfo = {
sdkver,
2025-02-13 15:30:48 +08:00
appver: AppStorage.get('baseInfo').version,
2025-01-14 15:34:13 +08:00
kskm: examSubject * 1,
kchp: plateNo,
kchm: carId * 1,
kscx: carType,
cxcode: '1',
name: carName,
carmodel: getModelData(`${examType}/${carType}.txt`),
allitems,
iteminfo: [],
systemparm: systemparmArr,
mark: Reflect.ownKeys(markRuleListObj).map(ruleKey => (markRuleListObj[ruleKey])) || testMarkRules,
sysset: judgeUI.judgeConfig,
itemInfoObj,
2025-01-20 08:50:40 +08:00
carlist: judgeUI.carlist,
2025-01-14 15:34:13 +08:00
carinfo: carinfoArr,
};
let km3Config = {}
if (examSubject == 3) {
km3Config = await getKm3JudgeInitConfig();
}
// 获取科目三的评判配置
console.info(judgeTag, '3.获取评判初始化数据完成')
return {
...initInfo,
...km3Config,
}
}
// 获取开始考试数据
getJudgeBeginData = async () => {
2025-02-13 15:30:48 +08:00
const examinerInfo = AppStorage.get('examinerInfo')
const { code, name:examinerName } = examinerInfo;
2025-01-14 15:34:13 +08:00
let currentParams: any = router.getParams();
2025-02-11 09:18:16 +08:00
const { sczb, kfdm } = currentParams;
const { isExam } = this;
2025-01-14 15:34:13 +08:00
const judgeUI = this.judgeUI
2025-02-11 09:18:16 +08:00
const { projects, carType, kssycs, isDdxk, ddxkTime, projectsCenterObj, ddxkKsxmArr, ddxkKfArr, passingScore } =
judgeUI;
2025-01-14 15:34:13 +08:00
const beginInfo = {
kgid: '012',
kgxm: decodeURI(examinerName || ''),
exam: isExam ? 1 : 0,
//是否回放
replay: 0,
//生成的轨迹文件
track: '',
xm: judgeUI.name,
sex: 0,
kslsh: judgeUI.lsh,
sfzmhm: judgeUI.idCard,
ksyy: '',
kscx: carType,
2025-01-20 08:50:40 +08:00
kkcs: Number(kssycs) || 2,
2025-01-14 15:34:13 +08:00
sfyk: 0,
ykkkcs: 1,
wayno: judgeUI.wayno * 1,
czlx: 0,
kskssj: await systemTime.getCurrentTime(),
2025-01-20 08:50:40 +08:00
passing: passingScore * 1,
2025-01-14 15:34:13 +08:00
ksxm: projects.map(project => {
return {
xmdm: project.projectCode * 1,
xmxh: '',
}
}),
//断点续考
ddxk: isDdxk ? 1 : 0,
ddkssj: ddxkTime || 0,
ykxm: (ddxkKsxmArr?.map(projectCenterCode => (projectsCenterObj[projectCenterCode]?.projectCode) * 1)) || [],
kfxm: isDdxk ? (ddxkKfArr?.map(kf => {
const [xmdm, kfdm] = kf.split(',')
2025-01-20 08:50:40 +08:00
return {
xmdm: xmdm * 1, kfdm
}
2025-01-14 15:34:13 +08:00
})) : [],
//TODO 已考里程待修改
yklc: 0,
special: [],
//TODO 科目三参数临时写死
sczb: (sczb === undefined || sczb == 0) ? 0 : 1,
sczbkf: kfdm,
dmndg: false,
mfxx: false,
mfxxn: false
}
console.info(judgeTag, '5.获取开始考试数据完成')
return beginInfo
}
//处理评判过程回调
handleRealExam = async (strData, callBack) => {
let examData: EXAMDATA = JSON.parse(strData);
2025-02-11 09:18:16 +08:00
const { getDqxmStr, getKfStr, goJudgeVoice, setMndg, avPlayer, fileLog, judgeUI } = this;
const { carzt, xmks, kf, event, xmjs, xmqx, ksjs, sound, mndg, lane, precast, nongps } = examData
2025-01-20 08:50:40 +08:00
const param512 = (judgeUI.judgeConfigObj['512'] || '').split(',');
2025-01-14 15:34:13 +08:00
//获取项目结束、项目开始代码
const xmdm = event == 2 ? xmjs.xmdm : xmks.xmdm
const xmxh = event == 2 ? xmjs.xmxh : xmks.xmxh;
const isManualProjectIn = this.artSubject3ProjectsCodesArr.includes(xmdm);
2025-02-11 09:18:16 +08:00
const { examSubject, projects, judgeConfigObj } = this.judgeUI;
2025-01-14 15:34:13 +08:00
const param611 = judgeConfigObj['611'] || '';
switch (event) {
//项目开始
case 1:
judgeUI.projectsObj[xmdm].type = '2';
if (isManualProjectIn) {
//手动项目是否在进行中
this.judgeUI.isManualProjectIn = true
}
if (xmdm == 41 && examSubject == 3) {
this.rmndg = 1
}
this.judgeUI.currentXmdm = xmdm;
const xmmcStr = judgeUI.projectsObj[xmdm].name;
const xmmcCode = judgeUI.projectsObj[xmdm].projectCodeCenter;
const xmmcSingleCode = judgeUI.projectsObj[xmdm].projectCode;
this.testKmItems[xmmcCode].status = 2;
this.xmmcStr = xmmcStr;
this.xmmcCode = xmmcCode;
this.xmmcSingleCode = xmmcSingleCode
this.xmmcEndCode = xmmcCode
this.xmdm = xmdm;
this.xmxh = xmxh;
this.judgeUI.isProjectIn = true
break;
//项目结束
case 2: {
const xmmcCode = judgeUI.projectsObj[xmdm].projectCodeCenter;
judgeUI.projectsObj[xmdm].type = (xmjs.xmhg === 0 ? '4' : '3');
//计算项目是否全部结束
this.judgeUI.isProjectIn = (Reflect.ownKeys(judgeUI.projectsObj).filter(
projectKey => judgeUI.projectsObj[projectKey].type == '2').length
) > 0;
if (isManualProjectIn) {
this.judgeUI.isManualProjectIn = false
}
this.testKmItems[xmmcCode].status = 3;
//统计必考项目数量
this.xmmcStr = '无';
this.xmmcCode = '';
this.xmdm = '';
this.judgeUI.currentXmdm = undefined;
break;
}
//扣分
case 3:
const thisKf = getKfStr(`${kf.xmdm}_${kf.kfdm}`)
2025-02-11 09:18:16 +08:00
//扣分信息
2025-01-14 15:34:13 +08:00
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,
//扣分类型
type: kf.type
})
this.judgeUI.totalScore += thisKf.score * 1;
2025-01-20 08:50:40 +08:00
if (kf.xmdm != 20) {
2025-01-14 15:34:13 +08:00
const type = judgeUI.projectsObj[kf.xmdm].type;
judgeUI.projectsObj[kf.xmdm].type = (type == 3 || type == 4) ? '4' : '5';
}
break;
//考车状态
case 4:
this.carztStr = getCarStatus(carzt);
break;
//考试结束
case 5:
this.ksjs = ksjs;
await fileLog.setExamJudgeData({
method: 'examJudgeEndExam',
})
break;
//项目取消
2025-01-20 08:50:40 +08:00
case 6: {
console.info(judgeTag, '项目取消');
2025-02-11 09:18:16 +08:00
const { examSubject } = this.judgeUI
2025-01-14 15:34:13 +08:00
const xmdm = xmqx.xmdm;
const xmmcCode = judgeUI.projectsObj[xmdm].projectCodeCenter;
2025-01-20 08:50:40 +08:00
const voiceCode = getKmProjectCancelVoice(examSubject, xmmcCode);
2025-01-14 15:34:13 +08:00
// avPlayer.playAudio([`voice/${voiceCode}.mp3`],true)
this.judgeUI.projectsObj[xmdm].type = '1';
this.testKmItems[xmmcCode].status = '1';
break;
}
//语音播放和提示
case 7:
goJudgeVoice(sound)
break;
//模拟灯光事件
case 8:
setMndg(mndg)
break;
//车道和路段变化
case 9:
this.judgeUI.lane = lane
this.lane = lane;
break;
//预进项目事件
2025-01-20 08:50:40 +08:00
case 10: {
2025-01-14 15:34:13 +08:00
const param611 = judgeConfigObj['611'] || '';
2025-01-20 08:50:40 +08:00
const [f, s] = param611.split('/')
2025-02-11 09:18:16 +08:00
const { xmdm, xmxh } = precast;
2025-01-14 15:34:13 +08:00
const xmmcCode = judgeUI.projectsObj[xmdm].projectCodeCenter;
const xmmcSingleCode = judgeUI.projectsObj[xmdm].projectCode;
// if(examSubject == 2 && ((xmdm == 0 && f == 1) || (xmdm == 1 && s == 1) || xmdm == 3)){
// //倒车入库/桩考/侧方停车
// avPlayer.playAudio([`voice/${xmmcCode}.mp3`],false)
// }
this.testKmItems[xmmcCode].status = 2;
this.xmmcStr = xmmcStr;
this.xmmcCode = xmmcCode;
this.xmdm = xmdm;
this.xmxh = xmxh;
this.xmmcSingleCode = xmmcSingleCode;
judgeUI.projectsObj[xmdm].type = '2';
}
break;
//差分事件
2025-01-20 08:50:40 +08:00
case 11: {
2025-02-11 09:18:16 +08:00
const { type } = nongps
2025-01-14 15:34:13 +08:00
this.checkDwzt(type)
}
default:
break;
}
2024-07-31 13:47:40 +08:00
2025-02-11 09:18:16 +08:00
const { xmmcStr, carztStr, kfArr } = this;
2024-07-31 13:47:40 +08:00
2025-01-14 15:34:13 +08:00
await callBack({
//项目名称 考车状态 扣分arr
xmmcStr, carztStr, kfArr
2025-01-14 15:13:50 +08:00
});
2025-01-14 15:34:13 +08:00
//语音播报
2025-01-20 08:50:40 +08:00
this.goVoiceAnnounce(event, xmdm, this.kfArr, xmjs, ksjs, xmxh)
2025-01-14 15:34:13 +08:00
//更新UI
if (event == 1 || event == 2 || event == 3 || event == 6) {
const copyProjectsObj = this.judgeUI.projectsObj;
judgeUI.projectsObj = deepClone(copyProjectsObj);
}
}
// 更改考试状态
2025-01-20 08:50:40 +08:00
goVoiceAnnounce = async (event, xmdm, kf, xmjs, ksjs, xmxh) => {
2025-01-14 15:34:13 +08:00
const {
beginProject,
pointsDedute,
endProject,
avPlayer,
uploadProgressPhoto,
judgeTask,
handEndExam,
judgeUI,
checkExamIsEnd,
checkProjectIsStart,
lane,
closeAllFiles
} = this;
2025-02-11 09:18:16 +08:00
const { projectsObj, judgeConfigObj, examSubject, examMileage, jl, isAllProjectsEnd } = judgeUI;
2025-01-14 15:34:13 +08:00
const kfLen = kf.length;
//不报语音的项目列表
const ignoreVoiceCodeArr = (judgeConfigObj['312'] || '').split(',')
const param611 = judgeConfigObj['611'] || '';
const param512 = (judgeConfigObj['512'] || '').split(',');
2025-01-20 08:50:40 +08:00
const [f, s] = param611.split('/')
2025-01-14 15:34:13 +08:00
switch (event) {
// 项目开始
case 1:
const code = projectsObj[xmdm].projectCodeCenter;
const isEnd = projectsObj[xmdm].isEnd;
2025-01-20 08:50:40 +08:00
const kmCode = getKmProjectVoice(code, 1, judgeConfigObj, lane, xmxh)
2025-02-11 09:18:16 +08:00
// if (!ignoreVoiceCodeArr.includes(code)) {
// if(examSubject == 2 && ((xmdm == 0 && f == 2) || (xmdm == 1 && s == 2) || xmdm == 3)){
// //倒出入库、桩考\进项目语音控制
// }else{
// kmCode && avPlayer.playAudio([`voice/${kmCode}.mp3`],true)
// }
// }
2025-01-20 08:50:40 +08:00
setTimeout(() => {
if (param512[7] != 0) {
clearTimeout(this.deductedPopShowTimer)
this.judgeUI.isDeductedPopShow = true
}
}, 200)
2025-02-11 09:18:16 +08:00
//项目已考不上传监管信息
2025-01-14 15:34:13 +08:00
if (!isEnd) {
judgeTask.addTask(async () => {
console.info(judgeTag, `项目开始-${xmdm}-${projectsObj[xmdm].name}`)
await beginProject(xmdm)
2025-01-20 08:50:40 +08:00
}, {
isDelay: true
})
2025-01-14 15:34:13 +08:00
judgeTask.addTask(async () => {
console.info(judgeTag, `项目-${xmdm}-上传照片 start`)
await uploadProgressPhoto(xmdm)
2025-01-20 08:50:40 +08:00
}, {
isDelay: true
})
2025-01-14 15:34:13 +08:00
this.judgeUI.projectsObj[xmdm].isUpload = true;
}
break;
// 项目结束
2025-01-20 08:50:40 +08:00
case 2: {
2025-01-14 15:34:13 +08:00
const endCode = projectsObj[xmdm].projectCodeCenter;
const projectIsEnd = projectsObj[xmdm].isEnd;
2025-01-20 08:50:40 +08:00
const endKmCode = getKmProjectVoice(endCode, 2, judgeConfigObj, lane, xmxh)
2025-01-14 15:34:13 +08:00
// if (!ignoreVoiceCodeArr.includes(endCode) && examSubject == 3) {
// endKmCode && avPlayer.playAudio([`voice/${endKmCode}.mp3`])
// }
2025-01-20 08:50:40 +08:00
const isStart = await checkProjectIsStart(xmdm, 1);
if (isStart) {
2025-01-14 15:34:13 +08:00
//项目结束了就不再生成数据
2025-01-20 08:50:40 +08:00
console.info(judgeTag + ' projectIsEnd =>', projectIsEnd)
2025-01-14 15:34:13 +08:00
if (!projectIsEnd) {
judgeTask.addTask(async () => {
console.info(judgeTag, `项目结束-${xmdm}-${projectsObj[xmdm].name}`)
await endProject(xmdm);
this.xmmcSingleCode = 0;
this.xmmcEndCode = undefined;
2025-01-20 08:50:40 +08:00
}, {
isDelay: true
})
2025-01-14 15:34:13 +08:00
}
}
2025-01-20 08:50:40 +08:00
if (!this.judgeUI.isProjectIn) {
this.deductedPopShowTimer = setTimeout(() => {
2025-01-14 15:34:13 +08:00
this.judgeUI.isDeductedPopShow = false
2025-01-20 08:50:40 +08:00
}, (param512[5] || 0) * 1000)
2025-01-14 15:34:13 +08:00
}
judgeUI.projectsObj[xmdm].isEnd = true;
break;
}
// 扣分
case 3:
2025-01-20 08:50:40 +08:00
console.info('surenjun', '扣分开始')
2025-02-11 09:18:16 +08:00
//扣分时实时播报语音0-否+1-是)
2025-01-14 15:34:13 +08:00
const currentKf = kf[kfLen -1];
2025-02-11 09:18:16 +08:00
if (judgeConfig.kfVoiceOpen || (examSubject == 2 && judgeConfigObj['618'] == '1') ||
(examSubject == 3 && judgeConfigObj['418'] == '1')) {
2025-01-20 08:50:40 +08:00
avPlayer.playAudio([`voice/${currentKf.markcatalog}.mp3`, `voice/mark_${Math.abs(currentKf.score)}.mp3`])
2025-01-14 15:34:13 +08:00
}
2025-01-20 08:50:40 +08:00
const isStart = await checkProjectIsStart(currentKf.xmdm, 2, currentKf);
if (isStart) {
2025-01-14 15:34:13 +08:00
await judgeTask.addTask(async () => {
console.info(judgeTag, `项目扣分-${currentKf.markcatalog}-${currentKf.desc}`)
await pointsDedute(currentKf.xmdm, currentKf)
2025-01-20 08:50:40 +08:00
}, {
isDelay: true
})
2025-01-14 15:34:13 +08:00
}
break;
// 考车状态
case 4:
break
// 考试结束
case 5:
console.info(judgeTag, '考试结束')
2025-02-11 09:18:16 +08:00
//关闭录像
const singlePlay = AppStorage.get('singlePlay') as boolean
2025-02-13 15:30:48 +08:00
if (!singlePlay) {
2025-01-14 15:34:13 +08:00
await endRecordVideo(this.videoData)
}
judgeTask.addTask(async () => {
console.info(judgeTag, '考试结束 start')
AppStorage.setOrCreate('isJudge', false)
2025-01-14 15:34:13 +08:00
await handEndExam(ksjs)
})
clearInterval(globalThis.judgeTimer)
break
default:
break
}
if (event == 2 || event == 3) {
setTimeout(() => {
this.judgeUI.kfArrScroller.scrollTo({
yOffset: 999999, xOffset: 0
})
2025-01-20 08:50:40 +08:00
}, 500)
2025-01-14 15:34:13 +08:00
//统计必考项目完成数量
await this.setCountItems();
await checkExamIsEnd()
}
}
// 考试扣分
pointsDedute = async (ksxm, kf) => {
2025-02-13 15:30:48 +08:00
const carInfo = AppStorage.get('carInfo');
2025-02-11 09:18:16 +08:00
const { examSubject, plateNo, carNo } = carInfo;
const { judgeUI, getProjectInfo, fileLog, xmmcSingleCode, xmmcEndCode, filePath } = this;
const { lsh, idCard, serialNumber, ksdd, projectsObj } = judgeUI
const time = await GetCurrentTime();
2025-01-14 15:34:13 +08:00
const project = getProjectInfo(ksxm);
//科目三夜间行驶.模拟灯光、上车准备出现通用评判ksxm为当前进行的项目
const checkProjects = ['17', '41', '1'];
//获取正在进行的项目
const inProjects = Reflect.ownKeys(projectsObj).filter(projectKey => projectsObj[projectKey].type == 2);
let commonKsxm = '';
2025-01-20 08:50:40 +08:00
checkProjects.forEach(projectCode => {
if (inProjects.includes(projectCode)) {
2025-01-14 15:34:13 +08:00
commonKsxm = projectCode
}
})
const data = {
2025-02-11 09:18:16 +08:00
xtlb: '17',
jkxlh: serialNumber,
jkid: '17C53',
2025-01-14 15:34:13 +08:00
drvexam: {
lsh,
kskm: examSubject,
ksxm: project == undefined
? (commonKsxm
? (projectsObj[commonKsxm].projectCodeCenter)
: (examSubject == 3 ? 30000 : (xmmcEndCode == undefined ? 10000 : xmmcEndCode)))
2025-01-20 08:50:40 +08:00
: project.projectCodeCenter,
2025-01-14 15:34:13 +08:00
kfxm: kf.markcatalog,
kfxmmx: `${ksxm},${kf.markserial}`,
sfzmhm: idCard,
kchp: encodeURI(carInfo.plateNo),
//扣分方式
kffs: kf.type == 0 ? 1 : 2,
ksdd: encodeURI(ksdd),
kfsj: time
}
}
2025-01-20 08:50:40 +08:00
console.info(judgeTag + 'ksxm=>', data.drvexam.ksxm)
2025-01-14 15:34:13 +08:00
2025-02-11 09:18:16 +08:00
const { code } = await this.sendWriteObjectOut(data, filePath);
2025-01-14 15:34:13 +08:00
if (code == 2300007) {
this.isJudgeDisConnect = true
}
console.info(judgeTag, '项目扣分 end')
promptWxCode('17C53', code)
}
// 评判语音提示
goJudgeVoice = async (sound: SOUND) => {
2025-02-11 09:18:16 +08:00
const { avPlayer, fileLog } = this;
const { xmdm, code, type } = sound;
2025-01-20 08:50:40 +08:00
console.info('surenjun code=>', JSON.stringify(code))
2025-01-14 15:34:13 +08:00
//判断是不是模拟灯光语音
if (type == 1) {
avPlayer.playAudio([`voice/${code[0]}.mp3`], false, () => {
examJudgeSoundEnd({
2025-01-20 08:50:40 +08:00
itemno: xmdm, code: code[0], type
2025-01-14 15:34:13 +08:00
})
fileLog.setExamJudgeData({
method: 'examJudgeSoundEnd',
itemno: xmdm,
2025-01-20 08:50:40 +08:00
code: code[0],
2025-01-14 15:34:13 +08:00
type,
})
})
2025-01-20 08:50:40 +08:00
} else {
avPlayer.playAudio([`voice/${code[0]}.mp3`])
2025-01-14 15:34:13 +08:00
}
2025-01-20 08:50:40 +08:00
}
2025-01-14 15:34:13 +08:00
// 处理考试结束
public handEndExam = async (ksjs: KSJS) => {
this.judgeUI.loadingPopupVisible = true;
this.judgeUI.endPopupVisible = false;
this.judgeUI.isDeductedPopShow = false;
2025-02-11 09:18:16 +08:00
const { qjjl, dcjl } = ksjs
const { judgeUI, endExam, handleSEP, kfArr, avPlayer, judgeTask, isManual, closeAllFiles } = this;
const { judgeConfigObj, examSubject, isAllProjectsEnd, totalScore, passingScore } = judgeUI;
2025-01-14 15:34:13 +08:00
//计算考试分数
// this.judgeUI.totalScore = isAllProjectsEnd ? totalScore : 0;
2025-02-13 15:30:48 +08:00
const singlePlay = AppStorage.get('singlePlay')
2025-01-14 15:34:13 +08:00
const param302 = judgeConfigObj['302'];
// globalThis.windowClass.setWindowSystemBarEnable(['navigation'])
//自动退出待验证并且不合格
2025-02-11 09:18:16 +08:00
if (!isManual && examSubject == 3 && (param302 == 1 || (singlePlay && param302 == 2)) &&
totalScore < passingScore) {
2025-01-14 15:34:13 +08:00
avPlayer.playAudio([`voice/考试结束.mp3`])
}
//联网模式下手动结束的直接退出
if (!singlePlay && isManual && !isAllProjectsEnd) {
avPlayer.playAudio(['voice/empty.mp3'], true, () => {
this.isUdpEnd = true;
closeAllFiles()
router.back();
})
return
}
if (examSubject == 3) {
const param302 = judgeConfigObj['302'];
if (totalScore < passingScore) {
//考试不合格;考试模式,自动退出;
if (param302 == 4 || param302 == 5 || param302 == 7 || param302 == 8) {
}
} else {
//考试合格
}
}
await handleSEP(306);
2025-02-13 15:30:48 +08:00
avPlayer.playAudio(['voice/exam_waiting.mp3'], AppStorage.get('singlePlay'), async () => {
2025-01-14 15:34:13 +08:00
try {
if (!singlePlay) {
const bytes = await this.getMessageHeartbeat(true);
globalThis.judgeUdp.send(bytes)
}
} catch (e) {
2025-01-20 08:50:40 +08:00
console.info(judgeTag, JSON.stringify(e))
2025-01-14 15:34:13 +08:00
// setTimeout(() => {
// // avPlayer.avPlayerStop();
// router.back();
// }, 3000)
}
await endExam()
2025-01-14 15:34:13 +08:00
});
}
// 考试结束
public endExam = async (isManual?: Boolean) => {
2025-02-13 15:30:48 +08:00
const carInfo = AppStorage.get('carInfo');
const singlePlay = AppStorage.get('singlePlay')
2025-02-11 09:18:16 +08:00
const { examSubject, plateNo } = carInfo;
2025-01-20 08:50:40 +08:00
const {
judgeUI,
ksjs,
getPhoto,
uploadProgressData,
uploadDisConnectData,
avPlayer,
kfArr,
judgeTask,
filePath,
closeAllFiles
} = this;
2025-02-11 09:18:16 +08:00
const { lsh, idCard, serialNumber, kssycs, totalScore, judgeConfigObj, isAllProjectsEnd, passingScore } = judgeUI
2025-01-14 15:34:13 +08:00
//TODO 断网考试结束补传
// await uploadDisConnectData();
const time = await GetCurrentTime();
2025-01-14 15:34:13 +08:00
const photoBase64 = await getPhoto();
2025-02-11 09:18:16 +08:00
const { d1, d2, d3, d4, d5 } = ksjs
2025-01-14 15:34:13 +08:00
const data = {
2025-02-11 09:18:16 +08:00
xtlb: '17',
jkxlh: serialNumber,
jkid: '17C56',
2025-01-14 15:34:13 +08:00
drvexam: {
lsh,
kchp: encodeURI(plateNo),
kskm: examSubject,
sfzmhm: idCard,
zp: photoBase64,
jssj: time,
kscj: (totalScore * 1) > 0 ? totalScore : 0,
kslc: Math.ceil(((ksjs?.qjjl + ksjs?.dcjl) || 0) / 100),
// 1,22;2,560;3,128;4,0;5,0;
2025-01-20 08:50:40 +08:00
dwlc: [d1, d2, d3, d4, d5].map((d, index) => `${index + 1},${Math.floor(d / 100)}`).join(';'),
2025-01-14 15:34:13 +08:00
}
}
2025-01-20 08:50:40 +08:00
let backTimeOut = setTimeout(() => {
router.back()
}, 90 * 1000)
2025-02-11 09:18:16 +08:00
const { code, keystr, message } = await this.sendWriteObjectOut(data, filePath);
2025-01-14 15:34:13 +08:00
promptWxCode('17C56', code)
2025-01-20 08:50:40 +08:00
if (code != 1) {
2025-01-14 15:34:13 +08:00
avPlayer.playAudio(['voice/监管失败.mp3'])
this.judgeUI.errorMsg = decodeURIComponent(message)
2025-01-20 08:50:40 +08:00
if (code == 2300028 || code == 2300007) {
2025-01-14 15:34:13 +08:00
this.judgeUI.errorMsg = '当前的考试过程信息监管审核未通过,程序将退出!'
}
this.isUdpEnd = true;
closeAllFiles()
this.judgeUI.loadingPopupVisible = false;
return
}
console.info(judgeTag, '考试结束 end')
const param302 = judgeConfigObj['302'];
judgeUI.loadingPopupVisible = true;
2025-01-20 08:50:40 +08:00
let currentKssycs = 0;
2025-01-14 15:34:13 +08:00
let voiceURL = ''
if (examSubject == 2) {
if (isAllProjectsEnd) {
2025-02-11 09:18:16 +08:00
voiceURL =
(totalScore < passingScore ? `voice/unqualified_${kssycs == 1 ? 'one' : 'two'}.wav` : 'voice/qualified.mp3')
2025-01-20 08:50:40 +08:00
} else {
2025-01-14 15:34:13 +08:00
voiceURL = `voice/unqualified_${kssycs == 1 ? 'one' : 'two'}.wav`
currentKssycs = kssycs == 1 ? 0 : 1
}
2025-01-20 08:50:40 +08:00
switch (voiceURL) {
2025-01-14 15:34:13 +08:00
case 'voice/unqualified_one.wav':
currentKssycs = 0;
break;
case 'voice/unqualified_two.wav':
currentKssycs = 1;
break;
case 'voice/qualified.mp3':
currentKssycs = 0;
break;
}
}
if (examSubject == 3) {
if (isAllProjectsEnd) {
if (totalScore < passingScore) {
voiceURL = `voice/${kssycs == 1 ? 'exam_no_pass_finish' : 'exam_no_pass'}.mp3`
currentKssycs = kssycs == 1 ? 0 : 1
} else {
voiceURL = 'voice/exam_pass.mp3'
currentKssycs = 0
2024-07-31 13:47:40 +08:00
}
2025-01-14 15:34:13 +08:00
} else {
voiceURL = `voice/${kssycs == 1 ? 'exam_no_pass_finish' : 'exam_no_pass'}.mp3`
currentKssycs = kssycs == 1 ? 0 : 1
2024-07-11 10:22:31 +08:00
}
2025-01-20 08:50:40 +08:00
switch (voiceURL) {
2025-01-14 15:34:13 +08:00
case 'voice/exam_no_pass_finish.mp3':
currentKssycs = 0;
break;
2024-08-19 10:11:22 +08:00
2025-01-14 15:34:13 +08:00
case 'voice/exam_no_pass.mp3':
currentKssycs = 1;
break;
case 'voice/exam_pass.mp3':
currentKssycs = 0;
break;
}
}
const USER = await getSyncData('USER');
await upDateTableByArray('USER', [{
...USER[0],
2025-01-20 08:50:40 +08:00
kssycs: currentKssycs
2025-01-14 15:34:13 +08:00
}])
console.info(judgeTag, `考试成绩:${totalScore}`)
2025-01-20 08:50:40 +08:00
if (!singlePlay) {
// await uploadProgressData();
2025-01-14 15:34:13 +08:00
}
2025-01-20 08:50:40 +08:00
clearTimeout(backTimeOut)
2025-01-14 15:34:13 +08:00
//语音播放扣分项
let score = 0;
//结束考试时候是否播报一遍所有扣分
const param634 = judgeConfigObj['634'];
if (kfArr.length && ((examSubject == 2 && param634 == 1) || examSubject == 3)) {
avPlayer.playAudio([`voice/kfdesc.mp3`], false, () => {
try {
kfArr.forEach((kf, index) => {
score += Math.abs(Number(kf.score));
//TODO 考试分数待替换
if (score <= (examSubject == 3 ? 10 : 20)) {
if (kfArr.length - 1 === index) {
avPlayer.playAudio([`voice/${kf.markcatalog}.mp3`, voiceURL], false, () => {
this.isUdpEnd = true;
closeAllFiles()
router.back();
})
throw new Error('End Loop')
}
avPlayer.playAudio([`voice/${kf.markcatalog}.mp3`])
} else {
avPlayer.playAudio([`voice/${kf.markcatalog}.mp3`, voiceURL], false, () => {
this.isUdpEnd = true;
closeAllFiles()
router.back();
})
throw new Error('End Loop')
}
})
} catch (e) {
2025-01-20 08:50:40 +08:00
console.info(judgeTag, JSON.stringify(e))
2024-07-05 09:08:17 +08:00
}
2025-01-14 15:34:13 +08:00
})
} else {
avPlayer.playAudio([voiceURL], true, () => {
setTimeout(() => {
this.isUdpEnd = true
closeAllFiles()
router.back();
}, param302 == 8 ? 3000 : 0)
})
}
2025-01-20 08:50:40 +08:00
2025-01-14 15:34:13 +08:00
}
// 当前项目转换
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
}
}
// 消息心跳发送
getMessageHeartbeat = async (isEnd?: Boolean) => {
2025-02-13 15:30:48 +08:00
const carInfo = AppStorage.get('carInfo');
2025-02-11 09:18:16 +08:00
const { examSubject, plateNo, ksyh } = carInfo;
2025-01-14 15:34:13 +08:00
const {
judgeUI,
isExam,
serialIndex,
tempData,
xmmcCode,
xmxh,
xmmcSingleCode,
xmdm,
performInfo,
kfArr,
getTranslateProject,
getSbxh,
fileLog,
} = this;
2025-02-13 15:30:48 +08:00
const singlePlay = AppStorage.get('singlePlay')
2025-02-11 09:18:16 +08:00
const { lsh, startHourTime, totalScore, examTime, judgeConfigObj } = judgeUI;
const {
fourInOneScreen:{
gpsDigit
}
} = judgeConfig
2025-01-20 08:50:40 +08:00
const examType = examSubject == 2 ? 2 : 3
2025-02-11 09:18:16 +08:00
const { sensor, gps } = tempData;
2025-01-20 08:50:40 +08:00
if (tempData.sensor === undefined) {
2025-01-14 15:34:13 +08:00
return
}
2025-02-11 09:18:16 +08:00
const { zfxd, yfxd, shtd, ygd, jgd, skd, dh1, dh2, lhq, jsc, ssc, fsc, lb, mkg, aqd, ygq, cs, fdjzs, dw } = sensor
const { jd, wd, hxj, fyj, hbg, sd } = gps;
2025-01-14 15:34:13 +08:00
//过滤错误数据
2025-01-20 08:50:40 +08:00
if (jd == 0) {
2025-01-14 15:34:13 +08:00
return
}
const translateProject = getTranslateProject();
const sbxh = getSbxh(xmdm, xmxh)
2025-02-11 09:18:16 +08:00
const { carzt, dcjl, qjjl, dxjl, bxjl } = performInfo || {};
const asclshArr = StringToASCII(
2025-01-20 08:50:40 +08:00
fillZero((singlePlay ? (examSubject == 2 ? '0000000000000' : '1111111111111') : lsh) || 0, 13)
2025-01-14 15:34:13 +08:00
);
//13不足要补0
const ascksyhArr = StringToASCII(fillZero(ksyh || 0, 13))
const ascsbxhArr = StringToASCII(sbxh)
2025-01-14 15:34:13 +08:00
const translateSignals = getTranslateSignals(
2025-02-11 09:18:16 +08:00
[zfxd, yfxd, shtd, ygd, jgd, skd, dh1, dh2, lhq, jsc, ssc, fsc, lb, mkg, aqd].concat(getDwStatusType(dw))
.concat(getCarStatusType(carzt)).concat([ygq, sensor.wd, 0])
2025-01-14 15:34:13 +08:00
)
const translateJd = convertGpsCoord2(wd).toFixed(gpsDigit) * Math.pow(10, gpsDigit);
const translateWd = convertGpsCoord2(jd).toFixed(gpsDigit) * Math.pow(10, gpsDigit)
const translateProjects = translateProject.map(numStr => string2Bytes(parseInt(numStr, 2), 8)[0])
2025-01-20 08:50:40 +08:00
let tempSd = ((judgeConfigObj['350'] == 0 ? sd : cs) * 1.852).toFixed(0) * 1
if (tempSd < 1) {
2025-01-14 15:34:13 +08:00
tempSd = 0
}
const arr = [
//考生号
asclshArr.map(lsh => string2Bytes(lsh, 8)[0]),
//考试员号
ascksyhArr.map(ksyh => string2Bytes(ksyh, 8)[0]),
//科目类型(0:未考试 1:科目二 2:科目三) + 考试开始时间
2025-02-13 15:30:48 +08:00
string2Bytes(`${examType}${AppStorage.get('startHourTime') || startHourTime}`, 4 * 8),
2025-01-14 15:34:13 +08:00
// TODO 消息序号从1开始0结束
string2Bytes(isEnd ? 0 : serialIndex, 2 * 8),
/*左向灯 右向灯 双跳灯 远光灯 近光灯 视宽灯 点火1 点火2 离合器 脚刹 手刹 副刹 喇叭 门开关 安全带 档位 车辆状态 雨刮器 雾灯 0*/
translateSignals,
//速度 发动机转速 GPS纬度 GPS经度 主天线位置
2025-02-11 09:18:16 +08:00
string2Bytes(tempSd * 100, 2 * 8), string2Bytes(fdjzs / 100, 8), string2Bytes(translateJd, 4 * 8),
string2Bytes(translateWd, 4 * 8), string2Bytes(1, 8),
2025-01-14 15:34:13 +08:00
//GPS东向距离
string2Bytes(dxjl < 0 ? (dxjl + 4294967296) : dxjl, 4 * 8),
//GPS北向距离
string2Bytes(bxjl < 0 ? (bxjl + 4294967296) : bxjl, 4 * 8),
//航向角 俯仰角 高程(海拔)
string2Bytes((hxj) * 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]),
//TODO 牵引车第二gps精度、纬度
string2Bytes(0, 4 * 8), string2Bytes(0, 4 * 8),
//TODO 牵引车第二航向角
string2Bytes(0, 2 * 8),
//TODO 摩托压线 Byte[20],
string2Bytes(0, 20 * 8),
//考试用时
string2Bytes(examTime, 4 * 8),
//TODO 项目用时
2025-01-20 08:50:40 +08:00
string2Bytes(fillZero(0, 2), 2 * 8),
2025-01-14 15:34:13 +08:00
//TODO 设备信号状态
string2Bytes(0, 4 * 8),
]
let tempArr = [];
arr.forEach(itemArr => {
tempArr = tempArr.concat(itemArr)
})
this.serialIndex += 1;
2025-02-13 15:30:48 +08:00
fileLog.setFourAndOneLogData(`${lsh},${ksyh},${examType}${AppStorage.get('startHourTime') || startHourTime},`);
2025-01-14 15:34:13 +08:00
fileLog.setFourAndOneLogDataBytes(tempArr.toString());
return Array2Byte(tempArr)
}
//获取场地序号
getSbxh = (ksxm, xmxh) => {
2025-02-11 09:18:16 +08:00
const { judgeUI } = this;
const { cdsbInfoObj, projectsObj } = judgeUI;
2025-01-14 15:34:13 +08:00
const project = projectsObj[ksxm]
2025-01-20 08:50:40 +08:00
if (project == 3) {
2025-01-14 15:34:13 +08:00
return '0000000000'
}
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) => {
2025-02-11 09:18:16 +08:00
const { judgeUI } = this;
const { cdsbInfoObj, projectsObj, examSubject } = judgeUI;
2025-01-20 08:50:40 +08:00
const project = projectsObj[ksxm]
//科目三不需要
if (examSubject == 3) {
return undefined
}
if (project === undefined) {
return '00000000'
}
const projectKey = `${ksxm}_${xmxh}`;
const currentCdsb = cdsbInfoObj[projectKey] || {};
const sbxh = currentCdsb.sbbm || '00000000'
return sbxh
}
// 中心所有项目转换
getTranslateProject = () => {
2025-02-11 09:18:16 +08:00
const { examSubject } = this.judgeUI;
2025-01-20 08:50:40 +08:00
const tempItems = (examSubject == 2 ? testKm2Items : testKm3Items).map(item => {
const current = this.testKmItems[item.code];
return {
code: item.code,
status: getCenterProjectStatus(current.status)
2025-01-14 15:34:13 +08:00
}
2025-01-20 08:50:40 +08:00
})
const arr = [];
for (let i = 0; i <= 4; i++) {
const temp = tempItems.slice(i * 4, (i + 1) * 4);
let tempArr = temp.map(item => item.status)
if (i === 4) {
tempArr = examSubject == 2
//bit36-bit39保留
? tempArr.concat(['00', '00'])
//bit30-bit39保留
: tempArr.concat(['00', '00', '00'])
2025-01-14 15:34:13 +08:00
}
2025-01-20 08:50:40 +08:00
// if (i === 3 && examSubject == 3) {
// tempArr = tempArr.concat(['00'])
// }
2025-01-14 15:34:13 +08:00
2025-01-20 08:50:40 +08:00
arr.push(tempArr.join(''));
}
return arr
}
// 获取考试项目详情
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
2025-01-14 15:34:13 +08:00
}
// 统计必考项目、所有项目、已考数量
setCountItems = async () => {
2025-02-13 15:30:48 +08:00
const carInfo = AppStorage.get('carInfo');
2025-02-11 09:18:16 +08:00
const { examSubject } = carInfo;
const { projectsObj } = this.judgeUI;
2025-01-14 15:34:13 +08:00
//必考项目数量 必考项目已考数量
let projectNum = 0, endProjectsNum = 0;
// 所有考试项目数量 项目已考项目数量
let allProjectNum = 0, allEndProjectsNum = 0;
Reflect.ownKeys(projectsObj).forEach(projectKey => {
2025-02-11 09:18:16 +08:00
const { type, isRequired } = projectsObj[projectKey];
2025-01-14 15:34:13 +08:00
allProjectNum += 1;
if (type == 3 || type == 4) {
allEndProjectsNum += 1;
}
if (isRequired) {
projectNum += 1;
if (type == 3 || type == 4) {
endProjectsNum += 1;
2024-07-11 10:22:31 +08:00
}
2024-07-31 13:47:40 +08:00
}
2025-01-14 15:34:13 +08:00
})
2025-01-20 08:50:40 +08:00
console.info(judgeTag, '项目状态projectsObj:' + JSON.stringify(projectsObj));
console.info(judgeTag, '所有考试项目数量:' + allProjectNum)
console.info(judgeTag, '必考项目数量:' + projectNum)
console.info(judgeTag, '必考项目已考数量:' + endProjectsNum)
2025-01-14 15:34:13 +08:00
//必考项目除靠边停车是否全部完成
this.judgeUI.isRequiredProjectsEnd = (projectNum - endProjectsNum === 0)
this.judgeUI.isAllProjectsEnd = (allProjectNum - allEndProjectsNum === 0)
}
// 检测差分状态
checkDwzt = async (type) => {
2025-02-11 09:18:16 +08:00
const { avPlayer } = this;
2025-01-14 15:34:13 +08:00
const judgeConfig = this.judgeUI.judgeConfig;
2025-01-20 08:50:40 +08:00
switch (type) {
2025-01-14 15:34:13 +08:00
case 0:
this.judgeUI.isDwztRight = true;
break;
case 1:
this.judgeUI.dwztErrorVisible = true;
2025-01-20 08:50:40 +08:00
avPlayer.playAudio([`voice/差分状态异常.mp3`], true)
setTimeout(() => {
2025-01-14 15:34:13 +08:00
router.back()
2025-01-20 08:50:40 +08:00
}, 3000)
2025-01-14 15:34:13 +08:00
break;
case 2:
2025-01-20 08:50:40 +08:00
avPlayer.playAudio([`voice/差分状态异常.mp3`], true);
2025-01-14 15:34:13 +08:00
break;
case 3:
this.judgeUI.dwztErrorVisible = true;
2025-01-20 08:50:40 +08:00
avPlayer.playAudio([`voice/差分状态异常.mp3`], true);
2025-01-14 15:34:13 +08:00
break;
case 4:
this.judgeUI.isDwztRight = false;
2025-02-11 09:18:16 +08:00
//差分异常上报
2025-01-14 15:34:13 +08:00
break;
2024-08-23 15:59:56 +08:00
}
2025-01-14 15:34:13 +08:00
}
2025-01-20 08:50:40 +08:00
closeAllFiles = () => {
setTimeout(() => {
2025-01-14 15:34:13 +08:00
this.fileLog.closeAllFiles()
2025-01-20 08:50:40 +08:00
}, 1000)
2025-01-14 15:34:13 +08:00
}
2025-01-20 08:50:40 +08:00
//开始评判
private async judging(callBack: Function) {
2025-02-11 09:18:16 +08:00
const { judgeUI } = this;
const { name, lsh, idCard, kssycs, manualMarkRules } = judgeUI;
2025-01-20 08:50:40 +08:00
const fileLog = new FileLog(judgeUI.context);
const filePath = await fileLog.initFileLogo({
name, lsh, idCard
});
this.fileLog = fileLog;
this.filePath = filePath;
2025-01-14 15:34:13 +08:00
2025-01-20 08:50:40 +08:00
const {
getJudgeBeginData,
handleUdp,
handDistance,
fileUtil,
handleTrajectoryUdp,
isTrajectoryOpen,
trajectoryPath,
avPlayer
} = this;
2025-02-13 15:30:48 +08:00
const isJudgeInitBool = AppStorage.get('isJudgeInitBool');
2025-01-20 08:50:40 +08:00
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);
})
2025-01-14 15:34:13 +08:00
2025-01-20 08:50:40 +08:00
console.info(judgeTag, '2.注册日志回调完成')
let initInfo = isTrajectoryOpen ? JSON.parse(strArr[0]) : await this.getJudgeInitData();
await fileLog.setExamJudgeData(initInfo)
//相关评判初始化只做一次
if (!isJudgeInitBool) {
const tempJudge = await examJudgeInit(initInfo);
AppStorage.setOrCreate('isJudgeInitBool', true)
2025-01-20 08:50:40 +08:00
console.info(judgeTag, '4.评判初始化完成')
}
AppStorage.setOrCreate('isJudge', true)
2025-01-20 08:50:40 +08:00
// 2.评判过程回调
await examJudgeSetRealExamCallback(async (strData, len) => {
await fileLog.setExamJudgeCallbackData(strData)
console.info('评判回调数据', strData)
this.handleRealExam(strData, callBack)
})
await examJudgeSetPerformCallback(async (info) => {
console.info('评判实时数据', info)
const performInfo = JSON.parse(info)
this.performInfo = performInfo
const jl = Math.floor((performInfo.qjjl + performInfo.dcjl) / 100);
if (jl > this.judgeUI.examMileage) {
this.checkExamIsEnd()
}
this.judgeUI.jl = jl
//TODO 待优化 跨组件传值不生效
globalThis.laneData = performInfo.lane;
})
// 3.开始考试
let beginExamInfo = isTrajectoryOpen ? {
...JSON.parse(strArr[1]),
replay: 1,
} : await getJudgeBeginData()
await fileLog.setExamJudgeData(beginExamInfo)
await examJudgeBeginExam(beginExamInfo);
console.info(judgeTag, '6.开始考试注册完成')
avPlayer.playAudio([globalThis.singlePlay ? 'voice/ksks.wav' : 'voice/监管成功.mp3'])
if (!globalThis.singlePlay) {
this.videoData = await saveStartRecordVideo(`${name}_${kssycs}`, this.context)
2025-01-20 08:50:40 +08:00
}
2025-02-11 09:18:16 +08:00
const { examSubject, projectsObj } = this.judgeUI
2025-01-20 08:50:40 +08:00
// if(examSubject == 3){
// //不做模拟灯光,需要做上车准备 =>(请上车准备)
// if(projectsObj[41]?.type == 3 && projectsObj[1]?.type != 3){
// avPlayer.playAudio(['voice/上车准备.mp3'])
// }
// //不做模拟灯光,不做上车准备 =>(请起步,完成考试)
// if(projectsObj[41]?.type == 3 && projectsObj[1]?.type == 3){
// avPlayer.playAudio(['voice/402001.mp3'])
// }
// }
this.judgeUI.draw = true
// 处理轨迹plc信息
if (isTrajectoryOpen) {
handleTrajectoryUdp(strArr);
return
}
// 处理实时udp里的plc信号
// globalThis.udpClient.closeMessage_1();
globalThis.udpClient.onMessage_1(async (msg) => {
console.info('socketTag[PLC.UdpClient]', '收到udp回调数据')
handleUdp(msg)
const udpIndex = globalThis.udpIndex;
if (udpIndex % 5 === 0) {
handDistance();
}
});
2025-01-20 08:50:40 +08:00
// this.checkExamIsEnd()
//监听远程结束考试
globalThis.udpEvent.onEndExam(async () => {
this.checkExamIsEnd(true);
})
console.info(judgeTag, JSON.stringify(manualMarkRules))
//监听远程扣分
globalThis.udpEvent.onKfExam(async (content) => {
console.info('评判收到远程扣分项目内容' + JSON.stringify(content))
2025-02-11 09:18:16 +08:00
const { kfxh, directives } = content.data;
2025-01-20 08:50:40 +08:00
console.info(judgeTag, '评判收到远程扣分项目内容,扣分序号:' + `kfxh=>${kfxh}; directives=>${directives}`)
//根据扣分序号找扣分代码
const currentKf = manualMarkRules.filter(mark => mark.kfxh == kfxh)[0];
console.info(judgeTag, '扣分项目:' + JSON.stringify(currentKf))
this.setJudgeMark(currentKf.itemno, currentKf.markserial, 2);
globalThis.judgeUdp.confirmKf(directives, 1)
})
this.checkExamIsEnd();
}
2025-01-14 15:34:13 +08:00
}