2025-07-02 10:41:49 +08:00

1282 lines
46 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 DeductedPopup from './compontents/judge/DeductionPopup';
import AmplifyPopup from './compontents/judge/AmplifyPopup';
import Judge from './judgeSDK/judge';
import { uploadExamMileage } from '../api/judge';
import DwztErrorPopup from './compontents/judge/DwztErrorPopup';
import MsgPopup from './compontents/judge/MsgPopup';
import { JudgeConfig, JudgeTag } from '../config';
import {
AmplifyItem,
CARINFO,
CarInfoType,
CDSBInfo,
CDSBInfos,
DefaultJudgeConfigObj,
ES_CARINFOType,
ItemInfos,
JudgeBeginObj,
JudgeCallBacData,
JudgeInitObj,
LANE,
MA_CDSBINFOType,
MA_ITEMINFOType,
MA_MAP_POINT_ITEMType,
MA_MAP_POINTType,
MA_SYSTEMPARMType,
MAPITEMPOINTITEM,
MAPPOINT,
MarkRule,
MarkRules,
MASYSSETTableType,
Project,
ProjectInfo,
ProjectInfos,
ProjectRoads,
RouteParamsType,
SYSSET,
SyssetConfig,
SYSTEMPARMARR,
User
} from '../model';
import { GetSyncData } from '../utils/table/Operation';
import dayTs from '../utils/Date';
import { CutArray, GetCurrentTime } from '../utils/Common';
import FileUtils from '../utils/FileUtils';
import SignalTrajectoryDialog from './Judge/SignalTrajectoryDialog';
import { DefaultJudgeConfigData } from '../mock';
import { dConsole } from '../utils/LogWorker';
import ConfirmDialog from './compontents/ConfirmDialog';
import CarLoadingDialog from './compontents/CarLoading';
import HeaderComponent from './compontents/Header';
import MessageComponent from './Judge/Message';
import OperatingAreaComponent from './Judge/OperatingArea';
@Entry
@Component
struct JudgePage {
scroller: Scroller = new Scroller()
//页面通用字体大小
@State wayno: number = 0
@State FONTSIZE: number = 30
@State BIGFONTSIZE: number = 32
@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: ProjectInfos = {}
@State markRuleListObj: MarkRules = {}
@State cdsbInfoObj?: CDSBInfos = {}
@State itemInfoObj?: ItemInfos = {}
@State timer: number = 0
@State judgeConfig: SyssetConfig[] = []
@State judgeConfigObj: DefaultJudgeConfigObj = DefaultJudgeConfigData
//流水号
@State lsh: string = ''
@State kszp: string = ''
@State ksdd: string = ''
@State kssycs: string = ''
@State ksxl: string = ''
@State kslx: string = ''
//监管线路代码
@State xldm: string = ''
//监管接口序列号
@State serialNumber: string = ''
@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
//行驶距离
@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?: number = 0
// 必考项目除靠边停车是否全部完成
@State isRequiredProjectsEnd: boolean = false;
@State isAllProjectsEnd: boolean = false;
@State draw: 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 | null = 0;
@State carlist: string = ''
@State errorMsg: string = ''
@State carInfo: CarInfoType = {}
@State isErrorMsgEnd: boolean = false
@State disConnectErrorOpen: boolean = false
public context = getContext(this) as common.UIAbilityContext;
// 信号查看弹窗
signalTrajectoryDialogController: CustomDialogController = new CustomDialogController({
builder: SignalTrajectoryDialog(),
customStyle: true,
autoCancel: true
})
// 生成考试记录
generateExamRecordsDialogController: CustomDialogController = new CustomDialogController({
builder: CarLoadingDialog({
text: "正在生成考试记录,请稍等...",
}),
customStyle: true
})
private judge: Judge = new Judge(this)
// 结束考试弹窗
endExamDialogController: CustomDialogController = new CustomDialogController({
builder: ConfirmDialog({
text: "确认结束考试?",
onConfirm: async () => {
if (this.isErrorMsgEnd) {
dConsole.log(JudgeTag, "结束考试")
this.judge.closeAllFiles()
router.back()
return
}
if (Reflect.get(this.judgeConfigObj, '344') == 1) {
Prompt.showToast({
message: '考试未结束,不允许手动退出!',
duration: 4000
});
return
}
this.endExamDialogController.close()
// this.loadingPopupVisible = true
this.generateExamRecordsDialogController.open()
clearInterval(this.timer);
clearInterval(AppStorage.get('judgeTimer'))
try {
this.judge.checkExamIsEnd(true);
} catch (e) {
this.judge.closeAllFiles()
router.back()
}
}
}),
customStyle: true
})
async aboutToDisappear() {
this.generateExamRecordsDialogController.close()
clearInterval(this.mileageTimer)
}
async aboutToAppear() {
this.carInfo = AppStorage.get<CarInfoType>('carInfo')!
this.singlePlay = AppStorage.get<boolean>('singlePlay')!
this.startFullTime = GetCurrentTime(1);
// this.startHourTime = await getCurrentHourTime()
this.startTime = dayTs().format("YYYY-MM-DD HH:mm:ss")
this.startExamTime = dayTs().format("YYYY-MM-DD HH:mm:ss")
setInterval(async () => {
this.time = dayTs().format("YYYY-MM-DD HH:mm:ss");
this.examTime += 1;
}, 1000);
//初始化数据库表
await this.initDb()
//断点续考
await this.goDdxkItems()
//初始化评判
await this.initJudge();
}
//初始化相关数据库表
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_CARINFOType>("ES_CARINFO")
const carInfo = result[0] || {};
this.carName = decodeURI(carInfo.carclass!)
dConsole.log(JudgeTag, "查看carType", carInfo.cartype)
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!,
})
dConsole.info(JudgeTag, 'surenjun =>carinfoArrr', JSON.stringify(this.carinfoArr))
}
// 获取考生信息
async initStudent() {
const students = await GetSyncData<User>('USER')
const stuInfo = students[0];
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: Number(mark.itemno),
markcatalog: mark.markcatalog,
markshow: decodeURI(mark.markshow!),
markreal: Number(mark.markreal!),
markserial: mark.markserial,
kfxh: mark.kfxh,
OnlyOneKind: Number(mark.onlyoneid!),
NoCancelId: Number(mark.nocancelid!),
GPS_SID: mark.gps_sid == 0 ? false : true
}
//筛选出人工评判的扣分
if (Number(tempObj.markserial) > 100 && Number(tempObj.markserial) < 200) {
this.manualMarkRules.push(tempObj)
}
tempObj.markserial = mark.markserial
Reflect.set(this.markRuleListObj, `${mark.itemno}_${mark.markserial}`, tempObj)
})
}
// 考试项目是否全部完成
// 获取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');
dConsole.info(JudgeTag, 'surenjun serialNumberArr' + JSON.stringify(serialNumberArr))
this.serialNumber = (serialNumberArr[0] && serialNumberArr[0].v_value) || '';
const syssetJudgeConfigArr: SyssetConfig[] = []
syssetParams.forEach((sys: SYSSET | MASYSSETTableType) => {
if (JudgeConfig.isTrajectoryOpen) {
sys.v_no = String((sys as SYSSET).key!);
sys.v_name = (sys as SYSSET).name!;
sys.v_value = (sys as SYSSET).value!
}
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 kfdm = currentParams.kfdm;
currentParams.kfdm?.forEach(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 += Number(currentKf!.markreal);
})
const project_1: ProjectInfo = Reflect.get(this.projectsObj, 1)
project_1.type = kfdm!.length ? '4' : '3';
Reflect.set(this.projectsObj, 1, project_1)
}
Reflect.set(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 sCarTypes = ['C1', 'C2', 'C5']
if (this.singlePlay) {
this.wayno = Number(currentParams.wayno) || 1;
}
//真实监管下发的项目
let kStringArr: string[] = (currentParams.kString?.split(',') || []).filter(item => item);
dConsole.info(JudgeTag, 'surenjun kStringArr', JSON.stringify(kStringArr))
let isInExam = kStringArr.length > 0;
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 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 !== '')
dConsole.info(JudgeTag, '考试项目', 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 + ''))) {
dConsole.info(JudgeTag, 'surenjun =>', txt2)
dConsole.info(JudgeTag, '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 || ""),
})
})
dConsole.info(JudgeTag, '考试项目', JSON.stringify(this.ddxkKsxmArr))
dConsole.log(JudgeTag, "考试项目", this.projects)
if (!this.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) {
const cdsbInfo: CDSBInfo = {
kdid: cdsb.kdid,
sbbh: cdsb.sbbh,
sbbm: cdsb.sbbm,
itemsno: key,
modelKey: newKey,
xmdm,
xmxh: key.split('~')[1],
}
Reflect.set(this.cdsbInfoObj!, newKey, cdsbInfo)
}
})
}
// 获取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))) {
Reflect.set(this.itemInfoObj!, newKey, {
modelKey: newKey,
xmdm,
xmxh: key.split('~')[1],
})
}
})
}
// 评判相关初始化
async initJudge() {
await this.judge.onJudgeFn(async (judgeData: JudgeCallBacData) => {
this.xmmcStr = judgeData.xmmcStr || "";
this.carztStr = judgeData.carztStr || "";
dConsole.log(JudgeTag, "扣分", judgeData.kfArr)
this.kfArr = judgeData.kfArr || [];
});
}
// 断点续考判断
async goDdxkItems() {
const judgeConfigObj = this.judgeConfigObj
const config_432: string = Reflect.get(judgeConfigObj, '432')
//科目二强制开始断点续考
if (config_432 != '0' || this.examSubject == "2") {
//断点续考判断
let currentParams: RouteParamsType = router.getParams() as RouteParamsType;
const examItems: string | undefined = currentParams?.examItems;
// 2024-01-03 16:29:26;0;20300,;2,4^2,4;null;
if (examItems !== '' && examItems !== undefined) {
dConsole.info(JudgeTag, '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 (config_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 += Number(currentKf.markreal!)
})
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 => {
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 as MA_SYSTEMPARMType[])
await this.initMarkRules(initDataObj.mark);
await this.initSysset(initDataObj.sysset as 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
})
}
}
// 信号区域
@Builder
logoExpansionBuilder() {
Image($rawfile(this.isDwztRight ? 'judge/xh_green.png' : 'judge/xh_red.png')).width(50).margin({
left: 10
})
}
// 当前项目
@Builder
backAreaBuilder() {
Text(`当前项目:${this.xmmcStr || '无'} `).fontColor('#E5CCA1').fontSize(34)
}
build() {
Column() {
// 顶部
HeaderComponent({
logoExpansionBuilder: this.logoExpansionBuilder,
customizeReturnArea: true,
backAreaBuilder: this.backAreaBuilder
})
Row() {
Row() {
Column() {
// 考生信息展示区域
MessageComponent({
name: this.name,
idCard: this.idCard,
startTime: this.startTime,
examTime: this.examTime,
examSubject: this.examSubject,
examMileage: this.examMileage,
jl: this.jl,
wayno: this.wayno,
judgeConfigObj: this.judgeConfigObj,
})
Column() {
Row() {
Text(this.carztStr).fontColor('#FFA500').fontSize(this.FONTSIZE)
if (Reflect.get(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(CutArray(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%')
// 操作区域,分数显示区域
OperatingAreaComponent({
totalScore: this.totalScore,
kszp: this.kszp,
examSubject: this.examSubject,
singlePlay: this.singlePlay,
judgeConfigObj: this.judgeConfigObj,
signalViewingClick: () => {
this.signalTrajectoryDialogController.open()
},
artificialEvaluationClick: () => {
this.isDeductedPopShow = true
},
endTheExamClick: () => {
this.endExamDialogController.open()
}
})
}
.height('90%')
.justifyContent(FlexAlign.Start)
.padding({
top: 37,
left: 60,
bottom: 35,
right: 60
})
//科目三人工扣分弹窗
if (this.isDeductedPopShow && this.examSubject == '3' && Reflect.get(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),
currentItems: Object.entries(this.projectsObj).filter((item: [string, ProjectInfo]) => {
return item[1].type === '2'
}).map((item: [string, ProjectInfo]) => item[1].projectCode!),
markRules: this.manualMarkRules,
closePopup: () => {
this.isDeductedPopShow = false;
this.defaultTabIndex = 0;
},
confirmMark: async (itemno: string, serial: string) => {
clearTimeout(this.popTimer)
this.popTimer = setTimeout(async () => {
const judge = this.judge
await judge.setJudgeMark(itemno, serial);
this.isDeductedPopShow = false
this.popTimer = null;
}, 500)
}
})
}
//科目三人工项目确认框
if (this.isAmplifyPopShow && this.examSubject == '3') {
AmplifyPopup({
amplifyImgIndex: this.amplifiedImgIndex,
confirmAmplify: async (amplify: AmplifyItem) => {
clearTimeout(this.popTimer)
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.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';
case '2':
return '#FFAD33';
case '3':
return '#ff109d0a';
case '4':
return '#FF7566';
default:
return '#E6DECF';
}
}
//人工项目操作
async setManualProjectFn(index: number) {
const isManualProjectIn = this.isManualProjectIn;
const getIsExitManualProject = this.getIsExitManualProject;
const artSubject3ProjectsCodesArr = this.artSubject3ProjectsCodesArr;
const projectsObj = this.projectsObj;
const projectCode = artSubject3ProjectsCodesArr[index]
if (index === 5) {
dConsole.info(JudgeTag, 'surenjun 靠边停车状态=> ', getIsExitManualProject(index))
}
const currentProject: ProjectInfo = Reflect.get(projectsObj, projectCode)
if (getIsExitManualProject(index)) {
// 正在进行的项目 取消项目
if (isManualProjectIn && currentProject.type == '2') {
//判断人工是否能取消项目 && 当前项目有扣分的不能取消
if (Reflect.get(this.judgeConfigObj, '340') == 1) {
await this.judge.setJudgeItem(projectCode, 2);
Prompt.showToast({
message: '项目取消',
duration: 2000
})
return
}
}
// 靠边停车时候可以触发
if (Reflect.get(this.judgeConfigObj, '343') === '0') {
const xmmcStr = this.xmmcStr;
if (xmmcStr == '无' || xmmcStr == '') {
//512[6] 人工项目按钮放大确认
const param512: string[] = (Reflect.get(this.judgeConfigObj, '512') || '').split(',');
dConsole.info(JudgeTag, '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[] = Reflect.get(this.judgeConfigObj, '332').split(',') || [];
//直线行驶中不进其他考试项目(0-否 1-是)
const param348: string = Reflect.get(this.judgeConfigObj, '348') || '0',
//里程不够允许手工点靠边停车0-否 1-是)
param387: string = Reflect.get(this.judgeConfigObj, '387') || '0',
//里程不够不报靠边停车0-否+1-是+2-必考项目未完成且里程不够不报项目)
param319: string = Reflect.get(this.judgeConfigObj, '319') || '0',
//人工项目是否能取消 1:可取消;
param340: string = Reflect.get(this.judgeConfigObj, '340') || '0',
//307参数里设置的项目项目已经做过后续不能人工触发
param307: string[] = (Reflect.get(this.judgeConfigObj, '307') || '').split(',');
//非行驶状态(没有速度),人工项目不能触发(按钮灰色)
if (carztStr === '停车') {
return false
}
//车上是否能进行人工操作(0-能1-不能人工评判2-不能人工进项目3-都不能)
if (Reflect.get(this.judgeConfigObj, '342') === '3' || Reflect.get(this.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[] = (Reflect.get(this.judgeConfigObj, '514')?.split(',') || []);
const param_4: string[] = (Reflect.get(this.judgeConfigObj, '515')?.split(',') || []);
const param_10: string[] = (Reflect.get(this.judgeConfigObj, '516')?.split(',') || []);
const param_11: string[] = (Reflect.get(this.judgeConfigObj, '517')?.split(',') || []);
const param_9: string[] = (Reflect.get(this.judgeConfigObj, '518')?.split(',') || []);
const param_12: string[] = (Reflect.get(this.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 (Reflect.get(this.judgeConfigObj, '525') == '1') {
return false
}
} else {
return false
}
//405参数为2是如果在最左侧车道超车项目不能触发;
if (projectCode == '10' &&
Reflect.get(this.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`;
}
}