992 lines
		
	
	
		
			31 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			992 lines
		
	
	
		
			31 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| import { examinationStuAbsent, getExaminationItem, getExaminationStudentInfo } from '../api/userInfo';
 | ||
| import router from '@ohos.router';
 | ||
| import TopLogo from './compontents/TopLogo';
 | ||
| import Md5 from '../common/utils/md5';
 | ||
| import AccountTable from '../common/database/tables/AccountTable';
 | ||
| import USER from '../common/constants/USER';
 | ||
| import { dateFormat, getCurrentTime, string2Bytes } from '../common/utils/tools';
 | ||
| import MA_SYSSET from '../common//constants/MA_SYSSET';
 | ||
| import FaceCompare from './compontents/FaceCompare';
 | ||
| // import { initJudgeUdp } from '../common/utils/UdpJudge'
 | ||
| import { writeObjectOut } from '../api/judge';
 | ||
| import testNapi from '@ohos.idcard';
 | ||
| import common from '@ohos.app.ability.common';
 | ||
| import { User } from './interfaces';
 | ||
| import WebRTCVoice from './webRTC/';
 | ||
| import promptAction from '@ohos.promptAction';
 | ||
| import FilePhoto from './judgeSDK/utils/filePhoto';
 | ||
| import { getSyncData, upDateTableByArray } from '../common/service/initable';
 | ||
| import { CandidateData, EmptyCandidateObject } from '../mock/CandidateData';
 | ||
| import BoardPrePareSetPopup from './compontents/judge/BoardPrePareSetPopup'
 | ||
| import LoadingPopup from './compontents/judge/LoadingPopup';
 | ||
| import VoiceAnnounce from './judgeSDK/utils/voiceAnnouncements';
 | ||
| import { JudgeConfig } from '../config/judge';
 | ||
| import { judgeConfig } from './judgeSDK/utils/judgeConfig';
 | ||
| import { initJudgeUdp } from '../common/utils/UdpJudge';
 | ||
| @Entry
 | ||
| @Component
 | ||
