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 common from '@ohos.app.ability.common';
import router from '@ohos.router'; import router from '@ohos.router';
import { JudgeConfig } from "../config"; import { JudgeConfig } from '../config';
import promptAction from '@ohos.promptAction'; import promptAction from '@ohos.promptAction';
import errorMsgDialog from './compontents/errorMsgDialog';
import imageBtn from './compontents/imageBtn';
import VoiceAnnounce from './judgeSDK/utils/voiceAnnouncements'; import VoiceAnnounce from './judgeSDK/utils/voiceAnnouncements';
import { BaseInfoType, centerCallBackMsgType } from '../model/Common'; import { BaseInfoType, centerCallBackMsgType } from '../model/Common';
import { import { CarInfoType, InitializeTheCentralTableType, MASYSSETTableType, TimeSynchronizationRspBody } from '../model';
CarInfoType,
InitializeTheCentralTableType,
MASYSSETTableType,
TimeSynchronizationRspBody
} from '../model';
import { GetCarInfo, GetDeviceInfo, SetCurrentTime, UseAuth } from './Index/utils'; import { GetCarInfo, GetDeviceInfo, SetCurrentTime, UseAuth } from './Index/utils';
import { GetSyncData, InitializeTheCentralTable } from '../utils/table/Operation'; import { GetSyncData, InitializeTheCentralTable } from '../utils/table/Operation';
import { BusinessError } from '@ohos.base'; import { BusinessError } from '@ohos.base';
@ -24,8 +17,10 @@ import { CenterUDPBusinessInstance } from '../utils/business/CenterUdpBusiness';
import { DrivingDataStorage } from '../utils/business/DrivingDataStorage'; import { DrivingDataStorage } from '../utils/business/DrivingDataStorage';
import { JudgeUdpBusinessInstance } from '../utils/business/JudgeUdpBusiness'; import { JudgeUdpBusinessInstance } from '../utils/business/JudgeUdpBusiness';
import { JudgeEmitterInstance } from '../utils/business/UdpEvent'; import { JudgeEmitterInstance } from '../utils/business/UdpEvent';
import { LoadingDialog } from './Index/Loading'; import HeaderComponent from './compontents/Header';
import { ExitDialog } from './Index/ExitDialog' import CardComponent from './Index/Card';
import BottomMessageComponent from './Index/BottomMessage';
import LoadingComponent from './Index/Loading';
@Entry @Entry
@ -45,42 +40,17 @@ struct Index {
@State fd: number = -1; @State fd: number = -1;
@State carInfo: CarInfoType = {}; @State carInfo: CarInfoType = {};
@State num: number = 0; @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 context = getContext(this) as common.UIAbilityContext;
private fileHelper: FileHelper = new FileHelper(this.context) private fileHelper: FileHelper = new FileHelper(this.context)
private avPlayer: VoiceAnnounce = new VoiceAnnounce(this.context) private avPlayer: VoiceAnnounce = new VoiceAnnounce(this.context)
private timeInfo: TimeSynchronizationRspBody = {} 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 @Styles
commStyle(){ commStyle(){
@ -122,17 +92,15 @@ struct Index {
AppStorage.setOrCreate('lsh', '1111111111111') AppStorage.setOrCreate('lsh', '1111111111111')
} }
exam() { // 联网考试逻辑处理
this.loadingDialog.open() onlineExam() {
this.customDialogController.open()
if (!this.timeInfo) { if (!this.timeInfo) {
// AppStorage.setOrCreate('type', 1)
// AppStorage.setOrCreate('title', '时间同步接口连接失败')
this.errorDialog.open()
promptAction.showToast({ promptAction.showToast({
message: `时间同步接口连接失败`, message: `时间同步接口连接失败`,
duration: 3000 duration: 3000
}); });
this.loadingDialog.close() this.customDialogController.close()
return return
} }
if (!this.carInfo) { if (!this.carInfo) {
@ -140,16 +108,14 @@ struct Index {
message: `车辆信息接口获取失败`, message: `车辆信息接口获取失败`,
duration: 3000 duration: 3000
}); });
AppStorage.setOrCreate('type', 1) this.customDialogController.close()
AppStorage.setOrCreate('title', '车辆信息接口获取失败')
this.errorDialog.open()
this.loadingDialog.close()
return return
} }
this.testXMLToJSONInWorker() this.testXMLToJSONInWorker()
} }
practice() { // 单机训练逻辑处理
singlePlayerTraining() {
AppStorage.setOrCreate('singlePlay', true) AppStorage.setOrCreate('singlePlay', true)
if (JudgeConfig.isTrajectoryOpen) { if (JudgeConfig.isTrajectoryOpen) {
router.pushUrl({ router.pushUrl({
@ -184,7 +150,6 @@ struct Index {
singlePlay: this.singlePlay singlePlay: this.singlePlay
} }
InitializeTheCentralTable(param).then((ret) => { InitializeTheCentralTable(param).then((ret) => {
this.loadingDialog.close()
if (ret) { if (ret) {
GetSyncData<MASYSSETTableType>("MA_SYSSET").then(data => { GetSyncData<MASYSSETTableType>("MA_SYSSET").then(data => {
data.forEach(sys => { data.forEach(sys => {
@ -229,7 +194,6 @@ struct Index {
} }
},) },)
await GetDeviceInfo(this.context) await GetDeviceInfo(this.context)
// getTCP()
this.carInfo = AppStorage.get<CarInfoType>('carInfo')! this.carInfo = AppStorage.get<CarInfoType>('carInfo')!
this.deviceId = this.carInfo.carNo || "" this.deviceId = this.carInfo.carNo || ""
await SetCurrentTime() await SetCurrentTime()
@ -245,90 +209,39 @@ struct Index {
} }
build() { build() {
Column() { Flex({
Row() { justifyContent: FlexAlign.SpaceBetween,
Image($r('app.media.logo')).width('30%').margin({ left: 24 }) direction: FlexDirection.Column
Row() { }) {
Image($r('app.media.btn_setting')).width('16.7%') HeaderComponent({
.onClick(async () => { shortLogo: false
router.pushUrl({
url: 'pages/Settings',
}, router.RouterMode.Single);
}) })
Image($r('app.media.btn_back')).width('14.4%') CardComponent({
.onClick(() => { isSingle: this.singlePlay,
this.exitDialog.open() singleClick: () => {
}) this.singlePlayerTraining()
} },
} networkingClick: () => {
.width('100%') this.onlineExam()
.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()
} }
}) })
imageBtn({ btnWidth: '28%', imgSrc: $r('app.media.index_zj') }) BottomMessageComponent({
.margin({ right: 80 * this.ratio }) version: this.baseInfo.version,
.onClick(() => { judgeVersion: this.baseInfo.judgeVersion,
router.pushUrl({ hasAuth: this.baseInfo.hasAuth,
url: 'pages/CarCheck' examCarNumber: this.baseInfo.deviceNo,
}, router.RouterMode.Single); versionClick: () => {
})
}
.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(() => {
this.singlePlay = !this.singlePlay this.singlePlay = !this.singlePlay
AppStorage.setOrCreate('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%")
.width('100%') .height("100%")
.justifyContent(FlexAlign.SpaceBetween)
}
.width('100%')
.height('100%')
.justifyContent(FlexAlign.SpaceBetween)
.backgroundImage($r('app.media.index_bg')) .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 @CustomDialog
export struct LoadingDialog { export default struct LoadingComponent {
@Prop private text: string = "获取考车信息,请稍候……" @State angle: number = 0
@State private angle: number = 0 private controller?: CustomDialogController;
private controller: CustomDialogController
aboutToAppear(): void { aboutToAppear(): void {
// loading旋转动画
animateTo({ animateTo({
duration: 5000, duration: 1500,
curve: Curve.EaseOut, curve: Curve.Linear,
iterations: -1, iterations: -1,
playMode: PlayMode.Normal, playMode: PlayMode.Normal,
}, () => { }, () => {
@ -17,23 +17,29 @@ export struct LoadingDialog {
build() { build() {
Column() { Column() {
Stack() {
Image($r('app.media.car')).width(150).height(150)
Image($r('app.media.open_loading')) Image($r('app.media.open_loading'))
.width(200) .width(300)
.rotate({ angle: this.angle }) .height(300)
.height(200) .rotate({
.margin({ top: 30 }) angle: this.angle,
Image($r('app.media.car')) })
.width(80) }.margin({
.height(80) top: 40,
.position({ x: 288, y: 89 }) bottom: 40
Text(this.text) })
.fontSize(24)
.margin({ top: 20 }) Text("获取考车信息,请稍候...").fontSize(40).fontWeight(FontWeight.Bold)
.fontWeight(400)
} }
.width(660) .width(900)
.height(360) .height(500)
.backgroundColor('#E6E3DF') .borderRadius(20)
.borderRadius(19) .backgroundColor("#E5E3DF")
.shadow({
radius: 30,
color: "#E7B544"
})
} }
} }

View File

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

View File

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

View File

@ -92,8 +92,12 @@ struct Index {
centerIp: this.inputTextList1[2], centerIp: this.inputTextList1[2],
centerPort: this.inputTextList1[3] centerPort: this.inputTextList1[3]
} }
console.log("保存参数", JSON.stringify(param))
this.fileUtil.addFile(`${folderPath}/ipConfig.txt`, JSON.stringify(param)) this.fileUtil.addFile(`${folderPath}/ipConfig.txt`, JSON.stringify(param))
AppStorage.setOrCreate<EnvironmentConfigurationType>("EnvironmentConfiguration", 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", { ethernet.setIfaceConfig("eth0", {
mode: ethernet.IPSetMode.STATIC, mode: ethernet.IPSetMode.STATIC,
ipAddr: this.inputTextList1[9], ipAddr: this.inputTextList1[9],

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