diff --git a/entry/src/main/ets/pages/Index.ets b/entry/src/main/ets/pages/Index.ets index 72c9ef5..ca85dbf 100644 --- a/entry/src/main/ets/pages/Index.ets +++ b/entry/src/main/ets/pages/Index.ets @@ -18,9 +18,9 @@ import BottomMessageComponent from './Index/BottomMessage'; import LoadingComponent from './Index/Loading'; import Prompt from '@system.prompt'; import { DifferentialAndSignal } from '../utils/business/DifferentialAndSignalWorker'; +import { dConsole } from '../utils/LogWorker'; +import dayTs from '../utils/Date'; - -@Entry @Component struct Index { @State url: string = '' @@ -60,6 +60,11 @@ struct Index { } async aboutToAppear() { + dConsole.log(HomeTag, "首页测试 aboutToAppear测试", { + date: dayTs(), + time: new Date().getTime(), + message: "尾巴再添加一个尾巴再添加一个尾巴再添加一个尾巴再添加一个尾巴再添加一个尾巴再添加一个尾巴再添尾巴再添加一个尾巴再添加一个尾巴再添加一个尾巴再添加一个尾巴再添加一个尾巴再添加一个尾巴再添尾巴再添加一个尾巴再添加一个尾巴再添加一个尾巴再添加一个尾巴再添加一个尾巴再添加一个尾巴再添尾巴再添加一个尾巴再添加一个尾巴再添加一个尾巴再添加一个尾巴再添加一个尾巴再添加一个尾巴再添尾巴再添加一个尾巴再添加一个尾巴再添加一个尾巴再添加一个尾巴再添加一个尾巴再添加一个尾巴再添尾巴再添加一个尾巴再添加一个尾巴再添加一个尾巴再添加一个尾巴再添加一个尾巴再添加一个尾巴再添尾巴再添加一个尾巴再添加一个尾巴再添加一个尾巴再添加一个尾巴再添加一个尾巴再添加一个尾巴再添" + }); await UseAuth(this.context) this.ratio = AppStorage.get('baseInfo')?.ratio || 1.4 this.angle = 0 @@ -76,7 +81,7 @@ struct Index { } async onPageShow(): Promise { - console.log("首页 onPageShow") + dConsole.log("首页 onPageShow") await UseAuth(this.context) if (!this.isPlay) { this.avPlayer.playAudio(['welcome.wav']) @@ -180,12 +185,12 @@ struct Index { this.customDialogController.close() } }).catch((err: BusinessError) => { - console.error("初始化表失败", err) + dConsole.error("初始化表失败", err) }) } async initParams() { - console.log("test1111") + dConsole.log("test1111") await GetDeviceInfo(this.context) this.carInfo = await GetCarInfo() this.carInfo = AppStorage.get('carInfo')! @@ -206,7 +211,7 @@ struct Index { this.initWork = true } DifferentialAndSignal.onMsg(() => { - console.log("外层接受") + dConsole.log("外层接受") }) } @@ -222,11 +227,11 @@ struct Index { CardComponent({ isSingle: this.singlePlay, singleClick: () => { - console.log(HomeTag, "单机模式点击") + dConsole.log(HomeTag, "单机模式点击") this.singlePlayerTraining() }, networkingClick: () => { - console.log(HomeTag, "联网考试点击") + dConsole.log(HomeTag, "联网考试点击") this.onlineExam() } }) @@ -237,7 +242,7 @@ struct Index { hasAuth: this.baseInfo.hasAuth, examCarNumber: this.deviceId, versionClick: () => { - console.log(HomeTag, "版本号点击事件") + dConsole.log(HomeTag, "版本号点击事件") this.singlePlay = !this.singlePlay AppStorage.setOrCreate('singlePlay', this.singlePlay) } diff --git a/entry/src/main/ets/pages/judgeSDK/judge.ets b/entry/src/main/ets/pages/judgeSDK/judge.ets index aaee184..1d68ea5 100644 --- a/entry/src/main/ets/pages/judgeSDK/judge.ets +++ b/entry/src/main/ets/pages/judgeSDK/judge.ets @@ -74,6 +74,7 @@ import { PlcStrToWXJson, UploadRegulatoryCodeConversion } from '../Judge/utils'; +import { DifferentialAndSignal } from '../../utils/business/DifferentialAndSignalWorker'; type GetKm3JudgeInitConfig = () => Promise @@ -82,7 +83,6 @@ type SendWriteObjectOut = (data: RegulatoryInterfaceParams, filePath: string) => type GetKfStr = (code: string) => MarkRule type GetDqxmStr = (xmdm: number) => string -type TJudgeBeginObj = JudgeBeginObj export default class Judge { public plcStr: string = "" @@ -181,38 +181,6 @@ export default class Judge { private isExamEnd: boolean // 是否发送udp private isUdpEnd: boolean = false - // 处理udp plc信号 - handleUdp = async (msg: string) => { - console.info(JudgeTag, 'plc信号', msg) - const stachArr = msg.split(',') - if (stachArr[0] != '#DN_GD' || this.isUdpEnd) { - return - } - const plcData = await this.getPlcData(msg); - // 4.过程数据 - await this.fileLog?.setExamJudgeData(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服务序列号 @@ -232,7 +200,6 @@ export default class Judge { const time = GetCurrentTime(); const endTime = GetCurrentTime(1) let examDataBase64: string = '' - //TODO try catch报错待优化 const examDataStr: string = await this.fileUtil.readFile(`${folderPath}/wuxi_progress_data.txt`); try { let tempBuff = buffer.alloc(examDataStr.length, examDataStr) @@ -260,6 +227,60 @@ export default class Judge { console.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 + + //如果项目没有开始 + console.info(JudgeTag, 'surenjun isUpload=>', isUpload) + if (!isUpload) { + console.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 () => { @@ -423,6 +444,38 @@ export default class Judge { AppStorage.setOrCreate('msgStr', plc) return tempData } + // 处理udp plc信号 + handleUdp = async (msg: string) => { + console.info(JudgeTag, 'plc信号', msg) + const stachArr = msg.split(',') + if (stachArr[0] != '#DN_GD' || this.isUdpEnd) { + return + } + const plcData = await this.getPlcData(msg); + // 4.过程数据 + await this.fileLog?.setExamJudgeData(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++) + } // 处理轨迹plc信号 handleTrajectoryUdp = async (strArr: string[]) => { // const { fileLog, setJudgeItem, setJudgeMark, endExam } = this; @@ -461,9 +514,9 @@ export default class Judge { } //本地轨迹回放地址 private trajectoryPath: string + //当前科目二的考试项目 // private currentKm2ItemsObj: any private isTrajectoryOpen: boolean; - //当前科目二的考试项目 // 调代理接口是否断网了 private isJudgeDisConnect: boolean = false; // 断网数据补传 @@ -478,67 +531,6 @@ export default class Judge { const code = await writeObjectOut(JSON.parse(examDataStr), "", this.context); } } - // 考试过程照片 - uploadProgressPhoto = async (ksxm: number) => { - const time = GetCurrentTime(); - const judgeUI = this.judgeUI - const plcData = this.plcData - const photoBase64 = await this.getPhoto(); - const carInfo = AppStorage.get('carInfo'); - - const project: ProjectInfo = Reflect.get(judgeUI.projectsObj, ksxm) - const judgeConfig_305: number = Reflect.get(judgeUI.judgeConfigObj, '305') - const drvexam: DrvexamType = { - lsh: judgeUI.lsh, - kskm: carInfo?.examSubject || "2", - ksxm: project.projectCodeCenter, - sfzmhm: judgeUI.idCard, - kchp: encodeURI(carInfo?.plateNo || ""), - zpsj: time, - zp: photoBase64, - cs: Math.floor((judgeConfig_305 == 0 ? (plcData?.gps?.sd || 0) : (plcData?.sensor?.cs || 0)) * 1.852), - ksdd: encodeURI(judgeUI.ksdd) - } - const data: RegulatoryInterfaceParams = { - xtlb: '17', - jkxlh: judgeUI.serialNumber, - jkid: '17C54', - drvexam - }; - const temp: WR = await this.sendWriteObjectOut(data, this.filePath); - if (temp.code === 2300007) { - this.isJudgeDisConnect = true - } - UploadRegulatoryCodeConversion('17C54', temp.code || 0) - console.info(JudgeTag, '上传照片 end') - } - private artSubject3ProjectsCodesArr: number[] = [3, 9, 4, 10, 12, 11] - private lane: LANE = { - road: '', num: 0, count: 0 - } - private videoData?: RecordHandleType - private disConnectNum: number = 0; - //调用监管接口 - sendWriteObjectOut: SendWriteObjectOut = async (data, filePath) => { - const temp = await writeObjectOut(data, filePath, this.context); - console.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) { - console.info('surenjun', '123') - this.judgeUI.errorMsg = '当前的考试过程信息网络传输异常,程序点击确认将重启!'; - this.judgeUI.disConnectErrorOpen = true - } - - this.disConnectNum = 0 - return temp - } // 项目开始接口同步 beginProject = async (ksxm: number) => { const carInfo = AppStorage.get('carInfo'); @@ -608,59 +600,66 @@ export default class Judge { console.info(JudgeTag, '项目结束 end') UploadRegulatoryCodeConversion('17C55', temp.code || 0) } - // 检测扣分、结束项目时该项目是否开始 - checkProjectIsStart = async (xmdm: number, currentType: 1 | 2, kf?: MarkRule) => { - if (xmdm == 20) { - return true + private artSubject3ProjectsCodesArr: number[] = [3, 9, 4, 10, 12, 11] + private lane: LANE = { + road: '', num: 0, count: 0 + } + private videoData?: RecordHandleType + private disConnectNum: number = 0; + //调用监管接口 + sendWriteObjectOut: SendWriteObjectOut = async (data, filePath) => { + const temp = await writeObjectOut(data, filePath, this.context); + console.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) + } } - 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 - //如果项目没有开始 - console.info(JudgeTag, 'surenjun isUpload=>', isUpload) - if (!isUpload) { - console.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 + if (this.disConnectNum >= 5) { + console.info('surenjun', '123') + this.judgeUI.errorMsg = '当前的考试过程信息网络传输异常,程序点击确认将重启!'; + this.judgeUI.disConnectErrorOpen = true } + + this.disConnectNum = 0 + return temp + } + // 考试过程照片 + uploadProgressPhoto = async (ksxm: number) => { + const time = GetCurrentTime(); + const judgeUI = this.judgeUI + const plcData = this.plcData + const photoBase64 = await this.getPhoto(); + const carInfo = AppStorage.get('carInfo'); + + const project: ProjectInfo = Reflect.get(judgeUI.projectsObj, ksxm) + const judgeConfig_305: number = Reflect.get(judgeUI.judgeConfigObj, '305') + const drvexam: DrvexamType = { + lsh: judgeUI.lsh, + kskm: carInfo?.examSubject || "2", + ksxm: project.projectCodeCenter, + sfzmhm: judgeUI.idCard, + kchp: encodeURI(carInfo?.plateNo || ""), + zpsj: time, + zp: photoBase64, + cs: Math.floor((judgeConfig_305 == 0 ? (plcData?.gps?.sd || 0) : (plcData?.sensor?.cs || 0)) * 1.852), + ksdd: encodeURI(judgeUI.ksdd) + } + const data: RegulatoryInterfaceParams = { + xtlb: '17', + jkxlh: judgeUI.serialNumber, + jkid: '17C54', + drvexam + }; + const temp: WR = await this.sendWriteObjectOut(data, this.filePath); + if (temp.code === 2300007) { + this.isJudgeDisConnect = true + } + UploadRegulatoryCodeConversion('17C54', temp.code || 0) + console.info(JudgeTag, '上传照片 end') } constructor(judgeUI: JudgeUI) { @@ -1948,16 +1947,15 @@ export default class Judge { return } // 处理实时udp里的plc信号 - // globalThis.udpClient.closeMessage_1(); - //TODO UDP修改 - // globalThis.udpClient.onMessage_1(async (msg) => { - // console.info('socketTag[PLC.UdpClient]', '收到udp回调数据') - // handleUdp(msg) - // const udpIndex = globalThis.udpIndex; - // if (udpIndex % 5 === 0) { - // handDistance(); - // } - // }); + DifferentialAndSignal.onMsg((data: string) => { + console.info(JudgeTag, 'socketTag[PLC.UdpClient]', '收到udp回调数据') + handleUdp(data) + //TODO UDP修改 + // const udpIndex = globalThis.udpIndex; + // if (udpIndex % 5 === 0) { + // handDistance(); + // } + }) // this.checkExamIsEnd() diff --git a/entry/src/main/ets/utils/LogWorker.ets b/entry/src/main/ets/utils/LogWorker.ets new file mode 100644 index 0000000..56a2303 --- /dev/null +++ b/entry/src/main/ets/utils/LogWorker.ets @@ -0,0 +1,120 @@ +// 日志向外暴露的方法 +import dayTs from './Date'; +import worker from '@ohos.worker'; +import { EnvironmentConfigurationType, LogWorkerMessage, WorkerMessageType } from '../model/index'; +import Prompt from '@system.prompt'; + +const MAX_MESSAGE_LENGTH = 300; +const LOG_CHUNK_PREFIX = '[切割消息序号'; + +class logWorker { + private workerInstance = new worker.ThreadWorker("entry/ets/workers/Log.ets") + // 是否开启日志 + private isLogEnabled: boolean = true; + + // 正常日志 + log(...args: ESObject[]) { + this.logWithLevel('log', ...args); + } + + // 错误日志 + error(...args: ESObject[]) { + this.logWithLevel('error', ...args); + } + + // 信息日志 + info(...args: ESObject[]) { + this.logWithLevel('info', ...args); + } + + // 调试日志 + warn(msg: string) { + console.warn(msg) + } + + // 初始化板子,需要判断duolun是否存在,不存在则创建 + init() { + const config = AppStorage.get("EnvironmentConfiguration"); + if (!config) { + Prompt.showToast({ + message: "请先配置环境变量" + }) + return; + } + this.isLogEnabled = config.isOpenLog === "1" ? true : false; + if (this.isLogEnabled) { + this.workerInstance = new worker.ThreadWorker("entry/ets/workers/Log.ets"); + let data: LogWorkerMessage = { + type: WorkerMessageType.Init + } + this.workerInstance.postMessage(JSON.stringify(data)) + } + } + + // 过程数据初始化 + processDataInit(carNo: string, name: string) { + let date = dayTs().format("YYYY_MM_DD_HH_mm_ss"); + // 组装文件夹名 2025_06_18_09_14_36_2506474075216_371427200311275216_王宏伟 + let folderName = `${date}_${carNo}_${name}`; + // 内部包含文件 + } + + // 通用日志方法 + private logWithLevel(level: 'log' | 'info' | 'error', ...args: ESObject[]): void { + if (this.isLogEnabled) { + const message = this.formatMessage(...args); + if (message.length > MAX_MESSAGE_LENGTH) { + this.logLongMessage(level, message); + } else { + this.logConsole(level, message); + } + } + } + + // 日志输出到控制台 + private logConsole(level: 'log' | 'info' | 'error', msg: string) { + switch (level) { + case 'log': + console.log(msg); + break; + case 'info': + console.info(msg); + break; + case 'error': + console.error(msg); + break; + } + } + + // 处理长消息分割和记录 + private logLongMessage(level: 'log' | 'info' | 'error', message: string): void { + const chunks = this.splitLongMessage(message); + chunks.forEach((chunk, index) => { + this.logConsole(level, `${LOG_CHUNK_PREFIX} ${index + 1}/${chunks.length}] ${chunk}`); + }); + } + + // 切割长消息 + private splitLongMessage(message: string, maxLength: number = 300): string[] { + const chunks: string[] = []; + for (let i = 0; i < message.length; i += maxLength) { + chunks.push(message.substring(i, i + maxLength)); + } + return chunks; + } + + private formatMessage(...args: ESObject[]): string { + return args.map((arg: ESObject) => { + if (typeof arg === 'object') { + try { + return JSON.stringify(arg) + } catch { + return String(arg) + } + } + return String(arg) + }).join(' ') + } +} + +export const dConsole = new logWorker(); \ No newline at end of file diff --git a/entry/src/main/ets/utils/business/LogWorker.ets b/entry/src/main/ets/utils/business/LogWorker.ets deleted file mode 100644 index 53a31bf..0000000 --- a/entry/src/main/ets/utils/business/LogWorker.ets +++ /dev/null @@ -1,46 +0,0 @@ -import dayTs from '../Date' -import worker from '@ohos.worker' -import { LogWorkerMessage, WorkerMessageType } from '../../model' - -class logWorker { - private workerInstance = new worker.ThreadWorker("entry/ets/workers/Log.ets") - - // 正常日志 - log(msg: string) { - console.log(msg) - } - - // 信息日志 - info(msg: string) { - console.info(msg) - } - - // 调试日志 - warn(msg: string) { - console.warn(msg) - } - - // 错误日志 - error(msg: string) { - console.error(msg) - } - - // 初始化板子,需要判断duolun是否存在,不存在则创建 - init() { - this.workerInstance = new worker.ThreadWorker("entry/ets/workers/Log.ets"); - let data: LogWorkerMessage = { - type: WorkerMessageType.Init - } - this.workerInstance.postMessage(JSON.stringify(data)) - } - - // 过程数据初始化 - processDataInit(carNo: string, name: string) { - let date = dayTs().format("YYYY_MM_DD_HH_mm_ss"); - // 组装文件夹名 2025_06_18_09_14_36_2506474075216_371427200311275216_王宏伟 - let folderName = `${date}_${carNo}_${name}`; - // 内部包含文件 - } -} - -export const dConsole = new logWorker(); \ No newline at end of file