| struct UserInfo {
 | ||
|   private filePhoto: FilePhoto
 | ||
|   private avPlayer
 | ||
| 
 | ||
|   @State pageIndex: number = 0
 | ||
|   @State ratio: number = 1700 / 960
 | ||
|   @State index: number = 0
 | ||
|   @State stepFlag: boolean = false;
 | ||
|   @State errorMsg: string = ''
 | ||
|   @State ksxtbh: string = ''
 | ||
|   @State pic: string = ''
 | ||
|   @State jkxlh: string = ''
 | ||
|   @State @Watch('changeFaceCompareSuccess') faceCompareSucess: number = 0;
 | ||
|   @State @Watch('changeQkfn') getqkFlag: boolean = false;
 | ||
|   @State @Watch('outClick') outFlag: boolean = false;
 | ||
|   @State showFaceCompare: boolean = false;
 | ||
|   @State url: string = ''
 | ||
|   @State lsh: string = ''
 | ||
|   @State qkFlag: boolean = false
 | ||
|   @State isBoardPrePareSetPopupOpen: boolean = false
 | ||
|   @State isFirstBoardPrePareSetPopupBtnShow: boolean = false
 | ||
|   @State isBoardPrePareSetPopupShow: boolean = false
 | ||
|   @State isLoadingPopupVisible:boolean = false;
 | ||
|   @State loadingText:string = '正在认证监管信息,请稍后...'
 | ||
|   @State sczbkf:{xmdm:number,kfdm:string}[] = []
 | ||
|   @State currentUser: User = EmptyCandidateObject
 | ||
|   @State dataList: Array<User> = []
 | ||
|   @State list: Array<User> = []
 | ||
|   @State name: string = 'initName';
 | ||
|   @State sex: string = '';
 | ||
|   @State callBackFlag: boolean = false;
 | ||
|   @State born?: string = '';
 | ||
|   @State address: string = '';
 | ||
|   @State nation: string = '';
 | ||
|   @State idCard: string = '';
 | ||
|   @State grantDept: string = '';
 | ||
|   //是否已经开始考试
 | ||
|   @State isExamStart:boolean = false;
 | ||
|   @State effectDate: string = '';
 | ||
|   @State interval: any = null;
 | ||
|   @State studentRefreshStatue: string = '0';
 | ||
|   @State photo: string = 'data:image/bmp;base64,';
 | ||
|   @State numCount: number = 0;
 | ||
|   @State signNum: number = 0;
 | ||
|   @State isCanClick: boolean = true;
 | ||
|   @State updateTimeLimit: boolean = true
 | ||
|   @State faceFlag: string = '0';
 | ||
|   @State FaceOpenStatue: string = '0'; //是否开启人脸识别
 | ||
|   subscriber;
 | ||
|   @State faceCatchImg: string = ''
 | ||
|   @State Param803Str:string = ''
 | ||
|   // 过程照片拍照
 | ||
|   getPhoto = async (empty?: boolean) => {
 | ||
|     const singlePlay = globalThis.singlePlay
 | ||
|     //单机模式返回空照片
 | ||
|     if (singlePlay) {
 | ||
|       return ''
 | ||
|     } else {
 | ||
|       const {filePhoto} = this;
 | ||
|       const photoBase64 = await filePhoto.getPhoto();
 | ||
|       return photoBase64
 | ||
|     }
 | ||
|   }
 | ||
|   private AccountTable = new AccountTable(() => {}, USER);
 | ||
|   private context = getContext(this) as common.UIAbilityContext;
 | ||
|   private labelBlocks = [
 | ||
|     { label: '考生姓名', key: 'xm' },
 | ||
|     { label: '身份证号', key: 'sfzmhm' },
 | ||
|     { label: ' 流 水 号 ', key: 'lsh' },
 | ||
|     { label: '考试路线', key: 'ksxl' },
 | ||
|     { label: '待考次数', key: 'kssycs' },
 | ||
|     { label: '考官姓名', key: 'ksy1' },
 | ||
|   ]
 | ||
| 
 | ||
|   async onPageShow() {
 | ||
|     const mediaTest = new FilePhoto(this.context);
 | ||
|     this.filePhoto = new FilePhoto(this.context);
 | ||
|     //语音功能
 | ||
|     new WebRTCVoice(this.context);
 | ||
|     //初始化数据
 | ||
|     this.initData()
 | ||
|     //身份证读卡器初始化
 | ||
|     // this.openDeviceByIDCard()
 | ||
|     // 如果是单机模式则模拟假数据
 | ||
|     //获取sysset表数据
 | ||
|     this.initSysset()
 | ||
|     //心跳处理
 | ||
|     this.heartMsg()
 | ||
|     this.isExamStart = false
 | ||
|     this.sczbkf = [];
 | ||
|     this.avPlayer = new VoiceAnnounce();
 | ||
|   }
 | ||
| 
 | ||
|   //身份证读卡器初始化
 | ||
|   openDeviceByIDCard() {
 | ||
|     globalThis.indexComponent = this;
 | ||
|     // 应用启动时打开读卡设备
 | ||
|     let ret = testNapi.OpenDevice();
 | ||
|     if (ret == 0) {
 | ||
|       testNapi.StartReadCard(this.onReadCard);
 | ||
|     } else {
 | ||
|       console.error("zzctest Failed to Open Device");
 | ||
|     }
 | ||
|   }
 | ||
| 
 | ||
|   stopDeviceById() {
 | ||
|     if (this.faceFlag == '1') {
 | ||
|       testNapi && testNapi.StopReadCard()
 | ||
|     }
 | ||
|   }
 | ||
| 
 | ||
|   // 通过身份证获取当前学员
 | ||
|   getCurrentStudent(id) {
 | ||
|     let flag = false
 | ||
|     this.pageIndex
 | ||
|     this.list.map((res, index) => {
 | ||
|       if (res.sfzmhm == id) {
 | ||
|         flag = true
 | ||
|         this.currentUser = res
 | ||
|         this.lsh = this.currentUser.lsh
 | ||
|         globalThis.lsh = this.currentUser.lsh
 | ||
|         globalThis.ksyh = this.currentUser.ksy1sfzmhm || this.currentUser.ksy2sfzmhm
 | ||
|         const {examSubject} = globalThis.carInfo;
 | ||
|         // this.currentUser.kszp=this.photo+res.kszp
 | ||
|         // this.currentUser.ksmjzp=this.photo+this.currentUser.ksmjzp
 | ||
|         if (globalThis.singlePlay) {
 | ||
|           this.stopDeviceById()
 | ||
|           // globalThis.statue=4
 | ||
|           router.pushUrl({
 | ||
|             url: examSubject == 3 ? 'pages/Roads' : 'pages/Judge',
 | ||
|             params: {
 | ||
|               sczb: Number(this.isBoardPrePareSetPopupOpen),
 | ||
|               kfdm: this.sczbkf
 | ||
|             }
 | ||
|           }, router.RouterMode.Single);
 | ||
|           return
 | ||
|         }
 | ||
| 
 | ||
|         this.showFaceCompare = true
 | ||
|         this.pageIndex = Math.floor(index / 4)
 | ||
|       }
 | ||
|     })
 | ||
|     this.dataList = this.list.slice(this.pageIndex * 4, this.pageIndex * 4 + 4)
 | ||
|     if (!flag) {
 | ||
|       promptAction.showToast({
 | ||
|         message: '未匹配到对应下载学员',
 | ||
|         duration: 3000
 | ||
|       });
 | ||
|     }
 | ||
|   }
 | ||
| 
 | ||
|   onReadCard(ret) {
 | ||
|     console.info(`zzctest xx Read Card ret =${ret.status}`)
 | ||
|     let thisVar = globalThis.indexComponent;
 | ||
| 
 | ||
|     if (ret.status == 0) { // status = 1 为读到身份证信息; status = 1 为身份证离开读卡器
 | ||
|       // 收到身份证离开读卡器的事件通知,根据实际业务需要决定是否需要清空之前已读取的身份证信息。
 | ||
|       // 如果身份证卡片离开读卡器时,需要继续保留UI界面上已读取到的身份信息,以下代码可以注释掉。
 | ||
|       thisVar.name = "";
 | ||
|       thisVar.sex = "";
 | ||
|       thisVar.nation = "";
 | ||
|       thisVar.born = "";
 | ||
|       thisVar.address = "";
 | ||
|       thisVar.idCard = "";
 | ||
|       thisVar.photo = "";
 | ||
| 
 | ||
|       return true;
 | ||
|     }
 | ||
| 
 | ||
|     if (ret.baseInfo.length > 2) {
 | ||
|       // 收到身份证信息,填充页面
 | ||
|       console.info(`zzctest Read Card 1`);
 | ||
|       let subIndex = ret.baseInfo.indexOf(":")
 | ||
|       let baseInfo: string = ret.baseInfo.substring(subIndex + 1, ret.baseInfo.length - 1);
 | ||
|       console.info(`zzctest Read Card 2 baseInfo=${baseInfo}`);
 | ||
|       let baseInfos: string[] = baseInfo.split("|");
 | ||
|       thisVar.name = baseInfos[0];
 | ||
|       thisVar.sex = baseInfos[1];
 | ||
|       thisVar.nation = baseInfos[2];
 | ||
|       thisVar.born = baseInfos[3];
 | ||
|       thisVar.address = baseInfos[4];
 | ||
|       thisVar.idCard = baseInfos[5];
 | ||
|       setTimeout(() => {
 | ||
|         thisVar.getCurrentStudent(baseInfos[5])
 | ||
|       }, 1000)
 | ||
|     }
 | ||
| 
 | ||
|     // 身份证照片数据处理
 | ||
|     if (ret.photo instanceof ArrayBuffer) {
 | ||
|       let dataView = new DataView(ret.photo)
 | ||
|       console.info(`Read Card ret = length = ${dataView.byteLength}`)
 | ||
|       let str = ""
 | ||
|       for (let i = 0; i < dataView.byteLength; ++i) {
 | ||
|         let c = String.fromCharCode(dataView.getUint8(i))
 | ||
|         if (c !== "\n") {
 | ||
|           str += c
 | ||
|         }
 | ||
|       }
 | ||
|       thisVar.photo += str;
 | ||
|     }
 | ||
|     console.info(`zzctest Read Card end`);
 | ||
|     return true;
 | ||
|   }
 | ||
| 
 | ||
|   changeQkfn() {
 | ||
|     this.qkFn()
 | ||
|   }
 | ||
| 
 | ||
|   async initData() {
 | ||
|     this.isFirstBoardPrePareSetPopupBtnShow = false;
 | ||
|     this.stepFlag = false
 | ||
|     this.faceCompareSucess = 0
 | ||
|     this.showFaceCompare = false
 | ||
|     this.lsh = '0000000000000'
 | ||
|     this.callBackFlag = false
 | ||
|     globalThis.lsh = this.lsh
 | ||
|     // this.currentUser = EmptyCandidateObject
 | ||
|     globalThis.statue = 2
 | ||
|     this.numCount = 0
 | ||
|     if (globalThis.singlePlay) {
 | ||
|       // TODO 模拟假数据
 | ||
|       this.list = CandidateData
 | ||
|       this.pageIndex = 0
 | ||
|       this.dataList = this.list.slice(this.pageIndex * 4, this.pageIndex * 4 + 4)
 | ||
|       this.currentUser = this.dataList[0]
 | ||
|       this.lsh = this.currentUser.lsh
 | ||
|       globalThis.ksyh = this.currentUser.ksy1sfzmhm || this.currentUser.ksy2sfzmhm
 | ||
|       globalThis.lsh = this.lsh
 | ||
|     } else {
 | ||
|       this.getExaminationStudentInfoFn()
 | ||
|     }
 | ||
|     const syssetParams = await getSyncData('MA_SYSSET');
 | ||
|     //@ts-ignore
 | ||
|     syssetParams.forEach(sys => {
 | ||
|       //364	绕车一周评判时机(1-开始考试后判 2-开始考试前判)
 | ||
|       if (sys.v_no === '364' && decodeURIComponent(sys.v_value) == '2') {
 | ||
|         this.isBoardPrePareSetPopupOpen = true;
 | ||
|       }
 | ||
|       // 开始考试前必须解开安全带或关车门
 | ||
|       if (sys.v_no === '803'){
 | ||
|         this.Param803Str = sys.v_value+'';
 | ||
|       }
 | ||
|     })
 | ||
| 
 | ||
|   }
 | ||
| 
 | ||
|   async heartMsg() {
 | ||
|     globalThis.udpClient2 & globalThis.udpClient2.setMsgCallBack((val) => {
 | ||
|       if (val.id == '32') {
 | ||
|         globalThis.signNum = val.body[1]
 | ||
|         if (val.body[0] == '7') {
 | ||
|           //缺考处理
 | ||
|           this.getqkFn()
 | ||
|           this.signNum = val.body[1]
 | ||
|         }
 | ||
|       } else if (val.id == '42') {
 | ||
|         //收到中心缺考确认消息
 | ||
|         console.log('qkfnqkfn', val.body[0])
 | ||
|         this.qkFn()
 | ||
|       }
 | ||
|     })
 | ||
|   }
 | ||
| 
 | ||
|   //考点端查询缺考指令内容消息请求
 | ||
|   getqkFn() {
 | ||
|     let tmpList = [];
 | ||
|     tmpList.push(string2Bytes(globalThis.signNum, 1 * 8)[0])
 | ||
|     const param = {
 | ||
|       id: 41,
 | ||
|       list: tmpList,
 | ||
|       carNo: globalThis.carInfo.carNo,
 | ||
|       placeId: globalThis.carInfo.examinationRoomId
 | ||
|     }
 | ||
| 
 | ||
|     globalThis.udpClient2.sendMsgExt(param, this.context)
 | ||
|   }
 | ||
| 
 | ||
|   async initSysset() {
 | ||
|     const that = this;
 | ||
|     const db = new AccountTable(() => {
 | ||
|     }, MA_SYSSET);
 | ||
|     db.getRdbStore(() => {
 | ||
|       db.query('0', (syssetParams) => {
 | ||
|         const serialNumberArr = syssetParams.filter(sys => sys.v_no === '901')
 | ||
|         that.jkxlh = serialNumberArr?.[0]?.v_value || '1234567'
 | ||
|         const ksxtbhArr = syssetParams.filter(sys => sys.v_no === '902')
 | ||
|         that.ksxtbh = ksxtbhArr?.[0]?.v_value || '222'
 | ||
|         const studentRefreshParam = syssetParams.filter(sys => sys.v_no === '452')
 | ||
|         that.studentRefreshStatue = studentRefreshParam?.[0]?.v_value || '0'
 | ||
|         const faceParam = syssetParams.filter(sys => sys.v_no == '2413')
 | ||
|         that.FaceOpenStatue = faceParam?.[0]?.v_value == '3' ? '1' : '0'
 | ||
|         that.FaceOpenStatue = '0'
 | ||
|         console.log('that.FaceOpenStatue', that.FaceOpenStatue)
 | ||
|         // faceParam?.[0]?.v_value ||
 | ||
|         // 1身份证读卡器 2指纹 3人脸
 | ||
|         this.faceFlag = faceParam?.[0]?.v_value || '0'
 | ||
|         if (faceParam?.[0]?.v_value == '1') {
 | ||
|           that.openDeviceByIDCard()
 | ||
|         }
 | ||
|         //0不自动更新 1自动更新(不限次数) 2没有考生更新2次
 | ||
|         if (that.studentRefreshStatue == '2') {
 | ||
|           clearInterval(that.interval)
 | ||
|           that.interval = setInterval(() => {
 | ||
|             if (that.dataList.length == 0 && that.numCount < 3) {
 | ||
|               that.numCount++
 | ||
|               that.getExaminationStudentInfoFn()
 | ||
|             }
 | ||
|           }, 5000)
 | ||
|         } else if (that.studentRefreshStatue == '1') {
 | ||
|           clearInterval(that.interval)
 | ||
|           that.interval = setInterval(() => {
 | ||
|             if (that.dataList.length == 0) {
 | ||
|               that.getExaminationStudentInfoFn()
 | ||
|             }
 | ||
|           }, 5000)
 | ||
|         } else {
 | ||
|           this.getExaminationItemFn()
 | ||
|         }
 | ||
| 
 | ||
|       })
 | ||
|     })
 | ||
|   }
 | ||
| 
 | ||
|   //人脸比对窗口关闭
 | ||
|   changeFaceCompareSuccess() {
 | ||
|     console.log('this.faceCompareSuces', this.faceCompareSucess, JSON.stringify(this.currentUser))
 | ||
|     if (this.faceCompareSucess > 0) {
 | ||
|       //人脸比对通过
 | ||
|       this.sfbdinterfaceFn()
 | ||
|     }
 | ||
|   }
 | ||
| 
 | ||
|   nextClick() {
 | ||
|     if (this.list.length <= 4 || this.pageIndex == Math.floor(this.list.length / 4)) {
 | ||
|       return
 | ||
|     }
 | ||
|     this.pageIndex++;
 | ||
|     this.dataList = this.list.slice(this.pageIndex * 4, this.pageIndex * 4 + 4)
 | ||
|   }
 | ||
| 
 | ||
|   prevClick() {
 | ||
|     if (this.list.length <= 4 || this.pageIndex == 0) {
 | ||
|       return
 | ||
|     }
 | ||
|     this.pageIndex--;
 | ||
|     this.dataList = this.list.slice(this.pageIndex * 4, this.pageIndex * 4 + 4)
 | ||
|     this.dataList.forEach(listData => {
 | ||
|       for (let i in listData) {
 | ||
|         listData[i] = decodeURI(listData[i])
 | ||
|       }
 | ||
|       listData.kszp = this.photo + listData.kszp
 | ||
|       listData.ksmjzp = this.photo + listData.ksmjzp
 | ||
|     })
 | ||
|   }
 | ||
| 
 | ||
|   //获取下载考生
 | ||
|   getExaminationStudentInfoFn() {
 | ||
|     if (globalThis.singlePlay && this.updateTimeLimit) {
 | ||
|       return
 | ||
|     }
 | ||
|     const param = `<getExaminationStudentInfoReq><head><checkCode>${Md5.Instance.get_md5(globalThis.carInfo.carId + globalThis.carInfo.examinationRoomId + globalThis.username)}</checkCode></head><body><carId>${globalThis.carInfo.carId}</carId><examinationRoomId>${globalThis.carInfo.examinationRoomId}</examinationRoomId><examinerName>${globalThis.username}</examinerName></body></getExaminationStudentInfoReq>`
 | ||
|     getExaminationStudentInfo(param).then(async res => {
 | ||
|       setTimeout(() => {
 | ||
|         this.updateTimeLimit = true
 | ||
|       }, 30000)
 | ||
|       this.updateTimeLimit = false
 | ||
|       if (!res) {
 | ||
|         this.dataList = []
 | ||
|         this.currentUser = EmptyCandidateObject
 | ||
|         this.errorMsg = decodeURI(res.getExaminationStudentInfoRsp.head.resultMessage)
 | ||
|         return
 | ||
|       }
 | ||
|       let dataList = []
 | ||
|       this.list = []
 | ||
| 
 | ||
|       for (let key in res.getExaminationStudentInfoRsp.body) {
 | ||
|         const a = res.getExaminationStudentInfoRsp.body[key]
 | ||
|         if (a instanceof Array) {
 | ||
|           dataList = a
 | ||
|         } else {
 | ||
|           dataList = [a]
 | ||
|         }
 | ||
|       }
 | ||
|       if (dataList.length) {
 | ||
|         this.numCount = 0
 | ||
|       }
 | ||
| 
 | ||
|       this.list = JSON.parse(JSON.stringify(dataList))
 | ||
|       dataList = this.list.length > 4 ? this.list.slice(this.pageIndex * 4, this.pageIndex * 4 + 4) : this.list;
 | ||
|       this.dataList = dataList
 | ||
|       if (this.dataList.length) {
 | ||
|         this.currentUser = this.dataList[0]
 | ||
|       } else {
 | ||
|         this.currentUser = EmptyCandidateObject
 | ||
|       }
 | ||
| 
 | ||
|       this.lsh = this.currentUser.lsh
 | ||
|       globalThis.lsh = this.lsh
 | ||
|       globalThis.ksyh = this.currentUser.ksy1sfzmhm || this.currentUser.ksy2sfzmhm
 | ||
|       console.log('this.currentUse3' + JSON.stringify(this.currentUser))
 | ||
|       this.pageIndex = 0
 | ||
|       getSyncData('USER').then(data=>{
 | ||
|         if(data?.[0]){
 | ||
|           this.getCurrentStudent(data[0].sfzmhm)
 | ||
|         }
 | ||
|       })
 | ||
|     }).catch((error) => {
 | ||
|       console.log('error12error' + error)
 | ||
|     })
 | ||
|   }
 | ||
| 
 | ||
|   qkFn() {
 | ||
|     this.faceCompareSucess = 0
 | ||
|     if (globalThis.singlePlay) {
 | ||
|       this.qkFlag = false
 | ||
|       return
 | ||
|     }
 | ||
|     console.log('JsonJson', JSON.stringify(this.currentUser))
 | ||
|     const param = `<?xml version="1.0" encoding="UTF-8" ?><examinationStuAbsentReq><body><carId>${globalThis.carInfo.carId}</carId><cardNo>${this.currentUser.sfzmhm}</cardNo><examinationRoomId>${globalThis.carInfo.examinationRoomId}</examinationRoomId><examinerName>${globalThis.username}</examinerName><lsh>${this.lsh}</lsh></body></examinationStuAbsentReq>`
 | ||
|     console.log('carNo1111', param)
 | ||
| 
 | ||
|     examinationStuAbsent(param).then(res => {
 | ||
|       const arr = [this.signNum || 0, 1]
 | ||
|       let tmpList = [];
 | ||
|       tmpList.push(string2Bytes(arr[0], 1 * 8)[0])
 | ||
|       tmpList.push(string2Bytes(arr[1], 1 * 8)[0])
 | ||
|       console.log('globalThis.signNum', globalThis.signNum)
 | ||
|       const param = {
 | ||
|         id: 43,
 | ||
|         list: tmpList,
 | ||
|         carNo: globalThis.carInfo.carNo,
 | ||
|         placeId: globalThis.carInfo.examinationRoomId
 | ||
|       }
 | ||
| 
 | ||
|       globalThis.udpClient2.sendMsgExt(param, this.context)
 | ||
|       if (res.examinationStuAbsentRsp.head.resultCode == '0') {
 | ||
|         this.pageIndex = 0
 | ||
|         this.qkFlag = false
 | ||
|         this.currentUser = EmptyCandidateObject
 | ||
|         this.getExaminationStudentInfoFn()
 | ||
|         return
 | ||
|       }
 | ||
|     }).catch((error) => {
 | ||
|       console.log('error12error' + error)
 | ||
|     })
 | ||
| 
 | ||
|   }
 | ||
| 
 | ||
|   async getExaminationItemFn() {
 | ||
|     if (!this.currentUser.lsh || globalThis.singlePlay) {
 | ||
|       return
 | ||
|     }
 | ||
|     const carInfo = globalThis.carInfo;
 | ||
|     const {carId,examinationRoomId} = carInfo;
 | ||
|     const examItems = await getExaminationItem({
 | ||
|       time: getCurrentTime(),
 | ||
|       carId,
 | ||
|       lsh: this.currentUser.lsh || '',
 | ||
|       examinationRoomId
 | ||
|     });
 | ||
| 
 | ||
|     if (examItems?.getExaminationItemRsp?.body?.kssycs != 0) {
 | ||
|       this.getExaminationStudentInfoFn()
 | ||
|     } else {
 | ||
|       this.dataList = []
 | ||
|       this.currentUser = EmptyCandidateObject
 | ||
|     }
 | ||
| 
 | ||
|   }
 | ||
| 
 | ||
|   //身份比对
 | ||
|   async sfbdinterfaceFn() {
 | ||
|     this.stepFlag = true
 | ||
|     const carInfo = globalThis.carInfo;
 | ||
|     const {carId,examinationRoomId} = carInfo;
 | ||
|     this.showFaceCompare = false
 | ||
|     let examItems = { getExaminationItemRsp: { body: { ykxx: '' } } };
 | ||
|     if (!globalThis.singlePlay) {
 | ||
|       //获取已考项目
 | ||
|       examItems = await getExaminationItem({
 | ||
|         time: getCurrentTime(),
 | ||
|         carId,
 | ||
|         lsh: this.currentUser.lsh || '',
 | ||
|         examinationRoomId
 | ||
|       });
 | ||
|     }
 | ||
|     this.currentUser.id = '1'
 | ||
|     const avPlayer = this.avPlayer;
 | ||
|     this.isLoadingPopupVisible = true
 | ||
|     avPlayer.playAudio([`voice/监管通信中.mp3`],false,async ()=>{
 | ||
|       const temp = await this.beginExam();
 | ||
|       console.info('surenjun',JSON.stringify(temp))
 | ||
|       if (temp.code != 1) {
 | ||
|         promptAction.showToast({
 | ||
|           message:temp.message,
 | ||
|           duration:4000
 | ||
|         })
 | ||
|         return
 | ||
|       }
 | ||
|       await upDateTableByArray('USER', [this.currentUser])
 | ||
|       globalThis.statue = 4
 | ||
|       this.stepFlag = false
 | ||
|       this.isLoadingPopupVisible = false
 | ||
|       router.pushUrl({
 | ||
|         url: 'pages/Judge',
 | ||
|         params: {
 | ||
|           examItems: examItems?.getExaminationItemRsp?.body?.ykxx,
 | ||
|           sczb: Number(this.isBoardPrePareSetPopupOpen),
 | ||
|           kfdm: this.sczbkf
 | ||
|         }
 | ||
|       }, router.RouterMode.Single);
 | ||
|       this.stopDeviceById()
 | ||
|       this.stepFlag = false
 | ||
|     })
 | ||
|   }
 | ||
| 
 | ||
|   // 检测车门、熄火信号
 | ||
|   async checkSignal(): Promise<boolean> {
 | ||
|     const {isCheckFireOpen} = judgeConfig
 | ||
|     const {Param803Str,isBoardPrePareSetPopupOpen} = this;
 | ||
| 
 | ||
|     if(Param803Str === ''){
 | ||
|       return true
 | ||
|     }
 | ||
|     return new Promise((resolve,reject)=>{
 | ||
|       if(isCheckFireOpen){
 | ||
|         resolve(true)
 | ||
|         return
 | ||
|       }
 | ||
|       let plcValue =  globalThis.udpClient.getCurrentMessage();
 | ||
|       const msgArr = plcValue.split(',') || ''
 | ||
|       const mkg = msgArr[14];
 | ||
|       const fdjzs = msgArr[25];
 | ||
|       const aqd = msgArr[19];
 | ||
|       const jgd = msgArr[7];
 | ||
|       const ygd = msgArr[8];
 | ||
|       const ssc = msgArr[13];
 | ||
|       const dw = msgArr[28];
 | ||
|       // 开始考试信号检测
 | ||
|       if(Param803Str !== ''){
 | ||
|         //安全带
 | ||
|         if(aqd == 1 && Param803Str.includes('1')){
 | ||
|           this.avPlayer.playAudio(['voice/请解开安全带.mp3'])
 | ||
|           promptAction.showToast({
 | ||
|             message:'请解开安全带',
 | ||
|             duration:4000
 | ||
|           })
 | ||
|           reject(false)
 | ||
|         }
 | ||
|         //门开关
 | ||
|         if(mkg == 1 && Param803Str.includes('2')){
 | ||
|           this.avPlayer.playAudio(['voice/关门.mp3'])
 | ||
|           promptAction.showToast({
 | ||
|             message:'请关闭车门',
 | ||
|             duration:4000
 | ||
|           })
 | ||
|           reject(false)
 | ||
|         }
 | ||
|         //远、近光灯
 | ||
|         if((jgd == 1 || ygd == 1) && Param803Str.includes('3')){
 | ||
|           this.avPlayer.playAudio(['voice/请关闭远近光灯.mp3'])
 | ||
|           promptAction.showToast({
 | ||
|             message:'请关闭远近光灯',
 | ||
|             duration:4000
 | ||
|           })
 | ||
|           reject(false)
 | ||
|         }
 | ||
|         //拉手刹
 | ||
|         if(ssc == 0 && Param803Str.includes('4')){
 | ||
|           this.avPlayer.playAudio(['voice/请拉手刹.mp3'])
 | ||
|           promptAction.showToast({
 | ||
|             message:'请拉手刹',
 | ||
|             duration:4000
 | ||
|           })
 | ||
|           reject(false)
 | ||
| 
 | ||
|         }
 | ||
|         //请点火
 | ||
|         if(fdjzs*1 <=0 && Param803Str.includes('5')){
 | ||
|           this.avPlayer.playAudio(['voice/点火.mp3'])
 | ||
|           promptAction.showToast({
 | ||
|             message:'请点火',
 | ||
|             duration:4000
 | ||
|           })
 | ||
|           reject(false)
 | ||
|         }
 | ||
|         //置空档
 | ||
|         if(dw != 0 && Param803Str.includes('6')){
 | ||
|           this.avPlayer.playAudio(['voice/请置空档.mp3'])
 | ||
|           promptAction.showToast({
 | ||
|             message:'请置空档',
 | ||
|             duration:4000
 | ||
|           })
 | ||
|           reject(false)
 | ||
|         }
 | ||
|       }
 | ||
|       // 考前绕车一周信号检测
 | ||
|       if(isBoardPrePareSetPopupOpen){
 | ||
|         //请熄火
 | ||
|         if(fdjzs*1 > 0){
 | ||
|           this.avPlayer.playAudio(['voice/熄火.mp3'])
 | ||
|           promptAction.showToast({
 | ||
|             message:'请熄火',
 | ||
|             duration:4000
 | ||
|           })
 | ||
|           reject(false)
 | ||
|         }
 | ||
|         if(mkg == 1){
 | ||
|           this.avPlayer.playAudio(['voice/关门.mp3'])
 | ||
|           promptAction.showToast({
 | ||
|             message:'请关闭车门',
 | ||
|             duration:4000
 | ||
|           })
 | ||
|           reject(false)
 | ||
|         }
 | ||
|       }
 | ||
|       resolve(true)
 | ||
|     })
 | ||
|   }
 | ||
| 
 | ||
|   // 开始考试
 | ||
|   async beginExam() {
 | ||
|     const carInfo = globalThis.carInfo;
 | ||
|     const {carId,examinationRoomId} = carInfo;
 | ||
|     const { examSubject,plateNo } = carInfo;
 | ||
|     const date = new Date()
 | ||
|     console.info('surenjun', 'photoBase64')
 | ||
|     const photoBase64 = await this.getPhoto();
 | ||
|     console.info('surenjun', 'photoBase64End')
 | ||
|     const drvexam = {
 | ||
|       lsh: this.currentUser.lsh || '',
 | ||
|       kskm: examSubject,
 | ||
|       ksxtbh: this.ksxtbh || '222',
 | ||
|       sfzmhm: this.currentUser.sfzmhm || '',
 | ||
|       ksysfzmhm: this.currentUser.ksy1sfzmhm || '',
 | ||
|       ksxl: this.currentUser.ksxl,
 | ||
|       zp: photoBase64,
 | ||
|       kssj: dateFormat(date) || '',
 | ||
|       kchp: decodeURI(plateNo),
 | ||
|       Ksy2sfzmhm: this.currentUser.ksy2sfzmhm || ''
 | ||
|     }
 | ||
|     const param = {
 | ||
|       drvexam,
 | ||
|       xtlb: '17',
 | ||
|       //接口序列号
 | ||
|       jkxlh: this.jkxlh || '1234567',
 | ||
|       //接口标识
 | ||
|       jkid: '17C51',
 | ||
|     }
 | ||
|     console.info('surenjun',JSON.stringify(param))
 | ||
|     const temp = await writeObjectOut(param);
 | ||
|     globalThis.lsh = this.currentUser.lsh
 | ||
|     globalThis.ksyh = this.currentUser.ksy1sfzmhm || this.currentUser.ksy2sfzmhm;
 | ||
|     return temp
 | ||
|   }
 | ||
| 
 | ||
|   aboutToDisappear() {
 | ||
|     this.outClick()
 | ||
|   }
 | ||
| 
 | ||
|   outClick() {
 | ||
|     clearInterval(this.interval)
 | ||
|     this.stopDeviceById()
 | ||
|     globalThis.udpClient2 && globalThis.udpClient2?.setMsgCallBack(() => {
 | ||
|     })
 | ||
|   }
 | ||
| 
 | ||
|   // 几个按钮公共样式
 | ||
|   @Styles
 | ||
|   commStyle(){
 | ||
|     .width(220 * this.ratio)
 | ||
|     .height(69 * this.ratio)
 | ||
|     .backgroundImage($r('app.media.button_nor'))
 | ||
|     .backgroundImageSize({ width: '100%', height: '100%' })
 | ||
|     .margin({ bottom: 12 * this.ratio })
 | ||
|   }
 | ||
| 
 | ||
|   build() {
 | ||
|     Column() {
 | ||
| 
 | ||
|       TopLogo({ outFlag: $outFlag }).margin({ bottom: 10 })
 | ||
|       Row() {
 | ||
|         Row() {
 | ||
|           ForEach(this.dataList, (item) => {
 | ||
|             Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
 | ||
|               Column() {
 | ||
|                 CommText({
 | ||
|                   ratio: this.ratio,
 | ||
|                   color: item.sfzmhm != this.currentUser.sfzmhm ? '#FFFFFF' : '#000000',
 | ||
|                   text: item.lsh
 | ||
|                 })
 | ||
|                 CommText({
 | ||
|                   ratio: this.ratio,
 | ||
|                   color: item.sfzmhm != this.currentUser.sfzmhm ? '#FFFFFF' : '#000000',
 | ||
|                   text: decodeURIComponent(item.xm)
 | ||
|                 })
 | ||
|               }
 | ||
|             }
 | ||
|             .width(165 * this.ratio)
 | ||
|             .height(85 * this.ratio)
 | ||
|             .backgroundImage(item.sfzmhm != this.currentUser.sfzmhm ? $r('app.media.userbox2') : $r('app.media.userboxbg'))
 | ||
|             .backgroundImageSize({ width: '100%', height: '100%' })
 | ||
|             .onClick(() => {
 | ||
|               if(this.isExamStart){
 | ||
|                 return
 | ||
|               }
 | ||
|               this.currentUser = item
 | ||
|             })
 | ||
|           })
 | ||
|         }.width(640 * this.ratio).margin({ left: 30 * this.ratio })
 | ||
| 
 | ||
|         Image($r('app.media.dk_prev'))
 | ||
|           .width(90 * this.ratio)
 | ||
|           .height(70 * this.ratio)
 | ||
|           .margin({ left: 65 * this.ratio, right: 10 * this.ratio })
 | ||
|           .onClick(() => {
 | ||
|             this.prevClick()
 | ||
|           })
 | ||
|         Image($r('app.media.dk_next')).width(90 * this.ratio).height(70 * this.ratio).onClick(() => {
 | ||
|           this.nextClick()
 | ||
|         })
 | ||
|       }.margin({ top: 40 * this.ratio, bottom: 10 * this.ratio })
 | ||
| 
 | ||
|       Flex({ justifyContent: FlexAlign.SpaceBetween }) {
 | ||
|         Row() {
 | ||
|           Column() {
 | ||
|             if (this.currentUser['kszp']) {
 | ||
| 
 | ||
|               Avatar({
 | ||
|                 ratio: this.ratio,
 | ||
|                 url: this.currentUser['kszp'] ? this.currentUser['kszp'] : ''
 | ||
|               })
 | ||
|             } else {
 | ||
|               Avatar({
 | ||
|                 ratio: this.ratio,
 | ||
|                 url: ""
 | ||
|               })
 | ||
|             }
 | ||
|             if (this.currentUser['ksmjzp']) {
 | ||
|               Avatar({
 | ||
|                 ratio: this.ratio,
 | ||
|                 url: this.currentUser['ksmjzp'] ? this.currentUser['ksmjzp'] : ''
 | ||
|               })
 | ||
|             } else {
 | ||
| 
 | ||
|               Avatar({
 | ||
|                 ratio: this.ratio,
 | ||
|                 url: ""
 | ||
|               })
 | ||
|             }
 | ||
|           }
 | ||
| 
 | ||
|           Column() {
 | ||
|             ForEach(this.labelBlocks, (item) => {
 | ||
|               LabelBlock({ label: item.label, ratio: this.ratio, value: this.currentUser[item.key] })
 | ||
|             })
 | ||
|           }
 | ||
|         }
 | ||
|         .width(664 * this.ratio)
 | ||
|         .height(339 * this.ratio)
 | ||
|         .backgroundImage($r('app.media.dkbg'))
 | ||
|         .backgroundImageSize({ width: '100%', height: '100%' })
 | ||
|         .margin({ left: 53 * this.ratio })
 | ||
| 
 | ||
|         Column() {
 | ||
|           Image($r('app.media.yydj_btn'))
 | ||
|             .commStyle()
 | ||
|           Image($r('app.media.gx_btn'))
 | ||
|             .commStyle()
 | ||
|             .onClick(() => {
 | ||
|               this.faceCompareSucess = 0
 | ||
|               this.numCount = 0
 | ||
|               this.getExaminationStudentInfoFn()
 | ||
|             })
 | ||
|           Image($r('app.media.qk_btn'))
 | ||
|             .commStyle()
 | ||
|             .onClick(() => {
 | ||
|               this.qkFlag = true
 | ||
|             })
 | ||
| 
 | ||
|           if (this.isBoardPrePareSetPopupOpen && !this.isFirstBoardPrePareSetPopupBtnShow) {
 | ||
|             //上车准备
 | ||
|             Image($r('app.media.sczb_btn')).commStyle().onClick(async () => {
 | ||
|               try {
 | ||
|                 await this.checkSignal()
 | ||
|                 this.isExamStart = true
 | ||
|                 await upDateTableByArray('USER', [this.currentUser])
 | ||
|                 globalThis.statue = 4
 | ||
|                 this.isBoardPrePareSetPopupShow = true;
 | ||
|                 this.isFirstBoardPrePareSetPopupBtnShow = true;
 | ||
|                 this.stepFlag = false
 | ||
|                 this.stopDeviceById()
 | ||
|                 initJudgeUdp()
 | ||
|               } catch (e) {
 | ||
| 
 | ||
|               }
 | ||
|             })
 | ||
|           } else {
 | ||
|             Image($r('app.media.ksks_btn'))
 | ||
|               .commStyle()
 | ||
|               .onClick(async () => {
 | ||
|                 try {
 | ||
|                   await this.checkSignal()
 | ||
|                   this.faceCompareSucess = 0
 | ||
|                   globalThis.statue = 2
 | ||
|                   if (!this.currentUser.xm) {
 | ||
|                     return
 | ||
|                   }
 | ||
|                   if (globalThis.singlePlay) {
 | ||
|                     const {examSubject} = globalThis.carInfo;
 | ||
|                     await upDateTableByArray('USER', [this.currentUser])
 | ||
|                     router.pushUrl({
 | ||
|                       url: examSubject == 3 ? 'pages/Roads' : 'pages/Judge',
 | ||
|                       params: {
 | ||
|                         sczb: Number(this.isBoardPrePareSetPopupOpen),
 | ||
|                         kfdm: this.sczbkf
 | ||
|                       }
 | ||
|                     }, router.RouterMode.Single);
 | ||
|                     this.stopDeviceById()
 | ||
|                     return
 | ||
|                   }
 | ||
|                   if (this.FaceOpenStatue != '0') {
 | ||
|                     this.showFaceCompare = true
 | ||
|                   } else {
 | ||
|                     initJudgeUdp()
 | ||
|                     this.sfbdinterfaceFn()
 | ||
|                   }
 | ||
|                 } catch (e) {
 | ||
|                   console.info('Throw Error',JSON.stringify(e))
 | ||
|                 }
 | ||
| 
 | ||
|               })
 | ||
|           }
 | ||
|         }
 | ||
|       }
 | ||
| 
 | ||
|       if (this.showFaceCompare) {
 | ||
|         FaceCompare({
 | ||
|           sfzh: this.currentUser.sfzmhm,
 | ||
|           firstImage: this.currentUser.kszp,
 | ||
|           faceCompareSucess: $faceCompareSucess,
 | ||
|           getqkFlag: $getqkFlag,
 | ||
|           faceCatchImg: $faceCatchImg,
 | ||
|           showFaceCompare: $showFaceCompare,
 | ||
|           lsh: globalThis.lsh,
 | ||
|         })
 | ||
|       }
 | ||
|       if (this.qkFlag) {
 | ||
|         Column() {
 | ||
|           Text('确认考生:' + this.currentUser.xm + '是否缺考')
 | ||
|             .fontSize(28 * this.ratio)
 | ||
|             .position({ x: 160 * this.ratio, y: 122 * this.ratio })
 | ||
|           Row() {
 | ||
|             Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
 | ||
|               Text('  取   消  ').fontSize(24 * this.ratio).fontColor('#fff').width(100 * this.ratio)
 | ||
|             }
 | ||
|             .commStyle()
 | ||
|             .onClick(() => {
 | ||
|               this.qkFlag = false
 | ||
|             })
 | ||
| 
 | ||
|             Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
 | ||
|               Text('  确   定  ').fontSize(24 * this.ratio).fontColor('#fff').width(100 * this.ratio)
 | ||
|             }
 | ||
|             .commStyle()
 | ||
|             .onClick(() => {
 | ||
|               this.qkFn()
 | ||
|             })
 | ||
|           }.position({ y: 265 * this.ratio, x: 115 * this.ratio })
 | ||
| 
 | ||
|         }
 | ||
|         .width(660 * this.ratio)
 | ||
|         .height(360 * this.ratio)
 | ||
|         .position({ x: 150 * this.ratio, y: 98 * this.ratio })
 | ||
|         .backgroundColor('#E6E3DF')
 | ||
|         .borderRadius(19 * this.ratio)
 | ||
|       }
 | ||
