lixiao fca8d0ed08 大车代码合并
小红球udp开始时间修改
2025-10-30 16:10:45 +08:00

1255 lines
42 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 { examinationStuAbsent, getExaminationItem, getExaminationStudentInfo } from '../api/userInfo';
import router from '@ohos.router';
import FaceCompare from './compontents/FaceCompare';
import { writeObjectOut } from '../api/judge';
import testNapi from '@ohos.idcard';
import IDCardSDK from '@ohos.idcard';
import common from '@ohos.app.ability.common';
import promptAction from '@ohos.promptAction';
import { CandidateData, EmptyCandidateObject } from '../mock/CandidateData';
import BoardPrePareSetPopup from './compontents/judge/BoardPrePareSetPopup';
import VoiceAnnounce from './judgeSDK/utils/voiceAnnouncements';
import imageBtn from './compontents/imageBtn';
import { CryptoJS } from '@ohos/crypto-js';
import {
BeginExamRequest,
CarInfoType,
CenterCallBackMsgType,
DrvexamType,
ExaminationStuAbsentParams,
ExaminerLoginInfo,
GetExaminationItemRsp,
IdCard,
LabelBlockType,
MASYSSETTableType,
REFRESH_STRATEGY_MAP,
RegulatoryInterfaceParams,
RouteParamsType,
SckType,
SYSSET_VNO_MAP,
SystemParamType,
UDPParamType,
User,
WorkerBackMessage,
WorkerBackMessageType,
WorkerMessageDataType
} from '../model';
import { BusinessError } from '@ohos.base';
import { GetSyncData, SqlInsertTable } from '../utils/table/Operation';
import { CheckSignal, GetCurrentUserKeyValue, InitializeExamProcessData } from './UserInfo/utils';
import dayTs from '../utils/Date';
import { GetCurrentTime, GetPhotoBase64, NumberToByteArray } from '../utils/Common';
import DB from '../utils/DbSql';
import { StartEndExamTag, StartExamTag, UserInfoTag } from '../config';
import { dConsole } from '../utils/LogWorker';
import HeaderComponent from './compontents/Header';
import AvatarComponent from './UserInfo/Avatar';
import CommTextComponent from './UserInfo/CommText';
import LabelBlockComponent from './UserInfo/LabelBlock';
import CarLoadingDialog from './compontents/CarLoading';
import ConfirmDialog from './compontents/ConfirmDialog';
import { DifferentialAndSignal } from '../utils/business/DifferentialAndSignalWorker';
import FaceRecognitionDialog from './UserInfo/FaceRecognition';
@Entry
@Component
struct UserInfoPage {
@State pageIndex: number = 0
@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 isSecondBoardPrePareSetPopupOpen: boolean = false
@State isFirstBoardPrePareSetPopupBtnShow: boolean = false
@State isBoardPrePareSetPopupShow: boolean = false
@State sczbkf: SckType[] = []
@State currentUser: User = EmptyCandidateObject
// 开始考试弹窗
startExamDialogController: CustomDialogController = new CustomDialogController({
builder: CarLoadingDialog(),
autoCancel: false,
customStyle: true
})
@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: number = -1;
@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
// 缺考弹窗
missAnExamDialogController: CustomDialogController = new CustomDialogController({
builder: ConfirmDialog({
text: `确认考生:${this.currentUser.xm}是否缺考?`,
onConfirm: () => {
this.qkFn()
}
}),
customStyle: true,
autoCancel: true
})
//TODO 人脸对比弹窗
faceCompareController: CustomDialogController = new CustomDialogController({
builder: FaceRecognitionDialog({
sfzh: this.currentUser.sfzmhm,
firstImage: this.currentUser.kszp,
lsh: AppStorage.get<string>('lsh'),
}),
customStyle: true,
autoCancel: true
})
@State faceFlag: string = '0';
@State FaceOpenStatue: string = '0'; //是否开启人脸识别
@State faceCatchImg: string = ''
@State carInfo: CarInfoType = {
carId: '',
examinationRoomId: '',
plateNo: '',
isNeedCheck: '',
examSubject: ''
}
@State examinerLoginInfo: ExaminerLoginInfo = {
carId: '',
examinationRoomId: '',
plateNo: '',
isNeedCheck: '',
examSubject: ''
}
@State systemParam: SystemParamType = {
Param341: true,
Param803Str: '0',
Param612Str: '0',
Param770Str: '0',
Param305Str: '0',
Param352Str: '0',
Param828Str: '0',
Param830Str: '0',
Param364: '0',
Param398: '0'
}
@State startExam: boolean = false
@State singlePlay: boolean = false
private context: common.UIAbilityContext = getContext(this) as common.UIAbilityContext;
private avPlayer!: VoiceAnnounce
//开始考试准备
prePareExam = async () => {
dConsole.log(StartExamTag, 'prePareExam')
try {
// await this.checkSignal()
await CheckSignal(this.systemParam, this.avPlayer)
DifferentialAndSignal.clearMsg()
this.faceCompareSucess = 0
AppStorage.setOrCreate('statue', 2)
if (!this.currentUser.xm) {
return
}
// 单机
if (this.singlePlay) {
this.currentUser.id = '0'
dConsole.log(StartExamTag, '开始考试3', this.currentUser)
try {
// let data: Array<User> = JSON.parse(JSON.stringify([this.currentUser]))
await SqlInsertTable('USER', [this.currentUser])
} catch (e) {
dConsole.error(StartExamTag, '开始考试插入用户表失败', JSON.stringify(e))
}
// 初始化开始考试过程数据文件夹
InitializeExamProcessData(this.currentUser)
dConsole.log(StartExamTag, '开始考试4')
dConsole.log(StartEndExamTag, "-----------------------------身份证号:" + this.currentUser.sfzmhm + "考生开始考试-----------------------------")
router.pushUrl({
url: this.carInfo.examSubject == '3' ? 'pages/Roads' : 'pages/Judge',
params: {
sczb: Number(this.isBoardPrePareSetPopupOpen),
kfdm: this.sczbkf,
}
}, router.RouterMode.Single);
this.stopDeviceById()
return
}
dConsole.log(StartExamTag, '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) {
dConsole.error(UserInfoTag, 'Throw Error', JSON.stringify(e))
}
}
private labelBlocks: LabelBlockType[] = [
{ label: '考生姓名', key: 'xm' },
{ label: '身份证号', key: 'sfzmhm' },
{ label: ' 流 水 号 ', key: 'lsh' },
{ label: '考试路线', key: 'ksxl' },
{ label: '待考次数', key: 'kssycs' },
{ label: '考试员名', key: 'ksy2' },
]
async onPageShow() {
dConsole.closeProcessData()
this.avPlayer = new VoiceAnnounce(this.context);
this.isExamStart = false
this.startExam = false
this.updateTimeLimit = false
this.currentUser = EmptyCandidateObject
this.singlePlay = AppStorage.get<boolean>('singlePlay') || false
this.examinerLoginInfo = AppStorage.get<ExaminerLoginInfo>('examinerInfo')!
this.carInfo = AppStorage.get<CarInfoType>('carInfo')!
//语音功能on
// new WebRTCVoice(this.context);
//初始化数据
try {
this.initData()
dConsole.log(UserInfoTag, "初始化数据完成")
} catch (e) {
dConsole.error(UserInfoTag, '初始化数据失败', JSON.stringify(e))
}
//身份证读卡器初始化
// this.openDeviceByIDCard()
const routerParam: RouteParamsType = router.getParams() as RouteParamsType
dConsole.log(UserInfoTag, 'routerParam', JSON.stringify(routerParam))
if (!this.singlePlay) {
if (!routerParam) {
dConsole.log(UserInfoTag, "评判退出")
this.list = await GetSyncData<User>("USERLIST")
const data = await GetSyncData<User>("USER")
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 == '')) {
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 = this.examinerLoginInfo.kgxm || ""
AppStorage.setOrCreate('lsh', this.currentUser.lsh)
DifferentialAndSignal.sendMsg({
type: WorkerMessageDataType.SetExamData,
data: { lsh: this.currentUser.lsh }
})
}, 200)
} else {
this.currentUser = EmptyCandidateObject
}
}
this.list.forEach((res, index) => {
res.id = index.toString()
})
try {
await SqlInsertTable("USERLIST", this.list || [])
} catch (e) {
dConsole.error(UserInfoTag, '插入USERLIST表失败', JSON.stringify(e))
}
dConsole.log(UserInfoTag, '接口读取数据', JSON.stringify(this.currentUser))
// await this.getExaminationStudentInfoFn()
} else {
// 考官登录拉取学员
await this.getExaminationStudentInfoFn()
}
}
// 如果是单机模式则模拟假数据
//获取sysset表数据
this.initSysset()
//心跳处理
this.heartMsg()
// if(user[0]){
// // @ts-ignore
// this.currentUser=user
// }
this.sczbkf = [];
// initJudgeUdp()
// TODO UDP更改
//监听远程开始考试
}
async onPageHide(): Promise<void> {
DifferentialAndSignal.offMsg(this.heartMsg)
}
async aboutToDisappear(): Promise<void> {
// CenterUDPBusinessInstance.offMsg(this.onCenterMsg)
// DifferentialAndSignal.offMsg(this.onCenterMsg)
this.outClick()
}
//身份证读卡器初始化
openDeviceByIDCard() {
AppStorage.setOrCreate('indexComponent', this)
// 应用启动时打开读卡设备
let ret = testNapi.OpenDevice();
if (ret == 0) {
testNapi.StartReadCard(this.onReadCard);
} else {
dConsole.error(UserInfoTag, " Failed to Open Device");
}
}
stopDeviceById() {
if (this.faceFlag == '1') {
testNapi.StopReadCard()
}
}
// 通过身份证获取当前学员
async getCurrentStudent(id: string) {
let flag = false
// this.pageIndex
dConsole.log('currentidid', id)
this.list.map((res, index) => {
dConsole.log('tttt', res.sfzmhm, res.xm)
if (res.sfzmhm == id) {
flag = true
this.currentUser = EmptyCandidateObject
setTimeout(() => {
this.currentUser = res
this.currentUser.ksy2 = this.examinerLoginInfo.kgxm || ""
}, 200)
this.examinerLoginInfo.ksyh = res.ksy1sfzmhm
AppStorage.setOrCreate('examinerInfo', this.examinerLoginInfo)
AppStorage.setOrCreate('lsh', res.lsh)
DifferentialAndSignal.sendMsg({
type: WorkerMessageDataType.SetExamData,
data: { lsh: res.lsh }
})
// const { examSubject } = this.carInfo;
dConsole.log("开始考试2")
if (this.singlePlay) {
this.stopDeviceById()
// 初始化开始考试过程数据文件夹
InitializeExamProcessData(this.currentUser)
router.pushUrl({
url: this.carInfo.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) {
AppStorage.setOrCreate('lsh', '0000000000000')
await SqlInsertTable('USER', [])
setTimeout(() => {
this.currentUser = this.list[0]
this.currentUser.ksy2 = this.examinerLoginInfo.kgxm || ""
AppStorage.setOrCreate('lsh', this.currentUser.lsh)
DifferentialAndSignal.sendMsg({
type: WorkerMessageDataType.SetExamData,
data: { lsh: this.currentUser.lsh }
})
}, 200)
// promptAction.showToast({
// message: '未匹配到对应下载学员',
// duration: 3000
// });
}
}
onReadCard(ret: IDCardSDK.IDCardInfo) {
dConsole.log(`zzctest xx Read Card ret =${ret.status}`)
let thisVar: IdCard = AppStorage.get('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) {
// 收到身份证信息,填充页面
dConsole.log(`zzctest Read Card 1`);
let subIndex = ret.baseInfo.indexOf(":")
let baseInfo: string = ret.baseInfo.substring(subIndex + 1, ret.baseInfo.length - 1);
dConsole.log(`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(() => {
this.getCurrentStudent(baseInfos[5])
}, 1000)
}
// 身份证照片数据处理
if (ret.photo instanceof ArrayBuffer) {
let dataView = new DataView(ret.photo)
dConsole.log(`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;
}
dConsole.log(`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
AppStorage.setOrCreate('lsh', this.lsh)
AppStorage.setOrCreate('statue', 2)
DifferentialAndSignal.sendMsg({
type: WorkerMessageDataType.SetExamData,
data: { lsh: this.currentUser.lsh }
})
// this.currentUser = EmptyCandidateObject
this.numCount = 0
if (this.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
this.examinerLoginInfo.ksyh = this.currentUser.ksy1sfzmhm
AppStorage.setOrCreate('examinerInfo', this.examinerLoginInfo)
AppStorage.setOrCreate('lsh', this.lsh)
}
}
async heartMsg() {
DifferentialAndSignal.onMsg(this.onCenterMsg)
// CenterUDPBusinessInstance.onMsg((data) => {
// this.onCenterMsg(data)
// })
}
//考点端查询缺考指令内容消息请求
getqkFn() {
let tmpList: Array<number> = [];
const number = AppStorage.get<number>('signNum')!
tmpList.push(NumberToByteArray(number, 1 * 8)[0])
const param: UDPParamType = {
id: 41,
list: tmpList,
carNo: this.carInfo.carNo as string,
placeId: this.carInfo.examinationRoomId as string
}
// TODO
// CenterUDPBusinessInstance.sendData(param)
}
async initSysset() {
// 使用 try-catch 处理可能的异常
try {
const syssetParams = await GetSyncData<MASYSSETTableType>("MA_SYSSET");
// 创建映射表以避免多次 filter 操作
const syssetMap = new Map<string, MASYSSETTableType>();
syssetParams.forEach(sys => syssetMap.set(sys.v_no!, sys));
// 使用映射表获取所需参数
this.jkxlh = syssetMap.get(SYSSET_VNO_MAP.get('SERIAL_NUMBER')!)?.v_value || '';
this.ksxtbh = syssetMap.get(SYSSET_VNO_MAP.get("EXAM_SYSTEM_CODE")!)?.v_value || '222';
this.studentRefreshStatue = syssetMap.get(SYSSET_VNO_MAP.get("STUDENT_REFRESH")!)?.v_value || '0';
// 获取验证标志和人脸参数
const openCheckFlagParam = syssetMap.get(SYSSET_VNO_MAP.get("OPEN_CHECK_FLAG")!);
const openCheckFlag = openCheckFlagParam?.v_value === '1' ? '1' : '0';
const faceParam = syssetMap.get(SYSSET_VNO_MAP.get("FACE_PARAM")!);
dConsole.log('FaceOpenStatue', openCheckFlag, this.FaceOpenStatue);
// 处理人脸识别状态
if (openCheckFlag === '1') {
const faceValue = faceParam?.v_value || '0';
this.FaceOpenStatue = faceValue === '3' ? '1' : '0';
this.faceFlag = faceValue;
if (faceValue === '1') {
this.openDeviceByIDCard();
}
}
// 遍历处理系统参数
syssetParams.forEach(sys => {
const vNo = sys.v_no;
const vValue = decodeURIComponent(sys.v_value || '');
switch (vNo) {
case SYSSET_VNO_MAP.get("JUDGMENT_TIMING"):
// 绕车一周评判时机
if (vValue === '2') {
this.systemParam.Param364 = sys.v_value || '';
this.isBoardPrePareSetPopupOpen = true;
this.isFirstBoardPrePareSetPopupBtnShow = false;
}
break;
case SYSSET_VNO_MAP.get("SECOND_EXAM_PREPARE"):
// 第二场考试上车准备不考
if (vValue === '1') {
this.systemParam.Param398 = vValue;
this.isSecondBoardPrePareSetPopupOpen = true;
}
break;
case SYSSET_VNO_MAP.get("NO_ABSENT_FUNCTION"):
// 车上没有缺考功能
this.systemParam.Param770Str = sys.v_value || '';
break;
case SYSSET_VNO_MAP.get("SEATBELT_DOOR"):
// 开始考试前必须解开安全带或关车门
this.systemParam.Param803Str = sys.v_value + '';
break;
case SYSSET_VNO_MAP.get("EXAM_ORDER"):
// 判断是否考生是否按顺序考试
this.systemParam.Param341 = vValue === '1';
break;
case SYSSET_VNO_MAP.get("EXAM_TRIGGER"):
// 开始考试触发方式
this.systemParam.Param612Str = vValue;
break;
case SYSSET_VNO_MAP.get("NO_ABSENT_AFTER_ONCE"):
// 车上考试过一次就不能缺考
this.systemParam.Param352Str = vValue;
break;
case SYSSET_VNO_MAP.get("EXAMINER_DISPLAY"):
// 考生待考界面,安全员显示考试员
this.systemParam.Param828Str = vValue;
this.labelBlocks[5].label = vValue === '1' ? '安全员名' : '考试员名';
// 使用 Array.from 创建新数组,避免使用扩展运算符
this.labelBlocks = Array.from(this.labelBlocks);
break;
case SYSSET_VNO_MAP.get("VIDEO_SAVE_DAYS"):
// 视频保存天数
this.systemParam.Param305Str = vValue;
if (!Number(this.systemParam.Param305Str)) {
this.systemParam.Param305Str = '2';
}
break;
}
});
// 处理考生刷新逻辑
const handleStudentRefresh = () => {
// 清除旧的定时器
if (this.interval) {
clearInterval(this.interval);
this.interval = -1;
}
// 如果列表为空,设置定时器
if (this.list.length === 0) {
switch (this.studentRefreshStatue) {
case REFRESH_STRATEGY_MAP.get("AUTO_TWICE"):
this.interval = setInterval(() => {
if (this.numCount < 3) {
this.numCount++;
if (this.list.length === 0) {
this.getExaminationStudentInfoFn();
}
} else {
clearInterval(this.interval);
this.interval = -1;
}
}, 5000);
break;
case REFRESH_STRATEGY_MAP.get("AUTO_UNLIMITED"):
this.interval = setInterval(() => {
if (this.list.length === 0) {
this.getExaminationStudentInfoFn();
}
}, 5000);
break;
}
}
// 获取考生信息
this.getExaminationStudentInfoFn();
};
handleStudentRefresh();
} catch (error) {
dConsole.error('初始化系统设置失败:', error);
// 可以添加错误处理逻辑
}
}
//人脸比对窗口关闭
changeFaceCompareSuccess() {
dConsole.log('this.faceCompareSuces', this.faceCompareSucess, JSON.stringify(this.currentUser))
if (this.faceCompareSucess > 0) {
//人脸比对通过
AppStorage.setOrCreate('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 (this.singlePlay || this.updateTimeLimit) {
return
}
this.isExamStart = false
this.startExam = false
this.updateTimeLimit = false
this.isFirstBoardPrePareSetPopupBtnShow = false
dConsole.log('isFirstBoardPrePareSetPopupBtnShow', this.isFirstBoardPrePareSetPopupBtnShow,
this.isBoardPrePareSetPopupOpen)
this.startExam = false
await DB.clearTable('USER')
await DB.clearTable('USERLIST')
this.updateTimeLimit = true
let md5Message: string = CryptoJS.MD5(this.carInfo.carId! +
this.carInfo.examinationRoomId! +
this.examinerLoginInfo.username!).toString();
const param: ExaminationStuAbsentParams = {
md5Message: md5Message,
carId: this.carInfo.carId || "",
examinationRoomId: this.carInfo.examinationRoomId || "",
username: this.examinerLoginInfo.username || ""
}
try {
getExaminationStudentInfo(param).then(async (res) => {
dConsole.log("temp log ", JSON.stringify(res))
setTimeout(() => {
this.updateTimeLimit = false
}, 3000)
if (!res || res?.getExaminationStudentInfoRsp?.head?.resultCode == '1') {
this.dataList = []
this.list = []
return
}
let dataList: User[] = []
this.list = []
for (const key of Object.keys(res.getExaminationStudentInfoRsp.body)) {
const a: User[] | User = Reflect.get(res.getExaminationStudentInfoRsp.body, key);
if (Array.isArray(a)) {
dataList = a;
} else {
dataList = [a];
}
}
if (dataList.length) {
this.numCount = 0
}
this.list = JSON.parse(JSON.stringify(dataList))
dConsole.log(UserInfoTag, "temp list", JSON.stringify(this.list))
this.list.forEach((listData, index) => {
//考过一次不允许切换学员
if (listData.kssycs == '1') {
this.startExam = true
}
listData.id = index.toString()
Object.keys(listData).forEach((key) => {
Reflect.set(listData, key, decodeURI(Reflect.get(listData, key)));
});
if (this.systemParam.Param828Str == '1' || this.systemParam.Param828Str == '2') {
// listData.ksy2=listData.ksy1;
listData.ksy2 = this.examinerLoginInfo.kgxm || ""
} else {
// listData.ksy2=listData.ksy2;
listData.ksy2 = this.examinerLoginInfo.kgxm || ""
}
listData.kszp = this.photo + listData.kszp
listData.ksmjzp = this.photo + listData.ksmjzp
})
// await upDateTableByArray('USERLIST', this.list || [])
dConsole.log(UserInfoTag, "temp list", JSON.stringify(this.list))
// await sqlInsertCommonFn("USERLIST", this.list || [])
await SqlInsertTable('USERLIST', this.list || [])
dataList = this.list.length > 4 ? this.list.slice(this.pageIndex * 4, this.pageIndex * 4 + 4) : this.list;
this.dataList = dataList
dConsole.log("temp list", JSON.stringify(this.dataList))
const user = this.dataList.filter(res => {
return res.kssycs == '1'
})
if (this.dataList.length) {
setTimeout(() => {
this.currentUser = user.length ? user[0] : this.dataList[0]
this.currentUser.ksy2 = this.examinerLoginInfo.kgxm || ""
AppStorage.setOrCreate('lsh', this.currentUser.lsh)
DifferentialAndSignal.sendMsg({
type: WorkerMessageDataType.SetExamData,
data: { lsh: this.currentUser.lsh }
})
this.examinerLoginInfo.ksyh = this.currentUser.ksy1sfzmhm
AppStorage.setOrCreate('examinerInfo', this.examinerLoginInfo)
}, 200)
} else {
this.currentUser = EmptyCandidateObject
}
//364 绕车一周评判时机(1-开始考试后判 2-开始考试前判)
if (this.systemParam.Param364 == '2') {
this.isBoardPrePareSetPopupOpen = true;
this.isFirstBoardPrePareSetPopupBtnShow = false;
}
//398参数为1 第二场考试上车准备不考
if (this.systemParam.Param398 == '1') {
this.isSecondBoardPrePareSetPopupOpen = true;
}
this.pageIndex = 0
GetSyncData<User>("USER").then(data => {
if (data?.[0]) {
this.getCurrentStudent(data[0].sfzmhm)
}
})
}).catch((error: BusinessError) => {
this.updateTimeLimit = false
dConsole.log('error12error' + error)
})
} catch (error) {
this.updateTimeLimit = false
dConsole.log('error14error' + error)
}
}
// 缺考
qkFn() {
if (this.systemParam.Param352Str == '1' && this.currentUser.kssycs == '1') {
return
}
this.faceCompareSucess = 0
if (this.singlePlay) {
this.qkFlag = false
return
}
dConsole.log('JsonJson', JSON.stringify(this.currentUser))
const param: ExaminationStuAbsentParams = {
carId: this.carInfo.carId || "",
sfzmhm: this.currentUser.sfzmhm,
examinationRoomId: this.carInfo.examinationRoomId || "",
username: this.examinerLoginInfo.username || "",
lsh: this.lsh,
}
dConsole.log('carNo1111', param)
examinationStuAbsent(param).then(res => {
const arr = [this.signNum || 0, 1]
let tmpList: number[] = [];
tmpList.push(NumberToByteArray(arr[0], 1 * 8)[0])
tmpList.push(NumberToByteArray(arr[1] ?? 0, 1 * 8)[0])
const param: UDPParamType = {
id: 43,
list: tmpList,
carNo: this.carInfo.carNo || "",
placeId: this.carInfo.examinationRoomId || ""
}
// TODO
// CenterUDPBusinessInstance.sendData(param)
// globalThis.udpClient2.sendMsgExt(param, this.context)
if (res.examinationStuAbsentRsp && res.examinationStuAbsentRsp.head &&
res.examinationStuAbsentRsp.head.resultCode == '0') {
this.pageIndex = 0
this.qkFlag = false
this.currentUser = EmptyCandidateObject
this.missAnExamDialogController.close()
this.getExaminationStudentInfoFn()
return
}
}).catch((error: BusinessError) => {
dConsole.log('error12error' + error)
})
}
onCenterMsg = (msg: string) => {
let result = JSON.parse(msg) as WorkerBackMessage
if (result.type === WorkerBackMessageType.RemoteStartExam) {
dConsole.log('userInfo收到开始考试事件')
if (this.isBoardPrePareSetPopupOpen && !this.isFirstBoardPrePareSetPopupBtnShow) {
this.prePareSCZB()
} else {
this.prePareExam()
}
} else if (result.type === WorkerBackMessageType.CenterUdpData) {
let val = result.data as CenterCallBackMsgType
if (val.id == 32) {
AppStorage.setOrCreate('signNum', val.body[1])
if (val.body[0] == 7) {
//缺考处理
this.getqkFn()
this.signNum = val.body[1]
}
} else if (val.id == 42) {
//收到中心缺考确认消息
this.qkFn()
}
}
}
async getExaminationItemFn() {
if (!this.currentUser.lsh || this.singlePlay) {
return
}
const examItems = await getExaminationItem({
time: GetCurrentTime() || "",
carId: this.carInfo.carId || "",
lsh: this.currentUser.lsh || '',
examinationRoomId: this.carInfo.examinationRoomId || ""
});
if (examItems?.getExaminationItemRsp?.body?.kssycs != 0) {
this.getExaminationStudentInfoFn()
} else {
this.dataList = []
this.currentUser = EmptyCandidateObject
}
}
//身份比对
async sfbdinterfaceFn() {
AppStorage.setOrCreate('statue', 4)
this.stepFlag = true
let examItems: GetExaminationItemRsp = {
getExaminationItemRsp:
{
body: { ykxx: '' }
}
};
if (!this.singlePlay) {
//获取已考项目
examItems = await getExaminationItem({
time: GetCurrentTime(),
carId: this.carInfo.carId || "",
lsh: this.currentUser.lsh || '',
examinationRoomId: this.carInfo.examinationRoomId || ""
});
}
this.currentUser.id = '1'
const avPlayer = this.avPlayer;
this.startExamDialogController.open()
avPlayer.playAudio([`voice/监管通信中.mp3`], false, async () => {
dConsole.log(StartExamTag, '播放结束开始考试接口调用')
const res = await this.beginExam()
dConsole.log(StartExamTag, '开始考试接口调用结束', res)
//TODO code转换
if (res.code != 1) {
avPlayer.playAudio([res.code == -200 ? 'voice/photo_error.mp3' : 'voice/监管审核未通过.mp3']);
this.startExamDialogController.close()
this.isExamStart = false
promptAction.showToast({
message: res.message,
duration: 4000
})
return
}
this.currentUser.id = '0'
dConsole.log(StartExamTag, '插入用户表1')
try {
await SqlInsertTable('USER', [this.currentUser])
} catch (e) {
dConsole.error(StartExamTag, '插入用户表失败', e)
}
dConsole.log(StartExamTag, '插入用户表结束', res)
this.stepFlag = false
this.startExamDialogController.close()
// 初始化开始考试过程数据文件夹
InitializeExamProcessData(this.currentUser)
router.pushUrl({
url: 'pages/Judge',
params: {
examItems: examItems?.getExaminationItemRsp?.body?.ykxx,
sczb: Number(this.isBoardPrePareSetPopupOpen),
kfdm: this.sczbkf,
//真实监管项目
kString: decodeURIComponent(res.keystr || '')
}
}, router.RouterMode.Single);
this.updateTimeLimit = false
this.stopDeviceById()
this.stepFlag = false
})
}
// 开始考试
async beginExam(): Promise<BeginExamRequest> {
dConsole.log(StartExamTag, "开始考试")
const startHourTime = dayTs().format("HHmmssSSS")
AppStorage.setOrCreate('startHourTime', startHourTime)
const photoBase64 = await GetPhotoBase64(this.context);
dConsole.log(StartExamTag, "开始考试拍照完成")
if (photoBase64 == '') {
dConsole.log(StartExamTag, "拍照失败")
this.startExamDialogController.close()
return { code: -200 }
}
let startTime = new Date()
AppStorage.setOrCreate("startTime", startTime)
const drvexam: DrvexamType = {
lsh: this.currentUser.lsh,
kskm: this.carInfo.examSubject,
ksxtbh: this.ksxtbh || '222',
sfzmhm: this.currentUser.sfzmhm || '',
ksysfzmhm: this.currentUser.ksy1sfzmhm || '',
ksxl: this.currentUser.xldm,
zp: photoBase64,
kssj: dayTs(startTime).format("YYYY-MM-DD HH:mm:ss") || '',
kchp: decodeURI(this.carInfo.plateNo || ""),
Ksy2sfzmhm: this.currentUser.ksy2sfzmhm || ''
}
dConsole.log(StartExamTag, "开始考试参数", drvexam)
const param: RegulatoryInterfaceParams = {
drvexam,
xtlb: '17',
//接口序列号
jkxlh: this.jkxlh,
//接口标识
jkid: '17C51',
}
dConsole.log(StartExamTag, "开始考试上传中心参数", param)
try {
const temp = await writeObjectOut(param, "", this.context);
AppStorage.setOrCreate('lsh', this.currentUser.lsh)
dConsole.info(UserInfoTag, this.currentUser.lsh, this.currentUser)
this.examinerLoginInfo.ksyh = this.currentUser.ksy1sfzmhm
AppStorage.setOrCreate('examinerInfo', this.examinerLoginInfo)
DifferentialAndSignal.sendMsg({
type: WorkerMessageDataType.SetExamData,
data: {
lsh: this.currentUser.lsh
}
})
return temp
} catch (e) {
return e
}
}
//开始上车准备
prePareSCZB = async () => {
try {
await CheckSignal(this.systemParam, this.avPlayer)
DifferentialAndSignal.clearMsg()
this.isExamStart = true
this.currentUser.id = '0'
DB.insertData("USER", this.currentUser).then(() => {
dConsole.log("USER insert success",)
}).catch((err: BusinessError) => {
dConsole.log("USER insert fail", JSON.stringify(err))
})
dConsole.log("User", JSON.stringify(this.currentUser))
AppStorage.setOrCreate('statue', 4)
this.isBoardPrePareSetPopupShow = true;
this.isFirstBoardPrePareSetPopupBtnShow = true;
this.stepFlag = false
this.stopDeviceById()
} catch (e) {
dConsole.error(UserInfoTag, JSON.stringify(e))
}
}
outClick() {
clearInterval(this.interval)
this.stopDeviceById()
}
// 几个按钮公共样式
@Styles
commStyle(){
.width(389)
.height(122)
.backgroundImage($r('app.media.button_nor'))
.backgroundImageSize({ width: '100%', height: '100%' })
.margin({ bottom: 21 })
}
build() {
Column() {
HeaderComponent({
shortLogo: true,
shouBackArea: true
})
Column() {
Row() {
Row() {
ForEach(this.dataList, (item: User) => {
Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
Column() {
CommTextComponent({
color: item.sfzmhm != this.currentUser.sfzmhm ? '#FFFFFF' : '#000000',
text: item.lsh
})
CommTextComponent({
color: item.sfzmhm != this.currentUser.sfzmhm ? '#FFFFFF' : '#000000',
text: decodeURIComponent(item.xm)
})
}
}
.width(292) // 165 * 1.770833 ≈ 292.187 → 292
.height(151) // 85 * 1.770833 ≈ 150.52 → 151
.backgroundImage(item.sfzmhm != this.currentUser.sfzmhm ? $r('app.media.userbox2') :
$r('app.media.userboxbg'))
.backgroundImageSize({ width: '100%', height: '100%' })
.onClick(() => {
dConsole.log('this.startExam', this.startExam, this.systemParam.Param364, this.isExamStart)
if ((this.isExamStart && !this.singlePlay && this.systemParam.Param341) ||
(this.startExam && this.systemParam.Param364 == '2')) {
return
}
this.currentUser = EmptyCandidateObject
AppStorage.setOrCreate('lsh', item.lsh)
DifferentialAndSignal.sendMsg({
type: WorkerMessageDataType.SetExamData,
data: { lsh: item.lsh }
})
setTimeout(() => {
this.currentUser = item
this.currentUser.ksy2 = this.examinerLoginInfo.kgxm || ""
}, 200)
})
})
}.width(1133) // 640 * 1.770833 ≈ 1133.33 → 1133
.margin({ left: 53 }) // 30 * 1.770833 ≈ 53.12 → 53
Image($r('app.media.dk_prev'))
.width(159)// 90 * 1.770833 ≈ 159.37 → 159
.height(124)// 70 * 1.770833 ≈ 123.96 → 124
.margin({ left: 115, right: 18 })// 65→115, 10→18
.onClick(() => {
this.prevClick()
})
Image($r('app.media.dk_next'))
.width(159)// 90→159
.height(124)// 70→124
.onClick(() => {
this.nextClick()
})
}.margin({ top: 71, bottom: 18 }) // 40→71, 10→18
Flex({ justifyContent: FlexAlign.SpaceBetween }) {
Row() {
Column() {
if (this.currentUser.kszp) {
AvatarComponent({
url: this.currentUser.kszp ? this.currentUser.kszp : ''
})
} else {
AvatarComponent({
url: ""
})
}
if (this.currentUser.ksmjzp) {
AvatarComponent({
url: this.currentUser.ksmjzp ? this.currentUser.ksmjzp : ''
})
} else {
AvatarComponent({
url: ""
})
}
}
Column() {
ForEach(this.labelBlocks, (item: LabelBlockType) => {
LabelBlockComponent({
label: item.label,
value: GetCurrentUserKeyValue(this.currentUser, item.key)
})
})
}
}
.width(1176) // 664→1176
.height(600) // 339→600
.backgroundImage($r('app.media.dkbg'))
.backgroundImageSize({ width: '100%', height: '100%' })
.margin({ left: 94 }) // 53→94
Column() {
imageBtn({ btnWidth: 390, btnHeight: 122, imgSrc: $r('app.media.yydj_btn') })// 220→390, 69→122
.margin({ bottom: 21 }) // 12→21
imageBtn({ btnWidth: 390, btnHeight: 122, imgSrc: $r('app.media.gx_btn') })
.margin({ bottom: 21 })
.onClick(() => {
if (this.isExamStart && !this.singlePlay) {
return
}
this.faceCompareSucess = 0
this.numCount = 0
this.getExaminationStudentInfoFn()
})
imageBtn({ btnWidth: 390, btnHeight: 122, imgSrc: $r('app.media.qk_btn') })
.margin({ bottom: 21 })
.onClick(() => {
if ((this.systemParam.Param352Str == '1' && this.currentUser.kssycs == '1') ||
this.systemParam.Param770Str == '1') {
dConsole.log(UserInfoTag, '不允许缺考')
return
}
// this.qkFlag = true
console.log("打开缺考")
this.missAnExamDialogController.open()
})
if (this.isBoardPrePareSetPopupOpen &&
(this.isSecondBoardPrePareSetPopupOpen && this.currentUser.kssycs == '2') &&
!this.isFirstBoardPrePareSetPopupBtnShow) {
imageBtn({ btnWidth: 390, btnHeight: 122, imgSrc: $r('app.media.sczb_btn') })
.margin({ bottom: 21 })
.onClick(async () => {
if (this.systemParam.Param612Str == '1') {
return
}
await this.prePareSCZB()
})
} else {
imageBtn({ btnWidth: 390, btnHeight: 122, imgSrc: $r('app.media.ksks_btn') })
.margin({ bottom: 21 })
.onClick(async () => {
if (this.systemParam.Param612Str == '1') {
dConsole.log(UserInfoTag, "不给开始考试")
return
}
dConsole.log(StartExamTag, "开始考试按钮点击")
await this.prePareExam()
})
}
}
}
}.backgroundColor("#1E1E1E").width("100%").height("100%")
if (this.showFaceCompare) {
FaceCompare({
sfzh: this.currentUser.sfzmhm,
firstImage: this.currentUser.kszp,
faceCompareSuccess: $faceCompareSucess,
getqkFlag: $getqkFlag,
faceCatchImg: $faceCatchImg,
showFaceCompare: $showFaceCompare,
lsh: AppStorage.get<string>('lsh'),
})
}
if (this.isBoardPrePareSetPopupShow) {
BoardPrePareSetPopup({
closePopup: () => {
this.isBoardPrePareSetPopupShow = false;
},
confirmMark: (kfdm: SckType[]) => {
this.sczbkf = kfdm
}
})
}
}
.height('100%')
.width('100%')
.backgroundImage($r('app.media.bg'))
.backgroundImageSize({ width: '100%', height: '100%' })
}
}