Compare commits

...

9 Commits

Author SHA1 Message Date
wangzhongjie
baa6b80556 fix: 过程数据写入文件,压测0.1秒同时写入8个文件,写1000次,cpu最大波动5% 2025-07-16 16:44:00 +08:00
wangzhongjie
f0653c0c92 fix: 过程数据完善 2025-07-16 15:44:49 +08:00
wangzhongjie
797b785721 fix: 提交 2025-07-16 13:27:12 +08:00
wangzhongjie
9d95f11282 version: 0.0.8 2025-07-16 13:27:04 +08:00
wangzhongjie
52a8cec532 version: 0.0.8 2025-07-16 13:26:47 +08:00
wangzhongjie
71abff6dda version: 0.0.8 2025-07-16 13:26:36 +08:00
wangzhongjie
bc5a15b59a fix:过程数据方法补全部分 2025-07-16 11:29:01 +08:00
wangzhongjie
5bf2990a2c fix:过程数据方法补全部分 2025-07-16 11:28:44 +08:00
wangzhongjie
4832904345 fix:过程数据方法补全部分 2025-07-16 11:28:34 +08:00
14 changed files with 518 additions and 289 deletions

View File

@ -1,2 +1,2 @@
gitLog:
git log --since="2025-06-30 17:14" --until="2025-07-2 17:35" --pretty=format:"<details>%n <summary>%s</summary>%n <span style=\"color: #888;\">[提交人]:</span><span style=\"color: #333;\">%an</span><br>%n <span style=\"color: #888;\">[提交时间]:</span><span style=\"color: #333;\">%ad</span><br>%n <span style=\"color: #888;\">[提交版本]:</span><span style=\"color: #333;\">%h</span>%n</details>%n" --date=format:"%Y-%m-%d %H:%M" > release_note.md
git log --since="2025-06-30 17:14" --until="2025-07-16 10:00" --pretty=format:"<details>%n <summary>%s</summary>%n <span style=\"color: #888;\">[提交人]:</span><span style=\"color: #333;\">%an</span><br>%n <span style=\"color: #888;\">[提交时间]:</span><span style=\"color: #333;\">%ad</span><br>%n <span style=\"color: #888;\">[提交版本]:</span><span style=\"color: #333;\">%h</span>%n</details>%n" --date=format:"%Y-%m-%d %H:%M" > release_note.md

View File

@ -0,0 +1 @@
export const ProcessDataMock:string="#DN_GD,$PLC,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-0_0,0,0,0,0,0,0,0,0,511,0,0,0,0,0,0,0,0,0,0,0,0,15802,0,1,0_0_0_0,0.0.0.0,V9.1_V2.1_1,65535,0,0,0/0,15802/292,0,0/0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F,G,H,I,J,K,#END$GPS,1,16,6.068,1.301,0.000,1.07,0.64,+0.0000,+0.0000,0,091022,080109.20,3155.6715075,11851.9196718,0.012,#END"

View File

@ -6,4 +6,5 @@ export * from "./Judge"
export * from "./SignDisplay"
export * from "./CarCheck"
export * from "./CarCheck"
export * from "./Test"

View File

