2025-03-27 15:52:20 +08:00

1471 lines
51 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import router from '@ohos.router';
import Prompt from '@system.prompt';
import common from '@ohos.app.ability.common';
import EndPoPup from './compontents/judge/EndPopup';
import LoadingPopup from './compontents/judge/LoadingPopup';
import DeductedPopup from './compontents/judge/DeductionPopup';
import AmplifyPopup from './compontents/judge/AmplifyPopup';
import Judge from './judgeSDK/judge';
import { defaultJudgeConfigObj } from './judgeSDK/utils//judgeCommon';
import { uploadExamMileage } from '../api/judge';
import DwztErrorPopup from './compontents/judge/DwztErrorPopup';
import MsgPopup from './compontents/judge/MsgPopup';
import {
CARINFO,
CDSBInfo,
LANE,
MAPITEMPOINTITEM,
MAPPOINT,
MarkRule,
Project,
ProjectObj,
SYSTEMPARMARR
} from './judgeSDK/api/judgeSDK.d';
import { judgeConfig } from './judgeSDK/utils/judgeConfig';
import SignDisplayCom from './compontents/signDisplayCom';
import {
CarInfoType,
CommonType,
ES_CARINFOType,
KfdmType,
MA_CDSBINFOType,
MA_ITEMINFOType,
MA_MAP_POINT_ITEMType,
MA_MAP_POINTType,
MA_MARKRULEType,
MA_SYSTEMPARMType,
MASYSSETTableType,
RouteParamsType,
User,
SYSSET,
SyssetConfig,
ProjectInfo,
ProjectInfos,
ProjectCenterInfos,
JudgeInitObj,
JudgeBeginObj,
UploadExamMileage,
AmplifyItem,
ProjectRoads,
JudgeCallBacData
} from '../model';
import { GetSyncData } from '../utils/table/Operation';
import dayTs from '../utils/Date';
import { GetCurrentTime } from '../utils/Common';
import { chunkArr } from './judgeSDK/utils/Common';
import FileUtils from '../utils/FileUtils';
@Entry
@Component
struct Index {
scroller: Scroller = new Scroller()
//页面通用字体大小
@State wayno: number = 0
@State FONTSIZE: number = 30
@State BIGFONTSIZE: number = 32
//结束考试弹窗
@State endPopupVisible: boolean = false
//等待弹窗(考试及格,考试不及格使用)
@State loadingPopupVisible: boolean = false
//实时轨迹弹窗
@State signDisplayComVisible: boolean = false
@State isDdxk: boolean = false;
@State time: string = ''
//考试用时
@State examTime: number = 0
//开始时间
@State startTime: string = '00:00:00'
@State startFullTime: string = ''
@State startHourTime: string = ''
@State startExamTime: string = ''
//科目类型
@State examSubject: string = '3';
@State ddxkTime: number = 0;
@State ddxkKsxmArr: string[] = []
@State ddxkKfArr: string[] = []
@State xmmcStr: string = ''
@State carztStr: string = ''
@State kfArr: MarkRule[] = []
@State name: string = ''
@State idCard: string = ''
@State singlePlay: boolean = false;
@State totalScore: number = 100
//模拟考试项目
@State projects: ProjectInfo[] = []
@State projectsObj: ProjectInfos = {}
@State projectsCenterObj: ProjectInfo = {}
@State markRuleListObj: MarkRule = {}
@State cdsbInfoObj: CDSBInfo = {}
@State itemInfoObj: CDSBInfo = {}
@State timer: number = 0
@State judgeConfig: SyssetConfig[] = []
@State judgeConfigObj: object = defaultJudgeConfigObj
//流水号
@State lsh: string = ''
@State kszp: string = ''
@State ksdd: string = ''
@State kssycs: string = ''
@State ksxl: string = ''
@State kslx: string = ''
//监管线路代码
@State xldm: string = ''
//监管接口序列号
@State serialNumber: number|string = 0
@State syssetParam623: boolean = false;
@State syssetParam211: string = '';
@State carType: string = ''
@State carName: string = ''
@State isDeductedPopShow: boolean = false
@State isAmplifyPopShow: boolean = false
@State amplifiedImgIndex: number = 0
judge: Judge
//行驶距离
@State jl: number = 0
//应考里程
@State examMileage: string = '0'
@State artSubject3Projects: string[] = ['直线', '会车', '变道', '超车', '掉头', '停车']
@State artSubject3ProjectsCodesArr: string[] = ['3', '9', '4', '10', '12', '11']
@State manualMarkRules: MarkRule[] = []
//科目三评判初始化数据
@State systemparmArr: SYSTEMPARMARR[] = []
@State mapPointItemArr: MAPITEMPOINTITEM[] = []
@State carinfoArr: CARINFO[] = []
@State mapPointArr: MAPPOINT[] = []
//手动项目是否在进行中
@State isManualProjectIn: boolean = false;
//项目是否进行中
@State isProjectIn: boolean = false;
//正在进行的项目代码
@State currentXmdm: string = ''
// 必考项目除靠边停车是否全部完成
@State isRequiredProjectsEnd: boolean = false;
// @State isAllProjectsEnd: boolean = false;
@State lane: LANE = { road: '', num: 0, count: 0 }
//定位差分状态时候正常
@State isDwztRight: boolean = true;
@State defaultTabIndex: number = 0;
public kfArrScroller: Scroller = new Scroller()
//档位
@State dw: string = ''
//速度
@State sd: string = ''
@State mileageTimer: number = 0;
@State passingScore: number = 80
@State dwztErrorVisible: boolean = false;
@State popTimer: number = 0;
@State carlist: string = ''
@State errorMsg: string = ''
@State carInfo: CarInfoType = {}
@State isErrorMsgEnd: boolean = false
@State disConnectErrorOpen: boolean = false
private context = getContext(this) as common.UIAbilityContext;
async aboutToDisappear() {
clearInterval(this.mileageTimer)
}
async aboutToAppear() {
const time = GetCurrentTime()
this.carInfo = AppStorage.get<CarInfoType>('carInfo')
this.singlePlay = AppStorage.get<boolean>('singlePlay')
this.startTime = time.split(' ')[1]
this.startFullTime = GetCurrentTime(1);
// this.startHourTime = await getCurrentHourTime()
this.startTime = dayTs().format("HHmmssSSS")
this.startExamTime = time
setInterval(async () => {
this.time = GetCurrentTime();
this.examTime += 1;
}, 1000);
//初始化数据库表
await this.initDb()
//断点续考
await this.goDdxkItems()
//初始化评判
const judge = await this.initJudge();
this.judge = judge
}
//初始化相关数据库表
async initDb() {
this.examSubject = this.carInfo.examSubject;
// const { isTrajectoryOpen, trajectoryPath } = judgeConfig
await this.initStudent();
await this.initCar();
//是否开启轨迹回放模式
if (judgeConfig.isTrajectoryOpen) {
this.initTrajectoryParam(judgeConfig.trajectoryPath)
} else {
await this.initSystemParam()
await this.initMarkRules();
await this.initSysset();
}
await this.initCDSBInfo()
await this.initItemInfo()
// 科目三新增读取表数据
if (this.examSubject == '3') {
await this.initMapPoint()
await this.initMapPointItem()
//定时上传考试里程
// let mileageTimer = setInterval(()=>{
// this.uploadMileage()
// },5000)
// this.mileageTimer = mileageTimer
}
}
// 查询考车信息
async initCar() {
// const result = await getSyncData('ES_CARINFO')
const result = await GetSyncData<ES_CARINFOType>("ES_CARINFO")
const carInfo = result[0] || {};
this.carName = decodeURI(carInfo.carclass)
this.carType = carInfo.kscx
this.carinfoArr.push({
CARID: carInfo.carid,
IPADDR: '',
CARCLASS: decodeURI(carInfo.carclass),
KSCX: carInfo.kscx,
// CARNAME: decodeURI(carInfo.carname),
CARNAME: "",
FLAG: carInfo.flag,
BK1: carInfo.bk1,
BK2: carInfo.bk2,
})
console.info('surenjun =>carinfoArrr', JSON.stringify(this.carinfoArr))
}
// 获取考生信息
async initStudent() {
const students = await GetSyncData<User>('USER')
const stuInfo = students[0];
// const { xm, sfzmhm, lsh, kszp, ksdd, kssycs, kslx, ksxl, xldm } = stuInfo;
this.name = stuInfo.xm || '测试考生';
this.idCard = stuInfo.sfzmhm || '01234567891010';
this.lsh = this.singlePlay ? '0000000000000' : stuInfo.lsh;
this.kszp = stuInfo.kszp;
this.ksdd = stuInfo.ksdd;
this.kssycs = stuInfo.kssycs;
this.ksxl = stuInfo.ksxl;
this.wayno = Number(stuInfo.ksxl);
this.xldm = stuInfo.xldm;
this.kslx = stuInfo.kslx;
}
// 获取扣分代码信息
async initMarkRules(markRules ?: MarkRule[]) {
const markRuleParams = markRules || await GetSyncData<MarkRule>('MA_MARKRULE')
markRuleParams.forEach(mark => {
const tempObj:MarkRule = {
itemno: mark.itemno * 1,
markcatalog: mark.markcatalog,
markshow: decodeURI(mark.markshow),
markreal: mark.markreal * 1,
markserial: mark.markserial,
kfxh: mark.kfxh,
OnlyOneKind: mark.onlyoneid * 1,
NoCancelId: mark.nocancelid * 1,
GPS_SID: mark.gps_sid == 0 ? false : true
}
//筛选出人工评判的扣分
if (Number(tempObj.markserial) > 100 && Number(tempObj.markserial) < 200) {
this.manualMarkRules.push(tempObj)
}
this.markRuleListObj[`${mark.itemno}_${mark.markserial}`] = tempObj
this.markRuleListObj[`${mark.itemno}_${mark.markserial}`].markserial = mark.markserial
})
}
// 考试项目是否全部完成
// 获取sysset表信息
async initSysset(sysset?: SYSSET[]) {
const syssetParams: SYSSET[] | MASYSSETTableType[] = sysset || await GetSyncData<MASYSSETTableType>('MA_SYSSET')
const serialNumberArr = (syssetParams as SYSSET[]).filter(sys => sys.v_no === '901');
console.info('surenjun serialNumberArr' + JSON.stringify(serialNumberArr))
this.serialNumber = (serialNumberArr[0] && serialNumberArr[0].v_value) || '';
// const { isTrajectoryOpen } = judgeConfig
const syssetJudgeConfigArr:SyssetConfig[] = []
syssetParams.forEach((sys:SYSSET) => {
if (judgeConfig.isTrajectoryOpen) {
sys.v_no = sys.key;
sys.v_name = sys.name;
sys.v_value = sys.value
}
// const { v_no, v_value } = sys;
const v_no_num = Number(sys.v_no)
const value = decodeURIComponent(sys.v_value)
if (v_no_num >= 10 && v_no_num <= 900) {
const name =
syssetJudgeConfigArr.push({
key: v_no_num, value: value,
name: decodeURI(sys.v_name)
})
}
//623 考试中是否可以查看轨迹画面(0-否+1-是)
if (sys.v_no == '623') {
this.syssetParam623 = value == '1' ? true : false
}
//科目三应行驶距离参数
if (sys.v_no == '303') {
this.examMileage = this.examMileage == '0' ? (sys.v_value + '') : this.examMileage;
}
// //地点版本参数
// if (sys.v_no == '211') {
// this.syssetParam211 = decodeURIComponent(sys.v_value + '')
// }
//364 绕车一周评判时机(1-开始考试后判 2-开始考试前判)
if (sys.v_no == '364' && sys.v_value == "2") {
let currentParams: RouteParamsType = router.getParams() as RouteParamsType;
// const { sczb, kfdm } = currentParams;
const kfdm = currentParams.kfdm;
currentParams.kfdm.forEach(kf => {
// const { xmdm, kfdm } = kf
const currentKf: MarkRule = Reflect.get(this.markRuleListObj,`${kf.xmdm}_${kf.kfdm}`)
const currentProject:ProjectInfo = Reflect.get(this.projectsObj,kf.xmdm)
// 过滤考前绕车一周上车准备的扣分
if (currentParams.sczb == "1" && kf.xmdm == '1') {
return
}
this.kfArr.push({
//扣分项目名称
xmmcStr: currentProject.name,
xmdm:kf.xmdm,
desc: currentKf.markshow,
score: currentKf.markreal,
markcatalog: currentKf.markcatalog,
markserial: currentKf.markserial,
kfxh: currentKf.kfxh
})
this.totalScore += currentKf.markreal * 1;
})
const project_1 = Reflect.get(this.projectsObj,1)
project_1.type = kfdm.length ? '4' : '3';
Reflect.set(this.projectsObj,1,project_1)
}
this.judgeConfigObj[sys.v_no] = value
});
this.judgeConfig = syssetJudgeConfigArr;
}
//初始化systemParam表
async initSystemParam(sysParam?: MA_SYSTEMPARMType[]) {
let systemParms: MA_SYSTEMPARMType[] = sysParam || await GetSyncData<MA_SYSTEMPARMType>('MA_SYSTEMPARM')
let currentParams: RouteParamsType = router.getParams() as RouteParamsType;
// const { carName, carType, examSubject } = this;
//小车车型列表
const sCarTypes = ['C1', 'C2', 'C5']
if (this.singlePlay) {
this.wayno = Number(currentParams.wayno) || 1;
}
//真实监管下发的项目
let kStringArr: string[] = (currentParams.kString?.split(',') || []).filter(item => item);
console.info('surenjun kStringArr', JSON.stringify(kStringArr))
let isInExam = kStringArr.length > 0;
// const { isTrajectoryOpen } = judgeConfig
let carNo = '', allItems:string[] = [];
systemParms.forEach((systemParm) => {
if (judgeConfig.isTrajectoryOpen) {
systemParm.no1 = systemParm.NO1 + '';
systemParm.no2 = systemParm.NO2 + '';
systemParm.no3 = systemParm.NO3 + '';
systemParm.txt1 = systemParm.TXT1;
systemParm.txt2 = systemParm.TXT2;
systemParm.txt3 = systemParm.TXT3;
}
// const { no1, no2, no3, } = systemParm;
const txt1 = decodeURI(systemParm.txt1)
const txt2 = decodeURI(systemParm.txt2)
const no1 = systemParm.no1;
const no2 = systemParm.no2;
const no3 = systemParm.no3;
//获取当前考车的no2
if (systemParm.no1 == "3" && systemParm.no3 == "1") {
if (txt1 === this.carName) {
carNo = systemParm.no2
this.carlist = carNo
}
}
//获取及格分数线
if (systemParm.no1 == "3" && systemParm.no3 == "3" && carNo === systemParm.no2) {
this.passingScore = Number(txt1) || 0;
}
//根据车型获取应行驶里程数
if (systemParm.no1 == "3" && systemParm.no3 == "15" && carNo === systemParm.no2) {
this.examMileage = ((decodeURI(systemParm.txt1)) || '').split('^')[0];
}
//获取当前考车的考试项目
if (carNo !== '' && systemParm.no1 == "3" && systemParm.no2 == carNo && systemParm.no3 == "10") {
allItems = decodeURIComponent(systemParm.txt1).split(',').filter(txt => txt !== '')
console.info('surenjun', JSON.stringify(allItems))
}
if (
//科目二获取项目
(this.examSubject == "2" && allItems.length && systemParm.no1 == '6' && allItems.includes(systemParm.no2))
||
//科目三获取项目
(this.examSubject == "3" && systemParm.no1 == "6")
) {
const name = decodeURI(systemParm.txt1)
//小车过滤掉 夜间模拟行驶
if (sCarTypes.includes(this.carType) && name === '夜间行驶') {
return
}
const currentProject:ProjectInfo = {
name,
abbreviation: decodeURI(systemParm.txt3),
projectCode: no2,
projectCodeCenter: txt2,
//是否是必考 加减档设置成非必考
isRequired: no2 == '14' ? false : allItems.includes(no2 + ''),
//是否考过了
isEnd: false,
//项目开始数据是否上传过
isUpload: false,
}
const no2Num = Number(systemParm.no2)
//真实监管下发考试项目
if (isInExam && !(kStringArr.includes(txt2) || kStringArr.includes(no2 + ''))) {
console.info('surenjun =>', txt2)
console.info('surenjun => no2', systemParm.no2)
currentProject.type = '3'
currentProject.isUpload = true
currentProject.isEnd = true
this.ddxkKsxmArr.push(txt2)
}
Reflect.set(this.projectsObj, no2Num, currentProject)
Reflect.set(this.projectsCenterObj, txt2, currentProject)
this.projects.push(currentProject);
}
this.systemparmArr.push({
'NO1': Number(systemParm.no1),
'NO2': Number(systemParm.no2),
'NO3': Number(systemParm.no3),
'TXT1': decodeURIComponent(systemParm.txt1),
'TXT2': decodeURIComponent(systemParm.txt2),
'TXT3': decodeURIComponent(systemParm.txt3),
})
})
const projects = this.projects;
console.info('surenjun', JSON.stringify(this.ddxkKsxmArr))
if (!projects.length) {
Prompt.showToast({
message: '读取数据库信息失败,请重新联网更新!',
duration: 8000
});
router.back();
}
}
// 获取场地设备信息
async initCDSBInfo() {
const cdsbParams: MA_CDSBINFOType[] = await GetSyncData<MA_CDSBINFOType>('MA_CDSBINFO')
//只记录考试项目的模型
const projectsObj = this.projectsObj
cdsbParams.forEach((cdsb) => {
const key = decodeURI(cdsb.itemsno)
const newKey = key.split('~').join('_')
const xmdm = Number( key.split('~')[0] )
const currentProject:ProjectInfo = Reflect.get(projectsObj, xmdm)
if (currentProject) {
this.cdsbInfoObj[newKey] = {
kdid: cdsb.kdid,
sbbh: cdsb.sbbh,
sbbm: cdsb.sbbm,
itemsno: key,
modelKey: newKey,
xmdm,
xmxh: key.split('~')[1],
}
}
})
}
// 获取itemInfo表信息
async initItemInfo() {
const infoParams: MA_ITEMINFOType[] = await GetSyncData<MA_ITEMINFOType>('MA_ITEMINFO');
const carlist = this.carlist;
const projectsObj = this.projectsObj
infoParams.forEach((info) => {
const key = decodeURI(info.itemsno);
const carlistArr = info.carlist === '' ? [] : (decodeURI(info.carlist).split(',') || []);
const newKey = key.split('~').join('_')
const xmdm = Number(key.split('~')[0])
const currentProject:ProjectInfo = Reflect.get(projectsObj,xmdm)
if (currentProject && (carlistArr.length == 0 || carlistArr.includes(carlist))) {
this.itemInfoObj[newKey] = {
modelKey: newKey,
xmdm,
xmxh: key.split('~')[1],
}
}
})
}
// 评判相关初始化
async initJudge() {
const judge = new Judge(this);
await judge.onJudgeFn(async (judgeData:JudgeCallBacData) => {
// const { xmmcStr, carztStr, kfArr } = judgeData;
this.xmmcStr = judgeData.xmmcStr;
this.carztStr = judgeData.carztStr;
this.kfArr = judgeData.kfArr;
});
return judge
}
// 断点续考判断
async goDdxkItems() {
const judgeConfigObj = this.judgeConfigObj
//科目二强制开始断点续考
if (judgeConfigObj['432'] != 0 || this.examSubject == "2") {
//断点续考判断
let currentParams: RouteParamsType = router.getParams() as RouteParamsType;
const examItems: string = currentParams?.examItems;
// 2024-01-03 16:29:26;0;20300,;2,4^2,4;null;
if (examItems !== '' && examItems !== undefined) {
console.info('surenjun examItems=>', JSON.stringify(examItems))
const examItemsArrs = examItems.split(';');
const startTime = examItemsArrs[0]
const ddxkKsxmArr = examItemsArrs[2]?.split(',').filter(item => item) || []
const ddxkKfArr = examItemsArrs[3]?.split('^').filter(item => item) || []
if (judgeConfigObj['432'] == 2 || this.examSubject == "2") {
//TODO 带项目带里程
if (ddxkKsxmArr?.length) {
//断点续考
ddxkKsxmArr.forEach(xmdm => {
const currentProjectCenter:Project = Reflect.get(this.projectsCenterObj, xmdm)
const projectCode = currentProjectCenter.projectCode
const currentProject:Project = Reflect.get(this.projectsObj,projectCode)
if (currentProject) {
currentProject.type = '3'
currentProject.isUpload = true
currentProject.isEnd = true
Reflect.set(this.projectsObj, projectCode, currentProject)
}
})
this.ddxkKsxmArr = ddxkKsxmArr
}
}
//扣分续考
ddxkKfArr.forEach((kf) => {
const xmdm = kf.split(',')[0]
const kfdm = kf.split(',')[1]
const currentKf:MarkRule = Reflect.get(this.markRuleListObj, `${xmdm}_${kfdm}`)
const currentProject:ProjectInfo = Reflect.get(this.projectsObj,xmdm) || { name: '通用评判' }
if (currentProject) {
currentProject.type = '4'
Reflect.set(this.projectsObj, xmdm, currentProject)
}
this.kfArr.push({
//扣分项目名称
xmmcStr: currentProject.name,
desc: currentKf.markshow,
score: currentKf.markreal,
markcatalog: currentKf.markcatalog,
markserial: currentKf.markserial,
kfxh: currentKf.kfxh
})
this.totalScore += currentKf.markreal * 1;
})
this.ddxkKfArr = ddxkKfArr
this.ddxkTime = Date.parse(startTime);
this.isDdxk = true
}
}
}
// 初始化mapPoint表
async initMapPoint() {
const pointParams: MA_MAP_POINTType[] = await GetSyncData<MA_MAP_POINTType>('MA_MAP_POINT')
pointParams.forEach(item => {
this.mapPointArr.push({
point_no: Number(item.point_no),
gps_e: Number(item.gps_e),
gps_n: Number(item.gps_n),
point_no_f: Number(item.point_no_f),
point_type: Number(item.point_type),
road_code: item.road_code,
gps_e_Location: Number(item.gps_e_location),
gps_n_Location: Number(item.gps_n_location),
f_gps_e: Number(item.f_gps_e),
f_gps_n: Number(item.f_gps_n),
passed: Number(item.passed)
})
})
}
// 初始化mapPointItem表
async initMapPointItem() {
const pointItemPoints: MA_MAP_POINT_ITEMType[] = await GetSyncData<MA_MAP_POINT_ITEMType>('MA_MAP_POINT_ITEM');
pointItemPoints.forEach(item => {
// const { point_no, itemno, itemno1, subname } = itemPoint
this.mapPointItemArr.push({
point_no: Number(item.point_no),
itemno: Number(item.itemno),
itemno1: Number(item.itemno1),
subname: item.subname
})
})
}
// 初始化本地systemparam表、markrule表
async initTrajectoryParam(trajectoryPath: string) {
const isTrajectoryOpen = judgeConfig.isTrajectoryOpen
//轨迹回放读取 systemparam表、markrule表
const fileUtil = new FileUtils(this.context);
const folderPath = await fileUtil.initFolder(trajectoryPath);
const str = await fileUtil.readFile(folderPath);
const strArr = str.split('\n');
const initData = strArr[0]
const beginData = strArr[1]
const initDataObj:JudgeInitObj = JSON.parse(initData)
const beginDataObj:JudgeBeginObj = JSON.parse(beginData)
const examSubject = this.carInfo.examSubject;
this.examSubject = isTrajectoryOpen ? (initDataObj.kskm) : examSubject;
this.carInfo.examSubject = this.examSubject
this.singlePlay = beginDataObj.exam == 0;
this.carName = initDataObj.name;
await this.initSystemParam(initDataObj.systemparm)
await this.initMarkRules(initDataObj.mark);
await this.initSysset(initDataObj.sysset);
}
// 上传考试里程
async uploadMileage() {
if (!this.singlePlay) {
const carInfo = this.carInfo
await uploadExamMileage({
carId:carInfo.carId,
examinationRoomId:carInfo.examinationRoomId,
lsh:this.lsh,
kskssj:this.startExamTime,
kslc:this.jl
})
}
}
build() {
Column() {
Row() {
Row() {
Image($rawfile('judge/signal_logoS.png')).width(120)
Text(this.time).fontColor('#CCB48F').fontSize(34).padding({ left: 10, right: 5 })
Image($rawfile(this.isDwztRight ? 'judge/xh_green.png' : 'judge/xh_red.png')).width(50)
}.padding({ left: 20 })
Row() {
Text(`当前项目:${this.xmmcStr || '无'} `).fontColor('#E5CCA1').fontSize(34)
}
}
.width('100%')
.height('96')
.backgroundColor('#001A33')
.padding({ left: 15, right: 15 })
.justifyContent(FlexAlign.SpaceBetween)
.alignItems(VerticalAlign.Center)
Row() {
Row() {
Column() {
Row() {
Column() {
Row() {
Text('考生姓名:').fontColor('#E5CCA1').fontSize(this.FONTSIZE)
Text(this.name).fontColor('#FFF').fontSize(this.FONTSIZE)
}.margin({ bottom: 10 })
Row() {
Text('开始时间:').fontColor('#E5CCA1').fontSize(this.FONTSIZE)
Text(this.startTime).fontColor('#FFF').fontSize(this.FONTSIZE)
}.margin({ bottom: 10 })
if (this.examSubject == "3") {
Row() {
Text('考试路线:').fontColor('#E5CCA1').fontSize(this.FONTSIZE)
Text(`线路${this.wayno || 3}`).fontColor('#FFAD33').fontSize(this.FONTSIZE)
}
}
}.width('45%').alignItems(HorizontalAlign.Start)
Column() {
Row() {
Text('身份证号:').fontColor('#E5CCA1').fontSize(this.FONTSIZE)
Text(this.idCard).fontColor('#FFF').fontSize(this.FONTSIZE)
}.margin({ bottom: 10 })
Row() {
Text('考试用时:').fontColor('#E5CCA1').fontSize(this.FONTSIZE)
// Text(formatTime(this.examTime)).fontColor('#FFF').fontSize(this.FONTSIZE)
Text(dayTs(this.examTime).format("YYYY-MM-DD HH:mm:ss")).fontColor('#FFF').fontSize(this.FONTSIZE)
}.margin({ bottom: 10 })
if (this.examSubject == "3") {
Row() {
if (this.judgeConfigObj['375'] == '0') {
Text(`应行驶:${this.examMileage}m`)
.fontColor('#E5CCA1')
.fontSize(this.FONTSIZE)
.padding({ right: 20 })
}
Text(`已行驶:${this.jl}m`).fontColor('#FFAD33').fontSize(this.FONTSIZE)
}
}
}.alignItems(HorizontalAlign.Start)
}.width('100%')
Column() {
Row() {
Text(this.carztStr).fontColor('#FFA500').fontSize(this.FONTSIZE)
if (this.judgeConfigObj['342'] == '0') {
Text(`${this.dw}挡`).fontColor('#FFA500').fontSize(this.FONTSIZE).padding({ left: 15, right: 15 })
Text(`${this.sd}km/h`).fontColor('#FFA500').fontSize(this.FONTSIZE)
}
}.height(40)
Row() {
Flex({ direction: FlexDirection.Column }) {
if (this.kfArr.length) {
List({ scroller: this.kfArrScroller }) {
ForEach(this.kfArr, (item:MarkRule) => {
ListItem() {
Column() {
Row() {
Text(item.xmmcStr).fontSize(this.BIGFONTSIZE).fontColor('#FFF')
Text(`${item.score}分`).fontSize(this.BIGFONTSIZE).fontColor('#FFF')
}
.width('100%')
.backgroundColor('#38260B')
.justifyContent(FlexAlign.SpaceBetween)
.padding({
top: 12,
bottom: 12,
left: 8,
right: 5
})
Text(item.desc + `(${item.markcatalog})`)
.fontSize(this.BIGFONTSIZE)
.fontColor('#E5CBA1')
.margin({
top: 10,
bottom: 8,
left: 5,
right: 5
})
}.margin({ top: 15 }).alignItems(HorizontalAlign.Start)
}.margin({ bottom: 25 })
})
}
.padding({
left: 15,
right: 15,
top: 30,
bottom: 5
})
} else {
Column() {
Row() {
Text('暂无扣分项').fontSize(this.BIGFONTSIZE).fontColor('#FFF')
}
.width('100%')
.backgroundColor('#38260B')
.justifyContent(FlexAlign.SpaceBetween)
.padding({
top: 12,
bottom: 12,
left: 8,
right: 3
})
}.margin({ top: 35 }).padding({ left: 20, right: 20 }).alignItems(HorizontalAlign.Start)
}
}
.backgroundImage($rawfile('judge/score_bg.png'), ImageRepeat.NoRepeat)
.backgroundImageSize({ width: '100%', height: '100%' })
.width(514)
.height(618)
.padding({
top: 18,
bottom: 15,
left: 13,
right: 14
})
//科目二
if (this.examSubject == "2") {
Flex({ wrap: FlexWrap.Wrap, direction: FlexDirection.Row, justifyContent: FlexAlign.SpaceBetween }) {
List({}) {
ForEach(chunkArr(this.projects, 2), (item:[ProjectInfo,ProjectInfo]) => {
ListItem() {
Row() {
Row() {
//#FF7566 #00FFD5 #E6DECF
// Text(this.projectsObj[item[0].projectCode])
Text(item[0].abbreviation)
.fontSize(item[0].abbreviation.length > 5 ? 28 : 32)
.fontColor(this.getProjectColor(item[0]))
}
.backgroundImage($rawfile('judge/project_item.png'), ImageRepeat.NoRepeat)
.backgroundImageSize({ width: '100%', height: '100%' })
.width('48.5%')
.height(115)
.margin({ bottom: 5 })
.justifyContent(FlexAlign.Center)
if (item[1]) {
Row() {
//#FF7566 #00FFD5 #E6DECF
Text(item[1].abbreviation)
.fontSize(item[1].abbreviation.length > 5 ? 28 : 32)
.fontColor(this.getProjectColor(item[1]))
}
.backgroundImage($rawfile('judge/project_item.png'), ImageRepeat.NoRepeat)
.backgroundImageSize({ width: '100%', height: '100%' })
.width('48.5%')
.height(115)
.margin({ left: 5, bottom: 5 })
.justifyContent(FlexAlign.Center)
}
}
}
});
}
}
.backgroundImage($rawfile('judge/project_bg.png'), ImageRepeat.NoRepeat)
.backgroundImageSize({ width: '100%', height: '100%' })
.width('57%')
.height('100%')
.padding(30)
.margin({ right: 10 })
}
//科目三
if (this.examSubject == '3') {
Column() {
Flex({
wrap: FlexWrap.Wrap,
direction: FlexDirection.Row,
justifyContent: FlexAlign.SpaceBetween
}) {
List({}) {
ForEach(this.projects, (project:ProjectInfo) => {
ListItem() {
Text(project.name) {
}
.fontColor(this.getProjectColor(project))
.margin({ bottom: 2 })
.fontSize(24)
}.margin({ bottom: 2 })
})
}.lanes(2).margin({ left: 25 })
}
.width('100%')
.height('57%')
.backgroundImage($rawfile('judge/project_km3_bg.png'), ImageRepeat.NoRepeat)
.backgroundImageSize({ width: '100%', height: '100%' })
.padding(30)
.margin({ right: 5 })
if (this.projects.length) {
Flex({
wrap: FlexWrap.Wrap,
direction: FlexDirection.Row,
justifyContent: FlexAlign.SpaceAround
}) {
List() {
ForEach(this.artSubject3Projects, (item:string, index) => {
ListItem() {
}
.backgroundImage(
$rawfile(
`judge/km3/${this.getIsExitManualProject(index) ? (this.getIsEndManualProject(index)) :
(item + '_gray')}.png`
), ImageRepeat.NoRepeat)
.backgroundImageSize({ width: '100%', height: '100%' })
.width(174)
.height(118 * 0.95)
.margin({ bottom: 8 })
.onClick(() => {
// this.vocObj.playAudio({
// type: 1,
// name: 'button_media.wav'
// })
this.setManualProjectFn(index)
})
})
}.lanes(3).margin({ left: 5, top: 12 })
}
}
}
.backgroundImage($rawfile('judge/project_bg.png'), ImageRepeat.NoRepeat)
.backgroundImageSize({ width: '100%', height: '100%' })
.width(660)
.height(640)
.padding(44)
.margin({ right: 10 })
}
}.margin({ top: 15 }).height('80%').justifyContent(FlexAlign.SpaceBetween)
}.width('100%').height('100%').alignItems(HorizontalAlign.Start).margin({ top: 10 })
}.height('100%').alignItems(HorizontalAlign.Start)
}.width('75%').height('100%')
Column() {
Column() {
Row() {
Text(this.totalScore <= 0 ? '0' : this.totalScore + '').fontColor('#FFEECC').fontSize(55)
Text('分').fontColor('#FFEECC').fontSize(30).padding({ top: 5 })
}
.width(334)
.height(120)
.justifyContent(FlexAlign.Center)
.alignItems(VerticalAlign.Center)
.border({ width: 5, color: '#4D4136', radius: 30 })
.onClick(() => {
// this.vocObj.playAudio({
// type: 1,
// name: 'button_media.wav'
// })
this.signDisplayComVisible = true
})
Row() {
Image(this.kszp).width('85%').height('85%')
}
.width(226)
.height(312)
.backgroundImage($rawfile('judge/photo_bg.png'), ImageRepeat.NoRepeat)
.backgroundImageSize({ width: '100%', height: '100%' })
.justifyContent(FlexAlign.Center)
.alignItems(VerticalAlign.Center)
.margin({ top: 30, bottom: 15 })
}
Column() {
if (this.getIsManualKf()) {
Row() {
Row() {
}
.width(60)
.height(60)
.backgroundImage($rawfile('judge/manual_judge.png'), ImageRepeat.NoRepeat)
.backgroundImageSize({ width: '100%', height: '100%' })
Text('人工评判').fontColor('#FFF').fontSize(32).padding({ right: 12 })
}
.width(334)
.height(110)
.justifyContent(FlexAlign.Center)
.alignItems(VerticalAlign.Center)
.backgroundImage($rawfile('judge/button_nor.png'), ImageRepeat.NoRepeat)
.backgroundImageSize({ width: '100%', height: '100%' })
.margin({ bottom: 10 })
.onClick(() => {
// this.vocObj.playAudio({
// type: 1,
// name: 'button_media.wav'
// })
this.isDeductedPopShow = true
})
}
Row() {
Row() {
}
.width(60)
.height(60)
.backgroundImage($rawfile('judge/phone.png'), ImageRepeat.NoRepeat)
.backgroundImageSize({ width: '100%', height: '100%' })
Text('呼叫请求').fontColor('#FFF').fontSize(32).padding({ right: 12 })
}
.width(334)
.height(110)
.justifyContent(FlexAlign.Center)
.alignItems(VerticalAlign.Center)
.backgroundImage($rawfile('judge/button_nor.png'), ImageRepeat.NoRepeat)
.backgroundImageSize({ width: '100%', height: '100%' })
.margin({ bottom: 10 })
Row() {
}
.width(334)
.height(100)
.backgroundImage($rawfile('judge/anniu_nor.png'), ImageRepeat.NoRepeat)
.backgroundImageSize({ width: '100%', height: '100%' })
.onClick(() => {
// this.vocObj.playAudio({
// type: 1,
// name: 'button_media.wav'
// })
if (this.judgeConfigObj['353'] == '0') {
this.endPopupVisible = true
} else {
Prompt.showToast({
message: '车上不允许手动结束考试!',
duration: 4000
});
}
})
}.margin({ bottom: 30 })
}
.width('25%')
.height('100%')
.justifyContent(FlexAlign.SpaceBetween)
.alignItems(HorizontalAlign.Center)
.margin({ bottom: 20 })
}
.height('90%')
.justifyContent(FlexAlign.Start)
.padding({
top: 37,
left: 60,
bottom: 35,
right: 60
})
//科目三人工扣分弹窗
if (this.isDeductedPopShow && this.examSubject == '3' && this.judgeConfigObj['342'] == '0') {
DeductedPopup({
defaultTabIndex: this.defaultTabIndex,
currentItems: Reflect.ownKeys(this.projectsObj).map(projectKey => {
const project:ProjectInfo = Reflect.get(this.projectsObj,projectKey)
return project.type == '2' ? project.projectCode : undefined
}).filter(project => project !== undefined),
markRules: this.manualMarkRules,
closePopup: () => {
this.isDeductedPopShow = false;
this.defaultTabIndex = 0;
},
confirmMark: async (itemno:string, serial:string) => {
clearTimeout(this.popTimer)
this.popTimer = null
this.popTimer = setTimeout(async () => {
const judge = this.judge
await judge.setJudgeMark(itemno, serial);
this.isDeductedPopShow = false
this.popTimer = null;
}, 500)
}
})
}
if (this.signDisplayComVisible) {
Column() {
SignDisplayCom({
showBack: false,
scaleNum: 1.8,
msgStr: this.judge.plcStr || '',
showTrajectory: this.singlePlay ? true : (this.syssetParam623),
}).margin({ top: 100 })
Row() {
}
.width(240)
.height(240)
.position({ x: '81%', y: 80 })
.backgroundImage($rawfile('judge/close.png'), ImageRepeat.NoRepeat)
.backgroundImageSize({ width: '33.33%', height: '33.33%' })
.onClick(() => {
// this.vocObj.playAudio({
// type: 1,
// name: 'button_media.wav'
// })
this.signDisplayComVisible = false
})
}.width('100%').height('100%').position({ y: 0 }).backgroundColor('rgba(0,0,0,0.6)')
}
//科目三人工项目确认框
if (this.isAmplifyPopShow && this.examSubject == '3') {
AmplifyPopup({
amplifyImgIndex: this.amplifiedImgIndex,
confirmAmplify: async (amplify:AmplifyItem) => {
clearTimeout(this.popTimer)
this.popTimer = null
this.popTimer = setTimeout(async () => {
const judge = this.judge
await judge.setJudgeItem(amplify.projectCode, 1);
this.isAmplifyPopShow = false
this.popTimer = null;
}, 500)
},
closeAmplifyPop: () => {
this.isAmplifyPopShow = false
}
})
}
//结束考试弹窗
if (this.endPopupVisible) {
EndPoPup({
title: '确定结束考试吗?',
cancelFn: () => {
this.endPopupVisible = false;
},
confirmFn: async () => {
if (this.isErrorMsgEnd) {
this.judge.closeAllFiles()
router.back()
return
}
if (this.judgeConfigObj['344'] == 1) {
Prompt.showToast({
message: '考试未结束,不允许手动退出!',
duration: 4000
});
return
}
this.endPopupVisible = false;
this.loadingPopupVisible = true
clearInterval(this.timer);
clearInterval(AppStorage.get('judgeTimer'))
try {
this.judge.checkExamIsEnd(true);
} catch (e) {
this.judge.closeAllFiles()
router.back()
}
}
})
}
//loading 弹窗
if (this.loadingPopupVisible) {
LoadingPopup({
title: '正在生成考试记录,请稍后...',
})
}
if (this.errorMsg) {
MsgPopup({
title: this.errorMsg,
confirmFn: () => {
this.errorMsg = ''
this.isErrorMsgEnd = true;
if (this.disConnectErrorOpen) {
this.context.terminateSelf()
} else {
router.back()
}
},
})
}
if (this.dwztErrorVisible) {
DwztErrorPopup({
title: '当前差分状态异常,学员将无法正常进行考试评判,请将车辆行驶到开阔地,等待程序自检,差分正常后会自动关闭该对话框',
cancelFn: () => {
this.dwztErrorVisible = false;
},
confirmFn: () => {
clearInterval(this.timer);
clearInterval(AppStorage.get('judgeTimer'))
this.judge.checkExamIsEnd(true);
},
})
}
if (this.disConnectErrorOpen) {
}
}
.height('100%').backgroundColor('#000').justifyContent(FlexAlign.Start)
}
getProjectColor(project: ProjectInfo) {
const type = project.type;
switch (type) {
case '1':
return '#E6DECF';
break;
case '2':
return '#FFAD33';
break;
case '3':
return '#ff109d0a';
break;
case '4':
return '#FF7566';
break;
default:
return '#E6DECF';
break;
}
}
//人工项目操作
async setManualProjectFn(index: number) {
const judgeConfigObj = this.judgeConfigObj;
const isManualProjectIn = this.isManualProjectIn;
const getIsExitManualProject = this.getIsExitManualProject;
const artSubject3ProjectsCodesArr = this.artSubject3ProjectsCodesArr;
const projectsObj = this.projectsObj;
const projectCode = Reflect.get(artSubject3ProjectsCodesArr,index)
if (index === 5) {
console.info('surenjun 靠边停车状态=> ', getIsExitManualProject(index))
}
const currentProject:ProjectInfo = Reflect.get(projectsObj,projectCode)
if (getIsExitManualProject(index)) {
// 正在进行的项目 取消项目
if (isManualProjectIn && currentProject.type == '2') {
//判断人工是否能取消项目 && 当前项目有扣分的不能取消
if (judgeConfigObj['340'] == 1) {
await this.judge.setJudgeItem(projectCode, 2);
Prompt.showToast({
message: '项目取消',
duration: 2000
})
return
}
}
// 靠边停车时候可以触发
if (judgeConfigObj['343'] === '0') {
const xmmcStr = this.xmmcStr;
if (xmmcStr == '无' || xmmcStr == '') {
//512[6] 人工项目按钮放大确认
const param512:string[] = (judgeConfigObj['512'] || '').split(',');
console.info('surenjun', param512)
if (param512[6] !== '0') {
this.amplifiedImgIndex = index;
this.isAmplifyPopShow = true
} else {
const judge = this.judge
await judge.setJudgeItem(projectCode, 1);
}
} else {
if (index === 5) {
Prompt.showToast({
message: `${xmmcStr}未结束,不允许靠边停车`,
duration: 8000
});
}
}
} else {
this.amplifiedImgIndex = index;
this.isAmplifyPopShow = true
}
}
}
// 获取是否能人工进项目
getIsExitManualProject = (index: number) => {
const judgeConfigObj = this.judgeConfigObj;
const artSubject3ProjectsCodesArr = this.artSubject3ProjectsCodesArr;
const projectsObj = this.projectsObj;
const carztStr = this.carztStr;
const isManualProjectIn = this.isManualProjectIn;
const isProjectIn = this.isProjectIn;
const getProjectIsInRoad = this.getProjectIsInRoad;
const projectCode = artSubject3ProjectsCodesArr[index];
const currentProject:ProjectInfo = Reflect.get(projectsObj,projectCode)
if (currentProject === undefined) {
return false
}
const projectType = currentProject.type;
//不允许人工触发的项目列表,以","分隔
const unExitManualProjects:string[] = judgeConfigObj['332'].split(',') || [];
//直线行驶中不进其他考试项目(0-否 1-是)
const param348:string = judgeConfigObj['348'] || '0',
//里程不够允许手工点靠边停车0-否 1-是)
param387:string = judgeConfigObj['387'] || '0',
//里程不够不报靠边停车0-否+1-是+2-必考项目未完成且里程不够不报项目)
param319:string = judgeConfigObj['319'] || '0',
//人工项目是否能取消 1:可取消;
param340:string = judgeConfigObj['340'] || '0',
//307参数里设置的项目项目已经做过后续不能人工触发
param307:string[] = (judgeConfigObj['307'] || '').split(',');
//非行驶状态(没有速度),人工项目不能触发(按钮灰色)
if (carztStr === '停车') {
return false
}
//车上是否能进行人工操作(0-能1-不能人工评判2-不能人工进项目3-都不能)
if (judgeConfigObj['342'] === '3' || judgeConfigObj['342'] === '2') {
return false
}
//不允许人工触发的项目列表
if (unExitManualProjects.includes(artSubject3ProjectsCodesArr[index])) {
return false
}
//项目进行中不能人工触发
if (isProjectIn) {
if (param340 == '1') {
if (isManualProjectIn && (currentProject.type == '2')) {
return true
} else {
return false
}
}
return false
}
//项目路段信息判断
if (!getProjectIsInRoad(projectCode + '')) {
return false
}
const project_9:ProjectInfo = Reflect.get(projectsObj,'9')
// 直线行驶中不进其他考试项目(0-否 1-是)
if (param348 == '0' && project_9.type == '2') {
return index === 0 ? true : false
}
//项目已经做过,后续不能人工触发
if (param307.includes(projectCode) && (projectType == '3' || projectType == '4')) {
return false
}
//319不为0或者387不为1里程不够时靠边停车项目不能触发
if ((param387 != '1' || param319 != '0') && index === 5) {
const examMileage = this.examMileage
const isRequiredProjectsEnd = this.isRequiredProjectsEnd
const jl = this.jl
//里程是否达标 && 必考项目是否全完成
return jl >= Number(examMileage) && isRequiredProjectsEnd
}
return true
}
// 判断项目是否在当前路段号
getProjectIsInRoad = (projectCode: string,) => {
const judgeConfigObj = this.judgeConfigObj;
const lane = this.lane;
const road = lane.road;
const num = lane.num;
const count = lane.count;
const param_3:string[] = (judgeConfigObj['514']?.split(',') || []);
const param_4:string[] = (judgeConfigObj['515']?.split(',') || []);
const param_10:string[] = (judgeConfigObj['516']?.split(',') || []);
const param_11:string[] = (judgeConfigObj['517']?.split(',') || []);
const param_9:string[] = (judgeConfigObj['518']?.split(',') || []);
const param_12:string[] = (judgeConfigObj['519']?.split(',') || []);
const projectRoads:ProjectRoads = {
//直线行驶
param_3,
//变更车道
param_4,
//超车
param_10,
//靠边停车
param_11,
//会车
param_9,
//掉头
param_12,
};
//未测绘得道路上或者不在差分状态
if (road === '') {
return false
}
const currentProjectRoad:string[] = Reflect.get(projectRoads,`param_${projectCode}`)
if (currentProjectRoad.length == 0) {
return true
}
//设置了514-519参数只能在设置的路段触发对应项目
if (currentProjectRoad.includes(road)) {
//如果525为1则514-519设置的路段不能触发对应项目
if (judgeConfigObj['525'] == '1') {
return false
}
} else {
return false
}
//405参数为2是如果在最左侧车道超车项目不能触发;
if (projectCode == '10' &&
judgeConfigObj['405'] == '2' &&
(num === count) &&
num > 0
) {
return false
}
// 车道总数少于2条超车和变道不能触发
if (projectCode == '10' || projectCode == '4') {
if (count < 2) {
return false
}
}
return true
}
// 获取人工项目是否已做
getIsEndManualProject = (index: number) => {
const projectName = this.artSubject3Projects[index];
const projectCode = this.artSubject3ProjectsCodesArr[index];
const currentProject:ProjectInfo = Reflect.get(this.projectsObj,projectCode)
const type = currentProject.type
if (type == '2') {
return projectName
}
return (type == '3' || type == '4') ? `${projectName}_red` : `${projectName}_green`;
}
// 获取是否能进行人工评判
getIsManualKf = () => {
if (this.examSubject == '3') {
//杭州训练模式不允许人工评判
if (this.singlePlay && this.judgeConfigObj['211'] == 'zjhz') {
return false
}
if (this.judgeConfigObj['342'] == '0') {
return true
}
} else {
return false
}
}
}