2025-01-21 10:00:27 +08:00

667 lines
23 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 common from '@ohos.app.ability.common';
import router from '@ohos.router';
import { getCarInfo, getDeviceInfo } from '../common/service/terminalService';
import { setCurrentTime } from '../common/service/timeService';
import { string2Bytes } from '../common/utils/tools';
import { FileHelper } from '../common/service/FileHelper';
import { getEsCarModel, } from '../common/service/initable';
import FileUtil from '../common/utils/File';
import { getUDP, getUDP2 } from '../common/utils/GlobalUdp';
import { initJudgeUdp } from '../common/utils/UdpJudge';
import { judgeConfig } from './judgeSDK/utils/judgeConfig';
import { getTCP } from '../common/utils/GlobalTcp';
import { setliushuiNum, takePhotoFn, setVideoParam } from '../common/service/indexService';
import abilityAccessCtrl, { Permissions } from '@ohos.abilityAccessCtrl';
import worker, { MessageEvents } from '@ohos.worker';
import promptAction from '@ohos.promptAction'
import { voiceService } from '../common/service/voiceService';
import errorMsgDialog from './compontents/errorMsgDialog'
import { getSyncData } from '../common/service/initable';
import GetDistance from '../common/utils/GetDistance'
import UdpEvent from '../common/utils/UdpEvent'
import installer from '@ohos.bundle.installer';
// @ts-ignore
import { BusinessError } from '@ohos.base';
import { getModalValueCdAndCar } from '../api';
import request from '@ohos.request'
import fs from '@ohos.file.fs'
import zlib from '@ohos.zlib';
import { GlobalConfig } from '../config/global'
import UIAbility from '@ohos.app.ability.UIAbility';
import { endRecordVideo, getUserAlbumItemByDisplayName, saveStartRecordVideo } from '../common/service/videoService';
import imageBtn from './compontents/imageBtn'
import VoiceAnnounce from './judgeSDK/utils/voiceAnnouncements';
import EndPopup from './compontents//judge/EndPopup'
// import VoiceAnnounce from './judgeSDK/utils/voiceAnnouncements';
@Entry
@Component
struct Index {
@State carNum: string = ''
@State version: string = ''
@State url: string = ''
@State hasAuth: boolean = false;
@State dialogVisiable: boolean = false;
@State isSingle: boolean = false;
@State deviceId: string = '';
@State angle: number = 0
@State dialogRatio: number = 0.8
@State ratio: number = 1700 / 960
@State loading: boolean = true
@State initParamFlag: boolean = false
@State fd: number = -1;
@State num: number = 0;
@State mxwjDownloadFlag: boolean = false;
@State isUpdatePopShow: boolean = false;
fileHelper = null;
private fileUtil: FileUtil
private interval = null;
// private vocObj = null;
private avPlayer
private workerInstance = null;
private context = getContext(this) as common.UIAbilityContext;
errorDialog: CustomDialogController = new CustomDialogController({
builder: errorMsgDialog({
title: globalThis.title,
type: globalThis.type,
cancel: () => {
},
confirm: () => {
}
}),
customStyle: true,
alignment: DialogAlignment.Center,
},
)
@Styles
commStyle(){
.width(220 * this.ratio * this.dialogRatio)
.height(69 * this.ratio * this.dialogRatio)
.backgroundImage($r('app.media.button_nor'))
.backgroundImageSize({ width: '100%', height: '100%' })
// .margin({ bottom: 12 * this.ratio })
}
build() {
Column() {
Column() {
Row() {
Image($r('app.media.logo')).width('30%').height('5.5%').margin({ left: 24 })
Row() {
Image($r('app.media.btn_setting')).width('16.7%').height('12.2%')
.onClick(async () => {
if (this.loading) {
return
}
router.pushUrl({
url: 'pages/Settings',
}, router.RouterMode.Single);
})
Image($r('app.media.btn_back')).width('14.4%').height('12.2%')
.onClick(() => {
this.dialogVisiable = true
})
}
}
.width('100%')
.justifyContent(FlexAlign.SpaceBetween)
}
Column() {
Row() {
if (!this.isSingle) {
imageBtn({btnWidth:'28%',btnHeight:'71%',imgSrc:$r('app.media.index_lw')})
.margin({ left: 80 * globalThis.ratio })
.onClick(async () => {
// this.vocObj.playAudio({
// type: 1,
// name: 'button_media.wav'
// })
// ||!this.initParamFlag
if (this.loading) {
// globalThis.title = '正在初始化请等待5s后重试'
// this.errorDialog.open()
return
}
setTimeout(() => {
this.angle = 360
}, 1000)
this.angle = 0
if (!globalThis.timeInfo) {
globalThis.type = '1'
globalThis.title = '时间同步接口连接失败'
this.errorDialog.open()
promptAction.showToast({
message: `时间同步接口连接失败`,
duration: 3000
});
this.loading = false
return
}
if (!globalThis.carInfo) {
promptAction.showToast({
message: `车辆信息接口获取失败`,
duration: 3000
});
globalThis.type = '1'
globalThis.title = '车辆信息接口获取失败'
this.errorDialog.open()
this.loading = false
return
}
this.testXMLToJSONInWorker()
})
}
if (this.isSingle) {
imageBtn({btnWidth:'28%',btnHeight:'71%',imgSrc:$r('app.media.index_dj')})
.margin({ left: 80 * globalThis.ratio })
.onClick(() => {
if (this.loading) {
return
}
// this.vocObj.playAudio({
// type: 1,
// name: 'button_media.wav'
// })
if (judgeConfig.isTrajectoryOpen) {
router.pushUrl({
url: 'pages/UserInfo',
}, router.RouterMode.Single)
return
}
//判断数据库是否有表数据,有则直接跳转,没有则读取本地数据
getSyncData('MA_SYSSET').then(data => {
console.log('datadata', JSON.stringify(data))
if (data?.[0]) {
router.pushUrl({
url: 'pages/UserInfo',
}, router.RouterMode.Single)
} else {
this.testXMLToJSONInWorker()
}
});
})
}
imageBtn({btnWidth:'28%',btnHeight:'71%',imgSrc:$r('app.media.index_zj')})
.margin({ right: 80 * globalThis.ratio })
.onClick(() => {
if (this.loading) {
return
}
router.pushUrl({
url: 'pages/CarCheck'
}, router.RouterMode.Single);
})
}
.width('100%')
.justifyContent(FlexAlign.SpaceAround)
}
Column() {
Row() {
Column() {
Text('V外壳' + GlobalConfig.appVersion)
.fontColor('#CCAE7A')
.fontSize(18 * globalThis.ratio)
.width('30%')
.margin({ bottom: 10 })
// Text('V评判' + globalThis.judgeVersion)
// .fontColor('#CCAE7A')
// .fontSize(18 * globalThis.ratio)
// .width('30%')
// .margin({ bottom: 10 })
// Text('V 1.0')
// .fontColor('#CCAE7A')
// .fontSize(22 * globalThis.ratio)
// .width('30%')
// .margin({ bottom: 10 })
Text('授权信息:' + (this.hasAuth ? '已授权' : '未授权'))
.fontColor('#CCAE7A')
.fontSize(18 * globalThis.ratio)
.width('30%')
}
.margin({ left: 24 })
.gesture(
GestureGroup(GestureMode.Exclusive,
TapGesture({ count: 2 })
.onAction(() => {
// takePhotoFn(this.context)
globalThis.singlePlay = !globalThis.singlePlay
this.isSingle = globalThis.singlePlay
})
)
)
Text('考车号:' + this.deviceId)
.fontColor('#CCAE7A')
.fontSize(22 * globalThis.ratio)
.margin({ right: 24 })
}
.width('100%')
.justifyContent(FlexAlign.SpaceBetween)
.margin({ bottom: 10 })
}
//
if (this.dialogVisiable) {
Flex({ justifyContent: FlexAlign.Center }) {
Text('确认是否退出应用')
.fontSize(28 * this.ratio * this.dialogRatio)
.margin({ top: 100 * this.ratio * this.dialogRatio })
Row() {
Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
Text(' 取 消 ')
.fontSize(24 * this.ratio * this.dialogRatio)
.fontColor('#fff')
.width(100 * this.ratio * this.dialogRatio)
}
.commStyle()
.onClick(() => {
this.dialogVisiable = false
}).margin({ right: 10 * this.ratio })
Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
Text(' 确 定 ')
.fontSize(24 * this.ratio * this.dialogRatio)
.fontColor('#fff')
.width(100 * this.ratio * this.dialogRatio)
}
.commStyle()
.onClick(() => {
router.back()
})
}.position({ y: 265 * this.ratio * this.dialogRatio, x: 115 * this.ratio * this.dialogRatio })
}
.width(660 * this.ratio * this.dialogRatio)
.height(360 * this.ratio * this.dialogRatio)
.position({ x: 220 * this.ratio, y: 98 * this.ratio - 265 / 2 * (1 - this.ratio * this.dialogRatio) })
.backgroundColor('#E6E3DF')
//
.borderRadius(19 * this.ratio * this.dialogRatio)
}
if (this.loading) {
Column() {
Image($r('app.media.open_loading'))
.width(200 * globalThis.ratio)
.rotate({ angle: this.angle })
.height(200 * globalThis.ratio)
.animation({
duration: 5000, // 动画时长
curve: Curve.EaseOut, // 动画曲线
delay: 500, // 动画延迟
iterations: -1, // 播放次数
playMode: PlayMode.Normal, // 动画模式
})
.margin({ top: 30 * globalThis.ratio })
Image($r('app.media.car'))
.width(80 * globalThis.ratio)
.height(80 * globalThis.ratio)
.position({ x: 288 * globalThis.ratio, y: 89 * globalThis.ratio })
Text('获取考车信息,请稍候……')
.fontSize(24 * globalThis.ratio)
.margin({ top: 20 * globalThis.ratio })
.fontWeight(400)
}
.visibility(this.loading ? Visibility.Visible : Visibility.Hidden)
.width(660 * globalThis.ratio)
.height(360 * globalThis.ratio)
.position({ x: 150 * globalThis.ratio, y: 98 * globalThis.ratio })
.backgroundColor('#E6E3DF')
.borderRadius(19 * globalThis.ratio)
}
}
.width('100%')
.height('100%')
.justifyContent(FlexAlign.SpaceBetween)
.backgroundImagePosition({ x: 0, y: 0 })
.backgroundImage($r('app.media.index_bg'))
.backgroundImageSize({ width: '100%', height: '100%' })
}
async aboutToAppear() {
console.log('context.filesDir', this.context.filesDir)
this.dialogVisiable = false
this.angle = 0
this.loading = false
globalThis.lsh = '1111111111111'
globalThis.errorDialog = this.errorDialog
globalThis.udpEvent = new UdpEvent();
getTCP()
}
// 解压
unzip(inFile: string, outFile: string) {
return new Promise((resolve, reject) => {
let options: zlib.Options = {
level: zlib.CompressLevel.COMPRESS_LEVEL_DEFAULT_COMPRESSION,
memLevel: zlib.MemLevel.MEM_LEVEL_DEFAULT,
strategy: zlib.CompressStrategy.COMPRESS_STRATEGY_DEFAULT_STRATEGY,
};
try {
console.info('解压文件夹:', inFile, '解压文件夹out', outFile);
zlib.decompressFile(inFile, outFile, options, (errData) => {
console.log('解压成功', errData)
if (errData !== null) {
console.log('解压失败')
reject(false)
}
if (fs.accessSync(inFile)) {
fs.unlinkSync(inFile);
}
resolve(true)
})
} catch (err) {
console.error('解压失败error', err)
reject(false)
}
})
}
// 安装
async installBundle() {
// let hapFilePaths = ['/data/storage/el2/base/haps/entry/files/entry-default-signed.hap'];
let hapFilePaths = ['/data/storage/el2/base/haps/entry/files/entry-default-signed.hap'];
let installParam: installer.InstallParam = {
userId: 100,
isKeepData: false,
installFlag: 1,
};
try {
installer.getBundleInstaller().then((data: installer.BundleInstaller) => {
console.info('开始安装')
data.install(hapFilePaths, installParam, (err: BusinessError) => {
if (err) {
console.error('install failed:' + err.message);
} else {
console.info('install successfully.');
}
});
}).catch((error: BusinessError) => {
console.error('getBundleInstaller failed. Cause: ' + error.message);
});
} catch (error) {
let message = (error as BusinessError).message;
console.error('getBundleInstaller failed. Cause: ' + message);
}
}
async testXMLToJSONInWorker() {
if (this.loading) {
return
}
let workerInstance = new worker.ThreadWorker('entry/ets/workers/worker.ts');
const param = {
carId: globalThis.carInfo?.carId,
examinationRoomId: globalThis.carInfo?.examinationRoomId,
judgeVersion: globalThis.judgeVersion,
shellVersion: GlobalConfig.appVersion,
paraKdid: globalThis.timeInfo?.paraKdid || globalThis.timeInfo?.kdid,
kdid: globalThis.timeInfo?.kdid || globalThis.timeInfo?.paraKdid,
mode: globalThis.timeInfo?.mode,
context: this.context,
host: globalThis.host,
centerHost: globalThis.timeInfo?.url,
singlePlay: globalThis.singlePlay
}
this.loading = true
workerInstance.postMessage(param);
workerInstance.onmessage = (e: MessageEvents): void => {
console.log("baoyihu after postMessage :", JSON.stringify(e));
console.log("baoyihu after postMessage :", JSON.stringify(e.data));
//软件更新
if(e.data?.error?.resultCode == '-1'){
this.getModalValueCdAndCar(true)
}
// @ts-ignore
let workData: WorkData = e.data;
this.loading = false
if (workData.isComplete) {
if (globalThis.singlePlay) {
router.pushUrl({
url: 'pages/UserInfo',
}, router.RouterMode.Single)
return
}
getSyncData('MA_SYSSET').then(data => {
console.log('datadata', JSON.stringify(data))
// @ts-ignore
data.forEach(sys => {
//判断是否能点开始考试
if (sys.v_no === '854') {
globalThis.param854Str = sys.v_value
}
if (sys.v_no === '824' && decodeURIComponent(sys.v_value) == '0') {
// this.Param612Str= decodeURIComponent(sys.v_value)
router.pushUrl({
url: 'pages/CarCheck',
params: {
'fromIndex': true
}
}, router.RouterMode.Single)
} else {
router.pushUrl({
url: 'pages/ExaminerLogin',
}, router.RouterMode.Single)
}
})
});
}
workerInstance.terminate();
}
}
async heartMsg() {
const arr = [globalThis.signNum || 0, globalThis.statue || 1]
let tmpList = [];
tmpList.push(string2Bytes(arr[0], 1 * 8)[0])
tmpList.push(string2Bytes(arr[1], 1 * 8)[0])
const str = globalThis.lsh || '0000000000000'
for (let i = 0; i < str.length; i++) {
tmpList.push(string2Bytes(str.charCodeAt(i), 1 * 8)[0])
}
// console.log('kkkkmmm.carInfo', JSON.stringify(globalThis.carInfo))
const param = {
id: 31,
list: tmpList,
carNo: globalThis.carInfo.carNo,
placeId: globalThis.carInfo.examinationRoomId
}
// console.log('paramparam', JSON.stringify(param))
// globalThis.udpClient2.initHeartSendMsg(param,this.context)
if (globalThis.udpClient2.getStatus()) {
globalThis.udpClient2.sendMsgExt(param, this.context)
}
}
async onPageShow() {
console.log('ttttt', 1111)
await this.userAuth();
let resourceManager = this.context.resourceManager;
// this.vocObj = new voiceService(async (status, val, next) => {
// });
console.log('globalThis.singlePlay', globalThis.singlePlay)
if (globalThis.singlePlay == undefined || globalThis.singlePlay == null) {
setVideoParam()
this.context.resourceManager.getRawFileContent("welcome.wav").then(value => {
// this.vocObj.playAudio({
// type: 1,
// name: 'welcome.wav'
// })
// let rawFile = value;
}).catch(error => {
console.log("getRawFileContent promise error is " + error);
});
globalThis.singlePlay = false
}
this.isSingle = globalThis.singlePlay
this.loading = false
this.createAlbum()
this.num = 0
// const TcpClient: TcpClient =new TcpClient(result[0].tcplocalIp, result[0].tcplocalIpPort,result[0].tcpOppositeIp,result[0].tcpOppositePort)
globalThis.lsh = '1111111111111'
}
async createAlbum() {
this.fileHelper = new FileHelper();
this.fileHelper.createAlbum('jt')
this.fileHelper.createAlbum('pz');
}
userAuth() {
return new Promise((reslove,reject)=>{
const permissions: Array<Permissions> = ["ohos.permission.SET_TIME", "ohos.permission.READ_IMAGEVIDEO", "ohos.permission.DISTRIBUTED_DATASYNC", 'ohos.permission.CONNECTIVITY_INTERNAL', 'ohos.permission.CAMERA', 'ohos.permission.READ_MEDIA', 'ohos.permission.WRITE_MEDIA', 'ohos.permission.FILE_ACCESS_MANAGER'];
let context = this.context;
let atManager = abilityAccessCtrl.createAtManager();
// requestPermissionsFromUser会判断权限的授权状态来决定是否唤起弹窗
atManager.requestPermissionsFromUser(context, permissions).then((data) => {
this.initParams()
let grantStatus: Array<number> = data.authResults;
let length: number = grantStatus.length;
for (let i = 0; i < length; i++) {
if (grantStatus[i] === 0) {
// 用户授权,可以继续访问目标操作
reslove(true)
} else {
reject()
// 用户拒绝授权,提示用户必须授权才能访问当前页面的功能,并引导用户到系统设置中打开相应的权限
return;
}
}
// 授权成功
}).catch((err) => {
console.error(`Failed to request permissions from user. Code is ${err.code}, message is ${err.message}`);
})
})
}
requestDownload(httpPath, path, outFile, flag?) {
request.downloadFile(this.context, {
url: httpPath,
filePath: path
})
.then((downloadTask) => {
downloadTask.on('complete', async () => {
console.info('file download complete')
this.loading = false
await this.unzip(path, outFile)
if(flag){
this.installBundle()
}
})
if (!flag) {
this.mxwjDownloadFlag = false
}
}).catch(error => {
console.info('surenjun','download error')
console.log('响应头地址downloadeerror', JSON.stringify(error))
})
}
//flag true hap包 false 模型文件
async getModalValueCdAndCar(flag) {
this.loading = true
console.info('globalThis.carInfo.carId',globalThis.carInfo.carId)
const data = await getModalValueCdAndCar({
carid: globalThis.carInfo.carId,
// kdid: globalThis.timeInfo?.paraKdid || globalThis.timeInfo?.kdid
})
const outFile = flag ? '/data/storage/el2/base/haps/entry/files/' : '/mnt/hmdfs/100/account/device_view/local/files/models/'
const httpPath = flag ? data.getModalValueCdAndCarRsp.body.appPath : data.getModalValueCdAndCarRsp.body.filePath
const arr = httpPath.split('/')
let path
if (flag) {
console.info('outFile=>',outFile)
console.info('httpPath=>',httpPath)
path = '/data/storage/el2/base/haps/entry/files/' + arr[arr.length-1]
const isHapExit = fs.accessSync('/data/storage/el2/base/haps/entry/files/entry-default-signed.hap');
const isZipExit = fs.accessSync(path);
console.info('entry-default-signed.hap文件是否存在',isHapExit)
console.info( `${arr[arr.length-1]}文件是否存在`,isZipExit)
if(isHapExit){
fs.unlinkSync('/data/storage/el2/base/haps/entry/files/entry-default-signed.hap')
}
this.requestDownload(httpPath, path, outFile, flag)
return
} else {
this.mxwjDownloadFlag = true
const fileUtil = new FileUtil(globalThis.context)
await fileUtil.deleteF('models',1)
const folderPath = await fileUtil.initFolder(`/models`);
path = folderPath + '/' + arr[arr.length-1]
this.requestDownload(httpPath, path, outFile, flag)
return
}
}
async initParams() {
// deleteAllFIleLog(GlobalConfig.comoonfileWriteAddress + '/PLC/')
//设置plc udp 同步requesthost
await getUDP(this.context, false)
this.loading = false
await getDeviceInfo(this.context)
await getCarInfo()
await getUDP2(this.context, false)
getTCP()
this.deviceId = globalThis.carInfo.carNo
await setCurrentTime();
if(!globalThis.distanceClass){
const distanceClass = new GetDistance(globalThis.context)
await distanceClass.initFolder()
globalThis.distanceClass = distanceClass
console.info('surenjun','distanceClass=>初始化完成')
}
this.carNum = globalThis.carInfo.plateNo;
this.version = globalThis.version;
this.hasAuth = globalThis.hasAuth;
setTimeout(()=>{
this.initParamFlag=true
},3000)
initJudgeUdp()
takePhotoFn(this.context)
clearInterval(this.interval)
this.interval = setInterval(() => {
this.num++
setliushuiNum()
// getliushuiNum(this.context)
if (this.num >= 3) {
this.heartMsg()
}
}, 1000)
//下载软件包
// this.getModalValueCdAndCar(true)
//下载模型
this.getModalValueCdAndCar(false)
//下载模型
// await this.getModel()
// const arr = [0x55, 0xaa, 0x01, 0x00, 0x02, 0x01, 0x03, 0x00]
// globalThis.udpClientByTopLine.sendMsg(Array2Byte(arr).buffer)
}
async getModel() {
const context = this.context;
//下载模型
await getEsCarModel(context)
}
}