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/FaceCompareByhaikang'; // 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, VideoConfig } from './interfaces'; import WebRTCVoice from './webRTC/'; import promptAction from '@ohos.promptAction'; import { CandidateData, EmptyCandidateObject } from '../mock/CandidateData'; import { getSyncData } from '../common/service/initable'; @Entry @Component export default 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 currentUser: User = EmptyCandidateObject @State dataList: Array = [] @State list: Array = [] @State param: VideoConfig = { spls: '', faceFlag: false, pztd: '2', ljlx: '', ip: '192.168.7.112', port: '554', userName: 'admin', pwd: '12345qwe', td1: '1', td2: '2', td3: '3', td4: '4', videoRecord1: false, videoRecord2: false, videoRecord3: false, videoRecord4: false, rlls: '1', spzd4: false, spzd3: false, spzd2: false, spzd1: false, zdyz: '500' } @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 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 faceFlag: string = '0'; @State FaceOpenStatue: string = '0'; //是否开启人脸识别 subscriber; @State faceCatchImg: string = '' 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: 'kslx' }, { label: '待考次数', key: 'kssycs' }, { label: '考官姓名', key: 'ksy1' }, ] async onPageShow() { //语音功能 const systemParms: any = await getSyncData('MA_SYSTEMPARM') console.log('systemParms', systemParms.length) new WebRTCVoice(this.context); //初始化数据 this.initData() //身份证读卡器初始化 // this.openDeviceByIDCard() // 如果是单机模式则模拟假数据 this.initSysset() // initJudgeUdp() this.heartMsg() } //身份证读卡器初始化 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 // 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: 'pages/Judge', }, 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() } initData() { 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() } } 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.sendMsg(param, this.context) } facePass() { if (!this.stepFlag) { this.sfbdinterfaceFn() } } 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 === '2313') 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) } getExaminationStudentInfoFn() { if (globalThis.singlePlay) { return } const param = `${Md5.Instance.get_md5(globalThis.carInfo.carId + globalThis.carInfo.examinationRoomId + globalThis.username)}${globalThis.carInfo.carId}${globalThis.carInfo.examinationRoomId}${globalThis.username}` getExaminationStudentInfo(param).then(res => { 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 = dataList.length > 4 ? dataList.slice(this.pageIndex * 4, this.pageIndex * 4 + 4) : dataList; 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 }) 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 }).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 = `${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.sendMsg(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() { console.info('surenjun', this.currentUser.lsh) 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 console.info('surenjun', this.currentUser.lsh) const carInfo = globalThis.carInfo; const {carId,examinationRoomId} = carInfo; const examItems = await getExaminationItem({ time: getCurrentTime(), carId, lsh: this.currentUser.lsh || '', examinationRoomId }); //获取已考项目 console.log('goroute') const date = new Date() this.showFaceCompare = false const { examSubject,plateNo } = carInfo; const drvexam = { lsh: this.currentUser.lsh || '', kskm: 2, ksxtbh: this.ksxtbh || '222', sfzmhm: this.currentUser.sfzmhm || '', ksysfzmhm: this.currentUser.ksy1sfzmhm || '', zp: encodeURIComponent((this.faceCatchImg || this.currentUser.kszp.substr(22)) || ''), kssj: dateFormat(date) || '', kchp: decodeURI(plateNo), Ksy2sfzmhm: this.currentUser.ksy2sfzmhm || '' } const param = { drvexam: drvexam, xtlb: '17', //接口序列号 jkxlh: this.jkxlh || '1234567', //接口标识 jkid: '17C51', } const code = await writeObjectOut(param); globalThis.lsh = this.currentUser.lsh globalThis.ksyh = this.currentUser.ksy1sfzmhm || this.currentUser.ksy2sfzmhm this.currentUser.id = '1' if (code) { this.AccountTable.query('0', (result) => { if (result.length == 0) { this.AccountTable.insertData(this.currentUser, (id) => { this.AccountTable.query('0', (result) => { globalThis.statue = 4 this.stepFlag = false router.pushUrl({ url: 'pages/Judge', params: { examItems: examItems?.getExaminationItemRsp?.body?.ykxx } }, router.RouterMode.Single); this.stopDeviceById() }) }) } else { this.AccountTable.updateData(this.currentUser, (id) => { this.AccountTable.query('0', (result) => { this.stepFlag = false router.pushUrl({ url: 'pages/Judge', params: { examItems: examItems?.getExaminationItemRsp?.body?.ykxx } }, router.RouterMode.Single); globalThis.statue = 4 this.stopDeviceById() }) }) } }) } else { this.stepFlag = false } } 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(() => { 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 }) Image($r('app.media.ksks_btn')) .commStyle() .onClick(() => { this.faceCompareSucess = 0 globalThis.statue = 2 if (!this.currentUser.xm) { return } // if(globalThis.spzdFlag){ // promptAction.showToast({ // message: '摄像头被遮挡', // duration: 2000 // }); // return // } if (globalThis.singlePlay) { this.AccountTable.query('0', (result) => { if (result.length == 0) { this.AccountTable.insertData(this.currentUser, (id) => { this.AccountTable.query('0', (result) => { console.log(result) router.pushUrl({ url: 'pages/Judge', }, router.RouterMode.Single); this.stopDeviceById() }) }) } else { this.AccountTable.updateData(this.currentUser, (id) => { this.AccountTable.query('0', (result) => { router.pushUrl({ url: 'pages/Judge', }, router.RouterMode.Single); this.stopDeviceById() }) }) } }) return } if (this.FaceOpenStatue != '0') { this.showFaceCompare = true } else { this.sfbdinterfaceFn() } }) } } 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) } } .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(this.value).fontColor('#fff').textAlign(TextAlign.Center).width('100%') } .commLabelStyle() }.margin({ bottom: 10 * this.ratio }) } }