| 
 | ||
|       // 上车准备弹窗
 | ||
|       if (this.isBoardPrePareSetPopupShow) {
 | ||
|         BoardPrePareSetPopup({
 | ||
|           closePopup: (bool) => {
 | ||
|             this.isBoardPrePareSetPopupShow = false;
 | ||
|           },
 | ||
|           confirmMark: (kfdm) => {
 | ||
|             this.sczbkf = kfdm
 | ||
|           }
 | ||
|         })
 | ||
|       }
 | ||
| 
 | ||
|       // loading
 | ||
|       if(this.isLoadingPopupVisible){
 | ||
|         LoadingPopup({
 | ||
|           title: this.loadingText,
 | ||
|         })
 | ||
|       }
 | ||
|     }
 | ||
|     .height('100%')
 | ||
|     .width('100%')
 | ||
|     .backgroundImage($r('app.media.bg'))
 | ||
|     .backgroundImageSize({ width: '100%', height: '100%' })
 | ||
|   }
 | ||
| }
 | ||
| 
 | ||
| // 头像组件
 | ||
| @Component
 | ||
| struct Avatar {
 | ||
|   @State ratio: number = 0
 | ||
|   @State url: string = ""
 | ||
| 
 | ||
|   build() {
 | ||
|     Row() {
 | ||
|       Image(this.url)
 | ||
|         .width(93 * this.ratio)
 | ||
|         .height(130.5 * this.ratio)
 | ||
|         .margin({ bottom: 10 * this.ratio, right: 58 * this.ratio, left: 55 * this.ratio })
 | ||
|         .backgroundColor('orange')
 | ||
|         .border({ color: '#fff', width: 1, style: BorderStyle.Solid })
 | ||
|     }
 | ||
|   }
 | ||
| }
 | ||
