diff --git a/entry/src/main/ets/model/Judge.ets b/entry/src/main/ets/model/Judge.ets index e4ab1d5..1753dc9 100644 --- a/entry/src/main/ets/model/Judge.ets +++ b/entry/src/main/ets/model/Judge.ets @@ -41,7 +41,6 @@ export interface UDPParamType { /** 扣分代码项 */ export interface KfdmType { - xmmcStr: string xmdm: number desc: string @@ -451,7 +450,7 @@ export interface JudgeUI { systemparmArr: SYSTEMPARMARR[] carinfoArr: CARINFO[] kfArr: MarkRule[] - judgeConfigObj: object + judgeConfigObj: DefaultJudgeConfigObj judgeConfig: SyssetConfig[] projectsObj: ESObject projects: ProjectInfo[] @@ -656,11 +655,19 @@ export interface JudgeXMJS { xmhg: 0 | 1 } +export interface DeductionProjectConversionType { + desc: string + score: number + markcatalog: string + markserial: string + kfxh: string +} + export interface JudgeKf { xmdm: number kfdm?: string markcatalog: string - type: 0 | 1 | 2 | 3 + type?: 0 | 1 | 2 | 3 xmmcStr?: string desc?: string score?: number diff --git a/entry/src/main/ets/pages/Index.ets b/entry/src/main/ets/pages/Index.ets index b621866..c4769a5 100644 --- a/entry/src/main/ets/pages/Index.ets +++ b/entry/src/main/ets/pages/Index.ets @@ -19,7 +19,6 @@ import Prompt from '@system.prompt'; import { DifferentialAndSignal } from '../utils/business/DifferentialAndSignalWorker'; import { dConsole } from '../utils/LogWorker'; import CarLoadingComponent from './Index/Loading'; -import { CreateFile } from '../utils/Common'; @Entry @Component @@ -78,7 +77,6 @@ struct Index { async onPageShow(): Promise { dConsole.log("权限首页 onPageShow2") - CreateFile("/mnt/hmdfs/100/account/device_view/local/files/duolun/logs/test.text") if (!this.isPlay) { this.avPlayer.playAudio(['welcome.wav']) this.isPlay = true @@ -218,7 +216,6 @@ struct Index { HeaderComponent({ shortLogo: false }) - CardComponent({ isSingle: this.singlePlay, singleClick: () => { diff --git a/entry/src/main/ets/pages/Index/utils.ets b/entry/src/main/ets/pages/Index/utils.ets index 873998a..ba82d8f 100644 --- a/entry/src/main/ets/pages/Index/utils.ets +++ b/entry/src/main/ets/pages/Index/utils.ets @@ -141,4 +141,3 @@ export function CreateAlbum(fileHelper: FileHelper) { fileHelper.createAlbum(date); } - diff --git a/entry/src/main/ets/pages/Judge.ets b/entry/src/main/ets/pages/Judge.ets index 1184498..9b05d7d 100644 --- a/entry/src/main/ets/pages/Judge.ets +++ b/entry/src/main/ets/pages/Judge.ets @@ -396,6 +396,7 @@ struct JudgePage { Reflect.set(this.projectsObj, 1, project_1) } Reflect.set(this.judgeConfigObj, sys.v_no!, value) + dConsole.log("寻找", this.judgeConfigObj) }); this.judgeConfig = syssetJudgeConfigArr; } diff --git a/entry/src/main/ets/pages/Judge/JudgeBusiness.ets b/entry/src/main/ets/pages/Judge/JudgeBusiness.ets new file mode 100644 index 0000000..b24bafb --- /dev/null +++ b/entry/src/main/ets/pages/Judge/JudgeBusiness.ets @@ -0,0 +1,160 @@ +import { + JudgeConfigObjKmItems, + JudgePerformInfo, + JudgeUI, + MarkRule, + PLCType, + ProcessDataEnumType, + RecordHandleType, + WorkerBackMessage, + WorkerBackMessageType +} from '../../model' +import FileUtils from '../../utils/FileUtils' +import VoiceAnnounce from '../judgeSDK/utils/voiceAnnouncements' +import common from '@ohos.app.ability.common' +import { JudgeStartFn } from './JudgeStart' +import { dConsole } from '../../utils/LogWorker' +import { JudgeTag } from '../../config' +import { examJudgeRealExam } from './JudgeSDKUtils' +import { JudgingFn, SetJudgeItem } from './JudgeIng' +import { DifferentialAndSignal } from '../../utils/business/DifferentialAndSignalWorker' +import { PlcStrToJson, PlcStrToWXJson } from './utils' +import { JudgeEndFn } from './JudgeEnd' + +export default class JudgeBusiness { + public fileUtil: FileUtils + public avPlayer?: VoiceAnnounce + public performInfo?: JudgePerformInfo + public context: common.UIAbilityContext = getContext(this) as common.UIAbilityContext; + //考试是否结束了 + public isExamEnd: boolean + public isEndTip: boolean = false; + //是否手动结束考试 + public isManual: boolean = false + public deductedPopShowTimer: number = 0; + public videoData?: RecordHandleType + //是否是考试模式 + public isExam: boolean + // PLC原始数据 + public plcStr: string = "" + public rmndg: 0 | 1 = 0 + //所有的科目考试项目(大车&小车) + public kmItems: JudgeConfigObjKmItems + public xmmcStr: string = "" + public xmmcCode: string = "" + public xmmcSingleCode: string = "" + public xmmcEndCode?: string + public xmdm: string | number = "" + public xmxh: string = "" + public kfArr?: MarkRule[] + public carztStr: string + private judgeUI: JudgeUI + private tempData?: PLCType + private plcData?: PLCType + // 是否发送udp + private isUdpEnd: boolean = false + private mndgStr: string | undefined + + constructor(judgeUI: JudgeUI) { + this.judgeUI = judgeUI + this.fileUtil = new FileUtils(judgeUI.context) + this.avPlayer = new VoiceAnnounce(this.context); + } + + // 单机轨迹模式 + public async SingleMachineTrajectory(strArr: string[]) { + let num = 2 + const judgeTimer = setInterval(async () => { + const msgStr = strArr[num] + if (msgStr == '') { + dConsole.info(JudgeTag, '模拟数据考试结束') + clearInterval(judgeTimer) + this.JudgeEnd(true) + return + } + const msg: PLCType = JSON.parse(strArr[num]); + num++ + // 4.过程数据 + this.tempData = msg + this.judgeUI.sd = Math.floor(msg?.gps?.sd * 1.852) + ''; + this.judgeUI.dw = Math.floor(msg?.sensor?.dw) + '' + this.plcData = msg + AppStorage.setOrCreate('msgStr', '') + if (msg.method === 'examJudgeArtificialItem') { + SetJudgeItem(msg.itemno, msg.type) + } + if (msg.method === 'examJudgeArtificialMark') { + SetJudgeItem(msg.itemno, msg.serial) + } + await examJudgeRealExam(msg) + }, 200) + } + + // 开始考试 + public async JudgeStart(callBack: Function) { + // 处理考试前需要做的业务 + // 调用开始考试 + JudgeStartFn(callBack, this.judgeUI, this) + // 处理PLC数据 + // 处理实时udp里的plc信号 + DifferentialAndSignal.onMsg((data: string) => { + const result: WorkerBackMessage = JSON.parse(data) + if (result.type === WorkerBackMessageType.ObtainUdpData) { + this.HandlePLCData(result.data as string) + dConsole.writeProcessData(ProcessDataEnumType.PlcData, result.data as string) + } + }) + this.JudgeEnd() + } + + // 考试过程 callback优化 + public async Judging(strData: string, callBack: Function) { + JudgingFn(strData, callBack, this.judgeUI, this) + } + + // 结束考试 + public JudgeEnd(isManual?: boolean) { + JudgeEndFn(this.judgeUI, this, isManual) + } + + // 处理PLC数据 + private async HandlePLCData(msg: string) { + const plcArr = msg.split(',') + if (plcArr[0] != '#DN_GD' || this.isUdpEnd) { + return + } + const gpsPart = msg.split("#END$GPS,")[1]; + const gpsStatus = gpsPart.split(",")[0]; + if (gpsStatus === "4") { + dConsole.log(JudgeTag, "差分状态正常", gpsStatus) + this.judgeUI.isDwztRight = true + } else { + dConsole.log(JudgeTag, "差分状态异常", gpsStatus) + this.judgeUI.isDwztRight = false + } + // 记录原始PLC数据 + dConsole.writeProcessData(ProcessDataEnumType.PlcData, msg) + const tempData = await PlcStrToJson(msg); + tempData.sensor.rmndg = this.rmndg; + tempData.sensor.mndg = this.mndgStr || ""; + const wuXiDataStr = await PlcStrToWXJson(msg) + // 无锡所数据记录 + dConsole.writeProcessData(ProcessDataEnumType.WuxiProgressData, wuXiDataStr) + this.plcData = tempData + this.tempData = tempData + this.plcStr = msg; + this.mndgStr = ''; + this.rmndg = 0; + AppStorage.setOrCreate('msgStr', msg) + // 4.过程数据 + dConsole.writeProcessData(ProcessDataEnumType.JudgeExamData, JSON.stringify(this.plcData)) + const param350: number = Reflect.get(this.judgeUI.judgeConfigObj, '350') + this.judgeUI.sd = ((param350 == 0 ? this.plcData.gps.sd : this.plcData.sensor.cs) as number * 1.852).toFixed(0) + '' + this.judgeUI.dw = (Math.floor(this.plcData.sensor.dw as number) || 0) + '' + if (!this.isExamEnd) { + await examJudgeRealExam(this.plcData) + } + + } +} + diff --git a/entry/src/main/ets/pages/Judge/JudgeEnd.ets b/entry/src/main/ets/pages/Judge/JudgeEnd.ets new file mode 100644 index 0000000..b224356 --- /dev/null +++ b/entry/src/main/ets/pages/Judge/JudgeEnd.ets @@ -0,0 +1,110 @@ +import { JudgeTag } from '../../config' +import { JudgeUI } from '../../model' +import { dConsole } from '../../utils/LogWorker' +import JudgeBusiness from './JudgeBusiness' +import { examJudgeEndExam } from './JudgeSDKUtils' + +export const JudgeEndFn = async (judgeUI: JudgeUI, that: JudgeBusiness, isManual?: boolean) => { + const isAllProjectsEnd = judgeUI.isAllProjectsEnd + const examSubject = judgeUI.examSubject + const singlePlay = judgeUI.singlePlay + const totalScore = Number(judgeUI.totalScore) + const judgeConfigObj = judgeUI.judgeConfigObj + const examMileage = Number(judgeUI.examMileage) + const passingScore = Number(judgeUI.passingScore) + const jl = judgeUI.jl + if (that.isExamEnd) { + return + } + if (isManual) { + // 考试不合格 + await examJudgeEndExam() + that.isExamEnd = true + that.isManual = true + } else { + const param302: number = Reflect.get(judgeConfigObj, '302') + const param342: number = Reflect.get(judgeConfigObj, '342') + const param512: number[] = (Reflect.get(judgeConfigObj, '512') || '').split(','); + + //单机模式 + if (singlePlay) { + dConsole.info(JudgeTag + ' 单机模式结束 => ', isAllProjectsEnd) + if (isAllProjectsEnd && jl >= examMileage) { + //成绩合格 + if (totalScore >= passingScore && !that.isEndTip) { + if (examSubject == '3' && (param342 == 0 || param342 == 2) && + (param302 != 6 && param302 != 7 && param302 != 8)) { + if (param512[7] != 0) { + clearTimeout(that.deductedPopShowTimer) + that.avPlayer?.playAudio(['voice/综合评判.mp3']) + judgeUI.isDeductedPopShow = true + judgeUI.defaultTabIndex = 1 + that.isEndTip = true + return + } + } else { + await examJudgeEndExam() + that.isExamEnd = true + return + } + } else { + if (examSubject == '3' && (param302 == 4 || param302 == 5 || param302 == 7 || param302 == 8)) { + await examJudgeEndExam() + that.isExamEnd = true + return + } + } + await examJudgeEndExam() + that.isExamEnd = true + } + } else { + //成绩不合格 + if (totalScore < passingScore) { + //科目三不合格报靠边停车 + if (examSubject == '3' && param302 == 1) { + that.avPlayer?.playAudio([`voice/考试结束.mp3`]); + return + } + await examJudgeEndExam() + that.isExamEnd = true + return + } + + //成绩合格 + if (isAllProjectsEnd && totalScore >= passingScore && !that.isEndTip) { + if (examSubject == '2') { + await examJudgeEndExam() + that.isExamEnd = true + return + } + + //考试里程判断 + if (examSubject == '3' && jl < examMileage) { + return + } + + //考试合格自动退出 + if (examSubject == '3' && (param302 == 4 || param302 == 7) || param302 == 8) { + await examJudgeEndExam() + that.isExamEnd = true + return + } + + if (examSubject == '3' && (param342 == 0 || param342 == 2) && + (param302 != 6 && param302 != 7 && param302 != 8)) { + if (param512[7] != 0) { + clearTimeout(that.deductedPopShowTimer) + judgeUI.isDeductedPopShow = false + that.avPlayer?.playAudio(['voice/综合评判.mp3']) + judgeUI.isDeductedPopShow = true + judgeUI.defaultTabIndex = 1 + that.isEndTip = true + } + } else { + await examJudgeEndExam() + that.isExamEnd = true + } + } + } + } +} \ No newline at end of file diff --git a/entry/src/main/ets/pages/Judge/JudgeIng.ets b/entry/src/main/ets/pages/Judge/JudgeIng.ets new file mode 100644 index 0000000..a4a8329 --- /dev/null +++ b/entry/src/main/ets/pages/Judge/JudgeIng.ets @@ -0,0 +1,154 @@ +import { JudgeTag } from '../../config'; +import { JudgeCallBackData, JudgeUI, KmItem, MarkRule, ProcessDataEnumType, ProjectInfo } from '../../model'; +import { dConsole } from '../../utils/LogWorker'; +import JudgeBusiness from './JudgeBusiness'; +import { examJudgeArtificialItem } from './JudgeSDKUtils'; +import { CurrentProjectConversion, DeductionProjectConversion } from './utils'; + +export const JudgingFn = async (strData: string, callBack: Function, judgeUI: JudgeUI, that: JudgeBusiness) => { + let examData: JudgeCallBackData = JSON.parse(strData); + const carzt = examData.carzt + const xmks = examData.xmks + const kf = examData.kf + const event = examData.event + const xmjs = examData.xmjs + const xmqx = examData.xmqx + const ksjs = examData.ksjs + const sound = examData.sound + const mndg = examData.mndg + const lane = examData.lane + const precast = examData.precast + const nongps = examData.nongps + //获取项目结束、项目开始代码 + const xmdm = event == 2 ? xmjs.xmdm : xmks.xmdm + const xmxh = event == 2 ? xmjs.xmxh : xmks.xmxh; + let artSubject3ProjectsCodesArr: number[] = [3, 9, 4, 10, 12, 11] + const isManualProjectIn = artSubject3ProjectsCodesArr.includes(xmdm); + const examSubject = judgeUI.examSubject + const judgeConfigObj = judgeUI.judgeConfigObj + let project: ProjectInfo = Reflect.get(judgeUI.projectsObj, xmdm) + const xmmcCode = project.projectCodeCenter || ""; + const kmItem: KmItem = Reflect.get(that.kmItems, xmmcCode) + + switch (event) { + // 项目开始 + case 1: + project.type = '2'; + if (isManualProjectIn) { + //手动项目是否在进行中 + judgeUI.isManualProjectIn = true + } + if (xmdm == 41 && examSubject == '3') { + that.rmndg = 1 + } + judgeUI.currentXmdm = xmdm; + const xmmcStr = project.name || ""; + const xmmcSingleCode = project.projectCode || ""; + kmItem.status = 2; + that.xmmcStr = xmmcStr; + that.xmmcCode = xmmcCode; + that.xmmcSingleCode = xmmcSingleCode + that.xmmcEndCode = xmmcCode + that.xmdm = xmdm; + that.xmxh = xmxh; + judgeUI.isProjectIn = true + Reflect.set(judgeUI.projectsObj, xmdm, project) + Reflect.set(that.kmItems, xmmcCode || 0, kmItem) + break; + // 项目结束 + case 2: + project.type = (xmjs.xmhg === 0 ? '4' : '3') + //计算项目是否全部结束 + judgeUI.isProjectIn = (Reflect.ownKeys(judgeUI.projectsObj).filter((projectKey) => { + const fillProject: ProjectInfo = Reflect.get(judgeUI.projectsObj, projectKey) + return fillProject.type == '2' + }).length) > 0; + if (isManualProjectIn) { + judgeUI.isManualProjectIn = false + } + kmItem.status = 3; + //统计必考项目数量 + that.xmmcStr = '无'; + that.xmmcCode = ''; + that.xmdm = ''; + judgeUI.currentXmdm = undefined; + Reflect.set(judgeUI.projectsObj, xmdm, project) + Reflect.set(that.kmItems, xmmcCode, kmItem) + break; + // 扣分 + case 3: + const thisKf = DeductionProjectConversion(`${kf.xmdm}_${kf.kfdm}`, judgeUI.markRuleListObj) + const kfObj: MarkRule = { + //扣分项目名称 + xmmcStr: CurrentProjectConversion(kf.xmdm, judgeUI.projectsObj), + xmdm: kf.xmdm + "", + //扣分描述 + desc: thisKf.desc, + //扣分分数 + score: thisKf.score, + // 扣分无锡所代码 + markcatalog: thisKf.markcatalog, + markserial: thisKf.markserial, + kfxh: thisKf.kfxh, + //扣分类型 + type: kf.type + } + dConsole.log(JudgeTag, "扣分组装", kfObj) + that.kfArr?.push(kfObj) + dConsole.log(JudgeTag, "扣分类组装", that.kfArr) + judgeUI.totalScore += Number(thisKf?.score); + if (kf.xmdm != 20) { + const project: ProjectInfo = Reflect.get(judgeUI.projectsObj, kf.xmdm) + const type = project.type; + project.type = (type == '3' || type == '4') ? '4' : '5' + Reflect.set(judgeUI.projectsObj, kf.xmdm, project) + } + break; + // 考试状态 + case 4: + break; + // 考试结束 + case 5: + break; + // 项目取消 + case 6: + break; + // 语音播报和提示 + case 7: + break; + // 模拟灯光事件 + case 8: + break; + // 车道和路段变化 + case 9: + break; + // 预进项目事件 + case 10: + break; + // 差分事件 + case 11: + break; + default: + 83 + break; + } + await callBack({ + //项目名称 考车状态 扣分arr + xmmcStr: that.xmmcStr, carztStr: that.carztStr, kfArr: that.kfArr + }); + +} + +// + + +export const SetJudgeItem = async (itemno: string, type: 1 | 2) => { + await examJudgeArtificialItem(Number(itemno), type); + const str = JSON.stringify({ + method: 'examJudgeArtificialItem', + itemno: Number(itemno), + type + }) + dConsole.writeProcessData(ProcessDataEnumType.JudgeExamData, str) + dConsole.info(JudgeTag, `人工评判${type == 1 ? '进入' : '取消'}项目-${itemno}`) +} \ No newline at end of file diff --git a/entry/src/main/ets/pages/Judge/JudgeUtils.ets b/entry/src/main/ets/pages/Judge/JudgeSDKUtils.ets similarity index 100% rename from entry/src/main/ets/pages/Judge/JudgeUtils.ets rename to entry/src/main/ets/pages/Judge/JudgeSDKUtils.ets diff --git a/entry/src/main/ets/pages/Judge/JudgeStart.ets b/entry/src/main/ets/pages/Judge/JudgeStart.ets new file mode 100644 index 0000000..bad0c84 --- /dev/null +++ b/entry/src/main/ets/pages/Judge/JudgeStart.ets @@ -0,0 +1,249 @@ +//开始评判 +import { JudgeConfig, JudgeTag } from '../../config'; +import { + BaseInfoType, + CARINFO, + CarInfoType, + CDSBInfo, + ExaminerInfoType, + ItemInfo, + ItemInfos, + JudgeBeginObj, + JudgeInitObj, + JudgeKFXM, + JudgeKSXM, + JudgeUI, + Km3JudgeInitConfig, + MAPITEMPOINTITEM, + MAPPOINT, + MarkRule, + ProcessDataEnumType, + ProjectInfo, + RouteParamsType, + SyssetConfig, + SYSTEMPARMARR +} from '../../model'; +import common from '@ohos.app.ability.common'; +import { dConsole } from '../../utils/LogWorker'; +import { + examJudgeBeginExam, + examJudgeInit, + examJudgeSetLogCallback, + examJudgeSetPerformCallback, + examJudgeSetRealExamCallback, + examJudgeVersion +} from './JudgeSDKUtils'; +import FileModel from '../judgeSDK/utils/fileModel'; +import JudgeBusiness from './JudgeBusiness'; +import { saveStartRecordVideo } from '../../utils/Video'; +import router from '@ohos.router'; +import systemTime from '@ohos.systemTime'; + +export const JudgeStartFn = async (callBack: Function, judgeUI: JudgeUI, that: JudgeBusiness) => { + const name = judgeUI.name + const kssycs = judgeUI.kssycs + const manualMarkRules = judgeUI.manualMarkRules + // 处理单机模式 + const isTrajectoryOpen = JudgeConfig.isTrajectoryOpen; + const isJudgeInitBool = AppStorage.get('isJudgeInitBool'); + const trajectoryPath = JudgeConfig.trajectoryPath; + let strArr: string[] = []; + if (isTrajectoryOpen) { + const folderPath = await that.fileUtil.initFolder(trajectoryPath); + const str: string = await that.fileUtil.readFile(folderPath) + strArr = str.split('\n') + } + //日志回调 + dConsole.info(JudgeTag, '1.进入评判入口') + await examJudgeSetLogCallback(6, async (level: number, info: string, len: number) => { + dConsole.log(JudgeTag, '评判日志:' + info) + dConsole.writeProcessData(ProcessDataEnumType.JudgeLogData, info) + }) + + dConsole.info(JudgeTag, '2.注册日志回调完成') + + let initInfo: JudgeInitObj = isTrajectoryOpen ? JSON.parse(strArr[0]) : await GetJudgeInitData(judgeUI.context, judgeUI.markRuleListObj, judgeUI.carType, judgeUI.carName, judgeUI.systemparmArr, judgeUI.carinfoArr, judgeUI.examSubject, judgeUI.itemInfoObj, judgeUI.judgeConfig, judgeUI.carlist, judgeUI.mapPointArr, judgeUI.mapPointItemArr); + //相关评判初始化只做一次 + if (!isJudgeInitBool) { + dConsole.log(JudgeTag, "评判初始化参数", initInfo) + await examJudgeInit(initInfo); + AppStorage.setOrCreate('isJudgeInitBool', true) + dConsole.info(JudgeTag, '4.评判初始化完成') + } + AppStorage.setOrCreate('isJudge', true) + // 2.评判过程回调 + await examJudgeSetRealExamCallback(async (strData: string, len: number) => { + // 评判回调日志 + dConsole.writeProcessData(ProcessDataEnumType.JudgeProgressCallbackData, strData) + dConsole.info(JudgeTag, '评判回调数据', strData) + await that.Judging(strData, callBack) + }) + await examJudgeSetPerformCallback(async (info: string) => { + dConsole.info('评判实时数据', info) + that.performInfo = JSON.parse(info) + const jl = Math.floor((that.performInfo.qjjl + that.performInfo.dcjl) / 100); + if (jl > Number(judgeUI.examMileage)) { + that.JudgeEnd() + } + judgeUI.jl = jl + judgeUI.laneSignal = that.performInfo.lane + }) + let beginExamInfo: JudgeBeginObj | undefined = undefined + // 3.开始考试 + if (isTrajectoryOpen) { + beginExamInfo = JSON.parse(strArr[1]) + beginExamInfo && (beginExamInfo.replay = 1) + } else { + beginExamInfo = await GetJudgeBeginData(judgeUI.projects, judgeUI.carType, judgeUI.kssycs, judgeUI.isDdxk, judgeUI.ddxkTime, judgeUI.projectsCenterObj, judgeUI.ddxkKsxmArr, judgeUI.ddxkKfArr, judgeUI.passingScore, judgeUI.wayno, judgeUI.name, judgeUI.lsh, judgeUI.idCard, that.isExam) + } + if (beginExamInfo) { + await examJudgeBeginExam(beginExamInfo); + } + dConsole.info(JudgeTag, '6.开始考试注册完成') + that.avPlayer?.playAudio([judgeUI.singlePlay ? 'voice/ksks.wav' : 'voice/监管成功.mp3']) + if (!judgeUI.singlePlay) { + that.videoData = await saveStartRecordVideo(`${name}_${kssycs}`, that.context) + } + judgeUI.draw = true + // 处理单机泡轨迹模式 + if (isTrajectoryOpen) { + that.SingleMachineTrajectory(strArr) + return + } +} + +// 获取评判开始考试数据 +const GetJudgeBeginData = async (projects: ProjectInfo[], carType: string, kssycs: string, isDdxk: boolean, ddxkTime: number, projectsCenterObj: Object, ddxkKsxmArr: string[], ddxkKfArr: string[], passingScore: number, wayno: number, name: string, lsh: string, idCard: string, isExam: boolean) => { + const examinerInfo = AppStorage.get('examinerInfo') + const examinerName = examinerInfo?.name || "" + let currentParams: RouteParamsType = router.getParams() as RouteParamsType; + const sczb = currentParams.sczb; + const kfdm = currentParams.kfdm; + const ksxm: JudgeKSXM[] = projects.map(project => { + const temp: JudgeKSXM = { + xmdm: Number(project.projectCode), xmxh: '' + } + return temp + }) + const ykxm: number[] = (ddxkKsxmArr?.map(projectCenterCode => { + const currentProject: ProjectInfo = Reflect.get(projectsCenterObj, projectCenterCode) + return Number(currentProject.projectCode) + })) || []; + const kfxm: JudgeKFXM[] = isDdxk ? (ddxkKfArr?.map(kf => { + return { + xmdm: Number(kf.split(',')[0]), kfdm: kf.split(',')[1] + } as JudgeKFXM + })) : [] + const beginInfo: JudgeBeginObj = { + kgid: '012', + kgxm: decodeURI(examinerName || ''), + exam: isExam ? 1 : 0, + //是否回放 + replay: 0, + //生成的轨迹文件 + track: '', + xm: name, + sex: 0, + kslsh: lsh, + sfzmhm: idCard, + ksyy: '', + kscx: carType, + kkcs: Number(kssycs) || 2, + sfyk: 0, + ykkkcs: 1, + wayno: Number(wayno), + czlx: 0, + kskssj: await systemTime.getCurrentTime(), + passing: Number(passingScore), + ksxm, + //断点续考 + ddxk: isDdxk ? 1 : 0, + ddkssj: ddxkTime || 0, + ykxm, + kfxm, + yklc: 0, + special: [], + sczb: (sczb === undefined || sczb == '0') ? 0 : 1, + sczbkf: kfdm, + dmndg: false, + mfxx: false, + mfxxn: false + } + dConsole.info(JudgeTag, '5.获取开始考试数据完成') + return beginInfo +} + +// 获取评判初始化数据 +const GetJudgeInitData = async (context: common.UIAbilityContext, markRuleListObj: object, carType: string, carName: string, systemparmArr: SYSTEMPARMARR[], carinfoArr: CARINFO[], examSubject: string, itemInfoObj: ItemInfos, judgeConfig: SyssetConfig[], carlist: string, mapPointArr: MAPPOINT[], mapPointItemArr: MAPITEMPOINTITEM[]) => { + const carInfo = AppStorage.get('carInfo'); + const examType = carInfo?.examSubject == '2' ? 'km2' : 'km3' + + let allitems: ItemInfo[] = []; + if (examSubject == '2' && itemInfoObj) { + allitems = Reflect.ownKeys(itemInfoObj).map(cdsbKey => { + const cdsb: CDSBInfo = Reflect.get(itemInfoObj, cdsbKey); + const model = GetModelData(`${examType}/${cdsb.modelKey}.txt`, context) + const temp: ItemInfo = { + xmdm: cdsb?.xmdm || 0, + xmxh: cdsb?.xmxh || "", + model: model || "" + } + return temp + }) + } + + //获取版本号 + const mark: MarkRule[] = Reflect.ownKeys(markRuleListObj).map(ruleKey => { + const current: MarkRule = Reflect.get(markRuleListObj, ruleKey) + return current + }) + const initInfo: JudgeInitObj = { + sdkver: await examJudgeVersion(), + appver: AppStorage.get('baseInfo')?.version || "", + kskm: Number(carInfo?.examSubject || "2"), + kchp: carInfo?.plateNo || "", + kchm: Number(carInfo?.carId || ""), + kscx: carType, + cxcode: '1', + name: carName, + carmodel: GetModelData(`${examType}/${carType}.txt`, context) || "", + allitems, + iteminfo: [], + systemparm: systemparmArr, + mark, + sysset: judgeConfig, + itemInfoObj, + carlist: carlist, + carinfo: carinfoArr, + }; + let km3Config: Km3JudgeInitConfig = {} + if (examSubject == '3') { + km3Config = { + map_point: mapPointArr, + map_point_item: mapPointItemArr, + //科目三暂时为空 + iteminfo: [], + roads: GetModelData('km3/Roads.txt', context) || "", + sharps: GetModelData('km3/Sharps.txt', context) || "" + }; + initInfo.map_point = km3Config.map_point + initInfo.map_point_item = km3Config.map_point_item + initInfo.iteminfo = km3Config.iteminfo + initInfo.roads = km3Config.roads + initInfo.sharps = km3Config.sharps + } + // 获取科目三的评判配置 + dConsole.info(JudgeTag, '3.获取评判初始化数据完成') + return initInfo +} + +export const GetModelData = (modelName: string, context: common.UIAbilityContext): string => { + try { + return new FileModel(context).getModelContent(JudgeConfig.modelPath, modelName); + } catch (e) { + // 可根据实际需求,返回空字符串或抛出异常 + dConsole.error(JudgeTag, `获取模型数据失败: ${modelName}`, e.message) + return ''; + } +}; + diff --git a/entry/src/main/ets/pages/Judge/JudgeVariable.ets b/entry/src/main/ets/pages/Judge/JudgeVariable.ets new file mode 100644 index 0000000..fb241fa --- /dev/null +++ b/entry/src/main/ets/pages/Judge/JudgeVariable.ets @@ -0,0 +1,28 @@ +import { testKm2Items, testKm3Items } from '../../mock'; +import { JudgeConfigObjKmItems, ProjectInfo, ProjectInfos } from '../../model'; + +class judgeVariable { + public rmndg: 0 | 1 = 0 + public kmItems: JudgeConfigObjKmItems = {} + public xmmcStr: string = "" + public xmmcEndCode?: string = "" + public xmxh: string = "" + public status: string = "开始" + + constructor() { + + } + + public initKmItems(examSubject: string, projectsCenterObj: ProjectInfos) { + (examSubject == '2' ? testKm2Items : testKm3Items).forEach(item => { + const projectCenterObj: ProjectInfo = Reflect.get(projectsCenterObj, item.code) + Reflect.set(this.kmItems, item.code, { + code: item.code, + status: projectCenterObj === undefined ? 0 : (projectCenterObj.isEnd ? 3 : 1) + }) + }) + + } +} + +export const JudgeVariable = new judgeVariable(); \ No newline at end of file diff --git a/entry/src/main/ets/pages/Judge/utils.ets b/entry/src/main/ets/pages/Judge/utils.ets index 10e4b79..e3f1c5c 100644 --- a/entry/src/main/ets/pages/Judge/utils.ets +++ b/entry/src/main/ets/pages/Judge/utils.ets @@ -2,25 +2,22 @@ import systemTime from '@ohos.systemDateTime'; import { TestRealExam } from '../../mock'; import { CarInfoType, + DeductionProjectConversionType, DefaultJudgeConfigObj, ExtendType, Gps, LANE, + MarkRule, PLCType, ProjectInfo, ProjectInfos, ProjectRoads, Radar, - VideoConfig, Vision } from '../../model'; import { ArrayToByteArray, NumberToByteArray } from '../../utils/Common'; import dayTs from '../../utils/Date'; import { dConsole } from '../../utils/LogWorker'; -import common from '@ohos.app.ability.common'; -import { JudgeConfig, JudgeTag } from '../../config'; -import { takePhoto } from '../../utils/Video'; -import Prompt from '@system.prompt'; // 中心信号转换 @@ -838,3 +835,21 @@ export const GetIsEndManualProject = (index: number, artSubject3Projects: string return (type == '3' || type == '4') ? `${projectName}_red` : `${projectName}_green`; } + +//扣分项目转换 +export const DeductionProjectConversion = (code: string, markRuleListObj: object): DeductionProjectConversionType => { + const thisMark: MarkRule = Reflect.get(markRuleListObj, code) + return { + desc: thisMark.markshow, + score: thisMark.markreal, + markcatalog: thisMark.markcatalog, + markserial: thisMark.markserial, + kfxh: thisMark.kfxh + } +} + +//当前项目转换 +export const CurrentProjectConversion = (code: number, projectsObj: object): string => { + const project: ProjectInfo = Reflect.get(projectsObj, code) + return project?.abbreviation || '通用评判' +} \ No newline at end of file diff --git a/entry/src/main/ets/pages/compontents/TrajectoryView.ets b/entry/src/main/ets/pages/compontents/TrajectoryView.ets index e75183f..6a8bfa9 100644 --- a/entry/src/main/ets/pages/compontents/TrajectoryView.ets +++ b/entry/src/main/ets/pages/compontents/TrajectoryView.ets @@ -3,10 +3,11 @@ import { GPSData } from '../../mock' import { PerLane, RoadDataType, SignalDataType, WorkerBackMessage, WorkerBackMessageType } from '../../model' import { DifferentialAndSignal } from '../../utils/business/DifferentialAndSignalWorker' import { dConsole } from '../../utils/LogWorker' -import { examJudgeMapSetDrawing, examJudgeMapSetScaling } from '../Judge/JudgeUtils' +import { examJudgeMapSetDrawing, examJudgeMapSetScaling } from '../Judge/JudgeSDKUtils' import BlockComponent from './Block' import CoordinateComponent from './Coordinate' + @Component export default struct TrajectoryViewComponent { // GPS信号 diff --git a/entry/src/main/ets/pages/judgeSDK/judge.ets b/entry/src/main/ets/pages/judgeSDK/judge.ets index 28167d5..291c471 100644 --- a/entry/src/main/ets/pages/judgeSDK/judge.ets +++ b/entry/src/main/ets/pages/judgeSDK/judge.ets @@ -66,7 +66,7 @@ import { examJudgeSetRealExamCallback, examJudgeSoundEnd, examJudgeVersion -} from '../Judge/JudgeUtils'; +} from '../Judge/JudgeSDKUtils'; import { GetCarStatus, GetCenterProjectStatus, @@ -142,7 +142,7 @@ export default class Judge { switch (code) { //结束考试方式 case 306: - if (judgeConfigObj[code] == 5) { + if (Reflect.get(judgeConfigObj, code) == 5) { //靠边停车 avPlayer?.playAudio(['voice/406001.mp3']) } @@ -170,48 +170,6 @@ export default class Judge { private isExamEnd: boolean // 是否发送udp private isUdpEnd: boolean = false - // 处理udp plc信号 - handleUdp = async (msg: string) => { - const stachArr = msg.split(',') - if (stachArr[0] != '#DN_GD' || this.isUdpEnd) { - return - } - const gpsPart = msg.split("#END$GPS,")[1]; - const gpsStatus = gpsPart.split(",")[0]; - if (gpsStatus === "4") { - dConsole.log(JudgeTag, "差分状态正常", gpsStatus) - this.judgeUI.isDwztRight = true - } else { - dConsole.log(JudgeTag, "差分状态异常", gpsStatus) - this.judgeUI.isDwztRight = false - } - this.judgeUI.isDwztRight - const plcData = await this.getPlcData(msg); - // 4.过程数据 - // await this.fileLog?.setExamJudgeData(JSON.stringify(plcData)) - dConsole.writeProcessData(ProcessDataEnumType.JudgeExamData, JSON.stringify(plcData)) - //检测到有无锡所设备接入,需要发送特定的数据,供检测 - // if (this.usbService.isWXUSBDevice) { - // const str = await senorToWXDataStr(msg); - // this.usbService.sendUSB(str) - // } - const param350: number = Reflect.get(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') || 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++) - } //是否手动结束考试 private isManual: boolean = false //UDP服务序列号 @@ -256,60 +214,6 @@ export default class Judge { dConsole.info(JudgeTag, '过程数据文件上传 end') } private judgeTask: JudgeTask - // 检测扣分、结束项目时该项目是否开始 - checkProjectIsStart = async (xmdm: number, currentType: 1 | 2, kf?: MarkRule) => { - if (xmdm == 20) { - return true - } - const judgeUI = this.judgeUI; - const judgeTask = this.judgeTask; - const projectsObj: object = this.judgeUI.projectsObj - const currentProject: ProjectInfo = Reflect.get(projectsObj, xmdm) - const isUpload = currentProject.isUpload - - //如果项目没有开始 - dConsole.info(JudgeTag, 'surenjun isUpload=>', isUpload) - if (!isUpload) { - dConsole.info(JudgeTag, '项目补传开始') - //项目开始补传 - judgeTask.addTask(async () => { - await this.beginProject(xmdm) - }, { - isDelay: true - }) - judgeTask.addTask(async () => { - await this.uploadProgressPhoto(xmdm) - }, { - isDelay: true - }) - currentProject.isUpload = true; - Reflect.set(this.judgeUI.projectsObj, xmdm, currentProject) - //扣分补传 - if (currentType == 2) { - judgeTask.addTask(async () => { - await this.pointsDedute(xmdm, kf!) - }, { - isDelay: true - }) - } - //扣分补传判断是否合格 不合格补传项目结束 - if (currentType == 1 || (currentType == 2 && this.totalScore < judgeUI.passingScore)) { - judgeTask.addTask(async () => { - await this.endProject(xmdm) - }, { - isDelay: true - }) - currentProject.isEnd = true; - Reflect.set(this.judgeUI.projectsObj, xmdm, currentProject) - } - judgeTask.addTask(async () => { - this.checkExamIsEnd() - }) - return false; - } else { - return true - } - } private tempData?: PLCType //实时计算gps经纬度距离 handDistance = async () => { @@ -360,40 +264,47 @@ export default class Judge { AppStorage.setOrCreate('msgStr', plc) return tempData } - // 处理轨迹plc信号 - handleTrajectoryUdp = async (strArr: string[]) => { - let num = 2; - const judgeTimer = setInterval(async () => { - const msgStr = strArr[num]; - if (msgStr == '') { - dConsole.info(JudgeTag, '模拟数据考试结束') - clearInterval(judgeTimer) - this.checkExamIsEnd(true) - return - } - const msg: PLCType = 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', '') - if (msg.method === 'examJudgeArtificialItem') { - this.setJudgeItem(msg.itemno, msg.type) - } - if (msg.method === 'examJudgeArtificialMark') { - this.setJudgeItem(msg.itemno, msg.serial) - } - await examJudgeRealExam(msg) - // const bytes = await this.getMessageHeartbeat(); - // bytes && globalThis.judgeUdp.send(bytes) - - }, 200) - // TODO 定时器缺失 - // globalThis.judgeTimer = judgeTimer; + // 处理udp plc信号 + handleUdp = async (msg: string) => { + const stachArr = msg.split(',') + if (stachArr[0] != '#DN_GD' || this.isUdpEnd) { + return + } + const gpsPart = msg.split("#END$GPS,")[1]; + const gpsStatus = gpsPart.split(",")[0]; + if (gpsStatus === "4") { + dConsole.log(JudgeTag, "差分状态正常", gpsStatus) + this.judgeUI.isDwztRight = true + } else { + dConsole.log(JudgeTag, "差分状态异常", gpsStatus) + this.judgeUI.isDwztRight = false + } + this.judgeUI.isDwztRight + const plcData = await this.getPlcData(msg); + // 4.过程数据 + // await this.fileLog?.setExamJudgeData(JSON.stringify(plcData)) + dConsole.writeProcessData(ProcessDataEnumType.JudgeExamData, JSON.stringify(plcData)) + //检测到有无锡所设备接入,需要发送特定的数据,供检测 + // if (this.usbService.isWXUSBDevice) { + // const str = await senorToWXDataStr(msg); + // this.usbService.sendUSB(str) + // } + const param350: number = Reflect.get(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') || 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++) } private isEndTip: boolean = false; //本地轨迹回放地址 @@ -413,6 +324,32 @@ export default class Judge { const code = await writeObjectOut(JSON.parse(examDataStr), "", this.context); } } + private artSubject3ProjectsCodesArr: number[] = [3, 9, 4, 10, 12, 11] + private lane: LANE = { + road: '', num: 0, count: 0 + } + private disConnectNum: number = 0; + //调用监管接口 + sendWriteObjectOut: SendWriteObjectOut = async (data, filePath) => { + const temp = await writeObjectOut(data, filePath, this.context); + dConsole.log(JudgeTag, "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) { + dConsole.info('surenjun', '123') + this.judgeUI.errorMsg = '当前的考试过程信息网络传输异常,程序点击确认将重启!'; + this.judgeUI.disConnectErrorOpen = true + } + + this.disConnectNum = 0 + return temp + } // 项目开始接口同步 beginProject = async (ksxm: number) => { const carInfo = AppStorage.get('carInfo'); @@ -516,32 +453,6 @@ export default class Judge { UploadRegulatoryCodeConversion('17C54', temp.code || 0) dConsole.info(JudgeTag, '上传照片 end') } - private artSubject3ProjectsCodesArr: number[] = [3, 9, 4, 10, 12, 11] - private lane: LANE = { - road: '', num: 0, count: 0 - } - private disConnectNum: number = 0; - //调用监管接口 - sendWriteObjectOut: SendWriteObjectOut = async (data, filePath) => { - const temp = await writeObjectOut(data, filePath, this.context); - dConsole.log(JudgeTag, "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) { - dConsole.info('surenjun', '123') - this.judgeUI.errorMsg = '当前的考试过程信息网络传输异常,程序点击确认将重启!'; - this.judgeUI.disConnectErrorOpen = true - } - - this.disConnectNum = 0 - return temp - } private videoData?: RecordHandleType //当前科目二的考试项目 private deductedPopShowTimer: number = 0; @@ -655,6 +566,95 @@ export default class Judge { } } } + // 检测扣分、结束项目时该项目是否开始 + checkProjectIsStart = async (xmdm: number, currentType: 1 | 2, kf?: MarkRule) => { + if (xmdm == 20) { + return true + } + const judgeUI = this.judgeUI; + const judgeTask = this.judgeTask; + const projectsObj: object = this.judgeUI.projectsObj + const currentProject: ProjectInfo = Reflect.get(projectsObj, xmdm) + const isUpload = currentProject.isUpload + + //如果项目没有开始 + dConsole.info(JudgeTag, 'surenjun isUpload=>', isUpload) + if (!isUpload) { + dConsole.info(JudgeTag, '项目补传开始') + //项目开始补传 + judgeTask.addTask(async () => { + await this.beginProject(xmdm) + }, { + isDelay: true + }) + judgeTask.addTask(async () => { + await this.uploadProgressPhoto(xmdm) + }, { + isDelay: true + }) + currentProject.isUpload = true; + Reflect.set(this.judgeUI.projectsObj, xmdm, currentProject) + //扣分补传 + if (currentType == 2) { + judgeTask.addTask(async () => { + await this.pointsDedute(xmdm, kf!) + }, { + isDelay: true + }) + } + //扣分补传判断是否合格 不合格补传项目结束 + if (currentType == 1 || (currentType == 2 && this.totalScore < judgeUI.passingScore)) { + judgeTask.addTask(async () => { + await this.endProject(xmdm) + }, { + isDelay: true + }) + currentProject.isEnd = true; + Reflect.set(this.judgeUI.projectsObj, xmdm, currentProject) + } + judgeTask.addTask(async () => { + this.checkExamIsEnd() + }) + return false; + } else { + return true + } + } + // 处理轨迹plc信号 + handleTrajectoryUdp = async (strArr: string[]) => { + let num = 2; + const judgeTimer = setInterval(async () => { + const msgStr = strArr[num]; + if (msgStr == '') { + dConsole.info(JudgeTag, '模拟数据考试结束') + clearInterval(judgeTimer) + this.checkExamIsEnd(true) + return + } + const msg: PLCType = 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', '') + if (msg.method === 'examJudgeArtificialItem') { + this.setJudgeItem(msg.itemno, msg.type) + } + if (msg.method === 'examJudgeArtificialMark') { + this.setJudgeItem(msg.itemno, msg.serial) + } + await examJudgeRealExam(msg) + // const bytes = await this.getMessageHeartbeat(); + // bytes && globalThis.judgeUdp.send(bytes) + + }, 200) + // TODO 定时器缺失 + // globalThis.judgeTimer = judgeTimer; + } constructor(judgeUI: JudgeUI) { this.serialIndex = 1; diff --git a/entry/src/main/resources/rawfile/voice/end_tip.mp3 b/entry/src/main/resources/rawfile/voice/end_tip.mp3 new file mode 100644 index 0000000..3e1aac0 Binary files /dev/null and b/entry/src/main/resources/rawfile/voice/end_tip.mp3 differ diff --git a/entry/src/main/resources/rawfile/voice/zhpp.mp3 b/entry/src/main/resources/rawfile/voice/zhpp.mp3 new file mode 100644 index 0000000..f49a6c8 Binary files /dev/null and b/entry/src/main/resources/rawfile/voice/zhpp.mp3 differ