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 './judgeSDK/utils/judgeConfig'; import { initJudgeUdp } from '../common/utils/UdpJudge'; import errorMsgDialog from './compontents/errorMsgDialog' import { delPic } from '../common/service/videoService'; import { getCurrentHourTime } from '../common/utils/tools'; @Entry @Component struct UserInfo { @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 = [] @State list: Array = [] @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 = false @State ksksLimit: boolean = false @State faceFlag: string = '0'; @State FaceOpenStatue: string = '0'; //是否开启人脸识别 @State faceCatchImg: string = '' @State systemParam:systemParam={ 'Param341':false,//是否按顺序考试 'Param803Str':'0',//开始考试前必须解开安全带或关车门 'Param612Str':'0',//开始考试触发方式 'Param770Str':'0',//车上没有缺考功能 'Param305Str':'0',//视频保存天数 'Param352Str':'0',//车上考试过一次就不能缺考 'Param828Str':'0',//828考生待考界面,安全员显示考试员 'Param830Str':'0',//同一学员连续第二次考试时不再验证身份 } private title = '' private type = '2' // 过程照片拍照 getPhoto = async (empty?: boolean) => { const singlePlay = globalThis.singlePlay //单机模式返回空照片 if (singlePlay) { return '' } else { const {filePhoto} = this; const photoBase64 = await filePhoto.getPhoto(); return photoBase64 } } private filePhoto: FilePhoto private avPlayer 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: 'ksy2' }, ] errorDialog: CustomDialogController = new CustomDialogController({ builder: errorMsgDialog({ title: this.title, type: this.type, cancel: () => { }, confirm: () => { } }), customStyle: true, alignment: DialogAlignment.Center, }, ) async onPageShow() { this.updateTimeLimit = false this.ksksLimit = false this.currentUser=EmptyCandidateObject const mediaTest = new FilePhoto(this.context); this.filePhoto = new FilePhoto(this.context); //语音功能on new WebRTCVoice(this.context); //初始化数据 this.initData() //身份证读卡器初始化 // this.openDeviceByIDCard() const routerParam = router.getParams() || { type: 0 }; console.log('routerParam', JSON.stringify(routerParam)) if (!globalThis.singlePlay) { // @ts-ignore if (routerParam.type != 1) { // @ts-ignore this.list = await getSyncData('USERLIST') // @ts-ignore const data = await getSyncData('USER') console.log('useruser,',JSON.stringify(this.list)) console.log('useruser1,',JSON.stringify(data)) const user = data[0] if (user && Number(user.kssycs)) { let flag=false this.list.forEach(res => { if (res.sfzmhm == user.sfzmhm) { flag=true res.kssycs = user.kssycs this.getCurrentStudent(res.sfzmhm) } }) if(!flag){ this.currentUser=(this.list.length?this.list[0]:EmptyCandidateObject) } } else if (user && (user.kssycs == '0' || user.kssycs == '')) { console.log('datadatadatadata') this.list = this.list.filter(res => { return res.sfzmhm != user.sfzmhm }) this.pageIndex = 0 this.dataList = this.list.slice(this.pageIndex * 4, this.pageIndex * 4 + 4) if (this.dataList.length) { setTimeout(()=>{ this.currentUser = this.dataList[0] this.currentUser.ksy2= globalThis.kgxm globalThis.lsh=this.currentUser.lsh },200) } else { this.currentUser = EmptyCandidateObject } } this.list.forEach((res, index) => { res.id = index.toString() }) await upDateTableByArray('USERLIST', this.list || []) } else { this.getExaminationStudentInfoFn() } } // 如果是单机模式则模拟假数据 //获取sysset表数据 this.initSysset() //心跳处理 this.heartMsg() // if(user[0]){ // // @ts-ignore // this.currentUser=user // } this.isExamStart = false this.sczbkf = []; this.avPlayer = new VoiceAnnounce(); initJudgeUdp() //监听远程开始考试 globalThis.udpEvent.onBeginExam(async ()=>{ console.info('surenjun','userInfo收到UdpEvent事件') if (this.isBoardPrePareSetPopupOpen && !this.isFirstBoardPrePareSetPopupBtnShow) { await this.prePareSCZB() }else{ await this.prePareExam() } }) } //身份证读卡器初始化 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() } } // 通过身份证获取当前学员 async getCurrentStudent(id) { let flag = false // this.pageIndex this.list.map((res, index) => { if (res.sfzmhm == id) { flag = true this.currentUser = res this.currentUser.ksy2= globalThis.kgxm this.lsh = this.currentUser.lsh globalThis.lsh = this.currentUser.lsh globalThis.ksyh = this.currentUser.ksy1sfzmhm 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.pageIndex = Math.floor(index / 4) } }) this.dataList = this.list.slice(this.pageIndex * 4, this.pageIndex * 4 + 4) if (!flag) { globalThis.lsh = '0000000000000' await upDateTableByArray('USER', []) setTimeout(()=>{ this.currentUser = this.list[0] this.currentUser.ksy2= globalThis.kgxm globalThis.lsh = this.currentUser.lsh },200) // 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 = '1111111111111' 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.currentUser.ksy2= '' this.lsh = this.currentUser.lsh globalThis.ksyh = this.currentUser.ksy1sfzmhm globalThis.lsh = this.lsh } // const syssetParams = await getSyncData('MA_SYSSET'); //@ts-ignore } async heartMsg() { globalThis.udpClient2 & globalThis.udpClient2.setMsgCallBack(async (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 || '' 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 openCheckFlagParam = syssetParams.filter(sys => sys.v_no == '17') //0 const openCheckFlag = openCheckFlagParam?.[0]?.v_value == '1' ? '1' : '0' const faceParam = syssetParams.filter(sys => sys.v_no == '2413') //3 console.log('FaceOpenStatue',openCheckFlag,this.FaceOpenStatue) // 1身份证读卡器 2指纹 3人脸 if (openCheckFlag == '1') { that.FaceOpenStatue = faceParam?.[0]?.v_value == '3' ? '1' : '0' this.faceFlag = faceParam?.[0]?.v_value || '0' if (faceParam?.[0]?.v_value == '1') { that.openDeviceByIDCard() } } syssetParams.forEach(sys => { //364 绕车一周评判时机(1-开始考试后判 2-开始考试前判) if (sys.v_no === '364' && decodeURIComponent(sys.v_value) == '2') { that.isBoardPrePareSetPopupOpen = true; } //398参数为1 第二场考试上车准备不考 if(sys.v_no === '398' && decodeURIComponent(sys.v_value) == '1' && this.currentUser.kssycs == '1'){ that.isBoardPrePareSetPopupOpen = false; } // 车上没有缺考功能 if (sys.v_no === '770') { that.systemParam.Param770Str = sys.v_value; } // 开始考试前必须解开安全带或关车门 if (sys.v_no === '803') { that.systemParam.Param803Str = sys.v_value + ''; } //判断是否考生是否按顺序考试 if (sys.v_no === '341'&&decodeURIComponent(sys.v_value) == '1') { that.systemParam.Param341= true }else{ that.systemParam.Param341= false } //开始考试触发方式 if (sys.v_no === '612') { that.systemParam.Param612Str= decodeURIComponent(sys.v_value) } //车上考试过一次就不能缺考 if (sys.v_no === '352') { that.systemParam.Param352Str= decodeURIComponent(sys.v_value) } //828考生待考界面,安全员显示考试员 if (sys.v_no === '828') { that.systemParam.Param828Str= decodeURIComponent(sys.v_value) if(that.systemParam.Param828Str=='1'){ that.labelBlocks[5].label='安全员名' }else{ that.labelBlocks[5].label='考试员名' } that.labelBlocks=JSON.parse(JSON.stringify(this.labelBlocks)) } //视频保存天数 if (sys.v_no === '305') { that.systemParam.Param305Str= decodeURIComponent(sys.v_value) if(!Number(this.systemParam.Param305Str)){ that.systemParam.Param305Str='2' } console.log('Param305Str',that.systemParam.Param305Str) // delHilog(this.Param305Str) delPic(that.systemParam.Param305Str,1) delPic(that.systemParam.Param305Str,2) } }) // faceParam?.[0]?.v_value || //0不自动更新 1自动更新(不限次数) 2没有考生更新2次 if (that.studentRefreshStatue == '2') { if(that.list.length == 0){ clearInterval(that.interval) that.interval = setInterval(() => { if (that.numCount < 3) { that.numCount++ if(that.list.length==0){ that.getExaminationStudentInfoFn() } } }, 5000) }else{ that.getExaminationStudentInfoFn() } } else if (that.studentRefreshStatue == '1') { if(that.list.length == 0){ clearInterval(that.interval) that.interval = setInterval(() => { if(that.list.length==0){ that.getExaminationStudentInfoFn() } }, 5000) }else{ that.getExaminationStudentInfoFn() } } else { // this.getExaminationItemFn() } }) }) } //人脸比对窗口关闭 changeFaceCompareSuccess() { this.ksksLimit = false console.log('this.faceCompareSuces', this.faceCompareSucess, JSON.stringify(this.currentUser)) if (this.faceCompareSucess > 0) { //人脸比对通过 globalThis.statue = 4 this.showFaceCompare = false 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) } //获取下载考生 async getExaminationStudentInfoFn() { if (globalThis.singlePlay || this.updateTimeLimit) { return } await upDateTableByArray('USER', []) await upDateTableByArray('USERLIST', []) this.type = '2' this.errorDialog.open() this.updateTimeLimit = true const param = `${Md5.Instance.get_md5(globalThis.carInfo.carId + globalThis.carInfo.examinationRoomId + globalThis.username)}${globalThis.carInfo.carId}${globalThis.carInfo.examinationRoomId}${globalThis.username}` try { getExaminationStudentInfo(param).then(async (res) => { this.errorDialog.close() setTimeout(() => { this.updateTimeLimit = false }, 3000) if (!res || res?.getExaminationStudentInfoRsp?.head?.resultCode == '1') { this.dataList = [] this.list = [] 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)) this.list.forEach((listData, index) => { listData.id = index.toString() for (let i in listData) { listData[i] = decodeURI(listData[i]) } if(this.systemParam.Param828Str=='1'||this.systemParam.Param828Str=='2'){ // listData.ksy2=listData.ksy1; listData.ksy2=globalThis.kgxm }else{ // listData.ksy2=listData.ksy2; listData.ksy2=globalThis.kgxm } listData.kszp = this.photo + listData.kszp listData.ksmjzp = this.photo + listData.ksmjzp }) await upDateTableByArray('USERLIST', this.list || []) dataList = this.list.length > 4 ? this.list.slice(this.pageIndex * 4, this.pageIndex * 4 + 4) : this.list; this.dataList = dataList if (this.dataList.length) { setTimeout(()=>{ this.currentUser = this.dataList[0] this.currentUser.ksy2= globalThis.kgxm globalThis.lsh=this.currentUser.lsh },200) // this.currentUser = this.dataList[0] console.log('this.currentUser1',JSON.stringify(this.currentUser)) } else { this.currentUser = EmptyCandidateObject } this.lsh = this.currentUser.lsh globalThis.lsh = this.lsh globalThis.ksyh = this.currentUser.ksy1sfzmhm this.pageIndex = 0 getSyncData('USER').then(data => { if (data?.[0]) { this.getCurrentStudent(data[0].sfzmhm) } }) }).catch((error) => { this.updateTimeLimit = false this.errorDialog.close() console.log('error12error' + error) }) } catch (error) { this.updateTimeLimit = false this.errorDialog.close() console.log('error14error' + error) } } qkFn() { if(this.systemParam.Param352Str=='1'&&this.currentUser.kssycs=='1'){ return } this.faceCompareSucess = 0 this.ksksLimit = false if (globalThis.singlePlay) { this.qkFlag = false return } console.log('JsonJson', JSON.stringify(this.currentUser)) const param = `${globalThis.carInfo.carId}${this.currentUser.sfzmhm}${globalThis.carInfo.examinationRoomId}${globalThis.username}${this.lsh}` 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() { globalThis.statue = 4 this.stepFlag = true const carInfo = globalThis.carInfo; const {carId,examinationRoomId} = carInfo; 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 () => { console.info('surenjun','播放结束开始考试接口调用') const {code,keystr,message} = await this.beginExam(); console.info('surenjun','开始考试接口调用结束') //@ts-ignore TODO code转换 if (code != 1) { promptAction.showToast({ message, duration: 4000 }) avPlayer.playAudio(['voice/监管审核未通过.mp3']); this.isLoadingPopupVisible = false this.isExamStart = false return } this.currentUser.id = '0' await upDateTableByArray('USER', [this.currentUser]) this.stepFlag = false this.isLoadingPopupVisible = false router.pushUrl({ url: 'pages/Judge', params: { examItems: examItems?.getExaminationItemRsp?.body?.ykxx, sczb: Number(this.isBoardPrePareSetPopupOpen), kfdm: this.sczbkf, //真实监管项目 kString: decodeURIComponent( keystr || '') } }, router.RouterMode.Single); this.updateTimeLimit = false this.stopDeviceById() this.stepFlag = false }) } // 检测车门、熄火信号 async checkSignal(): Promise { const {isCheckFireOpen} = judgeConfig const {systemParam,isBoardPrePareSetPopupOpen} = this; const Param803Str=systemParam.Param803Str 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) } } //TODO 考前绕车一周信号检测 // if (isBoardPrePareSetPopupOpen) { if (false) { //请熄火 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() globalThis.startHourTime = await getCurrentHourTime() const photoBase64 = await this.getPhoto(); if(photoBase64==''){ this.ksksLimit=false this.isLoadingPopupVisible=false return } const drvexam = { lsh: this.currentUser.lsh || '', kskm: examSubject, ksxtbh: this.ksxtbh || '222', sfzmhm: this.currentUser.sfzmhm || '', ksysfzmhm: this.currentUser.ksy1sfzmhm || '', ksxl: this.currentUser.xldm, zp: photoBase64, kssj: dateFormat(date) || '', kchp: decodeURI(plateNo), Ksy2sfzmhm: this.currentUser.ksy2sfzmhm || '' } const param = { drvexam, xtlb: '17', //接口序列号 jkxlh: this.jkxlh, //接口标识 jkid: '17C51', } console.info('surenjunjianguan', JSON.stringify(param)) const temp = await writeObjectOut(param); globalThis.lsh = this.currentUser.lsh globalThis.ksyh = this.currentUser.ksy1sfzmhm return temp } //开始上车准备 prePareSCZB = async () => { try { await this.checkSignal() this.isExamStart = true this.currentUser.id = '0' await upDateTableByArray('USER', [this.currentUser]) globalThis.statue = 4 this.isBoardPrePareSetPopupShow = true; this.isFirstBoardPrePareSetPopupBtnShow = true; this.stepFlag = false this.stopDeviceById() } catch (e) { } } //开始考试准备 prePareExam = async() => { if (this.ksksLimit) { return } console.log('routerParamrouterParam') try { await this.checkSignal() this.faceCompareSucess = 0 globalThis.statue = 2 if (!this.currentUser.xm) { return } this.ksksLimit = true if (globalThis.singlePlay) { const {examSubject} = globalThis.carInfo; this.currentUser.id = '0' 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.ksksLimit = false this.stopDeviceById() return } console.log('this.FaceOpenStatuethis.FaceOpenStatue',this.FaceOpenStatue) if (this.FaceOpenStatue != '0') { // 同一学员连续第二次考试时不再验证身份 if(this.currentUser.kssycs=='1'&&this.systemParam.Param830Str=='1'){ this.sfbdinterfaceFn() }else{ this.showFaceCompare = true } } else { this.sfbdinterfaceFn() } } catch (e) { console.info('Throw Error', JSON.stringify(e)) } } 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 && !globalThis.singlePlay&&this.systemParam.Param341) { return } this.currentUser=EmptyCandidateObject globalThis.lsh = item.lsh; setTimeout(()=>{ this.currentUser = item this.currentUser.ksy2= globalThis.kgxm },200) }) }) }.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.avPlayer.playAudio(['button_media.wav']) this.prevClick() }) Image($r('app.media.dk_next')).width(90 * this.ratio).height(70 * this.ratio).onClick(() => { // this.avPlayer.playAudio(['button_media.wav']) 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.avPlayer.playAudio(['button_media.wav']) if (this.isExamStart && !globalThis.singlePlay) { return } this.faceCompareSucess = 0 this.numCount = 0 this.getExaminationStudentInfoFn() }) Image($r('app.media.qk_btn')) .commStyle() .onClick(() => { // this.avPlayer.playAudio(['button_media.wav']) // 已开始考试不能缺考 已考过一次学员不能缺考 车上不能缺考 if (this.ksksLimit||(this.systemParam.Param352Str=='1'&&this.currentUser.kssycs=='1')||this.systemParam.Param770Str=='1') { return } this.ksksLimit = true this.qkFlag = true }) if (this.isBoardPrePareSetPopupOpen && !this.isFirstBoardPrePareSetPopupBtnShow) { //上车准备 Image($r('app.media.sczb_btn')).commStyle().onClick(async () => { if(this.systemParam.Param612Str=='1'){ return } await this.prePareSCZB() }) } else { Image($r('app.media.ksks_btn')) .commStyle() .onClick(async () => { if(this.systemParam.Param612Str=='1'){ return } await this.prePareExam() }) } } } 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.avPlayer.playAudio(['button_media.wav']) this.ksksLimit = false this.qkFlag = false }) Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) { Text(' 确 定 ').fontSize(24 * this.ratio).fontColor('#fff').width(100 * this.ratio) } .commStyle() .onClick(() => { // this.avPlayer.playAudio(['button_media.wav']) 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 }) .syncLoad(true) } } } // 横向滚动学员列表里面文字 @Component struct CommText { @Prop text: string @Prop color: string @Prop ratio: number build() { Text(this.text) .fontSize(19.5 * 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(20 * this.ratio).fontColor('#99948A') Row() { Text(decodeURIComponent(this.value||'')|| '') .fontColor('#fff') .textAlign(TextAlign.Center) .width('100%') .fontSize(18 * this.ratio) } .commLabelStyle() }.margin({ bottom: 10 * this.ratio }) } } type systemParam={ 'Param341':boolean,//是否按顺序考试 'Param803Str':string,//开始考试前必须解开安全带或关车门 'Param612Str':string,//开始考试触发方式 'Param305Str':string,//视频保存天数 'Param352Str':string,//车上考试过一次就不能缺考 'Param828Str':string,//828考生待考界面,安全员显示考试员 'Param770Str':string,//车上没有缺考功能 'Param830Str':string,//同一学员连续第二次考试时不再验证身份 }