This commit is contained in:
lixiao 2025-09-26 11:11:56 +08:00
parent 1baa3dd861
commit 39e161f670
17 changed files with 915 additions and 46 deletions

View File

@ -1,6 +1,11 @@
{
"apiType": "stageMode",
"buildOption": {
"arkOptions": {
"types": [
"./src/main/ets/api/typings"
]
}
},
"buildOptionSet": [
{

View File

@ -0,0 +1,4 @@
export * from './padController';
export * from './vehicleCollectionController';

View File

@ -0,0 +1,71 @@
import { request } from '../utils/Request';
import { http } from '@kit.NetworkKit';
/** 01、登录Pad POST /car-inspection-rest/pad/login */
export async function padLoginUsingPost(body: API.PadLoginReq) {
return request<API.RPadLoginRsp>('/car-inspection-rest/pad/login', {
method: http.RequestMethod.POST,
headers: {
'Content-Type': 'application/json',
},
data: body,
});
}
/** 02、获取Pad记录信息 GET /car-inspection-rest/pad/record/info */
export async function getPadRecordInfoUsingGet(params: API.getPadRecordInfoUsingGETParams,) {
return request<API.RPadRecordRsp>('/car-inspection-rest/pad/record/info', {
method: http.RequestMethod.GET,
params,
});
}
/** 03、获取查验线监控信息列表 GET /car-inspection-rest/pad/line/monitor */
export async function getLineMonitorInfoUsingGet() {
return request<API.RListBusiInspectVo>('/car-inspection-rest/pad/line/monitor', {
method: http.RequestMethod.GET,
});
}
/** 04、获取查验预警列表 POST /car-inspection-rest/pad/inspect/alarm */
export async function getInspectAlarmUsingPost(
body: API.InspectAlarmQueryReq,
) {
return request<API.RListInspectAlarmItemRsp>('/car-inspection-rest/pad/inspect/alarm', {
method: http.RequestMethod.POST,
headers: {
'Content-Type': 'application/json',
},
data: body,
});
}
/** 05、获取查验结果列表 POST /car-inspection-rest/pad/inspect/result/list */
export async function getInspectResultListUsingPost(body: API.InspectRecordResultReq,) {
return request<API.RListInspectRecordResultRsp>('/car-inspection-rest/pad/inspect/result/list', {
method: http.RequestMethod.POST,
headers: {
'Content-Type': 'application/json',
},
data: body,
});
}
/** 06、获取查验结果详情 GET /car-inspection-rest/pad/inspect/result/detail */
export async function getInspectResultDetailUsingGet(params: API.getInspectResultDetailUsingGETParams,) {
return request<API.RInspectRecordDetailVo>('/car-inspection-rest/pad/inspect/result/detail', {
method: http.RequestMethod.GET,
params
});
}
/** 07、获取流程阶段与步骤信息 GET /car-inspection-rest/pad/stage-step/info */
export async function getStageAndStepInfoUsingGet() {
return request<API.RListStageAndStepRsp>('/car-inspection-rest/pad/stage-step/info', {
method: http.RequestMethod.GET,
});
}

View File

@ -0,0 +1,589 @@
declare namespace API {
interface BusiInspectVo {
/** 管理辖区 */
administrativeJurisdiction?: string
/** 申请日期 */
applicationDate?: string
/** 业务原因 */
businessReason?: string
/** 业务类型:1新车注册登记 2二手车过户 3车辆年检 4车辆变更登记 5违法违规车辆 */
businessType?: string
/** 合格证编号 */
certificateNo?: string
/** 当前流程id */
currentStageId?: number
/** 当前步骤id */
currentStepId?: number
/** 结束时间 */
endTime?: string
id?: number
inspectorId?: number
/** 发证日期 */
issuingDate?: string
/** 号牌号码 */
licensePlateNumber?: string
/** 号牌种类 */
licensePlateType?: string
/** 线路编号 */
lineCode?: string
lineId?: number
/** 线路名称 */
lineName?: string
/** 车辆型号 */
model?: string
/** 机动车所有人 */
motorVehicleOwner?: string
/** 结果1未查验 2通过 3不通过 4终止 */
results?: string
/** 审核签名图片 */
reviewSignPhoto?: string
/** 审核状态 0未审核 1审核通过 2审核不通过 */
reviewStatus?: string
/** 流水号 */
serialNumber?: string
/** 流水状态:1等待查验 2受理凭证打印完成 3查验完成 4签字完成 */
serialStatus?: string
/** 开始时间 */
startTime?: string
stationId?: number
status?: string
/** 步骤名 */
stepName?: string
/** 车型id */
vehicleKindId?: number
/** 车辆识别代号 */
vin?: string
}
interface GetCamaraConfigReq {
/** 设备唯一标识 */
deviceNo?: string
}
interface GetCamaraConfigRsp {
/** 摄像头ID */
id?: number
/** IP地址 */
ipAddress?: string
/** 登录密码 */
password?: string
/** 安装位置,具体含义在平台系统字典上自定义。 */
postionCode?: string
/** rtsp流端口号 */
rtspPort?: string
/** 登录用户名 */
username?: string
}
interface getInspectResultDetailUsingGETParams {
/** id */
id: number
}
interface getPadRecordInfoUsingGETParams {
/** imei */
imei: string
}
interface ImageBase64Req {
/** Base64编码的图片 */
imageBase64: string
/** 图片格式 */
imageFormat?: string
}
interface InspectAlarmItemRsp {
/** 报警代码 */
alarmCode?: string
/** 报警信息 */
alarmInfo?: string
/** 告警状态1待处理 2待人工处理 5自动消除 6人工消除 */
alarmStatus?: string
/** 创建时间 */
createTime?: string
/** 处理信息 */
handleInfo?: string
/** 图片地址 */
photoUrl?: string
/** 流程名称 */
stageName?: string
/** 步骤名称 */
stepName?: string
}
interface InspectAlarmQueryReq {
/** 报警结束时间 */
alarmEndTime?: string
/** 报警开始时间 */
alarmStartTime?: string
/** 报警状态 */
alarmStatus?: string
/** 线路ID */
lineId?: number
/** 流程ID */
stageId?: number
/** 步骤ID */
stepId?: number
}
interface InspectionInfo {
/** 车辆类型 */
carType?: string
}
interface InspectionVo {
/** 流水Id */
certificateId?: number
}
interface InspectPhotoVo {
/** 主键ID */
id?: number
/** 照片URL */
photoUrl?: string
/** 任务编码 */
taskCode?: string
/** 任务名称 */
taskName?: string
}
interface InspectRecordDetailVo {
/** 业务类型1新车注册登记 2二手车过户 3车辆年检 4车辆变更登记 5违法违规车辆 */
businessType?: string
/** 创建时间 */
createTime?: string
/** 发动机型号(合格证model) */
engModel?: string
/** 生产厂家 */
factoryName?: string
/** 查验照片 */
inspectPhotos?: InspectPhotoVo[]
/** 查验员名称 */
inspectorName?: string
/** 号牌号码 */
licensePlateNumber?: string
/** 号牌种类 */
licensePlateType?: string
/** 查验线名称 */
lineName?: string
/** 合格证品牌名称 */
manufactureBrandName?: string
/** 车型型号 */
model?: string
/** 生产时间(年/月拼接) */
productionTime?: string
/** 查验结果1未查验 2通过 3不通过 4终止 */
results?: string
/** 机器人名称 */
robotName?: string
/** 流水号 */
serialNumber?: string
/** 流水状态1等待查验 2受理凭证打印完成 3查验完成 4签字完成 */
serialStatus?: string
/** 车型品牌名称 */
vehicleBrandName?: string
/** 车辆识别代号(VIN) */
vin?: string
}
interface InspectRecordResultReq {
/** 查验日期 */
inspectDate?: string
/** 查验线ID */
lineId?: string
/** 查验结果 */
results?: string
/** 当前阶段ID */
stageId?: string
}
interface InspectRecordResultRsp {
/** 品牌名称 */
brandName?: string
/** 业务类型 */
businessType?: string
/** 创建时间 */
createTime?: string
/** 查验记录id */
id?: string
/** 查验线名称 */
name?: string
/** 查验结果 */
results?: string
/** 流水号 */
serialNumber?: string
/** 车辆识别代号 */
vin?: string
}
interface LoginRobotReq {
/** imei号 */
imei?: string
/** 密码 */
password?: string
/** 用户名 */
username?: string
}
interface PadLoginReq {
/** pad唯一编号 */
imei?: string
/** 密码 */
password?: string
/** 用户名 */
username?: string
}
interface PadLoginRsp {
/** 线路 */
lines?: VcInspectionLine[]
/** 查验员姓名 */
name?: string
/** 检测站id */
stationId?: string
/** 检测站名称 */
stationName?: string
/** 用户id */
userId?: string
}
interface PadRecordRsp {
/** imei */
imei?: string
/** 线路 */
lines?: VcInspectionLine[]
}
interface QueryVehicleKindRsp {
/** 车架号遮挡描述:掀开主驾驶脚垫 */
blockInfo?: string
/** 充电口位置(快充) */
chargingPortPosition?: string
/** 车架号其他移动:轮胎左侧转向、备胎移出等 */
otherMove?: string
/** 铭牌位置 */
platePosition?: string
/** 车架号总体位置 */
position?: string
/** 车架号方位信息,类似左边、右边等 */
positionDirection?: string
/** 车架号座椅移动:后移、前移、左移、右移等 */
seatMove?: string
/** 慢充口位置 */
slowChargingPortPosition?: string
}
interface R {
code?: number
data?: Record<string, object>
msg?: string
}
interface RInspectionInfo {
code?: number
data?: InspectionInfo
msg?: string
}
interface RInspectionVo {
code?: number
data?: InspectionVo
msg?: string
}
interface RInspectRecordDetailVo {
code?: number
data?: InspectRecordDetailVo
msg?: string
}
interface RListBusiInspectVo {
code?: number
data?: BusiInspectVo[]
msg?: string
}
interface RListGetCamaraConfigRsp {
code?: number
data?: GetCamaraConfigRsp[]
msg?: string
}
interface RListInspectAlarmItemRsp {
code?: number
data?: InspectAlarmItemRsp[]
msg?: string
}
interface RListInspectRecordResultRsp {
code?: number
data?: InspectRecordResultRsp[]
msg?: string
}
interface RListStageAndStepRsp {
code?: number
data?: StageAndStepRsp[]
msg?: string
}
interface RobotInspectionInfoReq {
/** 管理辖区 */
administrativeJurisdiction?: string
/** 申请日期 */
applicationDate?: string
/** 轴荷 (kg) */
axleLoad?: string
/** 车身颜色 */
bodyColor?: string
/** 合格证编号 */
certificateConformityNumber?: string
/** 底盘型号 */
chassisModel?: string
/** 中文品牌 */
chineseBrand?: string
/** 排量和功率 */
displacemenAndPower?: string
/** 排放标准 */
emissionStandard?: string
/** 发动机型号 */
engineModel?: string
/** 发动机号 */
engineNumber?: string
/** 油耗 */
fuelConsumption?: string
/** 燃料种类 */
fuelType?: string
/** 总质量 (kg) */
grossVehicleMass?: string
/** 货厢内部尺寸 (mm) */
innerDimensionsOfCargoBox?: string
/** 查验站id */
inspectionStationId?: number
/** 发证日期 */
issuingDate?: string
/** 整备质量 (kg) */
kerbMass?: string
/** 号牌号码 */
licensePlateNumber?: string
/** 号牌种类 */
licensePlateType?: string
/** 机动车所有人 */
motorVehicleOwner?: string
/** 轴数 */
numberOfAxles?: string
/** 钢板弹簧片数 */
numberOfLeafSprings?: string
/** 轮胎数 */
numberOfTires?: string
/** 外廓尺寸 (mm) */
overallDimensions?: string
/** 额定载质量 (kg) */
ratedLoadMass?: string
/** 机器人id */
robotId?: number
/** 流水号 */
serialNumber?: number
/** 转向形式 */
steeringType?: string
/** 轮胎规格 */
tireSpecification?: string
/** 轮距 (前 / 后)(mm) */
trackFrontOrRear?: string
/** 车辆品牌 */
vehicleBrand?: string
/** 车辆识别代号 */
vehicleIdentificationNumber?: string
/** 车辆制造日期 */
vehicleManufacturingDate?: string
/** 车辆制造企业名称 */
vehicleManufacturingEnterpriseName?: string
/** 车辆型号 */
vehicleModel?: string
/** 车辆型号 */
vehicleModelAgain?: string
/** 车辆名称 */
vehicleName?: string
/** 轴距 (mm) */
wheelbase?: string
}
interface RobotInspectionPhotoReq {
/** 合格证照片 */
certConformityPhoto?: string
/** 查验id */
certificateId?: string
/** 发动机号照片 */
engNoPhoto?: string
/** 保险单照片 */
insPolicyPhoto?: string
/** 左前 45 度照片 */
photo45FL?: string
/** 右后 45 度照片 */
photo45RR?: string
/** 机器人id */
robotId?: string
/** 流水号 */
serialNumber?: string
/** 查验站id */
stationId?: string
/** 轮胎规格照片 */
tireSpecPhoto?: string
/** 车辆喷涂照片 */
vehPaintingPhoto?: string
/** 购车发票照片 */
vehPurInvPhoto?: string
/** 车辆识别号照片 */
vinPhoto?: string
}
interface RobotInspectionVideoReq {
/** 场地视频 */
areaVideo?: string
/** 查验id */
certificateId?: string
/** 发动机号视频 */
engNoVideo?: string
/** 机器人id */
robotId?: string
/** 流水号 */
serialNumber?: string
/** 查验站id */
stationId?: string
/** 轮胎规格视频 */
tireSpecVideo?: string
/** 车辆喷涂视频 */
vehPaintingVideo?: string
/** 左前 45 度视频 */
video45FL?: string
/** 右后 45 度视频 */
video45RR?: string
/** 车辆识别代号视频 */
vinVideo?: string
}
interface RobotLoginRsp {
/** 机器人id */
robotId?: string
/** 检测站id */
stationId?: string
/** token */
token?: string
/** 用户id */
userId?: string
}
interface RPadLoginRsp {
code?: number
data?: PadLoginRsp
msg?: string
}
interface RPadRecordRsp {
code?: number
data?: PadRecordRsp
msg?: string
}
interface RQueryVehicleKindRsp {
code?: number
data?: QueryVehicleKindRsp
msg?: string
}
interface RRobotLoginRsp {
code?: number
data?: RobotLoginRsp
msg?: string
}
interface Rstring {
code?: number
data?: string
msg?: string
}
interface StageAndStepRsp {
/** 阶段编号 */
stageCode?: string
/** 阶段id */
stageId?: number
/** 阶段名称 */
stageName?: string
/** 步骤列表 */
stepList?: StepVo[]
}
interface StepVo {
code?: string
id?: number
name?: string
orderNo?: number
stageId?: string
}
interface UploadPhotoReq {
/** base64的图片 */
base64?: string
/** 查验线id可以不传。如果上传了这个参数那么同一个查验站的图片会保存在一个目录下 */
lineId?: string
}
interface VcInspectionLine {
code?: string
createBy?: string
createTime?: string
deptIdStr?: string
doronCheckCode?: string
doronCheckResult?: string
id?: number
name?: string
params?: Record<string, object>
remark?: string
stationId?: number
status?: string
updateBy?: string
updateTime?: string
}
interface VehicleCollectionReq {
/** 车架号遮挡描述:掀开主驾驶脚垫 */
blockInfo?: string
/** 品牌 */
brandName?: string
/** 充电口图片 */
chargingPortPhotoUrl?: string
/** 充电口位置 */
chargingPortPosition?: string
/** 生产厂家 */
factoryName?: string
/** 型号 */
model?: string
/** 生产月份 */
month?: string
/** 其他移动:轮胎左侧转向、备胎移出等 */
otherMove?: string
/** padId */
padId?: number
/** 铭牌照片 */
platePhotoUrl?: string
/** 铭牌位置 */
platePosition?: string
/** 铭牌位置图片 */
platePositionUrl?: string
/** 车架号总体位置 */
position?: string
/** 车架号方位信息,类似左边、右边等 */
positionDirection?: string
/** 车架号座椅挪动 */
seatMove?: string
/** 慢充图片 */
slowChargingPortPhotoUrl?: string
/** 慢充位置 */
slowChargingPortPosition?: string
/** 车架号图片 */
vinPhotoUrl?: string
/** 生产年份 */
year?: string
}
}

View File

@ -0,0 +1,13 @@
import { request } from '../utils/Request';
import { http } from '@kit.NetworkKit';
/** 01、保存车型采集信息 POST /car-inspection-rest/pad/vehicleCollection/saveCollection.do */
export async function saveVinPositionUsingPost(body: API.VehicleCollectionReq,) {
return request<API.R>('/car-inspection-rest/pad/vehicleCollection/saveCollection.do', {
method: http.RequestMethod.POST,
headers: {
'Content-Type': 'application/json',
},
data: body,
});
}

View File

@ -0,0 +1,15 @@
zip:
targetFolder: ./dist
outName: date
openApi:
requestLibPath: import { request } from '../utils/Request'
schemaPath: http://88.22.20.118:8080/car-inspection-rest/v3/api-docs
serversPath: ./
upload:
serverType: linux
port: 22
host: ''
userName: ''
password: ''
targetDir: ''
localDir: dist

View File

@ -1,9 +1,10 @@
import { AbilityConstant, ConfigurationConstant, UIAbility, Want } from '@kit.AbilityKit';
import { hilog } from '@kit.PerformanceAnalysisKit';
import { window } from '@kit.ArkUI';
import Logger from '../utils/Logger';
import Logger, { LoggerLevel, LoggerMode } from '../utils/Logger';
import { text } from '@kit.ArkGraphics2D';
import { requestPermission } from '../utils/System';
import { getDeviceId, requestPermission } from '../utils/System';
import { commandService } from '../utils/CommandService';
const DOMAIN = 0x0000;
@ -14,18 +15,23 @@ export default class EntryAbility extends UIAbility {
}
onDestroy(): void {
Logger.destroy()
hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onDestroy');
}
async onWindowStageCreate(windowStage: window.WindowStage): Promise<void> {
hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageCreate');
Logger.setDir(this.context.filesDir)
// Logger.setLevel(LoggerLevel.Warn)
Logger.init({
mode: LoggerMode.Development,
level: LoggerLevel.Info,
})
let mainWindow = await windowStage.getMainWindow()
await mainWindow.setWindowLayoutFullScreen(true)
await mainWindow.setWindowSystemBarEnable([])
let fontCollection = text.FontCollection.getGlobalInstance()
fontCollection.loadFontSync("Alimama", $rawfile("AlimamaShuHeiTi-Bold.ttf"))
commandService.init()
await requestPermission(this.context, ["ohos.permission.CAMERA", "ohos.permission.FILE_ACCESS_MANAGER"])

View File

@ -313,7 +313,7 @@ export default struct VideoPlayer {
if (!this.canSeek) {
return
}
let deltaX = event.touches[0].screenX - this.origin.x
let deltaX = event.touches[0].windowX - this.origin.x
if (Math.abs(deltaX) > 5) {
this.touchMode = TouchMode.Seek
// 取消控制栏延时隐藏定时器

View File

@ -26,13 +26,14 @@ function TouchEventWrapper(callback: Function) {
}
const button: string[][] =
[["采集初始位置", "回到初始位置"], ["采集受理凭证位置", "回到受理凭证位置"], ["采集充电位置", "回到充电位置"]]
@Component
@Entry
struct Control {
@State select: number = 0
private menu: string[] = ["回到初始位置", "回到受理凭证位置", "回到充电位置", "自由控制"]
private button: string[][] =
[["采集初始位置", "回到初始位置"], ["采集受理凭证位置", "回到受理凭证位置"], ["采集充电位置", "回到充电位置"]]
private control: RebootControl = new RebootControl("", 0)
private forward: (event: TouchEvent) => void = TouchEventWrapper(() => {
this.control.forward()
@ -136,12 +137,12 @@ struct Control {
} else {
ControlButton({
title: this.button[this.select][0], button: "采集", onCustomClick: () => {
title: button[this.select][0], button: "采集", onCustomClick: () => {
this.onCollectCommand()
}
})
ControlButton({
title: this.button[this.select][1], button: "前往", onCustomClick: () => {
title: button[this.select][1], button: "前往", onCustomClick: () => {
this.onMoveCommand()
}
})

View File

@ -1,4 +1,5 @@
import { promptAction, router } from '@kit.ArkUI'
import { saveVinPositionUsingPost } from '../../api/vehicleCollectionController'
import { Option } from '../../typings/Common'
import { CusButton } from '../components/button/Index'
import { Layout } from '../components/layout/Index'
@ -166,7 +167,7 @@ struct Add {
}
}
save() {
async save() {
if (!this.picture1) {
promptAction.showToast({
message: "请上传铭牌图片"
@ -224,33 +225,37 @@ struct Add {
}
// const param = {
// // orgId: userInfo.orgId,
// // userId: userId,
//
// brandName: this.base[1].value,
// factoryName: this.base[0].value,
// model: this.base[2].value,
// year: this.base[3].value,
// month: this.base[4].value,
//
// position: this.nameplatePosition,
// platePhotoUrl: this.picture1,
//
// platePosition: this.vehicleIdentityPosition,
// platePositionUrl: this.picture2,
// positionDirection: this.vehicleIdentityDirection,
// seatMove: this.vehicleIdentitySeat,
// blockInfo: this.vehicleIdentityMask,
// otherMove: this.vehicleIdentityOther !== "其他" ?this.vehicleIdentityOther : this.otherInput,
//
// // vinPhotoUrl: this.picture2,
//
// chargingPortPhotoUrl:this.picture3 ,
// chargingPortPosition:this.quickElectric,
// slowChargingPortPhotoUrl:this.picture4,
// slowChargingPortPosition:this.slowElectric,
// };
const data: API.VehicleCollectionReq = {
brandName: this.base[1].value,
factoryName: this.base[0].value,
model: this.base[2].value,
year: this.base[3].value,
month: this.base[4].value,
platePhotoUrl: "",
platePosition: this.nameplatePosition,
platePositionUrl: this.picture1,
position: this.vehicleIdentityPosition,
positionDirection: this.vehicleIdentityDirection,
seatMove: this.vehicleIdentitySeat,
blockInfo: this.vehicleIdentityMask,
otherMove: this.vehicleIdentityOther !== "其他" ? this.vehicleIdentityOther : this.otherInput,
vinPhotoUrl: this.picture2,
chargingPortPhotoUrl: this.picture3,
chargingPortPosition: this.quickElectric,
slowChargingPortPhotoUrl: this.picture4,
slowChargingPortPosition: this.slowElectric,
padId: 0,
}
saveVinPositionUsingPost(data).then(res => {
promptAction.showToast({
message: res.msg,
alignment: Alignment.Center
})
})
}
build() {

View File

@ -0,0 +1,67 @@
import { TaskPool } from './TaskPool';
import { WebsocketClient } from './WebsocketUtils';
const Tag = "CommandService"
interface Message {
type: string
reqCode: string
body: object
}
export class CommandService {
private service?: WebsocketClient
private taskPool: TaskPool<boolean> = new TaskPool()
private static instance: CommandService
constructor(url: string) {
if (!CommandService.instance) {
this.service = new WebsocketClient(url, this.deal)
CommandService.instance = this
}
return CommandService.instance
}
deal(message: string) {
return message
}
init() {
return this.service!.connect()
}
subscribe(cb: Function) {
this.service!.subscribe(cb)
}
unsubscribe(cb: Function) {
this.service!.unsubscribe(cb)
}
send(message: Message) {
return new Promise<void>((resolve, reject) => {
this.taskPool.add({
execute: () => {
return this.service!.send(JSON.stringify(message))
},
repair: (): Promise<void> => {
return this.service!.reconnect();
},
success: () => {
resolve()
},
error: () => {
reject()
},
retryCount: 5
})
})
}
close(): Promise<boolean> {
return this.service!.close()
}
}
export const commandService =
new CommandService("ws://testdevice.duolunxc.com/car-inspection-rest/websocket/pad?deviceNo=666666")

View File

@ -1,6 +1,9 @@
import fs from '@ohos.file.fs'
import hilog from '@ohos.hilog'
import { dateFormat } from './Utils'
import { common } from '@kit.AbilityKit'
import { BusinessError } from '@kit.BasicServicesKit'
import { uploadFile } from './Request'
interface LoggerOption {
mode?: LoggerMode
@ -24,7 +27,6 @@ const MB = 1024 * 1024
const Tag = "Logger"
function pathJoin(...path: string[]) {
return path.join("/")
}
@ -35,7 +37,7 @@ export default class Logger {
private static size: number = MB * 10
private static date: string = dateFormat(new Date(), "yyyy_MM_dd")
private static time: string = dateFormat(new Date(), "HH_mm_ss.SSS")
private static fd: number = 0
private static fd: number = -1
private static dir: string = ""
private static createDir() {
@ -62,6 +64,7 @@ export default class Logger {
Logger.fd = file.fd
}
} catch (e) {
Logger.fd = -1
hilog.error(0x0000, Tag, JSON.stringify(e))
}
}
@ -91,6 +94,8 @@ export default class Logger {
} else {
try {
if (fs.statSync(Logger.fd).size >= Logger.size) {
fs.closeSync(Logger.fd)
Logger.fd = -1
Logger.createNewFile()
}
fs.writeSync(Logger.fd,
@ -101,6 +106,10 @@ export default class Logger {
}
}
static setMode(mode: LoggerMode) {
Logger.mode = mode
}
static setDir(dir: string) {
Logger.dir = dir + '/logs'
}
@ -119,6 +128,12 @@ export default class Logger {
}
}
static destroy() {
if (Logger.fd !== -1) {
fs.closeSync(Logger.fd)
}
}
static info(...message: Object[]) {
Logger.print(LoggerLevel.Info, ...message)
}
@ -134,4 +149,20 @@ export default class Logger {
static debug(...message: Object[]) {
Logger.print(LoggerLevel.Debug, ...message)
}
}
export function readLog(context: common.UIAbilityContext) {
let dir = context.filesDir + '/logs'
fs.listFile(dir).then(list => {
list.forEach(item => {
Logger.info(item)
})
}).catch((error: BusinessError) => {
Logger.error(error)
})
}
export function uploadLog(context: common.UIAbilityContext) {
let path = context.filesDir + '/logs/2025_09_25/14_25_31.331.log'
uploadFile(context, "http://192.168.67.190:8088/common/upload", path)
}

View File

@ -103,7 +103,7 @@ export async function uploadFile(context: common.UIAbilityContext, url: string,
filename,
name: 'file',
uri,
type: `video/${getFileExt(filename)}}`
type: getFileExt(filename)
}
],
data: []
@ -111,6 +111,7 @@ export async function uploadFile(context: common.UIAbilityContext, url: string,
.then((task) => {
task.on("fail", states => {
Logger.error(Tag, "UPLOAD FILE ERROR: ", states[0].message)
fs.unlinkSync(tempPath)
reject(states[0].message)
})
task.on("complete", (states) => {

View File

@ -3,6 +3,9 @@ import { camera, cameraPicker as picker } from '@kit.CameraKit';
import { fileIo, fileUri } from '@kit.CoreFileKit';
import { image } from '@kit.ImageKit';
import { util } from '@kit.ArkTS';
import { asset } from '@kit.AssetStoreKit';
import { BusinessError, deviceInfo } from '@kit.BasicServicesKit';
import Logger from './Logger';
export function requestPermission(context: common.UIAbilityContext, permissions: Permissions[]): Promise<void> {
@ -48,11 +51,6 @@ interface PictureOption {
base64?: boolean
}
/**
* 拉起摄像头拍照
* @param option 拍照设置
* @returns Promise<string> 返回图片的base64编码格式
*/
export function takePhoto(context: common.UIAbilityContext, option?: PictureOption): Promise<string> {
if (!fileIo.accessSync(context.tempDir + '/image')) {
fileIo.mkdirSync(context.tempDir + '/image')
@ -66,7 +64,7 @@ export function takePhoto(context: common.UIAbilityContext, option?: PictureOpti
};
return new Promise<string>((resolve, reject) => {
picker.pick(context, [picker.PickerMediaType.PHOTO], pickerProfile).then(async (res) => {
if(res.resultCode !== 0) {
if (res.resultCode !== 0) {
return Promise.reject("拍照取消")
}
let uri = res.resultUri
@ -88,4 +86,51 @@ export function takePhoto(context: common.UIAbilityContext, option?: PictureOpti
}
}).catch(reject)
})
}
}
export async function getDeviceId() {
const stringToArray = (str: string): Uint8Array => {
let textEncoder = new util.TextEncoder();
return textEncoder.encodeInto(str);
}
const arrayToString = (arr: Uint8Array): string => {
let textDecoder = util.TextDecoder.create('utf-8', { ignoreBOM: true });
let str = textDecoder.decodeToString(arr, { stream: false })
return str;
}
const setAttr = (id: string) => {
let attr: asset.AssetMap = new Map();
attr.set(asset.Tag.SECRET, stringToArray(id));
attr.set(asset.Tag.ALIAS, stringToArray('duolun_car_check_device_id'));
attr.set(asset.Tag.IS_PERSISTENT, true);
asset.add(attr).then(() => {
Logger.info(`Asset added successfully.`);
}).catch((error: BusinessError) => {
Logger.error(error);
})
}
const getAttr = async (): Promise<string> => {
let query: asset.AssetMap = new Map();
query.set(asset.Tag.ALIAS, stringToArray('duolun_car_check_device_id'));
query.set(asset.Tag.RETURN_TYPE, asset.ReturnType.ALL);
try {
const res: Array<asset.AssetMap> = await asset.query(query)
let secret: Uint8Array = res[0].get(asset.Tag.SECRET) as Uint8Array;
let secretStr: string = arrayToString(secret);
return secretStr;
} catch (error) {
Logger.error(`Failed to query Asset.`);
return '';
}
}
let deviceId = await getAttr()
if (!deviceId) {
setAttr(deviceInfo.ODID)
deviceId = deviceInfo.ODID
}
return deviceId
}

View File

@ -1,10 +1,13 @@
import Logger from './Logger'
import { BusinessError } from '@kit.BasicServicesKit'
const Tag = "TaskPool"
interface Task<T> {
execute: () => Promise<T>,
repair: () => Promise<void>
success?: () => void
error?: (error: BusinessError) => void
retryCount: number
}
@ -21,12 +24,20 @@ export class TaskPool<T> {
private async handleTask(task: Task<T>) {
let count = 0
let success = false
let error: BusinessError = {
code: 500,
message: "",
name: ""
}
while (count < task.retryCount && !success) {
try {
await task.execute()
Logger.info(Tag, "执行指令成功")
success = true
task.success?.()
return
} catch (e) {
error = e
Logger.error(Tag, "执行指令失败")
try {
count++
@ -36,6 +47,7 @@ export class TaskPool<T> {
}
}
}
task.error?.(error)
}
async execute() {

View File

@ -30,6 +30,7 @@ export class WebsocketClient {
connect(): Promise<void> {
return new Promise<void>((resolve, reject) => {
this.socket.connect(this.url).then(() => {
Logger.info(Tag, "连接" + this.url + "成功")
this.socket.on("message", (message) => {
this.callback.forEach(cb => {
cb(this.deal ? this.deal(message.message) : message.message)

View File

@ -52,6 +52,9 @@
{
"name": "ohos.permission.INTERNET"
},
{
"name": "ohos.permission.STORE_PERSISTENT_DATA"
},
{
"name": "ohos.permission.CAMERA",
"reason": "$string:module_desc",