@ -31,7 +31,8 @@ export enum WorkerBackMessageType {
export interface LogWorkerMessage {
type: WorkerMessageType;
data?: string;
studentDirName?: string
studentDirName?: string;
processDataType?: ProcessDataEnumType
}
//枚举
@ -44,10 +45,37 @@ export enum WorkerMessageType {
Init = 'init',
// 初始化过程数据,初始化到人员以及人员里面各个目录
ProcessDataInit = 'processDataInit',
// 打开过程数据文件
OpenProcessDataFile = 'openProcessDataFile',
// 初始化考试过程
ExamProcessInit = 'examProcessInit'
ExamProcessInit = 'examProcessInit',
// 写过程数据
WriteProcessData = 'writeProcessData',
// 关闭过程数据
CloseProcessData = 'closeProcessData'
}
// 过程数据枚举
export enum ProcessDataEnumType {
//four_one_log_byte_data
FourOneLogByteData = "0",
//four_one_log_data
FourOneLogData = "1",
//judge_exam_data
JudgeExamData = "2",
//judge_log_data
JudgeLogData = "3",
// judge_progress_callback_data
JudgeProgressCallbackData = "4",
//plc_data
PlcData = "5",
//wuxi_exam_data
WuxiExam = "6",
//wuxi_progress_data
WuxiProgressData = "7"
}
export interface FileQueueType {
type: ProcessDataEnumType,
data: string
}
export interface LogPathType {

View File

@ -19,6 +19,7 @@ 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
@ -77,6 +78,7 @@ struct Index {
async onPageShow(): Promise<void> {
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

View File

@ -37,14 +37,15 @@ import {
SYSSET,
SyssetConfig,
SYSTEMPARMARR,
User
User,
ProcessDataEnumType
} from '../model';
import { GetSyncData } from '../utils/table/Operation';
import dayTs from '../utils/Date';
import { GetCurrentTime } from '../utils/Common';
import FileUtils from '../utils/FileUtils';
import SignalTrajectoryDialog from './Judge/SignalTrajectoryDialog';
import { DefaultJudgeConfigData } from '../mock';
import { DefaultJudgeConfigData, ProcessDataMock } from '../mock';
import { dConsole } from '../utils/LogWorker';
import ConfirmDialog from './compontents/ConfirmDialog';
import CarLoadingDialog from './compontents/CarLoading';
@ -205,7 +206,28 @@ struct JudgePage {
this.startFullTime = GetCurrentTime(1);
this.startTime = dayTs().format("YYYY-MM-DD HH:mm:ss")
this.startExamTime = dayTs().format("YYYY-MM-DD HH:mm:ss")
// let count = 0;
// const totalTimes = 1000;
// const intervalTime = 100; // 0.1秒 = 100毫秒
//
// const timer = setInterval(() => {
// if (count < totalTimes) {
// dConsole.writeProcessData(ProcessDataEnumType.FourOneLogByteData, ProcessDataMock);
// dConsole.writeProcessData(ProcessDataEnumType.FourOneLogData, ProcessDataMock);
// dConsole.writeProcessData(ProcessDataEnumType.JudgeExamData, ProcessDataMock);
// dConsole.writeProcessData(ProcessDataEnumType.JudgeLogData, ProcessDataMock);
// dConsole.writeProcessData(ProcessDataEnumType.JudgeProgressCallbackData, ProcessDataMock);
// dConsole.writeProcessData(ProcessDataEnumType.PlcData, ProcessDataMock);
// dConsole.writeProcessData(ProcessDataEnumType.WuxiExam, ProcessDataMock);
// dConsole.writeProcessData(ProcessDataEnumType.WuxiProgressData, ProcessDataMock);
// count++;
// console.log(`已调用 ${count} 次`);
// } else {
// dConsole.closeProcessData()
// clearInterval(timer);
// console.log('已完成1000次调用');
// }
// }, intervalTime);
//初始化数据库表
await this.initDb()
//断点续考
@ -717,6 +739,7 @@ struct JudgePage {
singlePlay: this.singlePlay,
judgeConfigObj: this.judgeConfigObj,
signalViewingClick: () => {
dConsole.writeProcessData(ProcessDataEnumType.FourOneLogByteData, '测试测试')
this.signalTrajectoryDialogController.open()
},
artificialEvaluationClick: () => {

View File

@ -35,7 +35,7 @@ import {
} from '../model';
import { BusinessError } from '@ohos.base';
import { GetSyncData, SqlInsertTable } from '../utils/table/Operation';
import { GetCurrentUserKeyValue } from './UserInfo/utils';
import { GetCurrentUserKeyValue, InitializeExamProcessData } from './UserInfo/utils';
import dayTs from '../utils/Date';
import { GetCurrentTime, NumberToByteArray } from '../utils/Common';
import DB from '../utils/DbSql';
@ -174,10 +174,12 @@ struct UserInfoPage {
}
if (this.singlePlay) {
this.currentUser.id = '0'
dConsole.log('开始考试')
dConsole.log('开始考试3')
SqlInsertTable('USER', [this.currentUser]).catch((e: BusinessError) => {
dConsole.log("error", JSON.stringify(e))
})
// 初始化开始考试过程数据文件夹
InitializeExamProcessData(this.currentUser)
router.pushUrl({
url: this.carInfo.examSubject == '3' ? 'pages/Roads' : 'pages/Judge',
params: {
@ -342,8 +344,11 @@ struct UserInfoPage {
AppStorage.setOrCreate('examinerInfo', this.examinerLoginInfo)
AppStorage.setOrCreate('lsh', res.lsh)
// const { examSubject } = this.carInfo;
dConsole.log("开始考试2")
if (this.singlePlay) {
this.stopDeviceById()
// 初始化开始考试过程数据文件夹
InitializeExamProcessData(this.currentUser)
router.pushUrl({
url: this.carInfo.examSubject == "3" ? 'pages/Roads' : 'pages/Judge',
params: {
@ -874,6 +879,8 @@ struct UserInfoPage {
await SqlInsertTable('USER', [this.currentUser])
this.stepFlag = false
this.startExamDialogController.close()
// 初始化开始考试过程数据文件夹
InitializeExamProcessData(this.currentUser)
router.pushUrl({
url: 'pages/Judge',
params: {

View File

@ -1,4 +1,7 @@
import { UserInfoTag } from '../../config';
import { User } from '../../model';
import dayTs from '../../utils/Date';
import { dConsole } from '../../utils/LogWorker';
export const GetCurrentUserKeyValue = (user: User, key: string): string => {
switch (key) {
@ -51,4 +54,14 @@ export const GetCurrentUserKeyValue = (user: User, key: string): string => {
default:
return '';
}
}
export const InitializeExamProcessData = (user: User) => {
// 初始化考试过程数据
// 2025_07_04_11_35_26_0000000000000_342323199501470011_测试学员1
let date = dayTs().format("YYYY_MM_DD_HH_mm_ss")
const examDir: string = date + "_" + user.lsh + "_" + user.sfzmhm + "_" + user.xm
dConsole.log(UserInfoTag, "过程数据文件夹名", examDir)
dConsole.initExam(examDir)
dConsole.log("开始考试1")
}

View File

@ -44,6 +44,7 @@ import {
LANE,
MarkRule,
PLCType,
ProcessDataEnumType,
ProjectInfo,
RecordHandleType,
RegulatoryInterfaceParams,
@ -230,6 +231,54 @@ export default class Judge {
dConsole.info(JudgeTag, '过程数据文件上传 end')
}
private judgeTask: JudgeTask
private tempData?: PLCType
//实时计算gps经纬度距离
handDistance = async () => {
const dwzt = this.tempData?.gps?.dwzt || "";
const jdzt = this.tempData?.gps?.jdzt || "";
const tJD = ConvertDdmmToDecimalDegrees(this.tempData?.gps?.jd || 0)
const tWD = ConvertDdmmToDecimalDegrees(this.tempData?.gps?.wd || 0)
if (this.prevJd && dwzt == 4 && jdzt == 3) {
const distance = await examCalcGpsDistance({
jd1: this.prevJd,
wd1: this.prevWd,
jd2: tJD,
wd2: tWD,
h: this.tempData?.gps?.hxj || 1,
})
// const distanceClass = AppStorage.get<DistanceClass>('distanceClass')
// distanceClass?.setTimeData(Number(((distance / 100).toFixed(2))))
DrivingDataStorage.setDrivingProcessData(Number(((distance / 100).toFixed(2))))
}
this.prevJd = tJD;
this.prevWd = tWD;
}
private performInfo?: JudgePerformInfo
private ksjs?: JudgeKSJS
private kfArr?: MarkRule[]
//所有的科目考试项目(大车&小车)
private kmItems: JudgeConfigObjKmItems
private plcData?: PLCType
// 获取plc数据
getPlcData = async (plc: string) => {
await this.fileLog?.setPlcProgressData(plc)
//plc字符串转化成评判初始化数据
const tempData = await PlcStrToJson(plc);
//模拟灯光回放时刻
tempData.sensor.rmndg = this.rmndg;
//模拟灯灯光灯光项目
tempData.sensor.mndg = this.mndgStr || "";
//plc字符串转化成无锡所过程数据
const wuXiDataStr = await PlcStrToWXJson(plc)
this.plcData = tempData
await this.fileLog?.setExamJudgeWuxiProgressData(wuXiDataStr)
this.tempData = tempData
this.plcStr = plc;
this.mndgStr = '';
this.rmndg = 0;
AppStorage.setOrCreate('msgStr', plc)
return tempData
}
// 处理udp plc信号
handleUdp = async (msg: string) => {
const stachArr = msg.split(',')
@ -261,83 +310,157 @@ export default class Judge {
// }
// AppStorage.setOrCreate('udpIndex', udpIndex++)
}
// 检测扣分、结束项目时该项目是否开始
checkProjectIsStart = async (xmdm: number, currentType: 1 | 2, kf?: MarkRule) => {
if (xmdm == 20) {
return true
private isEndTip: boolean = false;
//本地轨迹回放地址
private trajectoryPath: string
// private currentKm2ItemsObj: any
private isTrajectoryOpen: boolean;
// 调代理接口是否断网了
private isJudgeDisConnect: boolean = false;
// 断网数据补传
uploadDisConnectData = async () => {
if (!this.isJudgeDisConnect) {
return
}
const folderPath = this.fileLog?.folderPath
const examDataStr = await this.fileUtil.readFile(`${folderPath}/wuxi_dis_progress_data.txt`);
const examDataArr = examDataStr.split('\n');
for (let examDataStr of examDataArr) {
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)
}
}
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
if (this.disConnectNum >= 5) {
dConsole.info('surenjun', '123')
this.judgeUI.errorMsg = '当前的考试过程信息网络传输异常,程序点击确认将重启!';
this.judgeUI.disConnectErrorOpen = true
}
this.disConnectNum = 0
return temp
}
private tempData?: PLCType
//实时计算gps经纬度距离
handDistance = async () => {
const dwzt = this.tempData?.gps?.dwzt || "";
const jdzt = this.tempData?.gps?.jdzt || "";
const tJD = ConvertDdmmToDecimalDegrees(this.tempData?.gps?.jd || 0)
const tWD = ConvertDdmmToDecimalDegrees(this.tempData?.gps?.wd || 0)
if (this.prevJd && dwzt == 4 && jdzt == 3) {
const distance = await examCalcGpsDistance({
jd1: this.prevJd,
wd1: this.prevWd,
jd2: tJD,
wd2: tWD,
h: this.tempData?.gps?.hxj || 1,
})
// const distanceClass = AppStorage.get<DistanceClass>('distanceClass')
// distanceClass?.setTimeData(Number(((distance / 100).toFixed(2))))
DrivingDataStorage.setDrivingProcessData(Number(((distance / 100).toFixed(2))))
// 项目开始接口同步
beginProject = async (ksxm: number) => {
const carInfo = AppStorage.get<CarInfoType>('carInfo');
const judgeUI = this.judgeUI
const time = GetCurrentTime();
const project: ProjectInfo = Reflect.get(judgeUI.projectsObj, ksxm)
const sbxh = this.getSbbm(ksxm, this.xmxh)
const drvexam: DrvexamType = {
lsh: judgeUI.lsh,
kskm: carInfo?.examSubject || "2",
sfzmhm: judgeUI.idCard,
ksxm: project.projectCodeCenter,
sbxh,
ksxl: judgeUI.xldm,
kchp: encodeURI(carInfo?.plateNo || ""),
ksdd: encodeURI(judgeUI.ksdd),
kslx: encodeURI(judgeUI.kslx) || '',
kssj: time
}
this.prevJd = tJD;
this.prevWd = tWD;
const data: RegulatoryInterfaceParams = {
//系统类别 接口序列号 接口标识
xtlb: '17',
jkxlh: judgeUI.serialNumber,
jkid: '17C52',
drvexam
}
const temp: WR = await this.sendWriteObjectOut(data, this.filePath)
dConsole.info(JudgeTag, '项目开始 end')
if (temp.code === 2300007) {
this.isJudgeDisConnect = true;
}
UploadRegulatoryCodeConversion('17C52', temp.code || 0)
}
private performInfo?: JudgePerformInfo
// 项目结束接口同步
endProject = async (ksxm: number) => {
const carInfo = AppStorage.get<CarInfoType>('carInfo');
const judgeUI = this.judgeUI;
const time = GetCurrentTime();
const project: ProjectInfo = Reflect.get(judgeUI.projectsObj, ksxm)
const sbxh = judgeUI.examSubject == '3' ? undefined : this.getSbbm(ksxm, this.xmxh)
const drvexam: DrvexamType = {
lsh: judgeUI.lsh,
kskm: carInfo?.examSubject || "2",
sfzmhm: judgeUI.idCard,
ksxm: project.projectCodeCenter,
sbxh,
//TODO 操作类型 1:正常 0:撤销该考试记录
czlx: '1',
ksxl: judgeUI.xldm,
kchp: encodeURI(carInfo?.plateNo || ""),
ksdd: encodeURI(judgeUI.ksdd),
kslx: encodeURI(judgeUI.kslx) || '',
jssj: time
}
const data: RegulatoryInterfaceParams = {
xtlb: '17',
jkxlh: judgeUI.serialNumber,
jkid: '17C55',
drvexam
}
const temp: WR = await this.sendWriteObjectOut(data, this.filePath)
if (temp.code === 2300007) {
this.isJudgeDisConnect = true;
}
dConsole.info(JudgeTag, '项目结束 end')
UploadRegulatoryCodeConversion('17C55', temp.code || 0)
}
// 考试过程照片
uploadProgressPhoto = async (ksxm: number) => {
const time = GetCurrentTime();
const judgeUI = this.judgeUI
const plcData = this.plcData
const photoBase64 = await this.getPhoto();
const carInfo = AppStorage.get<CarInfoType>('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)
dConsole.info(JudgeTag, '上传照片 end')
}
private videoData?: RecordHandleType
//当前科目二的考试项目
private deductedPopShowTimer: number = 0;
// 校验考试是否结束
checkExamIsEnd = async (isManual?: boolean) => {
dConsole.log(JudgeTag, "校验考试是否结束")
@ -453,32 +576,6 @@ export default class Judge {
}
}
}
private ksjs?: JudgeKSJS
private kfArr?: MarkRule[]
//所有的科目考试项目(大车&小车)
private kmItems: JudgeConfigObjKmItems
private plcData?: PLCType
// 获取plc数据
getPlcData = async (plc: string) => {
await this.fileLog?.setPlcProgressData(plc)
//plc字符串转化成评判初始化数据
const tempData = await PlcStrToJson(plc);
//模拟灯光回放时刻
tempData.sensor.rmndg = this.rmndg;
//模拟灯灯光灯光项目
tempData.sensor.mndg = this.mndgStr || "";
//plc字符串转化成无锡所过程数据
const wuXiDataStr = await PlcStrToWXJson(plc)
this.plcData = tempData
await this.fileLog?.setExamJudgeWuxiProgressData(wuXiDataStr)
this.tempData = tempData
this.plcStr = plc;
this.mndgStr = '';
this.rmndg = 0;
AppStorage.setOrCreate('msgStr', plc)
return tempData
}
private isEndTip: boolean = false;
// 处理轨迹plc信号
handleTrajectoryUdp = async (strArr: string[]) => {
let num = 2;
@ -514,155 +611,59 @@ export default class Judge {
// TODO 定时器缺失
// globalThis.judgeTimer = judgeTimer;
}
//本地轨迹回放地址
private trajectoryPath: string
// private currentKm2ItemsObj: any
private isTrajectoryOpen: boolean;
//当前科目二的考试项目
// 调代理接口是否断网了
private isJudgeDisConnect: boolean = false;
// 断网数据补传
uploadDisConnectData = async () => {
if (!this.isJudgeDisConnect) {
return
// 检测扣分、结束项目时该项目是否开始
checkProjectIsStart = async (xmdm: number, currentType: 1 | 2, kf?: MarkRule) => {
if (xmdm == 20) {
return true
}
const folderPath = this.fileLog?.folderPath
const examDataStr = await this.fileUtil.readFile(`${folderPath}/wuxi_dis_progress_data.txt`);
const examDataArr = examDataStr.split('\n');
for (let examDataStr of examDataArr) {
const code = await writeObjectOut(JSON.parse(examDataStr), "", this.context);
}
}
// 项目开始接口同步
beginProject = async (ksxm: number) => {
const carInfo = AppStorage.get<CarInfoType>('carInfo');
const judgeUI = this.judgeUI
const time = GetCurrentTime();
const project: ProjectInfo = Reflect.get(judgeUI.projectsObj, ksxm)
const sbxh = this.getSbbm(ksxm, this.xmxh)
const drvexam: DrvexamType = {
lsh: judgeUI.lsh,
kskm: carInfo?.examSubject || "2",
sfzmhm: judgeUI.idCard,
ksxm: project.projectCodeCenter,
sbxh,
ksxl: judgeUI.xldm,
kchp: encodeURI(carInfo?.plateNo || ""),
ksdd: encodeURI(judgeUI.ksdd),
kslx: encodeURI(judgeUI.kslx) || '',
kssj: time
}
const data: RegulatoryInterfaceParams = {
//系统类别 接口序列号 接口标识
xtlb: '17',
jkxlh: judgeUI.serialNumber,
jkid: '17C52',
drvexam
}
const temp: WR = await this.sendWriteObjectOut(data, this.filePath)
dConsole.info(JudgeTag, '项目开始 end')
if (temp.code === 2300007) {
this.isJudgeDisConnect = true;
}
UploadRegulatoryCodeConversion('17C52', temp.code || 0)
}
// 项目结束接口同步
endProject = async (ksxm: number) => {
const carInfo = AppStorage.get<CarInfoType>('carInfo');
const judgeUI = this.judgeUI;
const time = GetCurrentTime();
const project: ProjectInfo = Reflect.get(judgeUI.projectsObj, ksxm)
const sbxh = judgeUI.examSubject == '3' ? undefined : this.getSbbm(ksxm, this.xmxh)
const judgeTask = this.judgeTask;
const projectsObj: object = this.judgeUI.projectsObj
const currentProject: ProjectInfo = Reflect.get(projectsObj, xmdm)
const isUpload = currentProject.isUpload
const drvexam: DrvexamType = {
lsh: judgeUI.lsh,
kskm: carInfo?.examSubject || "2",
sfzmhm: judgeUI.idCard,
ksxm: project.projectCodeCenter,
sbxh,
//TODO 操作类型 1:正常 0:撤销该考试记录
czlx: '1',
ksxl: judgeUI.xldm,
kchp: encodeURI(carInfo?.plateNo || ""),
ksdd: encodeURI(judgeUI.ksdd),
kslx: encodeURI(judgeUI.kslx) || '',
jssj: time
}
const data: RegulatoryInterfaceParams = {
xtlb: '17',
jkxlh: judgeUI.serialNumber,
jkid: '17C55',
drvexam
}
const temp: WR = await this.sendWriteObjectOut(data, this.filePath)
if (temp.code === 2300007) {
this.isJudgeDisConnect = true;
}
dConsole.info(JudgeTag, '项目结束 end')
UploadRegulatoryCodeConversion('17C55', temp.code || 0)
}
// 考试过程照片
uploadProgressPhoto = async (ksxm: number) => {
const time = GetCurrentTime();
const judgeUI = this.judgeUI
const plcData = this.plcData
const photoBase64 = await this.getPhoto();
const carInfo = AppStorage.get<CarInfoType>('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)
dConsole.info(JudgeTag, '上传照片 end')
}
private deductedPopShowTimer: number = 0;
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);
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)
//如果项目没有开始
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
}
if (this.disConnectNum >= 5) {
dConsole.info('surenjun', '123')
this.judgeUI.errorMsg = '当前的考试过程信息网络传输异常,程序点击确认将重启!';
this.judgeUI.disConnectErrorOpen = true
}
this.disConnectNum = 0
return temp
}
constructor(judgeUI: JudgeUI) {
@ -1967,6 +1968,7 @@ export default class Judge {
const result: WorkerBackMessage = JSON.parse(data)
if (result.type === WorkerBackMessageType.ObtainUdpData) {
handleUdp(result.data as string)
dConsole.writeProcessData(ProcessDataEnumType.PlcData, result.data as string)
}
//TODO UDP修改
// const udpIndex = globalThis.udpIndex;

View File

@ -34,28 +34,28 @@ export default class FileLog {
}
// 无锡所过程数据
public setExamJudgeWuxiProgressData = async (str: string) => {
this.examJudgeWuxiProgressDataFd =
await this.fileUtil.editFile(`${this.folderPath}/wuxi_progress_data.txt`, str);
// this.examJudgeWuxiProgressDataFd =
// await this.fileUtil.editFile(`${this.folderPath}/wuxi_progress_data.txt`, str);
}
// plc文件数据
public setPlcProgressData = async (str: Object) => {
this.plcDataFd =
await this.fileUtil.editFile(`${this.folderPath}/plc_data.txt`, JSON.stringify(str));
// this.plcDataFd =
// await this.fileUtil.editFile(`${this.folderPath}/plc_data.txt`, JSON.stringify(str));
}
// 过程评判json数据
public setExamJudgeData = async (str: string) => {
this.examJudgeDataFd =
await this.fileUtil.editFile(`${this.folderPath}/judge_exam_data.txt`, str);
// this.examJudgeDataFd =
// await this.fileUtil.editFile(`${this.folderPath}/judge_exam_data.txt`, str);
}
// 过程评判回调数据
public setExamJudgeCallbackData = async (str: string) => {
this.examJudgeCallbackDataFd =
await this.fileUtil.editFile(`${this.folderPath}/judge_progress_callback_data.txt`, str);
// this.examJudgeCallbackDataFd =
// await this.fileUtil.editFile(`${this.folderPath}/judge_progress_callback_data.txt`, str);
}
// 过程评判日志调数据
public setExamJudgeLogData = async (str: string) => {
this.examJudgeLogDataFd =
await this.fileUtil.editFile(`${this.folderPath}/judge_log_data.txt`, str);
// this.examJudgeLogDataFd =
// await this.fileUtil.editFile(`${this.folderPath}/judge_log_data.txt`, str);
}
// 设置四合一画面数据
public setFourAndOneLogData = async (str: string) => {
@ -103,13 +103,13 @@ export default class FileLog {
// 设置文件夹
public initFileLogo = async (stuInfo: StuInfo) => {
// this.stuInfo = stuInfo;
const time = GetCurrentTime()
const date = time.split(' ')[0].split('-').join('_')
const hourTime = time.split(' ')[1].split(':').join('_')
const folderPath =
await this.fileUtil.initFolder(`/logs/${date}/${date}_${hourTime}_${stuInfo.lsh}_${stuInfo.idCard}_${stuInfo.name}`);
this.folderPath = folderPath;
return folderPath
// const time = GetCurrentTime()
// const date = time.split(' ')[0].split('-').join('_')
// const hourTime = time.split(' ')[1].split(':').join('_')
// const folderPath =
// await this.fileUtil.initFolder(`/logs/${date}/${date}_${hourTime}_${stuInfo.lsh}_${stuInfo.idCard}_${stuInfo.name}`);
// this.folderPath = folderPath;
return "folderPath"
}
constructor(context: common.UIAbilityContext) {

View File

@ -217,14 +217,35 @@ export function CreateDir(path: string): Promise<boolean> {
});
}
/**
* 写文件
*/
export function EditFile(fd: number, data: string): Promise<boolean> {
return new Promise((resolve, reject) => {
try {
fs.writeSync(fd, data + "\n")
resolve(true)
} catch (e) {
reject(false)
}
})
}
/**
* 创建文件
* @params path 文件具体路径
* @return 返回一个Promise
*/
export function CreateFile(path: string): Promise<boolean> {
export function CreateFile(path: string): Promise<number> {
return new Promise((resolve, reject) => {
try {
let file = fs.openSync(path, fs.OpenMode.READ_WRITE | fs.OpenMode.APPEND | fs.OpenMode.CREATE)
console.log(CommonFileTag, "创建文件成功", path)
resolve(file.fd)
} catch (e) {
console.log(CommonFileTag, "创建文件失败")
reject(-1)
}
})
}

View File

@ -1,7 +1,7 @@
// 日志向外暴露的方法
import dayTs from './Date';
import worker from '@ohos.worker';
import { LogWorkerMessage, WorkerMessageType } from '../model/index';
import { LogWorkerMessage, ProcessDataEnumType, WorkerMessageType } from '../model/index';
const MAX_MESSAGE_LENGTH = 300;
const LOG_CHUNK_PREFIX = '[切割消息序号';
@ -44,7 +44,7 @@ class logWorker {
console.log(`当前环境配置初始化: ${isOpenLog}`);
this.isLogEnabled = isOpenLog;
if (this.isLogEnabled === "1") {
this.workerInstance = new worker.ThreadWorker("entry/ets/workers/Log.ets");
this.workerInstance = new worker.ThreadWorker("entry/ets/workers/Log.ets")
let data: LogWorkerMessage = {
type: WorkerMessageType.Init
}
@ -52,12 +52,36 @@ class logWorker {
}
}
// 过程数据初始化
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}`;
// 内部包含文件
// 初始化考试过程数据文件夹以及文件
initExam(dirName: string) {
let data: LogWorkerMessage = {
type: WorkerMessageType.ExamProcessInit,
studentDirName: dirName
}
if (this.isLogEnabled === "1") {
this.workerInstance?.postMessage(JSON.stringify(data))
}
}
// 过程数据写入
writeProcessData(type: ProcessDataEnumType, data: string) {
let params: LogWorkerMessage = {
type: WorkerMessageType.WriteProcessData,
data,
processDataType: type
}
if (this.isLogEnabled === "1") {
this.workerInstance?.postMessage(JSON.stringify(params))
}
}
// 关闭过程数据写入
closeProcessData(){
let params: LogWorkerMessage = {
type: WorkerMessageType.CloseProcessData,
}
if (this.isLogEnabled === "1") {
this.workerInstance?.postMessage(JSON.stringify(params))
}
}
// 通用日志方法

View File

@ -1,11 +1,22 @@
import worker, { ErrorEvent, MessageEvents, ThreadWorkerGlobalScope } from '@ohos.worker';
import { GlobalConfig } from '../config';
import { LogFileFd, LogPathType, LogWorkerMessage, WorkerMessageType } from '../model';
import { CreateDir, IsExit } from '../utils/Common';
import {
FileQueueType,
LogFileFd,
LogPathType,
LogWorkerMessage,
ProcessDataEnumType,
WorkerMessageType
} from '../model';
import { CreateDir, CreateFile, EditFile, IsExit } from '../utils/Common';
import dayTs from '../utils/Date';
import fs from '@ohos.file.fs';
const workerPort: ThreadWorkerGlobalScope = worker.workerPort;
const fileNameArr: string[] = ["four_one_log_byte_data.txt", "four_one_log_data.txt", "judge_exam_data.txt", "judge_log_data.txt", "judge_progress_callback_data.txt", "plc_data.txt", "wuxi_exam_data.txt", "wuxi_progress_data.txt"]
let fileFdArr: number[] = []
let writeQueue: Array<FileQueueType> = [];
let isProcessing = false;
workerPort.onmessage = (e: MessageEvents) => {
console.log("日志系统worker收到消息")
// 日志文件目录
@ -13,17 +24,22 @@ workerPort.onmessage = (e: MessageEvents) => {
log: `${GlobalConfig.commonFileWriteAddress}/logs/${dayTs().format("YYYY_MM_DD")}/log/log.log`,
error: `${GlobalConfig.commonFileWriteAddress}/logs/${dayTs().format("YYYY_MM_DD")}/log/error.log`,
}
let logFileFd: LogFileFd = {}
const result: LogWorkerMessage = JSON.parse(e.data);
if (result.type === WorkerMessageType.Init) {
InitLog()
}
if (result.type === WorkerMessageType.OpenProcessDataFile) {
OpenProcessDataFile(logPaths, logFileFd, result.data || "")
}
// 初始化过程数据
if (result.type === WorkerMessageType.ExamProcessInit && result.studentDirName) {
InitExam(result.studentDirName)
}
// 写过程数据
if (result.type === WorkerMessageType.WriteProcessData && result.processDataType) {
WriteProcessData(result.processDataType, result.data || "")
}
// 关闭过程数据
if (result.type === WorkerMessageType.CloseProcessData) {
CloseProcessData()
}
}
// 初始化日志
@ -62,6 +78,7 @@ async function InitLog() {
// 初始化学员过程数据目录
async function InitExam(dirName: string) {
console.log("初始化过程", dirName)
let date = dayTs().format("YYYY_MM_DD")
const path = `${GlobalConfig.commonFileWriteAddress}/logs/${date}/${dirName}`
const nameDirIsExit = await IsExit(path)
@ -69,12 +86,39 @@ async function InitExam(dirName: string) {
await CreateDir(path);
}
// 创建几个文件
let fileNameArr: string[] = ["four_one_log_byte_data.text", "four_one_log_data.txt", "judge_exam_data.txt", "judge_log_data.txt", "judge_progress_callback_data.txt", "plc_data.txt", "wuxi_exam_data.txt", "wuxi_progress_data.txt"]
fileNameArr.forEach(async (item: string, index: number) => {
let filePath = path + "/" + item
console.log("创建文件", filePath)
let result = await CreateFile(filePath)
fileFdArr[index] = result
})
}
function OpenProcessDataFile(logPaths: LogPathType, logFileFd: LogFileFd, name: string) {
// 写过程数据
async function WriteProcessData(type: ProcessDataEnumType, data: string) {
writeQueue.push({ type, data });
if (!isProcessing) {
processQueue();
}
}
async function processQueue() {
isProcessing = true;
while (writeQueue.length > 0) {
const item = writeQueue.shift()!;
const index = Number(item.type);
await EditFile(fileFdArr[index], item.data);
}
isProcessing = false;
}
// 关闭过程数据
function CloseProcessData() {
fileFdArr.forEach((item: number) => {
fs.closeSync(item)
})
console.log("关闭过程数据")
}
workerPort.onmessageerror = (e: MessageEvents) => {

View File

@ -1,3 +1,66 @@
<details>
<summary>fix: 修复完善一些小问题</summary>
<span style="color: #888;">[提交人]:</span><span style="color: #333;">wangzhongjie</span><br>
<span style="color: #888;">[提交时间]:</span><span style="color: #333;">2025-07-16 09:30</span><br>
<span style="color: #888;">[提交版本]:</span><span style="color: #333;">46c9b8b</span>
</details>
<details>
<summary>Merge branch 'main' of http://47.122.70.237:3000/harmony_car/harmony_vehicle_terminal</summary>
<span style="color: #888;">[提交人]:</span><span style="color: #333;">wangzhongjie</span><br>
<span style="color: #888;">[提交时间]:</span><span style="color: #333;">2025-07-15 16:56</span><br>
<span style="color: #888;">[提交版本]:</span><span style="color: #333;">39bfed3</span>
</details>
<details>
<summary>fix: 解决考生缺考问题,解决进入不了联网考试问题</summary>
<span style="color: #888;">[提交人]:</span><span style="color: #333;">wangzhongjie</span><br>
<span style="color: #888;">[提交时间]:</span><span style="color: #333;">2025-07-15 16:55</span><br>
<span style="color: #888;">[提交版本]:</span><span style="color: #333;">5b48137</span>
</details>
<details>
<summary>请求类</summary>
<span style="color: #888;">[提交人]:</span><span style="color: #333;">lixiao</span><br>
<span style="color: #888;">[提交时间]:</span><span style="color: #333;">2025-07-15 15:48</span><br>
<span style="color: #888;">[提交版本]:</span><span style="color: #333;">4c1e569</span>
</details>
<details>
<summary>fix: 隐藏部分快速打印</summary>
<span style="color: #888;">[提交人]:</span><span style="color: #333;">wangzhongjie</span><br>
<span style="color: #888;">[提交时间]:</span><span style="color: #333;">2025-07-14 13:23</span><br>
<span style="color: #888;">[提交版本]:</span><span style="color: #333;">78be17b</span>
</details>
<details>
<summary>fix: 增加request打印请求信息</summary>
<span style="color: #888;">[提交人]:</span><span style="color: #333;">wangzhongjie</span><br>
<span style="color: #888;">[提交时间]:</span><span style="color: #333;">2025-07-04 16:31</span><br>
<span style="color: #888;">[提交版本]:</span><span style="color: #333;">8838072</span>
</details>
<details>
<summary>fix: 后置机拿不到信号问题</summary>
<span style="color: #888;">[提交人]:</span><span style="color: #333;">wangzhongjie</span><br>
<span style="color: #888;">[提交时间]:</span><span style="color: #333;">2025-06-26 14:27</span><br>
<span style="color: #888;">[提交版本]:</span><span style="color: #333;">a52a13e</span>
</details>
<details>
<summary>fix: 优化打印以及评判一个弹窗问题</summary>
<span style="color: #888;">[提交人]:</span><span style="color: #333;">wangzhongjie</span><br>
<span style="color: #888;">[提交时间]:</span><span style="color: #333;">2025-07-04 13:49</span><br>
<span style="color: #888;">[提交版本]:</span><span style="color: #333;">7bd3689</span>
</details>
<details>
<summary>fix: 增加一些日志</summary>
<span style="color: #888;">[提交人]:</span><span style="color: #333;">wangzhongjie</span><br>
<span style="color: #888;">[提交时间]:</span><span style="color: #333;">2025-07-04 10:50</span><br>
<span style="color: #888;">[提交版本]:</span><span style="color: #333;">af8b112</span>
</details>
<details>
<summary>fix: 优化首页获取车辆后才可以进入联网以及单机逻辑</summary>
<span style="color: #888;">[提交人]:</span><span style="color: #333;">wangzhongjie</span><br>