diff --git a/build-profile.json5 b/build-profile.json5 index 5d0750fa..83d9c49c 100644 --- a/build-profile.json5 +++ b/build-profile.json5 @@ -4,13 +4,13 @@ { "name": "default", "material": { - "certpath": "/Users/surenjun/.ohos/config/openharmony/auto_ohos_default_subject-two_com.oh.dts.cer", - "storePassword": "0000001BE4BBADDF656A884E7A7BB5FD51F64FBB61DD24A944FEA969482DD693210ED5FF3D29F13642E3A3", + "certpath": "/Users/wangzhongjie/.ohos/config/openharmony/default_subject-two_Kl4t-ZSvZeuUm9s8O-e6FIH2VFR_OaNyhDP8kPjIWgU=.cer", + "storePassword": "0000001BD004523136E83351C367AD0A3AFC9797D72EA8B63579A11B81D3039AF5135C9A6D6026BC82D364", "keyAlias": "debugKey", - "keyPassword": "0000001BDEFFDC280B45617E7FC447CB21F2D133540301F543454643D3F5E9F6E5ED2A583A7FA92B260433", - "profile": "/Users/surenjun/.ohos/config/openharmony/auto_ohos_default_subject-two_com.oh.dts.p7b", + "keyPassword": "0000001B82CED3504C6EBB88214DE43783D909FDE585469ACF850B4E4748888D321ACDD8DE471DA7506A35", + "profile": "/Users/wangzhongjie/.ohos/config/openharmony/default_subject-two_Kl4t-ZSvZeuUm9s8O-e6FIH2VFR_OaNyhDP8kPjIWgU=.p7b", "signAlg": "SHA256withECDSA", - "storeFile": "/Users/surenjun/.ohos/config/openharmony/auto_ohos_default_subject-two_com.oh.dts.p12" + "storeFile": "/Users/wangzhongjie/.ohos/config/openharmony/default_subject-two_Kl4t-ZSvZeuUm9s8O-e6FIH2VFR_OaNyhDP8kPjIWgU=.p12" } } ], diff --git a/entry/.DS_Store b/entry/.DS_Store index d79217fd..13591384 100644 Binary files a/entry/.DS_Store and b/entry/.DS_Store differ diff --git a/entry/build-profile.json5 b/entry/build-profile.json5 index 2160ea13..6cfa095d 100644 --- a/entry/build-profile.json5 +++ b/entry/build-profile.json5 @@ -2,6 +2,11 @@ "apiType": 'stageMode', "buildOption": { "externalNativeOptions": { + "abiFilters": [ + "arm64-v8a", + "armeabi-v7a", + "x86_64" + ], "path": "./src/main/cpp/CMakeLists.txt", "arguments": "", "cppFlags": "", diff --git a/entry/oh-package-lock.json5 b/entry/oh-package-lock.json5 index bc40219d..1f023b33 100644 --- a/entry/oh-package-lock.json5 +++ b/entry/oh-package-lock.json5 @@ -1,13 +1,15 @@ { - "lockfileVersion": 1, + "lockfileVersion": 2, "ATTENTION": "THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.", "specifiers": { "@ohos/hypium@1.0.6": "@ohos/hypium@1.0.6" }, "packages": { "@ohos/hypium@1.0.6": { - "resolved": "https://repo.harmonyos.com/ohpm/@ohos/hypium/-/hypium-1.0.6.tgz", - "integrity": "sha512-bb3DWeWhYrFqj9mPFV3yZQpkm36kbcK+YYaeY9g292QKSjOdmhEIQR2ULPvyMsgSR4usOBf5nnYrDmaCCXirgQ==" + "resolved": "https://ohpm.openharmony.cn/ohpm/@ohos/hypium/-/hypium-1.0.6.tgz", + "integrity": "sha512-bb3DWeWhYrFqj9mPFV3yZQpkm36kbcK+YYaeY9g292QKSjOdmhEIQR2ULPvyMsgSR4usOBf5nnYrDmaCCXirgQ==", + "registryType": "ohpm", + "shasum": "3f5fed65372633233264b3447705b0831dfe7ea1" } } } \ No newline at end of file diff --git a/entry/src/.DS_Store b/entry/src/.DS_Store index aba29283..95961b27 100644 Binary files a/entry/src/.DS_Store and b/entry/src/.DS_Store differ diff --git a/entry/src/main/.DS_Store b/entry/src/main/.DS_Store index 2a716477..44ff073b 100644 Binary files a/entry/src/main/.DS_Store and b/entry/src/main/.DS_Store differ diff --git a/entry/src/main/ets/.DS_Store b/entry/src/main/ets/.DS_Store index 0a32a4a0..e1838410 100644 Binary files a/entry/src/main/ets/.DS_Store and b/entry/src/main/ets/.DS_Store differ diff --git a/entry/src/main/ets/api/judgeNew.ts b/entry/src/main/ets/api/judgeNew.ts index 9fac6e5d..8bbc4277 100644 --- a/entry/src/main/ets/api/judgeNew.ts +++ b/entry/src/main/ets/api/judgeNew.ts @@ -3,7 +3,7 @@ import request from "../common/utils/request" let baseHost = globalThis.host; import FileUtil from '../common/utils/File'; import FileLog from '../pages/judgeSDK/utils/fileLog'; - +import tcp2ByteRequest from '../tcp2byte/index' //监管接口序列号映射 const gjxlhObj = { '17C51': '02-21-000009', @@ -26,6 +26,11 @@ export default async function writeObjectOutNew(data,filePath): Promise { const params = await getParams(jkid, drvexam); const {wglb,jkxlh,glbm,jgbh,sjbs} = basic; + const reqData = { + wglb,jkxlh,glbm,jgbh,sjbs, + data:params.data, + file:params.file + } if(filePath){ await fileUtil.editFile(`${filePath}/wuxi_exam_data.txt`,JSON.stringify({ wglb,jkxlh,glbm,jgbh,sjbs, @@ -38,36 +43,12 @@ export default async function writeObjectOutNew(data,filePath): Promise { console.info('surenjun','调用新监管') let temp try { - temp = await request({ - host: globalThis.JGHOST, - method: 'post', - //是否是新中心 - isNewCenter: true, - xml: true, - url: '/dems_ws/services/TmriOutAccess?wsdl', - data: ` - - - - ${wglb} - ${jkxlh} - ${glbm} - ${jgbh} - ${sjbs} - ${JSON.stringify(params.data)} - ${JSON.stringify(params.file)} - - - `, - }) - } catch (e) { + temp = await tcp2ByteRequest(reqData) + }catch (e){ console.log("新监管错误") temp = e } + console.log("temp message: ", JSON.stringify(temp)) if(filePath){ await fileUtil.editFile(`${filePath}/wuxi_exam_data.txt`,JSON.stringify(temp) +`\n`); diff --git a/entry/src/main/ets/config/global.ts b/entry/src/main/ets/config/global.ts index 6e16dd4d..8b772380 100644 --- a/entry/src/main/ets/config/global.ts +++ b/entry/src/main/ets/config/global.ts @@ -16,7 +16,7 @@ export const GlobalConfig={ //杭州 hz:{ km2:['2022.03.14.01','2022.03.17.1'], - km3:[], + km3:['2024.08.21.01','2024.08.24.1'], }, //黑龙江 hlg:{ diff --git a/entry/src/main/ets/tcp2byte/index.ts b/entry/src/main/ets/tcp2byte/index.ts new file mode 100644 index 00000000..2f81dfa3 --- /dev/null +++ b/entry/src/main/ets/tcp2byte/index.ts @@ -0,0 +1,138 @@ +import socket from '@ohos.net.socket' +import util from '@ohos.util' +import promptAction from '@ohos.promptAction' +import TcpToByte from './utils/tcp2byte' +import { bytesToDecimal } from './utils/tools' + +const TAG = '[TCP2BYTE]' + + +interface RES { + code: number | string, + message?: string +} + +const config = { + address: '172.37.55.191', + port: 40000 +} + +export default async function tcp2ByteRequest(data): Promise { + + return new Promise(async (resolve, reject) => { + const tcpClient: socket.TCPSocket = socket.constructTCPSocketInstance() + + const {address,port} = config + const tcp2Byte = new TcpToByte() + console.log("zj 1111") + const sendData = tcp2Byte.getRequest(data) + console.log("zj 2222") + console.info(TAG, 'sendData=>' + JSON.stringify(sendData)) + try { + await tcpClient.connect({ + address: { + address, port + } + }) + //发送消息 + handSendMessage(tcpClient, data.sjbs, sendData) + } catch (e) { + console.log(TAG, 'tcp client connect error' + JSON.stringify(e)) + promptAction.showToast({ + message: 'tcp client connect error' + JSON.stringify(e), + duration: 3000 + }); + reject(e) + } + + //收到消息 + tcpClient.on('message', (data) => { + const res = handReceiveMessage(tcpClient, sendData, data) + if (res) { + tcpClient.close() + resolve(res) + } + }) + + tcpClient.on('error', (e) => { + const errMsg = 'tcp client receive error' + JSON.stringify(e) + promptAction.showToast({ + message: 'tcp client receive error' + JSON.stringify(e), + duration: 3000 + }); + console.log(TAG, errMsg) + tcpClient.close() + resolve({ + code: -1, message: errMsg + }) + }) + + }) +} + +//处理发送的数据 +function handSendMessage(client: socket.TCPSocket, type, data) { + + switch (type) { + //开始考试 过程照片 考试结束需要分包 + case '02-21-000009': + case '02-21-000012': + case '02-21-000014': + data.forEach((item) => { + console.log("zj sendMessage", JSON.stringify(item)) + client.send({ data: new Uint8Array(item).buffer }).then(res => { + console.log("zj sendMessage success") + }).catch(e => { + console.log("zj sendMessage error", JSON.stringify(e)) + }) + }) + break; + case '02-21-000010': + case '02-21-000011': + case '02-21-000013': + client.send({ data: new Uint8Array(data) }) + break; + + default: + break; + } +} + +//处理接收的数据 +function handReceiveMessage(client: socket.TCPSocket, sendData, receiveData): RES { + console.info(TAG, 'receiveData=>' + JSON.stringify(receiveData)) + //返回的消息类型 + const messageType = receiveData[1]; + //流水号 + const lsh = bytesToDecimal([receiveData[2], receiveData[3]]); + + //开始补包 + if (messageType === 0xF0) { + //获取消息体长度 + const messageLength = receiveData[12] + //分包总数 + const packages = receiveData.slice(13, 13 + messageLength * 2); + const forArr = new Array(packages).fill(1) + + forArr.forEach((item, index) => { + const start = index * 2; + const end = start + 2; + const packageIndex = bytesToDecimal([start, end]); + console.info(TAG, '补包内容' + JSON.stringify(new Uint8Array(sendData[packageIndex]))) + client.send({ data: new Uint8Array(sendData[packageIndex]) }); + }) + } else { + const decoder = util.TextDecoder.create('utf-8'); + const messageLength = bytesToDecimal([receiveData[9], receiveData[10]]); + const markLength = receiveData[11]; + const markContent = decoder.decodeWithStream(receiveData.slice(12, 12 + markLength)); + console.info(TAG, 'markContent=>' + markContent) + const tipLength = receiveData[13]; + const messageContent = decoder.decodeWithStream(receiveData.slice(13 + markLength, 13 + markLength + tipLength)); + console.info(TAG, 'messageContent=>' + messageContent) + return { + code: markContent, + message: messageContent + } + } +} \ No newline at end of file diff --git a/entry/src/main/ets/tcp2byte/testData/testData.js b/entry/src/main/ets/tcp2byte/testData/testData.js new file mode 100644 index 00000000..538447b7 --- /dev/null +++ b/entry/src/main/ets/tcp2byte/testData/testData.js @@ -0,0 +1,125 @@ +const test17C51 = { + wglb: "700204", + jkxlh: "370170020500013133", + glbm: "370100000400", + jgbh: "37010034", + sjbs: "02-21-000010", + data: { + sjbs: "02-21-000010", + param: { + sfzmhm: "684363640692131968", + kskm: "3", + ksxl: "3700198502", + kchp: "鲁A25UU1", + kssj: "2025-02-25 19:31:55" + } + }, + file: { sjbs: "02-21-000010", param: [] } +} + +const test17C52 = { + "wglb": "700204", + "jkxlh": "370170020500013133", + "glbm": "370100000400", + "jgbh": "37010034", + "sjbs": "02-21-000010", + "data": { + "sjbs": "02-21-000010", + "param": { + "sfzmhm": "211421199203200614", + "kskm": "3", + "ksxm": "40100", + "ksxl": "3700198504", + "kchp": "鲁A00YM8", + "kssj": "2025-01-06 13:59:08" + } }, + "file": { "sjbs": "02-21-000010", "param": [] } +} + +const test17C53 = { + "wglb": "700204", + "jkxlh": "370170020500013133", + "glbm": "370100000400", + "jgbh": "37010034", + "sjbs": "02-21-000011", + "data": { + "sjbs": "02-21-000011", + "param": { + "kffs": 1, + "kfsj": "2025-02-26 16:40:21", + "kfxm": "30123", + "kfxmmx": "2,43", + "kskm": "3", + "ksxm": "40200", + "sfzmhm": "137457799873815456" + } + }, + "file": { "sjbs": "02-21-000011", "param": [] } +} + +const test17C54 = { + "wglb": "700204", + "jkxlh": "370170020500013133", + "glbm": "370100000400", + "jgbh": "37010034", + "sjbs": "02-21-000012", + "data": { + "sjbs": "02-21-000012", + "param": { + "cs": 0, + "kskm": "3", + "ksxm": "40200", + "sfzmhm": "137457799873815456", + "zpsj": "2025-02-26 16:39:52" + } }, + "file": { "sjbs": "02-21-000012", "param": [] } +} + +const test17C55 = { + "wglb": "700204", + "jkxlh": "370170020500013133", + "glbm": "370100000400", + "jgbh": "37010034", + "sjbs": "02-21-000013", + "data": { + "param": { + "czlx": "1", + "jssj": "2025-01-06 13:59:11", + "kskm": "3", + "ksxl": "3700198504", + "ksxm": "40100", + "sfzmhm": "211421199203200614" + }, + "sjbs": "02-21-000013" + }, + "file": { "sjbs": "02-21-000013", "param": [] } +} + +const test17C56 = { + "wglb": "700204", + "jkxlh": "370170020500013133", + "glbm": "370100000400", + "jgbh": "37010034", + "sjbs": "02-21-000014", + "data": { + "sjbs": "02-21-000014", + "param": { + "dwlc": "1,61;2,313;3,1223;4,1579;5,0", + "ghks": "0", + "jssj": "2025-01-06 14:08:04", + "kscj": 90, + "kskm": "3", + "kslc": 3193, + "sfzmhm": "211421199203200614" + } }, + "file": { "sjbs": "02-21-000014", "param": [] } +} + +export { + test17C51, + test17C52, + test17C53, + test17C54, + test17C55, + test17C56, +} \ No newline at end of file diff --git a/entry/src/main/ets/tcp2byte/testData/消息结构.pdf b/entry/src/main/ets/tcp2byte/testData/消息结构.pdf new file mode 100644 index 00000000..f1de3606 --- /dev/null +++ b/entry/src/main/ets/tcp2byte/testData/消息结构.pdf @@ -0,0 +1,273 @@ +A.1.1 消息结构 + 每条消息由标识位、消息头、消息体和校验码组成。 + + 标识位 消息头 消息体 标识位 + +A.1.1.1 标识位 + + 采用Ox7e表示,若校验码、消息头以及消息体中出现0x7e,则要进行转义处理,转义规 +则定义如下: + + 0x7e<——>0x7d后紧跟一个0x02; + 0x7d<——>0x7d后紧跟一个0x01。 + 转义处理过程如下: + 发送消息时:消息封装——>转义; + 接收消息时:转义还原——>解析消息。 + 示例: + 发送一包内容为0x30 0x7e 0x08 0x7d 0x55的数据包,则经过封装如下:0x7e 0x30 7d 0x02 +0x08 0x7d 0x01 0x55 0x7e。 + +A.1.1.2 消息头 + +消息头内容 + +一对请求和应答会使用相同的消息流水号。有分包时分包消息通知的流水号与请求一致。 + +起始字 字段 数据类型 描述及要求 + 节 + 消息类型 + 消息流水号 BYTE 对应不同业务,具体见消息体。 + 消息体长度 WORD 0-65535。用于并发是匹配应答 + 是否有分包 WORD 0-65535 + 分包总数 BYTE 0=无分包;1=有分包 + 分包序号 WORD 无分包时无此字段 + WORD 无分包时无此字段。序号从 01 开始。 + +A.1.1.3 分包 + + 当消息体长度超过 900 字节时,需启用分包对消息体进行拆分。 + 同一个请求的多个分包需要使用相同的消息流水号,并按照顺序从 01 开始依次提供序 + 号。 + 当接收到全部分包后,服务器会发送消息类型 0xF0 通知接收完全。 + 当某个消息流水号的分包未接收完全,且 5 秒内没有接收到新的分包,则会发送消息类 + 型消息类型 0xF0 通知需补发的分包序号。 + 当某个消息流水号的分包最后一次接收分包的时间点超过当前时间 10 分钟,该流水号 + 的分包内容将会被舍弃。该流水号将会可以重新用于新分包消息。 + +A.1.2 消息体 + 由head参数体、data参数体和files参数体组成。 + + head 参数体 data 参数体 files 参数体 + +A.1.2.1 head参数体 + + head参数体。请求需包含head参数体内容,应答head参数体为空,此时head参数体总长 +度为0,没有后续字段内容。 + +起始字节 字段 数据类型 描述及要求 + head参数体总长度 WORD + wglb长度 BYTE 0-65535 + wglb ASCII 0-255 + jkxlh长度 BYTE 0-255 + jkxlh ASCII 0-255 + glbm长度 BYTE 0-255 + glbm ASCII 0-255 + jgbh长度 BYTE + jgbh ASCII + sjbs长度 BYTE + sjbs ASCII + +A.1.2.2 data参数体和files参数体 + 当files参数体不存在时,仅保留file参数体总长度字段,值为0 + +A.1.2.2.1 消息0x01 02-21-000009-考试开始(17C51) + +请求data参数体结构 + +起始字节 字段 数据类型 描述及要求 + data参数体总长度 WORD + 考生身份证明号码长度 BYTE 0-65535 + 考生身份证明号码 ASCII 0-255 + 考车号牌长度 BYTE + 考车号牌 SRTING 0-255 + 考试科目 BYTE + 考试路线长度 BYTE 2:科目二,3:科目三 + 考试路线 SRTING 0-255.为空时长度填 0。 + 开始时间 BCD(7) 为空时没有内容。跳过字段 + yyyyMMddHHmmss + +请求files参数体结构 + +起始字节 字段 数据类型 描述及要求 + file参数体总长度 DWORD 0-4228250625 + 照片类型长度 BYTE 0-255 + 照片类型 ASCII + 文件长度 DWORD 0-4228250625 + 文件 BYTE[n] 照片文件本身,无需编码 + +应答data参数体结构 + +起始字节 字段 数据类型 描述及要求 + data参数体总长度 WORD + 标记长度 BYTE 0-65535 + 标记 ASCII 0-255 + 提示信息长度 BYTE + 提示信息 SRTING 0-255 + 考试项目长度 BYTE + 考试项目 SRTING 0-255. + +A.1.2.2.2 消息0x02 02-21-000010-考试项目开始(17C52) + +请求 data 参数体结构 + +起始字节 字段 数据类型 描述及要求 + data参数体总长度 WORD + 身份证明号码长度 BYTE 0-65535 + 身份证明号码 ASCII 0-255 + 考试科目 BYTE + 考试项目 WORD 2:科目二,3:科目三 + 设备编号长度 BYTE + 设备编号 ASCII yyyyMMddHHmmss + 考试路线长度 BYTE + 考试路线 ASCII + 考车号牌长度 BYTE + 考车号牌 STRING + 开始时间 BCD(7) + +应答 data 参数体结构 + +起始字节 字段 数据类型 描述及要求 + data参数体总长度 WORD + 标记长度 BYTE 0-65535 + 标记 ASCII 0-255 + 提示信息长度 BYTE + 提示信息 SRTING 0-255 + A.1.2.2.3 消息0x03 02-21-000011-考试扣分(17C53) + +请求 data 参数体结构 + +起始字节 字段 数据类型 描述及要求 + data参数体总长度 WORD + 身份证明号码长度 BYTE 0-65535 + 身份证明号码 ASCII 0-255 + 考试科目 BYTE + 考试项目长度 BYTE 2:科目二,3:科目三 + 考试项目 ASCII 0-255. + 扣分项目长度 BYTE + 扣分项目 ASCII yyyyMMddHHmmss + 扣分时间 BCD(7) 1:系统扣分,2:人工扣分 + 扣分方式 BYTE + +应答 data 参数体结构 + +起始字节 字段 数据类型 描述及要求 + data参数体总长度 WORD + 标记长度 BYTE 0-65535 + 标记 ASCII 0-255 + 提示信息长度 BYTE + 提示信息 SRTING 0-255 + +A.1.2.2.4 消息0x04 02-21-000012-考试过程图片(17C54) + +请求 data 参数体结构 + +起始字节 字段 数据类型 描述及要求 + data参数体总长度 WORD + 身份证明号码长度 BYTE 0-65535 + 身份证明号码 ASCII 0-255 + 考试科目 BYTE + 考试项目长度 BYTE 2:科目二,3:科目三 + 考试项目 ASCII 0-255. + 抓拍时间 BCD(7) + 车速 BYTE yyyyMMddHHmmss + 0-255.单位:km/H + +请求 files 参数体结构 + +起始字节 字段 数据类型 描述及要求 + file参数体总长度 DWORD 0-4228250625 + 照片类型长度 BYTE 0-255 + 照片类型 ASCII 0-4228250625 + 文件长度 DWORD 照片文件本身,无需编码 + 文件 BYTE[n] + +应答 data 参数体结构 + +起始字节 字段 数据类型 描述及要求 + data参数体总长度 WORD + 标记长度 BYTE 0-65535 + 标记 ASCII 0-255 + 提示信息长度 BYTE + 提示信息 SRTING 0-255 + +A.1.2.2.5 消息0x05 02-21-000013-考试项目结束(17C55) + +请求 data 参数体结构 + +起始字节 字段 数据类型 描述及要求 + data参数体总长度 WORD + 身份证明号码长度 BYTE 0-65535 + 身份证明号码 ASCII 0-255 + 考试科目 BYTE + 考试项目长度 BYTE 2:科目二,3:科目三 + 考试项目 SRTING 0-255. + 设备编号长度 BYTE + 设备编号 ASCII yyyyMMddHHmmss + 考试路线长度 BYTE 1:正常,0:撤销该考试项目记录 + 考试路线 ASCII + 考车号牌长度 BYTE + 考车号牌 STRING + 结束时间 BCD(7) + 操作类型 BYTE + +应答 data 参数体结构 + +起始字节 字段 数据类型 描述及要求 + data参数体总长度 WORD + 标记长度 BYTE 0-65535 + 标记 ASCII 0-255 + 提示信息长度 BYTE + 提示信息 SRTING 0-255 + +A.1.2.2.6 消息0x06 02-21-000014-考试科目考试结束(17C56) + 请求 data 参数体结构 + +起始字节 字段 数据类型 描述及要求 + data参数体总长度 WORD + 身份证明号码长度 BYTE 0-65535 + 身份证明号码 ASCII 0-255 + 考试科目 BYTE + 结束时间 BCD(7) 2:科目二,3:科目三 + 考试成绩 BYTE yyyyMMddHHmmss + 是否更换考生 ASCII 0-100. + 档位里程长度 BYTE 0:不更换,1:更换。 + 档位里程 ASCII + 考试里程 WORD + +请求 files 参数体结构 + +起始字节 字段 数据类型 描述及要求 + 0-4228250625 + file参数体总长度 DWORD + 0-255 + 照片类型长度 BYTE + 照片类型 ASCII 0-4228250625 + 文件长度 DWORD 照片文件本身,无需编码 + 文件 BYTE[n] + +应答 data 参数体结构 + +起始字节 字段 数据类型 描述及要求 + data参数体总长度 WORD + 标记长度 BYTE 0-65535 + 标记 ASCII 0-255 + 提示信息长度 BYTE + 提示信息 SRTING 0-255 + +A.1.2.2.7 消息0XF0 分包接收状态通知 + + 该消息由后台发送给设备。 + 当后台收到某个消息请求的报文头中存在分包信息,则必定会回复此应答。 + 当接收到某个消息的全部分包后,会立刻回复此应答。当最后一次接收到某个消息的分 +包超过一定时间,则会发送该消息要求重新上传缺失分包。 + +请求 data 参数体结构 + 起始字节 字段 数据类型 描述及要求 + data参数体总长度 WORD + 需补消息流水号 0-65535 + 需补分包数 + 需补分包序号1 BYTE + 需补分包序号 2 WORD + …… WORD + WORD + diff --git a/entry/src/main/ets/tcp2byte/utils/base64.js b/entry/src/main/ets/tcp2byte/utils/base64.js new file mode 100644 index 00000000..3b8ea4c4 --- /dev/null +++ b/entry/src/main/ets/tcp2byte/utils/base64.js @@ -0,0 +1,2 @@ +const photo = 'data:image/png;base64,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' +export default photo \ No newline at end of file diff --git a/entry/src/main/ets/tcp2byte/utils/tcp2byte.ts b/entry/src/main/ets/tcp2byte/utils/tcp2byte.ts new file mode 100644 index 00000000..6b65bf00 --- /dev/null +++ b/entry/src/main/ets/tcp2byte/utils/tcp2byte.ts @@ -0,0 +1,498 @@ +import { string2Bytes, str2UTF8, timeTOBCD } from './tools' +import Buffer from '@ohos.buffer' +import photo from './base64' + +export default class TcpToByte { + //WORD 流水号 + lsh = '' + //标识位 + prefix = 0x7e; + nPrefix = 0x7d + //分包大小配置 + packageSize = 900 + + constructor() { + } + + getRequest(data) { + const sjbs = data.sjbs + switch (sjbs) { + case '02-21-000009': + return this.get17C51(data) + case '02-21-000010': + return this.get17C52(data) + case '02-21-000011': + return this.get17C53(data) + case '02-21-000012': + return this.get17C54(data) + case '02-21-000013': + return this.get17C55(data) + case '02-21-000014': + return this.get17C56(data) + default: + return [] + } + } + + // 获取消息头 + getHead(type, message) { + const lsh = this.getRandomLsh() + console.log('lsh', lsh) + return [type] + .concat(string2Bytes(lsh, 16)) + .concat(string2Bytes(message.length, 16))//TODO 是否有分包 + .concat([0]) + //TODO 分包总数 + //TODO 分包序号 + } + + // 获取消息里的消息头 + getMsgHead(headMsg) { + const wglb = str2UTF8(headMsg.wglb) + const jkxlh = str2UTF8(headMsg.jkxlh) + const glbm = str2UTF8(headMsg.glbm) + const jgbh = str2UTF8(headMsg.jgbh) + const sjbs = str2UTF8(headMsg.sjbs) + + return this.comBMsg({ + wglb: { + values: wglb, isNeedLen: true + }, + jkxlh: { + values: jkxlh, isNeedLen: true + }, + glbm: { + values: glbm, isNeedLen: true + }, + jgbh: { + values: jgbh, isNeedLen: true + }, + sjbs: { + values: sjbs, isNeedLen: true + }, + }) + } + + // 考试开始 + get17C51(drvexam) { + const packageSize = this.packageSize; + const prefix = this.prefix; + const lsh = this.getRandomLsh(); + const temp = drvexam.data.param; + //身份证号码 + const sfzmhm = str2UTF8(temp.sfzmhm) + //考试科目 + const kskm = temp.kskm * 1 + //考试路线 + const ksxl = str2UTF8(temp.ksxl) + //考车号码 + const kchp = str2UTF8(temp.kchp) + const time = timeTOBCD(temp.kssj) + + const msgHead = this.getMsgHead(drvexam) + // const msg = this.comMsg([sfzmhm, [kskm], ksxm, time, cs]) + const msg = this.comBMsg({ + sfzmhm: { + values: sfzmhm, isNeedLen: true + }, + kchp: { + values: kchp, isNeedLen: true + }, + kskm: { + values: [kskm], isNeedLen: false + }, + ksxl: { + values: ksxl, isNeedLen: true + }, + time: { + values: time, isNeedLen: false + }, + }) + const file = this.getBytePhoto(drvexam.file.param[0].data); + //拼接消息 + const message = msgHead.concat(msg).concat(file) + const translateMessage = this.checkHasPrefix(message) + const emptyArr = new Array(Math.ceil(translateMessage.length / packageSize)).fill(1); + const packages = [] + emptyArr.forEach((item, index) => { + const currentMessage = translateMessage.slice(index * packageSize, (index + 1) * packageSize); + const currentPackage = + [prefix, 0x01] + .concat(string2Bytes(lsh, 16)) + .concat(string2Bytes(currentMessage.length, 16)) + .concat([1]) + .concat(string2Bytes(emptyArr.length, 16)) + .concat(string2Bytes(index + 1, 16)) + + .concat(currentMessage) + .concat(prefix); + packages.push(currentPackage) + + }) + return packages; + } + + // 项目开始 + get17C52(drvexam) { + const temp = drvexam.data.param + const msgHead = this.getMsgHead(drvexam) + //身份证号码 + const sfzmhm = str2UTF8(temp.sfzmhm) + //考试科目 + const kskm = temp.kskm * 1 + //考试项目 + const ksxm = string2Bytes(temp.ksxm, 16); + + //TODO 科目三设备编号为空 + + //考试路线 + const ksxl = str2UTF8(temp.ksxl) + //考车号码 + const kchp = str2UTF8(temp.kchp) + + const time = timeTOBCD(temp.kssj) + + //file内容为空 + const msg = this.comBMsg({ + sfzmhm: { + values: sfzmhm, isNeedLen: true + }, + kskm: { + values: [kskm], isNeedLen: false + }, + ksxm: { + values: ksxm, isNeedLen: false + }, + sbbm: { + values: [], isNeedLen: true + }, + ksxl: { + values: ksxl, isNeedLen: true + }, + kchp: { + values: kchp, isNeedLen: true + }, + time: { + values: time, isNeedLen: false + }, + }) + const file = [0, 0, 0, 0, 0] + //拼接消息 + const message = msgHead.concat(msg).concat(file) + const translateMessage = this.checkHasPrefix(message) + const head = this.getHead(0x02, translateMessage) + + const data = [0x7e].concat(head).concat(translateMessage).concat([0x7e]) + + return data + + + } + + // 扣分 + get17C53(drvexam) { + const msgHead = this.getMsgHead(drvexam) + const temp = drvexam.data.param; + + //身份证号码 + const sfzmhm = str2UTF8(temp.sfzmhm) + //考试科目 + const kskm = temp.kskm * 1 + //扣分方式 + const kffs = temp.kffs * 1 + //考试项目 + const ksxm = string2Bytes(temp.ksxm, 16); + //扣分项目 + const kfxm = string2Bytes(temp.kfxm, 16); + + //扣分时间 + const time = timeTOBCD(temp.kfsj) + //扣分项目明细 + const kfxmmx = str2UTF8(temp.kfxmmx); + + const msg = this.comBMsg({ + sfzmhm: { + values: sfzmhm, isNeedLen: true + }, + kskm: { + values: [kskm], isNeedLen: false + }, + ksxm: { + values: ksxm, isNeedLen: false + }, + kfxm: { + values: kfxm, isNeedLen: false + }, + time: { + values: time, isNeedLen: false + }, + kffs: { + values: [kffs], isNeedLen: false + }, + kfxmmx: { + values: kfxmmx, isNeedLen: true + }, + }) + //file内容为空 + const file = [0, 0, 0, 0, 0] + const message = msgHead.concat(msg).concat(file) + const translateMessage = this.checkHasPrefix(message) + const head = this.getHead(0x03, translateMessage) + const data = [0x7e].concat(head).concat(translateMessage).concat([0x7e]) + + return data + + } + + // 过程照片 + get17C54(drvexam) { + + const packageSize = this.packageSize; + const prefix = this.prefix; + const lsh = this.getRandomLsh(); + const temp = drvexam.data.param; + //身份证号码 + const sfzmhm = str2UTF8(temp.sfzmhm) + //考试科目 + const kskm = temp.kskm * 1 + //考试项目 + const ksxm = string2Bytes(temp.ksxm, 16); + //车速 + const cs = temp.cs * 1 + + const time = timeTOBCD(temp.zpsj); + const msgHead = this.getMsgHead(drvexam) + // const msg = this.comMsg([sfzmhm, [kskm], ksxm, time, cs]) + const msg = this.comBMsg({ + sfzmhm: { + values: sfzmhm, isNeedLen: true + }, + kskm: { + values: [kskm], isNeedLen: false + }, + ksxm: { + values: ksxm, isNeedLen: false + }, + time: { + values: time, isNeedLen: false + }, + cs: { + values: [cs], isNeedLen: false + }, + }) + const file = this.getBytePhoto(drvexam.file.param[0].data); + //拼接消息 + const message = msgHead.concat(msg).concat(file) + const translateMessage = this.checkHasPrefix(message) + const emptyArr = new Array(Math.ceil(translateMessage.length / packageSize)).fill(1); + const packages = [] + emptyArr.forEach((item, index) => { + const currentMessage = translateMessage.slice(index * packageSize, (index + 1) * packageSize); + const currentPackage = + [prefix, 0x04] + .concat(string2Bytes(lsh, 16)) + .concat(string2Bytes(currentMessage.length, 16)) + .concat([1]) + .concat(string2Bytes(emptyArr.length, 16)) + .concat(string2Bytes(index + 1, 16)) + .concat(currentMessage) + .concat(prefix); + packages.push(currentPackage) + + }) + return packages; + //进行拆包 + + } + + // 项目结束 + get17C55(drvexam) { + const msgHead = this.getMsgHead(drvexam) + const temp = drvexam.data.param; + //身份证号码 + const sfzmhm = str2UTF8(temp.sfzmhm) + //考试科目 + const kskm = temp.kskm * 1 + //考试项目 + const ksxm = string2Bytes(temp.ksxm, 16); + + //TODO 科目三设备编号为空 + + //考试路线 + const ksxl = str2UTF8(temp.ksxl) + //考车号码 + const kchp = str2UTF8(temp.kchp) + + const time = timeTOBCD(temp.jssj) + + const czlx = temp.czlx * 1; + + const msg = this.comBMsg({ + sfzmhm: { + values: sfzmhm, isNeedLen: true + }, + kskm: { + values: [kskm], isNeedLen: false + }, + ksxm: { + values: ksxm, isNeedLen: false + }, + sbbh: { + values: [], isNeedLen: true + }, + ksxl: { + values: ksxl, isNeedLen: true + }, + time: { + values: time, isNeedLen: false + }, + czlx: { + values: [czlx], isNeedLen: false + }, + }) + //file内容为空 + const file = [0, 0, 0, 0, 0] + const message = msgHead.concat(msg).concat(file) + const translateMessage = this.checkHasPrefix(message) + const head = this.getHead(0x05, msgHead) + const data = [0x7e].concat(head).concat(translateMessage).concat([0x7e]) + + return data + } + + // 考试结束 + get17C56(drvexam) { + const packageSize = this.packageSize; + const prefix = this.prefix; + const lsh = this.getRandomLsh(); + const temp = drvexam.data.param; + //身份证号码 + const sfzmhm = str2UTF8(temp.sfzmhm) + //考试科目 + const kskm = temp.kskm * 1 + //结束时间 + const time = timeTOBCD(temp.jssj); + //考试成绩 + const kscj = temp.kscj * 1; + //是否是更换考生 + const ghks = 0; + //档位里程 + const dwlc = str2UTF8(temp.dwlc); + //考试里程 + const kslc = string2Bytes(temp.kslc, 16); + const msgHead = this.getMsgHead(drvexam) + // const msg = this.comMsg([sfzmhm, [kskm], time, [kscj], [ghks],dwlc,kslc]) + const msg = this.comBMsg({ + sfzmhm: { + values: sfzmhm, isNeedLen: true + }, + kskm: { + values: [kskm], isNeedLen: false + }, + time: { + values: time, isNeedLen: false + }, + kscj: { + values: [kscj], isNeedLen: false + }, + ghks: { + values: [ghks], isNeedLen: false + }, + dwlc: { + values: dwlc, isNeedLen: true + }, + kslc: { + values: kslc, isNeedLen: false + }, + }) + const file = this.getBytePhoto(drvexam.file.param[0].data); + //拼接消息 + const message = msgHead.concat(msg).concat(file) + const translateMessage = this.checkHasPrefix(message) + const emptyArr = new Array(Math.ceil(translateMessage.length / packageSize)).fill(1); + const packages = [] + emptyArr.forEach((item, index) => { + const currentMessage = translateMessage.slice(index * packageSize, (index + 1) * packageSize); + const currentPackage = + [prefix, 0x06] + .concat(string2Bytes(lsh, 16)) + .concat(string2Bytes(currentMessage.length, 16)) + .concat([1]) + .concat(string2Bytes(emptyArr.length, 16)) + .concat(string2Bytes(index + 1, 16)) + .concat(currentMessage) + .concat(prefix); + packages.push(currentPackage) + + }) + return packages; + } + + // 组装msg + comBMsg(msg) { + const keys = Reflect.ownKeys(msg) + let temp = [] + keys.forEach(msgKey => { + const currentMsg = msg[msgKey] + const {isNeedLen,values} = currentMsg; + if (isNeedLen) { + temp = temp.concat([values.length]).concat(values) + } else { + temp = temp.concat(values) + } + }) + return (string2Bytes(temp.length, 16)).concat(temp) + } + + // 图片处理 + getBytePhoto(base64) { + const buffer = Buffer.from(base64, 'base64'); + let arr = [] + for (let i = 0; i < buffer.length; i++) { + arr.push(buffer[i]); + } + return (string2Bytes(arr.length + 5, 4 * 8)).concat([0]).concat(string2Bytes(arr.length, 4 * 8)).concat(arr) + } + + //随机获取流水号 + getRandomLsh() { + return Math.floor(Math.random() * 65535); + } + + //转换消息类型 + getMessageType(id) { + switch (id) { + case '17C51': + return 0x01 + case '17C52': + return 0x02 + case '17C53': + return 0x03 + case '17C54': + return 0x04 + case '17C55': + return 0x05 + } + } + + //检查字节中是否有标识头字段 + checkHasPrefix(message) { + const {prefix,nPrefix} = this; + let preMessage = []; + + message.forEach((i, index) => { + + if (i === prefix) { + preMessage = preMessage.concat([0x7d, 2]) + } else if (i === nPrefix) { + preMessage = preMessage.concat([0x7d, 1]) + } else { + preMessage.push(i) + } + }); + + return preMessage + + } +} + diff --git a/entry/src/main/ets/tcp2byte/utils/tools.ts b/entry/src/main/ets/tcp2byte/utils/tools.ts new file mode 100644 index 00000000..4cf9adfb --- /dev/null +++ b/entry/src/main/ets/tcp2byte/utils/tools.ts @@ -0,0 +1,68 @@ +import util from '@ohos.util' +//字符串转byte数组 +export function string2Bytes(number, len) { + let str = (Math.floor(+number)).toString(2); + if (str.length > len) { + console.log('数据长度不对~~'); + return + } + const byteString = fillZero(str, len); + + const arrBytes = new Array(); + for (let i = byteString.length; i > 0;) { + let j = i - 8; + if (j < 0) { + j = 0 + } + let s = byteString.slice(j, i); + let v = parseInt(s, 2); + arrBytes.push(v); + i = i - 8 + + } + return arrBytes.reverse(); +} + +//字符串转utf-8 +export function str2UTF8(str) { + let encoder = new util.TextEncoder() + return Array.from(encoder.encodeInto(str)); +} + +//时间转bcd格式 +export function timeTOBCD(timeStr) { + const time = timeStr.split(' ')[0].split('-').join('') + timeStr.split(' ')[1].split(':').join('') + const year_one = parseInt(time.slice(0, 2), 16) + const year_two = parseInt(time.slice(2, 4), 16) + const month = parseInt(time.slice(4, 6), 16) + const day = parseInt(time.slice(6, 8), 16) + const hour = parseInt(time.slice(8, 10), 16) + const min = parseInt(time.slice(10, 12), 16) + const sec = parseInt(time.slice(12, 14), 16) + + return [year_one,year_two,month, day, hour, min, sec] +} + +export function fillZero(str, len) { + str = str + ''; + if (str.length > len || !len) { + return str + } + + let num = len - str.length; + let zeroStr = ''; + for (var i = 0; i < num; i++) { + zeroStr = zeroStr + '0' + } + + return zeroStr + str; +} + +export function bytesToDecimal(bytes) { + let result = 0; + for (let i = 0; i < bytes.length; i++) { + result = (result << 8) + bytes[i]; + } + return result; +} + diff --git a/hvigor/hvigor-config.json5 b/hvigor/hvigor-config.json5 index 122677b1..64655e69 100644 --- a/hvigor/hvigor-config.json5 +++ b/hvigor/hvigor-config.json5 @@ -1,6 +1,6 @@ { - "hvigorVersion": "3.0.9", + "hvigorVersion": "3.2.4", "dependencies": { - "@ohos/hvigor-ohos-plugin": "3.0.9" + "@ohos/hvigor-ohos-plugin": "3.2.4" } } \ No newline at end of file diff --git a/oh-package-lock.json5 b/oh-package-lock.json5 index bc40219d..1f023b33 100644 --- a/oh-package-lock.json5 +++ b/oh-package-lock.json5 @@ -1,13 +1,15 @@ { - "lockfileVersion": 1, + "lockfileVersion": 2, "ATTENTION": "THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.", "specifiers": { "@ohos/hypium@1.0.6": "@ohos/hypium@1.0.6" }, "packages": { "@ohos/hypium@1.0.6": { - "resolved": "https://repo.harmonyos.com/ohpm/@ohos/hypium/-/hypium-1.0.6.tgz", - "integrity": "sha512-bb3DWeWhYrFqj9mPFV3yZQpkm36kbcK+YYaeY9g292QKSjOdmhEIQR2ULPvyMsgSR4usOBf5nnYrDmaCCXirgQ==" + "resolved": "https://ohpm.openharmony.cn/ohpm/@ohos/hypium/-/hypium-1.0.6.tgz", + "integrity": "sha512-bb3DWeWhYrFqj9mPFV3yZQpkm36kbcK+YYaeY9g292QKSjOdmhEIQR2ULPvyMsgSR4usOBf5nnYrDmaCCXirgQ==", + "registryType": "ohpm", + "shasum": "3f5fed65372633233264b3447705b0831dfe7ea1" } } } \ No newline at end of file