| 
 | ||
| // 横向滚动学员列表里面文字
 | ||
| @Component
 | ||
| struct CommText {
 | ||
|   @Prop text: string
 | ||
|   @Prop color: string
 | ||
|   @Prop ratio: number
 | ||
| 
 | ||
|   build() {
 | ||
|     Text(this.text)
 | ||
|       .fontSize(16 * this.ratio)
 | ||
|       .lineHeight(30 * this.ratio)
 | ||
|       .fontWeight(500)
 | ||
|       .fontColor(this.color)
 | ||
|   }
 | ||
| }
 | ||
| 
 | ||
| // 考生信息的labelBlock组件
 | ||
| @Component
 | ||
| struct LabelBlock {
 | ||
|   @State label: string = ''
 | ||
|   @State ratio: number = 0
 | ||
|   @Prop value: string = ''
 | ||
| 
 | ||
|   @Styles
 | ||
|   commLabelStyle(){
 | ||
|     .width(280 * this.ratio)
 | ||
|     .height(35 * this.ratio)
 | ||
|     .backgroundImageSize({ width: '100%', height: '100%' })
 | ||
|     .backgroundImage($r('app.media.userbox'))
 | ||
|     .margin({ left: 8 * this.ratio })
 | ||
|     .align(Alignment.Center)
 | ||
|   }
 | ||
| 
 | ||
|   build() {
 | ||
|     Row() {
 | ||
|       Text(this.label).fontSize(16 * this.ratio).fontColor('#99948A')
 | ||
|       Row() {
 | ||
|         Text(decodeURIComponent(this.value)).fontColor('#fff').textAlign(TextAlign.Center).width('100%')
 | ||
|       }
 | ||
|       .commLabelStyle()
 | ||
|     }.margin({ bottom: 10 * this.ratio })
 | ||
|   }
 | ||
| } |