Compare commits
	
		
			1 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | d1b9214a4e | 
| @ -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" | ||||
|         } | ||||
|       } | ||||
|     ], | ||||
|  | ||||
							
								
								
									
										
											BIN
										
									
								
								entry/.DS_Store
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										
											BIN
										
									
								
								entry/.DS_Store
									
									
									
									
										vendored
									
									
								
							
										
											Binary file not shown.
										
									
								
							| @ -2,6 +2,11 @@ | ||||
|   "apiType": 'stageMode', | ||||
|   "buildOption": { | ||||
|     "externalNativeOptions": { | ||||
|       "abiFilters": [ | ||||
|         "arm64-v8a", | ||||
|         "armeabi-v7a", | ||||
|         "x86_64" | ||||
|       ], | ||||
|       "path": "./src/main/cpp/CMakeLists.txt", | ||||
|       "arguments": "", | ||||
|       "cppFlags": "", | ||||
|  | ||||
| @ -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" | ||||
|     } | ||||
|   } | ||||
| } | ||||
							
								
								
									
										
											BIN
										
									
								
								entry/src/.DS_Store
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										
											BIN
										
									
								
								entry/src/.DS_Store
									
									
									
									
										vendored
									
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								entry/src/main/.DS_Store
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										
											BIN
										
									
								
								entry/src/main/.DS_Store
									
									
									
									
										vendored
									
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								entry/src/main/ets/.DS_Store
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										
											BIN
										
									
								
								entry/src/main/ets/.DS_Store
									
									
									
									
										vendored
									
									
								
							
										
											Binary file not shown.
										
									
								
							| @ -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<WR> { | ||||
|   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<WR> { | ||||
|   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: `<?xml version="1.0"?>
 | ||||
|                 <SOAP-ENV:Envelope | ||||
|                   xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" | ||||
|                   xmlns:xsd="http://www.w3.org/2001/XMLSchema" | ||||
|                   xmlns:xs="http://www.w3.org/2001/XMLSchema-instance" | ||||
|                  > | ||||
|                  <SOAP-ENV:Body> | ||||
|                     <writeObjectOut  xmlns="http://service.es.doron"> | ||||
|                       <wglb>${wglb}</wglb> | ||||
|                       <jkxlh>${jkxlh}</jkxlh> | ||||
|                       <glbm>${glbm}</glbm> | ||||
|                       <jgbh>${jgbh}</jgbh> | ||||
|                       <sjbs>${sjbs}</sjbs> | ||||
|                       <data>${JSON.stringify(params.data)}</data> | ||||
|                       <file>${JSON.stringify(params.file)}</file> | ||||
|                     </writeObjectOut> | ||||
|                  </SOAP-ENV:Body> | ||||
|                </SOAP-ENV:Envelope>`, | ||||
|     }) | ||||
|   } 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`); | ||||
|  | ||||
| @ -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:{ | ||||
|  | ||||
							
								
								
									
										138
									
								
								entry/src/main/ets/tcp2byte/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										138
									
								
								entry/src/main/ets/tcp2byte/index.ts
									
									
									
									
									
										Normal file
									
								
							| @ -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<RES> { | ||||
| 
 | ||||
|   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 | ||||
|     } | ||||
|   } | ||||
| } | ||||
							
								
								
									
										125
									
								
								entry/src/main/ets/tcp2byte/testData/testData.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										125
									
								
								entry/src/main/ets/tcp2byte/testData/testData.js
									
									
									
									
									
										Normal file
									
								
							| @ -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, | ||||
| } | ||||
							
								
								
									
										273
									
								
								entry/src/main/ets/tcp2byte/testData/消息结构.pdf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										273
									
								
								entry/src/main/ets/tcp2byte/testData/消息结构.pdf
									
									
									
									
									
										Normal file
									
								
							| @ -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 | ||||
|  | ||||
							
								
								
									
										2
									
								
								entry/src/main/ets/tcp2byte/utils/base64.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								entry/src/main/ets/tcp2byte/utils/base64.js
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										498
									
								
								entry/src/main/ets/tcp2byte/utils/tcp2byte.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										498
									
								
								entry/src/main/ets/tcp2byte/utils/tcp2byte.ts
									
									
									
									
									
										Normal file
									
								
							| @ -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 | ||||
| 
 | ||||
|   } | ||||
| } | ||||
| 
 | ||||
							
								
								
									
										68
									
								
								entry/src/main/ets/tcp2byte/utils/tools.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								entry/src/main/ets/tcp2byte/utils/tools.ts
									
									
									
									
									
										Normal file
									
								
							| @ -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; | ||||
| } | ||||
| 
 | ||||
| @ -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" | ||||
|   } | ||||
| } | ||||
| @ -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" | ||||
|     } | ||||
|   } | ||||
| } | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user