fix: 优化了xml转json

This commit is contained in:
wangzhongjie 2025-04-14 18:13:34 +08:00
parent ea12081e13
commit b1dfddda46
9 changed files with 321 additions and 184 deletions

View File

@ -1,18 +1,11 @@
import common from '@ohos.app.ability.common';
import router from '@ohos.router';
import { JudgeConfig } from "../config";
import { JudgeConfig } from '../config';
import promptAction from '@ohos.promptAction';
import errorMsgDialog from './compontents/errorMsgDialog';
import imageBtn from './compontents/imageBtn';
import VoiceAnnounce from './judgeSDK/utils/voiceAnnouncements';
import { BaseInfoType, centerCallBackMsgType } from '../model/Common';
import {
CarInfoType,
InitializeTheCentralTableType,
MASYSSETTableType,
TimeSynchronizationRspBody
} from '../model';
import { CarInfoType, InitializeTheCentralTableType, MASYSSETTableType, TimeSynchronizationRspBody } from '../model';
import { GetCarInfo, GetDeviceInfo, SetCurrentTime, UseAuth } from './Index/utils';
import { GetSyncData, InitializeTheCentralTable } from '../utils/table/Operation';
import { BusinessError } from '@ohos.base';
@ -24,8 +17,10 @@ import { CenterUDPBusinessInstance } from '../utils/business/CenterUdpBusiness';
import { DrivingDataStorage } from '../utils/business/DrivingDataStorage';
import { JudgeUdpBusinessInstance } from '../utils/business/JudgeUdpBusiness';
import { JudgeEmitterInstance } from '../utils/business/UdpEvent';
import { LoadingDialog } from './Index/Loading';
import { ExitDialog } from './Index/ExitDialog'
import HeaderComponent from './compontents/Header';
import CardComponent from './Index/Card';
import BottomMessageComponent from './Index/BottomMessage';
import LoadingComponent from './Index/Loading';
@Entry
@ -45,42 +40,17 @@ struct Index {
@State fd: number = -1;
@State carInfo: CarInfoType = {};
@State num: number = 0;
// 请求网络表等待弹窗
customDialogController: CustomDialogController = new CustomDialogController({
builder: LoadingComponent(),
customStyle: true,
alignment: DialogAlignment.Center,
autoCancel: true
});
private context = getContext(this) as common.UIAbilityContext;
private fileHelper: FileHelper = new FileHelper(this.context)
private avPlayer: VoiceAnnounce = new VoiceAnnounce(this.context)
private timeInfo: TimeSynchronizationRspBody = {}
private loadingDialog: CustomDialogController = new CustomDialogController({
builder: LoadingDialog(),
customStyle: true,
alignment: DialogAlignment.Center,
autoCancel: false
})
private delDialog: CustomDialogController = new CustomDialogController({
builder: LoadingDialog({
text: "正在清理本地数据,请稍候……"
}),
customStyle: true,
alignment: DialogAlignment.Center,
autoCancel: false
})
private exitDialog: CustomDialogController = new CustomDialogController({
builder: ExitDialog(),
customStyle: true,
alignment: DialogAlignment.Center,
autoCancel: false
})
private errorDialog: CustomDialogController = new CustomDialogController({
builder: errorMsgDialog({
title: AppStorage.get('title'),
type: AppStorage.get('type'),
cancel: () => {
},
confirm: () => {
}
}),
customStyle: true,
alignment: DialogAlignment.Center,
})
@Styles
commStyle(){
@ -122,17 +92,15 @@ struct Index {
AppStorage.setOrCreate('lsh', '1111111111111')
}
exam() {
this.loadingDialog.open()
// 联网考试逻辑处理
onlineExam() {
this.customDialogController.open()
if (!this.timeInfo) {
// AppStorage.setOrCreate('type', 1)
// AppStorage.setOrCreate('title', '时间同步接口连接失败')
this.errorDialog.open()
promptAction.showToast({
message: `时间同步接口连接失败`,
duration: 3000
});
this.loadingDialog.close()
this.customDialogController.close()
return
}
if (!this.carInfo) {
@ -140,16 +108,14 @@ struct Index {
message: `车辆信息接口获取失败`,
duration: 3000
});
AppStorage.setOrCreate('type', 1)
AppStorage.setOrCreate('title', '车辆信息接口获取失败')
this.errorDialog.open()
this.loadingDialog.close()
this.customDialogController.close()
return
}
this.testXMLToJSONInWorker()
}
practice() {
// 单机训练逻辑处理
singlePlayerTraining() {
AppStorage.setOrCreate('singlePlay', true)
if (JudgeConfig.isTrajectoryOpen) {
router.pushUrl({
@ -184,7 +150,6 @@ struct Index {
singlePlay: this.singlePlay
}
InitializeTheCentralTable(param).then((ret) => {
this.loadingDialog.close()
if (ret) {
GetSyncData<MASYSSETTableType>("MA_SYSSET").then(data => {
data.forEach(sys => {
@ -229,7 +194,6 @@ struct Index {
}
},)
await GetDeviceInfo(this.context)
// getTCP()
this.carInfo = AppStorage.get<CarInfoType>('carInfo')!
this.deviceId = this.carInfo.carNo || ""
await SetCurrentTime()
@ -245,90 +209,39 @@ struct Index {
}
build() {
Column() {
Row() {
Image($r('app.media.logo')).width('30%').margin({ left: 24 })
Row() {
Image($r('app.media.btn_setting')).width('16.7%')
.onClick(async () => {
router.pushUrl({
url: 'pages/Settings',
}, router.RouterMode.Single);
Flex({
justifyContent: FlexAlign.SpaceBetween,
direction: FlexDirection.Column
}) {
HeaderComponent({
shortLogo: false
})
Image($r('app.media.btn_back')).width('14.4%')
.onClick(() => {
this.exitDialog.open()
})
}
}
.width('100%')
.height(100)
.justifyContent(FlexAlign.SpaceBetween)
Row() {
imageBtn({ btnWidth: '28%', imgSrc: this.singlePlay ? $r('app.media.index_dj') : $r('app.media.index_lw') })
.margin({ left: 80 * this.ratio })
.onClick(() => {
if (this.singlePlay) {
this.practice()
} else {
this.exam()
CardComponent({
isSingle: this.singlePlay,
singleClick: () => {
this.singlePlayerTraining()
},
networkingClick: () => {
this.onlineExam()
}
})
imageBtn({ btnWidth: '28%', imgSrc: $r('app.media.index_zj') })
.margin({ right: 80 * this.ratio })
.onClick(() => {
router.pushUrl({
url: 'pages/CarCheck'
}, router.RouterMode.Single);
})
}
.padding({ top: 30, bottom: 30 })
.layoutWeight(1)
.width('100%')
.justifyContent(FlexAlign.SpaceAround)
Row() {
Column() {
Text('V外壳' + this.baseInfo?.version)
.fontColor('#CCAE7A')
.fontSize(28)
.width('30%')
.margin({ bottom: 10 })
Text('V评判' + this.baseInfo.judgeVersion)
.fontColor('#CCAE7A')
.fontSize(28)
.width('30%')
.margin({ bottom: 10 })
Text('授权信息:' + (this.baseInfo.hasAuth ? '已授权' : '未授权'))
.fontColor('#CCAE7A')
.fontSize(28)
.width('30%')
}
.margin({ left: 24 })
.gesture(
GestureGroup(GestureMode.Exclusive,
TapGesture({ count: 2 })
.onAction(() => {
BottomMessageComponent({
version: this.baseInfo.version,
judgeVersion: this.baseInfo.judgeVersion,
hasAuth: this.baseInfo.hasAuth,
examCarNumber: this.baseInfo.deviceNo,
versionClick: () => {
this.singlePlay = !this.singlePlay
AppStorage.setOrCreate('singlePlay', this.singlePlay)
}
})
)
)
Text('考车号:' + this.deviceId)
.fontColor('#CCAE7A')
.fontSize(36)
.margin({ right: 24 })
}
.padding({ top: 10, bottom: 10 })
.width('100%')
.justifyContent(FlexAlign.SpaceBetween)
}
.width('100%')
.height('100%')
.justifyContent(FlexAlign.SpaceBetween)
.width("100%")
.height("100%")
.backgroundImage($r('app.media.index_bg'))
.backgroundImageSize({
width: "100%",
height: "100%"
})
}
}

View File

@ -0,0 +1,38 @@
@Component
export default struct BottomMessageComponent {
@State version: string = ""
@State judgeVersion: string = ""
@State hasAuth: boolean = false
@State examCarNumber: string = ""
versionClick?: () => void
build() {
Flex(
{
justifyContent: FlexAlign.SpaceBetween,
alignItems: ItemAlign.End
}
) {
Column() {
Text('V外壳' + this.version).textCommonStyle()
Text('V评判' + this.judgeVersion).textCommonStyle()
Text("授权信息:" + this.hasAuth ? "已授权" : "未授权").textCommonStyle()
}.gesture(
GestureGroup(GestureMode.Exclusive,
TapGesture({ count: 2 })
.onAction(() => {
this.versionClick && this.versionClick()
})
)
)
Text("考车号: " + this.examCarNumber).textCommonStyle()
}
}
}
@Extend(Text)
function textCommonStyle() {
.fontSize(35)
.fontColor("#C7AF81")
}

View File

@ -0,0 +1,66 @@
import LoadingComponent from './Loading';
import router from '@ohos.router';
@Component
export default struct CardComponent {
// 是否单机
@Prop isSingle: boolean = false
// 单机点击
singleClick?: () => void
networkingClick?: () => void
build() {
Flex({
alignItems: ItemAlign.Center,
justifyContent: FlexAlign.SpaceAround
}) {
if (this.isSingle) {
// 单机
CardItemComponent({
url: $r("app.media.index_dj")
}).onClick(() => {
this.singleClick && this.singleClick()
// router.pushUrl({
// url: "pages/CandidatesList"
// })
})
} else {
// 联网
CardItemComponent({
url: $r("app.media.index_lw")
})
.onClick(() => {
this.networkingClick && this.networkingClick()
// this.customDialogController.open()
})
}
// 车辆自检
CardItemComponent({
url: $r("app.media.index_zj")
})
.onClick(() => {
router.pushUrl({
url: 'pages/CarCheck'
}, router.RouterMode.Single);
})
}.height(700)
}
}
@Component
struct CardItemComponent {
@State url: Resource = $r("app.media.index_zj")
build() {
Column() {
}
.backgroundImage(this.url)
.backgroundImageSize({
width: "100%",
height: "100%"
})
.width(500)
.height("100%")
}
}

View File

@ -1,13 +1,13 @@
@CustomDialog
export struct LoadingDialog {
@Prop private text: string = "获取考车信息,请稍候……"
@State private angle: number = 0
private controller: CustomDialogController
export default struct LoadingComponent {
@State angle: number = 0
private controller?: CustomDialogController;
aboutToAppear(): void {
// loading旋转动画
animateTo({
duration: 5000,
curve: Curve.EaseOut,
duration: 1500,
curve: Curve.Linear,
iterations: -1,
playMode: PlayMode.Normal,
}, () => {
@ -17,23 +17,29 @@ export struct LoadingDialog {
build() {
Column() {
Stack() {
Image($r('app.media.car')).width(150).height(150)
Image($r('app.media.open_loading'))
.width(200)
.rotate({ angle: this.angle })
.height(200)
.margin({ top: 30 })
Image($r('app.media.car'))
.width(80)
.height(80)
.position({ x: 288, y: 89 })
Text(this.text)
.fontSize(24)
.margin({ top: 20 })
.fontWeight(400)
.width(300)
.height(300)
.rotate({
angle: this.angle,
})
}.margin({
top: 40,
bottom: 40
})
Text("获取考车信息,请稍候...").fontSize(40).fontWeight(FontWeight.Bold)
}
.width(660)
.height(360)
.backgroundColor('#E6E3DF')
.borderRadius(19)
.width(900)
.height(500)
.borderRadius(20)
.backgroundColor("#E5E3DF")
.shadow({
radius: 30,
color: "#E7B544"
})
}
}

View File

@ -47,6 +47,7 @@ export async function GetCarInfo() {
deviceNo: AppStorage.get<string>('deviceNo') || ""
};
let res: ApiResponseType = await obtainCarExamInfo(params)
console.log("获取到的车辆信息", res)
if (res.obtainCarExamInfoRsp && res.obtainCarExamInfoRsp.body) {
const carInfo: ObtainCarExamInfoRspBody = res?.obtainCarExamInfoRsp?.body!
carInfo.plateNo = decodeURIComponent(carInfo.plateNo)
@ -54,6 +55,7 @@ export async function GetCarInfo() {
}
}
// 获取授权
export async function UseAuth(context: common.UIAbilityContext): Promise<boolean> {
return new Promise((resolve, reject) => {
const permissions: Array<Permissions> =
@ -63,13 +65,13 @@ export async function UseAuth(context: common.UIAbilityContext): Promise<boolean
abilityAccessCtrl.createAtManager().requestPermissionsFromUser(context, permissions).then(res => {
let grantStatus: Array<number> = res.authResults;
let length: number = grantStatus.length;
resolve(true)
for (let i = 0; i < length; i++) {
if (grantStatus[i] !== 0) {
reject(false)
return;
}
}
resolve(true)
}).catch((err: BusinessError) => {
console.log("获取权限失败", JSON.stringify(err))
reject(false)

View File

@ -125,7 +125,7 @@ struct Index {
const fileUtil = new FileUtils(this.context)
const folderPath = await fileUtil.initFolder(`/config`);
fileUtil.addFile(`${folderPath}/deviceNo.txt`, JSON.stringify(param))
AppStorage.setOrCreate('deviceNo', this.ip)
AppStorage.setOrCreate<string>('deviceNo', this.ip)
// upDateTableByArray('DeviceInfoTable', [{ deviceId: this.ip }])
registrationDeviceNo(param).then((res: ApiResponseType) => {
if (res.registrationDeviceNoRsp && res.registrationDeviceNoRsp.head &&

View File

@ -92,8 +92,12 @@ struct Index {
centerIp: this.inputTextList1[2],
centerPort: this.inputTextList1[3]
}
console.log("保存参数", JSON.stringify(param))
this.fileUtil.addFile(`${folderPath}/ipConfig.txt`, JSON.stringify(param))
AppStorage.setOrCreate<EnvironmentConfigurationType>("EnvironmentConfiguration", param)
const host = `http://${param.centerIp}:${param.centerPort}`
console.log("中心host",host)
AppStorage.setOrCreate<string>("host", host)
ethernet.setIfaceConfig("eth0", {
mode: ethernet.IPSetMode.STATIC,
ipAddr: this.inputTextList1[9],
@ -101,7 +105,7 @@ struct Index {
gateway: this.inputTextList1[5], //value.gateway网关
netMask: this.inputTextList1[4], //value.netMask网络掩码
dnsServers: this.inputTextList1[6],
domain:""
domain: ""
}, (error: BusinessError) => {
if (error) {
Prompt.showToast({

View File

@ -0,0 +1,110 @@
/*
* @Author: wangzhongjie
* @Date: 2024-07-18 15:53:08
* @LastEditors: wangzhongjie
* @LastEditTime: 2024-07-18 15:53:08
* @Description: 头部
* @Email: shutdown0630@163.com
*/
import dayTs from '../../utils/Date'
import router from '@ohos.router'
import Prompt from '@system.prompt'
import common from '@ohos.app.ability.common'
@Component
export default struct HeaderComponent {
@State shortLogo: boolean = true
@State time: string = ""
@State timer: number = 0
// 自定义返回区域
@BuilderParam
backAreaBuilder?: () => void = this.customBuilder
// 扩充Logo后面区域
@BuilderParam
logoExpansionBuilder?: () => void = this.customBuilder
@Builder
customBuilder() {
}
aboutToAppear(): void {
this.getCurrentTime()
this.timer = setInterval(() => {
this.getCurrentTime()
}, 1000)
}
aboutToDisappear(): void {
clearInterval(this.timer)
}
getCurrentTime() {
this.time = dayTs(new Date()).format("YYYY-MM-DD HH:mm:ss")
}
build() {
Flex({
justifyContent: FlexAlign.SpaceBetween,
alignItems: ItemAlign.Center
}) {
if (this.shortLogo) {
Row() {
Image($r('app.media.shortLogo')).height(100).width(150).objectFit(ImageFit.Contain).margin({
left: 10
})
Text(this.time)
.fontColor("#fff")
.margin({
left: 10
}).fontSize(16)
if (this.logoExpansionBuilder) {
this.logoExpansionBuilder()
}
}
} else {
Image($r('app.media.logo')).height(100).width(400).objectFit(ImageFit.Contain).margin({
left: 10
})
}
if (this.shortLogo) {
if (this.backAreaBuilder) {
this.backAreaBuilder()
} else {
Image($r('app.media.topB_back')).height(100).onClick(() => {
router.back()
})
}
} else {
Row() {
Image($r('app.media.btn_setting')).height(100).onClick(() => {
console.log("点击设置")
router.pushUrl({
url: 'pages/Settings',
}, router.RouterMode.Single);
})
Image($r('app.media.btn_back')).height(100).onClick(() => {
Prompt.showDialog({
title: "提示",
message: "确定要退出吗?",
buttons: [
{
text: '取消',
color: '#666666'
},
{
text: '退出',
color: '#666666'
}
],
success: () => {
(getContext(this) as common.UIAbilityContext).terminateSelf()
}
})
})
}
}
}
.height(100)
}
}

View File

@ -39,46 +39,43 @@ function setObj(target: Record<string, object>, key: string, value: object) {
}
function transfer(target: Array<object>, name?: string): object {
const result: object = new Object()
target.forEach((el: object) => {
const _elements: Array<object> = el['_elements']
const result: Record<string, ESObject> = {}; // 使用 Record 类型以便动态添加属性
target.forEach((el: ESObject) => {
const _elements: Array<object> = el['_elements'];
if (el['_type'] === "element") {
if (_elements === undefined) {
return
return;
}
const jsonObj: Record<string, object> = result[el['_name']] as Record<string, object>
const jsonObj: ESObject = result[el['_name']];
const handleCommonArray = (obj: object) => {
if (Array.isArray(jsonObj)) {
result[el['_name']].push(obj)
jsonObj.push(obj);
} else {
result[el['_name']] = [result[el['_name']], obj]
}
result[el['_name']] = [jsonObj, obj];
}
};
if (_elements && _elements.length === 1 && _elements[0]['_type'] === 'text') {
if (_elements && _elements.length && _elements[0]['_type'] === 'text') {
if (jsonObj) {
handleCommonArray(_elements[0]['_text'])
handleCommonArray(_elements[0]['_text']);
} else {
setObj(jsonObj, el['_name'], _elements[0]["_text"])
// jsonObj[el['_name'] as string] = _elements[0]["_text"] as object
result[el['_name']] = _elements[0]['_text'];
}
} else {
if (jsonObj) {
handleCommonArray(transfer(el['_elements'], el['_name']))
handleCommonArray(transfer(el['_elements'], el['_name']));
} else {
setObj(jsonObj, el['_name'], transfer(el['_elements'], el['_name']))
// jsonObj[el['_name'] as string] = transfer(el['_elements'], el['_name'])
result[el['_name']] = transfer(el['_elements'], el['_name']);
}
}
} else if (el['_attributes'] && name) {
result[name] = {
value: el['_text'],
attributes: el['__attributes']
attributes: el['_attributes'], // 修复属性名
};
}
}
})
return result
});
return result;
}
interface CenterCodeResult {
@ -123,6 +120,7 @@ export default function Request<T extends RequestResult>(options: RequestOption)
const instance = http.createHttp()
const baseURL = options.host || base
console.log(RequestTag, "基础url:", baseURL)
console.log(RequestTag, "参数", JSON.stringify(options.data))
instance.request(baseURL + options.url, {
method: options.method,
header: {
@ -172,7 +170,7 @@ export default function Request<T extends RequestResult>(options: RequestOption)
}
}).catch((err: BusinessError) => {
console.error(RequestTag, "出错的url:", options.url, "错误信息:", JSON.stringify(err))
console.error(RequestTag, "出错的url:", baseURL, options.url, "错误信息:", JSON.stringify(err))
if (!err || !(err?.message)) {
reject({
code: -1