Pu Zhibing
2025-03-07 297512bc22b179b7038d96a1ff033eceaed38c4b
新增加809对接逻辑
26个文件已修改
10个文件已删除
90个文件已添加
7060 ■■■■ 已修改文件
ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/factory/EnterpriseClientFallbackFactory.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/feignClient/EnterpriseClient.java 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/model/Enterprise.java 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-system/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-auth/pom.xml 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-modules/ruoyi-job/pom.xml 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-modules/ruoyi-system/pom.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/EnterpriseController.java 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/SysUserController.java 80 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/filter/AuthFilter.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/EnterpriseMapper.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/IEnterpriseService.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/EnterpriseServiceImpl.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-modules/ruoyi-system/src/main/resources/mapping/system/EnterpriseMapper.xml 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/pom.xml 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-admin/pom.xml 173 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/RuoYiAdminApplication.java 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/config/DataUpdateHandlerConfig.java 79 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/config/FileUploadConfig.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/config/HttpConfig.java 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/config/MybatisPlusConfig.java 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-admin/src/main/resources/logback.xml 74 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-admin/src/main/resources/mybatis-config.xml 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-admin/src/test/java/com/ruoyi/dataInterchange/account/RuoYiAccountApplicationTests.java 55 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-dataInterchange/pom.xml 64 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/RuoYiDataInterchangeApplication.java 16 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/dao/UPExgMsgHistoryLocationDao.java 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/dao/UPExgMsgRealLocationDao.java 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/dao/UPExgMsgRegisterDao.java 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/dao/UPExgMsgReportDriverInfoAckDao.java 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/dao/UPExgMsgTakeEwayBillAckDao.java 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/dao/UPWarnMsgAdptInfoDao.java 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/dao/UPWarnMsgUrgeTodoAckDao.java 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/CtrlMag.java 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/DOWNBaseMsgDrvLineAck.java 58 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/DOWNBaseMsgDrvLineReq.java 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/DOWNBaseMsgVehicleAdded.java 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/DOWNConnectReq.java 16 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/DOWNConnectRsp.java 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/DOWNCtrlMsgEmergencyMonitoringReq.java 73 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/DOWNCtrlMsgMonitorVehicleReq.java 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/DOWNCtrlMsgTakePhotoReq.java 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/DOWNCtrlMsgTakeTravelReq.java 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/DOWNCtrlMsgTextReq.java 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/DOWNDisconnectInform.java 15 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/DOWNExgMsgApplyForMonitorEndAck.java 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/DOWNExgMsgApplyForMonitorStartupAck.java 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/DOWNExgMsgApplyHisgnssDataAck.java 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/DOWNExgMsgReportDriverInfo.java 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/DOWNExgMsgTakeEwaybillReq.java 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/DOWNPlatformMsgInfoReq.java 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/DOWNPlatformMsgPostQueryReq.java 55 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/DOWNPlatformMsgRetranReq.java 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/DOWNWarnMsgExgInform.java 73 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/DOWNWarnMsgInformTips.java 78 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/DOWNWarnMsgUrgeTodoReq.java 131 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/GnssData.java 96 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/Message.java 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/UPBaseMsgDrvLineAddedReq.java 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/UPBaseMsgVehicleAddedAck.java 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/UPCloseLinkInform.java 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/UPConnectReq.java 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/UPConnectRsp.java 25 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/UPCtrlMsgEmergencyMonitoringAck.java 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/UPCtrlMsgMonitorVehicleAck.java 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/UPCtrlMsgTakePhotoAck.java 98 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/UPCtrlMsgTakeTravelAck.java 58 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/UPCtrlMsgTextInfoAck.java 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/UPDisconnectInform.java 15 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/UPDisconnectReq.java 20 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/UPExgMsg.java 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/UPExgMsgHistoryLocation.java 55 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/UPExgMsgRealLocation.java 44 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/UPExgMsgRegister.java 66 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/UPExgMsgReportDriverInfoAck.java 63 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/UPExgMsgTakeEwayBillAck.java 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/UPPlatformMsg.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/UPPlatformMsgInfoAck.java 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/UPPlatformMsgPostQueryAck.java 63 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/UPPlatformMsgRetranReq.java 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/UPWarnMsgAdptInfo.java 113 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/UPWarnMsgAdptTodoInfo.java 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/UPWarnMsgInformTips.java 74 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/UPWarnMsgUrgeTodoAck.java 73 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/UPWarnMsgUrgeTodoAckInfo.java 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/UPWarnMsgUrgeTodoReqInfo.java 71 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/WarnMsg.java 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/enu/DataType.java 144 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/enu/NonPositionAlarm.java 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/enu/PositionAlarm.java 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/netty/client/ChannelMap.java 118 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/netty/client/NettyClient.java 89 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/netty/client/NettyClientHandler.java 73 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/netty/server/NettyConfig.java 57 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/netty/server/NettyHandle.java 192 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/netty/server/NettyInitalizer.java 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/netty/server/NettyStart.java 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/pojo/BaseModel.java 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/server/BaseMsgService.java 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/server/ConnectReqService.java 197 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/server/CtrlMsgService.java 74 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/server/DOWNConnectRspService.java 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/server/DOWNTotalRecvBackMsgService.java 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/server/ExgMsgService.java 261 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/server/PlatformMsgService.java 64 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/server/UPCloseLinkInformService.java 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/server/UPDisconnectInformService.java 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/server/UPDisconnectReqService.java 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/server/UPLinkTestReqService.java 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/server/WarnMsgService.java 167 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/util/EncryptUtil.java 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/util/TaskUtil.java 54 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/util/jtt809/common/ByteArrayUtil.java 343 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/util/jtt809/common/CRC16CCITT.java 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/util/jtt809/common/Jtt809Constant.java 343 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/util/jtt809/common/Jtt809Util.java 177 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/util/jtt809/decoder/Jtt809Decoder.java 100 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/util/jtt809/encoder/Jtt809Encoder.java 78 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/util/jtt809/gnsscenter/GnssCenterService.java 91 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/util/jtt809/packet/DownTotalReceivePacket.java 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/util/jtt809/packet/common/OuterPacket.java 73 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/util/jtt809/packet/upexg/UpExgHistoryPacket.java 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/util/jtt809/packet/upexg/UpExgPacket.java 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/util/jtt809/packet/upexg/UpExgRealLocationPacket.java 66 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/wapper/UPConnect.java 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/factory/EnterpriseClientFallbackFactory.java
New file
@@ -0,0 +1,24 @@
package com.ruoyi.system.api.factory;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.system.api.RemoteFileService;
import com.ruoyi.system.api.feignClient.EnterpriseClient;
import com.ruoyi.system.api.model.Enterprise;
import org.springframework.cloud.openfeign.FallbackFactory;
/**
 * @author zhibing.pu
 * @Date 2025/3/4 18:35
 */
public class EnterpriseClientFallbackFactory implements FallbackFactory<EnterpriseClient> {
    @Override
    public EnterpriseClient create(Throwable cause) {
        return new EnterpriseClient(){
            @Override
            public R<Enterprise> getEnterprise(String username) {
                return R.fail("获取企业失败:" + cause.getMessage());
            }
        };
    }
}
ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/feignClient/EnterpriseClient.java
New file
@@ -0,0 +1,26 @@
package com.ruoyi.system.api.feignClient;
import com.ruoyi.common.core.constant.ServiceNameConstants;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.system.api.factory.EnterpriseClientFallbackFactory;
import com.ruoyi.system.api.model.Enterprise;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
/**
 * @author zhibing.pu
 * @Date 2025/3/4 18:34
 */
@FeignClient(contextId = "EnterpriseClient", value = ServiceNameConstants.SYSTEM_SERVICE, fallbackFactory = EnterpriseClientFallbackFactory.class)
public interface EnterpriseClient {
    /**
     * 获取企业
     * @param username
     * @return
     */
    @PostMapping("/enterprise/getEnterprise")
    R<Enterprise> getEnterprise(@RequestParam("username") String username);
}
ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/model/Enterprise.java
New file
@@ -0,0 +1,46 @@
package com.ruoyi.system.api.model;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
/**
 * @author zhibing.pu
 * @Date 2025/3/4 18:26
 */
@Data
@TableName("t_enterprise")
public class Enterprise {
    /**
     * 主键
     */
    @TableId(value = "id", type = IdType.AUTO)
    private Integer id;
    /**
     * 企业名称
     */
    @TableField("name")
    private String name;
    /**
     * 企业唯一码
     */
    @TableField("code")
    private String code;
    /**
     * 登录账号
     */
    @TableField("username")
    private String username;
    /**
     * 登录密码
     */
    @TableField("password")
    private String password;
    /**
     * IP白名单
     */
    @TableField("ip_whitelist")
    private String ipWhitelist;
}
ruoyi-api/ruoyi-api-system/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
@@ -6,3 +6,4 @@
com.ruoyi.system.api.factory.SysLoginLogFallbackFactory
com.ruoyi.system.api.factory.SysUserRoleFallbackFactory
com.ruoyi.system.api.factory.UserShopClientFallbackFactory
com.ruoyi.system.api.factory.EnterpriseClientFallbackFactory
ruoyi-auth/pom.xml
@@ -20,10 +20,6 @@
    </properties>
    
    <dependencies>
        <dependency>
            <groupId>com.ruoyi</groupId>
            <artifactId>ruoyi-api-other</artifactId>
        </dependency>
        <!-- SpringCloud Alibaba Nacos -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
ruoyi-modules/ruoyi-job/pom.xml
@@ -16,19 +16,6 @@
    </description>
    <dependencies>
        <dependency>
            <groupId>com.ruoyi</groupId>
            <artifactId>ruoyi-api-account</artifactId>
        </dependency>
        <dependency>
            <groupId>com.ruoyi</groupId>
            <artifactId>ruoyi-api-other</artifactId>
        </dependency>
        <dependency>
            <groupId>com.ruoyi</groupId>
            <artifactId>ruoyi-api-order</artifactId>
        </dependency>
        <!-- SpringCloud Alibaba Nacos -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
ruoyi-modules/ruoyi-system/pom.xml
@@ -110,11 +110,6 @@
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>com.ruoyi</groupId>
            <artifactId>ruoyi-api-other</artifactId>
        </dependency>
    </dependencies>
    <build>
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/EnterpriseController.java
New file
@@ -0,0 +1,35 @@
package com.ruoyi.system.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.system.api.model.Enterprise;
import com.ruoyi.system.service.IEnterpriseService;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource; /**
 * @author zhibing.pu
 * @Date 2025/3/6 11:01
 */
@RestController
@RequestMapping("/enterprise")
public class EnterpriseController {
    @Resource
    private IEnterpriseService enterpriseService;
    /**
     * 获取企业
     * @param username
     * @return
     */
    @PostMapping("/getEnterprise")
    public R<Enterprise> getEnterprise(@RequestParam("username") String username){
        Enterprise username1 = enterpriseService.getOne(new QueryWrapper<Enterprise>().eq("username", username));
        return R.ok(username1);
    }
}
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/SysUserController.java
@@ -3,10 +3,6 @@
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruoyi.admin.api.feignClient.AppUserClient;
import com.ruoyi.admin.api.feignClient.AppUserShopClient;
import com.ruoyi.admin.api.model.AppUser;
import com.ruoyi.admin.api.model.AppUserShop;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.core.web.controller.BaseController;
@@ -83,12 +79,6 @@
    @Autowired
    private ISysMenuService menuService;
    @Resource
    private AppUserClient appUserClient;
    @Resource
    private AppUserShopClient appUserShopClient;
    
    
    
@@ -131,76 +121,6 @@
        }
        if (StringUtils.isNotEmpty(user.getUserName()) && !userService.checkUserNameUnique(user)) {
            return error("登录账号重复");
        }
        //门店员工添加数据,需要判断账号是否存在,共用同一个账号
        if(2 == sysUser1.getRoleType()){
            AppUser appUser = appUserClient.getAppUserByPhone1(user.getPhonenumber()).getData();
            if(null == appUser){
                return error("请先注册小程序账号");
            }
            SysUser one2 = userService.getOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getUserName, user.getPhonenumber())
                    .eq(SysUser::getDelFlag, "0").eq(SysUser::getStatus, "0").eq(SysUser::getObjectId, sysUser1.getObjectId())
                    .eq(SysUser::getRoleType, 2));
            if(null != one2){
                return error("登录账号重复");
            }
            SysUser one = userService.getOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getUserName, user.getPhonenumber())
                    .eq(SysUser::getDelFlag, "0").eq(SysUser::getStatus, "0").eq(SysUser::getRoleType, 2));
            if(null == one){
                user.setCreateBy(SecurityUtils.getUsername());
                user.setPassword(SecurityUtils.encryptPassword(MD5Generator.generateMD5("a123456")));
                user.setRoleType(sysUser1.getRoleType());
                user.setObjectId(sysUser1.getObjectId());
                if(null != appUser){
                    user.setAppUserId(appUser.getId());
                }
                userService.insertUser(user);
                one = user;
                SysUserRole sysUserRole = new SysUserRole();
                sysUserRole.setRoleId(user.getRoleId());
                sysUserRole.setUserId(user.getUserId());
                userRoleService.insertSysUserRole(sysUserRole);
            }
            //添加小程序店员关系数据
            if(null != appUser){
                List<AppUserShop> data = appUserShopClient.getAppUserShop(appUser.getId()).getData();
                Optional<AppUserShop> first = data.stream().filter(s -> s.getShopId().equals(sysUser1.getObjectId())).findFirst();
                if(!first.isPresent()){
                    AppUserShop appUserShop = new AppUserShop();
                    appUserShop.setAppUserId(appUser.getId());
                    appUserShop.setShopId(sysUser1.getObjectId());
                    appUserShop.setRoleType(2);
                    appUserShopClient.saveAppUserShop(appUserShop);
                    appUser.setUserType(2);
                    appUserClient.editAppUserById(appUser);
                }
            }
            //添加门店员工关系数据
            UserShop one1 = userShopService.getOne(new LambdaQueryWrapper<UserShop>().eq(UserShop::getUserId, one.getUserId()).eq(UserShop::getShopId, sysUser1.getObjectId()));
            if(null == one1){
                UserShop userShop = new UserShop();
                userShop.setUserId(one.getUserId());
                userShop.setShopId(sysUser1.getObjectId());
                userShop.setRoleType(2);
                userShop.setRoleId(user.getRoleId());
                userShop.setDeptId(user.getDeptId());
                userShop.setNickName(user.getNickName());
                userShop.setCreateTime(LocalDateTime.now());
                userShopService.save(userShop);
            }
        }else{
            user.setCreateBy(SecurityUtils.getUsername());
            user.setPassword(SecurityUtils.encryptPassword(MD5Generator.generateMD5("a123456")));
            user.setRoleType(sysUser1.getRoleType());
            userService.insertUser(user);
            SysUserRole sysUserRole = new SysUserRole();
            sysUserRole.setRoleId(user.getRoleId());
            sysUserRole.setUserId(user.getUserId());
            userRoleService.insertSysUserRole(sysUserRole);
        }
        return AjaxResult.success();
    }
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/filter/AuthFilter.java
@@ -1,8 +1,6 @@
package com.ruoyi.system.filter;
import com.alibaba.fastjson.JSON;
import com.ruoyi.admin.api.feignClient.AppUserClient;
import com.ruoyi.admin.api.model.AppUser;
import com.ruoyi.common.core.constant.TokenConstants;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.utils.StringUtils;
@@ -35,10 +33,6 @@
    
    @Lazy
    @Resource
    private AppUserClient appUserClient;
    @Lazy
    @Resource
    private ISysUserService sysUserService;
    
    
@@ -63,20 +57,6 @@
            if("1".equals(sysUser.getStatus())){
                log.error("[账户异常处理]请求账户id:{}", userid);
                unauthorizedResponse(response,"账户已被停用,请联系系统管理员!");
                return;
            }
        }
        //小程序用户
        if ("applet".equals(userType)) {
            AppUser appUser = appUserClient.getAppUserById(Long.valueOf(userid));
            if(null == appUser || appUser.getDelFlag() || 3 == appUser.getStatus()){
                log.error("[账户异常处理]请求账户id:{}", userid);
                unauthorizedResponse(response,"无效的账户");
                return;
            }
            if(2 == appUser.getStatus()){
                log.error("[账户异常处理]请求账户id:{}", userid);
                unauthorizedResponse(response,"账户已被冻结,请联系系统管理员!");
                return;
            }
        }
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/EnterpriseMapper.java
New file
@@ -0,0 +1,11 @@
package com.ruoyi.system.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ruoyi.system.api.model.Enterprise;
/**
 * @author zhibing.pu
 * @Date 2025/3/4 18:30
 */
public interface EnterpriseMapper extends BaseMapper<Enterprise> {
}
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/IEnterpriseService.java
New file
@@ -0,0 +1,11 @@
package com.ruoyi.system.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.system.api.model.Enterprise;
/**
 * @author zhibing.pu
 * @Date 2025/3/4 18:32
 */
public interface IEnterpriseService extends IService<Enterprise> {
}
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/EnterpriseServiceImpl.java
New file
@@ -0,0 +1,15 @@
package com.ruoyi.system.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.system.api.model.Enterprise;
import com.ruoyi.system.mapper.EnterpriseMapper;
import com.ruoyi.system.service.IEnterpriseService;
import org.springframework.stereotype.Service;
/**
 * @author zhibing.pu
 * @Date 2025/3/4 18:32
 */
@Service
public class EnterpriseServiceImpl extends ServiceImpl<EnterpriseMapper, Enterprise> implements IEnterpriseService {
}
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java
@@ -2,10 +2,6 @@
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.admin.api.feignClient.AppUserClient;
import com.ruoyi.admin.api.feignClient.AppUserShopClient;
import com.ruoyi.admin.api.model.AppUser;
import com.ruoyi.admin.api.model.AppUserShop;
import com.ruoyi.common.core.constant.UserConstants;
import com.ruoyi.common.core.exception.ServiceException;
import com.ruoyi.common.core.utils.SpringUtils;
@@ -83,12 +79,6 @@
    
    @Resource
    private UserShopService userShopService;
    @Resource
    private AppUserShopClient appUserShopClient;
    @Resource
    private AppUserClient appUserClient;
    
    
    /**
@@ -460,22 +450,6 @@
        for (SysUser user : sysUsers) {
            if(2 == user.getRoleType()){
                userShopService.remove(new LambdaQueryWrapper<UserShop>().eq(UserShop::getUserId, user.getUserId()).eq(UserShop::getShopId, sysUser.getObjectId()));
                AppUser appUser = appUserClient.getAppUserByPhone1(user.getPhonenumber()).getData();
                if(null != appUser){
                    AppUserShop appUserShop = new AppUserShop();
                    appUserShop.setAppUserId(appUser.getId());
                    appUserShop.setShopId(sysUser.getObjectId());
                    appUserShopClient.delAppUserShop(appUserShop);
                    int size = appUserShopClient.getAppUserShop(appUser.getId()).getData().size();
                    if(size == 0){
                        appUser.setUserType(1);
                        appUserClient.editAppUserById(appUser);
                    }
                }
                long count = userShopService.count(new LambdaQueryWrapper<UserShop>().eq(UserShop::getUserId, user.getUserId()));
                if(0 == count){
                    userMapper.deleteUserById(user.getUserId());
                }
            }else{
                userMapper.deleteUserById(user.getUserId());
            }
ruoyi-modules/ruoyi-system/src/main/resources/mapping/system/EnterpriseMapper.xml
New file
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.system.mapper.EnterpriseMapper">
</mapper>
ruoyi-service/pom.xml
@@ -9,7 +9,6 @@
    <modelVersion>4.0.0</modelVersion>
    
    <modules>
        <module>ruoyi-admin</module>
        <module>ruoyi-dataInterchange</module>
    </modules>
ruoyi-service/ruoyi-admin/pom.xml
File was deleted
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/RuoYiAdminApplication.java
File was deleted
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/config/DataUpdateHandlerConfig.java
File was deleted
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/config/FileUploadConfig.java
File was deleted
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/config/HttpConfig.java
File was deleted
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/config/MybatisPlusConfig.java
File was deleted
ruoyi-service/ruoyi-admin/src/main/resources/logback.xml
File was deleted
ruoyi-service/ruoyi-admin/src/main/resources/mybatis-config.xml
File was deleted
ruoyi-service/ruoyi-admin/src/test/java/com/ruoyi/dataInterchange/account/RuoYiAccountApplicationTests.java
File was deleted
ruoyi-service/ruoyi-dataInterchange/pom.xml
@@ -15,32 +15,6 @@
    </description>
    <dependencies>
        <!--网易邮件-->
        <dependency>
            <groupId>javax.mail</groupId>
            <artifactId>javax.mail-api</artifactId>
            <version>1.6.2</version>
        </dependency>
        <dependency>
            <groupId>com.sun.mail</groupId>
            <artifactId>jakarta.mail</artifactId>
            <version>1.6.5</version>
        </dependency>
        <!-- ruoyi-modules-other-api -->
        <dependency>
            <groupId>com.ruoyi</groupId>
            <artifactId>ruoyi-api-other</artifactId>
        </dependency>
        <dependency>
            <groupId>com.ruoyi</groupId>
            <artifactId>ruoyi-api-account</artifactId>
        </dependency>
        <!-- ruoyi-modules-chargingPile-api -->
        <dependency>
            <groupId>com.ruoyi</groupId>
            <artifactId>ruoyi-api-order</artifactId>
        </dependency>
        <!-- SpringCloud Alibaba Nacos -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
@@ -132,43 +106,13 @@
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>cn.afterturn</groupId>
            <artifactId>easypoi-spring-boot-starter</artifactId>
            <version>4.1.2</version>
            <exclusions>
                <exclusion>
                    <artifactId>guava</artifactId>
                    <groupId>com.google.guava</groupId>
                </exclusion>
            </exclusions>
            <groupId>io.netty</groupId>
            <artifactId>netty-all</artifactId>
        </dependency>
        <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper-spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>com.github.kuaidi100-api</groupId>
            <artifactId>sdk</artifactId>
            <version>1.0.11</version>
        </dependency>
        <dependency>
            <groupId>com.github.wechatpay-apiv3</groupId>
            <artifactId>wechatpay-java</artifactId>
            <version>0.2.15</version>
        </dependency>
        <!-- 计算两坐标间的直线距离 -->
        <dependency>
            <groupId>org.gavaghan</groupId>
            <artifactId>geodesy</artifactId>
            <version>1.1.3</version>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
        </dependency>
    </dependencies>
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/RuoYiDataInterchangeApplication.java
@@ -15,25 +15,15 @@
 * @author ruoyi
 */
@EnableCustomConfig
@MapperScan({"com.ruoyi.order.mapper"})
@MapperScan({"com.ruoyi.dataInterchange.mapper"})
@EnableCustomSwagger2
@EnableRyFeignClients
@SpringBootApplication
@EnableScheduling//开启定时任务
@ServletComponentScan
@SpringBootApplication
@EnableTransactionManagement//开启事务
public class RuoYiDataInterchangeApplication {
    public static void main(String[] args) {
        SpringApplication.run(RuoYiDataInterchangeApplication.class, args);
        System.out.println("(♥◠‿◠)ノ゙  订单模块启动成功   ლ(´ڡ`ლ)゙  \n" +
                " .-------.       ____     __        \n" +
                " |  _ _   \\      \\   \\   /  /    \n" +
                " | ( ' )  |       \\  _. /  '       \n" +
                " |(_ o _) /        _( )_ .'         \n" +
                " | (_,_).' __  ___(_ o _)'          \n" +
                " |  |\\ \\  |  ||   |(_,_)'         \n" +
                " |  | \\ `'   /|   `-'  /           \n" +
                " |  |  \\    /  \\      /           \n" +
                " ''-'   `'-'    `-..-'              ");
        System.out.println("(♥◠‿◠)ノ゙  数据交互模块启动成功   ლ(´ڡ`ლ)゙ ");
    }
}
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/dao/UPExgMsgHistoryLocationDao.java
New file
@@ -0,0 +1,13 @@
package com.ruoyi.dataInterchange.dao;
import com.ruoyi.dataInterchange.model.UPExgMsgHistoryLocation;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import org.springframework.stereotype.Repository;
/**
 * @author zhibing.pu
 * @Date 2025/3/7 17:03
 */
@Repository
public interface UPExgMsgHistoryLocationDao extends ElasticsearchRepository<UPExgMsgHistoryLocation, Long> {
}
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/dao/UPExgMsgRealLocationDao.java
New file
@@ -0,0 +1,13 @@
package com.ruoyi.dataInterchange.dao;
import com.ruoyi.dataInterchange.model.UPExgMsgRealLocation;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import org.springframework.stereotype.Repository;
/**
 * @author zhibing.pu
 * @Date 2025/3/7 16:38
 */
@Repository
public interface UPExgMsgRealLocationDao extends ElasticsearchRepository<UPExgMsgRealLocation, Long> {
}
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/dao/UPExgMsgRegisterDao.java
New file
@@ -0,0 +1,13 @@
package com.ruoyi.dataInterchange.dao;
import com.ruoyi.dataInterchange.model.UPExgMsgRegister;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import org.springframework.stereotype.Repository;
/**
 * @author zhibing.pu
 * @Date 2025/3/7 16:10
 */
@Repository
public interface UPExgMsgRegisterDao extends ElasticsearchRepository<UPExgMsgRegister, Long> {
}
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/dao/UPExgMsgReportDriverInfoAckDao.java
New file
@@ -0,0 +1,13 @@
package com.ruoyi.dataInterchange.dao;
import com.ruoyi.dataInterchange.model.UPExgMsgReportDriverInfoAck;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import org.springframework.stereotype.Repository;
/**
 * @author zhibing.pu
 * @Date 2025/3/7 17:12
 */
@Repository
public interface UPExgMsgReportDriverInfoAckDao extends ElasticsearchRepository<UPExgMsgReportDriverInfoAck, Long> {
}
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/dao/UPExgMsgTakeEwayBillAckDao.java
New file
@@ -0,0 +1,13 @@
package com.ruoyi.dataInterchange.dao;
import com.ruoyi.dataInterchange.model.UPExgMsgTakeEwayBillAck;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import org.springframework.stereotype.Repository;
/**
 * @author zhibing.pu
 * @Date 2025/3/7 17:18
 */
@Repository
public interface UPExgMsgTakeEwayBillAckDao extends ElasticsearchRepository<UPExgMsgTakeEwayBillAck, Long> {
}
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/dao/UPWarnMsgAdptInfoDao.java
New file
@@ -0,0 +1,13 @@
package com.ruoyi.dataInterchange.dao;
import com.ruoyi.dataInterchange.model.UPWarnMsgAdptInfo;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import org.springframework.stereotype.Repository;
/**
 * @author zhibing.pu
 * @Date 2025/3/7 19:30
 */
@Repository
public interface UPWarnMsgAdptInfoDao extends ElasticsearchRepository<UPWarnMsgAdptInfo, Long> {
}
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/dao/UPWarnMsgUrgeTodoAckDao.java
New file
@@ -0,0 +1,13 @@
package com.ruoyi.dataInterchange.dao;
import com.ruoyi.dataInterchange.model.UPWarnMsgUrgeTodoAck;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import org.springframework.stereotype.Repository;
/**
 * @author zhibing.pu
 * @Date 2025/3/7 19:24
 */
@Repository
public interface UPWarnMsgUrgeTodoAckDao extends ElasticsearchRepository<UPWarnMsgUrgeTodoAck, Long> {
}
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/CtrlMag.java
New file
@@ -0,0 +1,31 @@
package com.ruoyi.dataInterchange.model;
import lombok.Data;
/**
 * @author zhibing.pu
 * @Date 2025/3/7 9:22
 */
@Data
public class CtrlMag {
    /**
     * 车牌号
     */
    private String vehicleNo;
    /**
     * 车牌颜色
     */
    private int vehicleColor;
    /**
     * 子业务类型标识
     */
    private int dataType;
    /**
     * 后续数据长度
     */
    private int dataLength;
    /**
     * 数据部分
     */
    private byte[] data;
}
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/DOWNBaseMsgDrvLineAck.java
New file
@@ -0,0 +1,58 @@
package com.ruoyi.dataInterchange.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
/**
 * 车辆行驶路线应答消息
 * @author zhibing.pu
 * @Date 2025/3/3 11:15
 */
@Data
public class DOWNBaseMsgDrvLineAck {
    /**
     * 车牌号
     */
    @JsonProperty("VEHICLE_NO")
    private String vehicleNo;
    /**
     * 车牌颜色
     */
    @JsonProperty("VEHICLE_COLOR")
    private String vehicleColor;
    /**
     * 子业务类型标识
     */
    @JsonProperty("DATA_TYPE")
    private String dataType;
    /**
     * 后续数据长度
     */
    @JsonProperty("DATA_LENGTH")
    private Integer dataLength;
    /**
     * 线路ID
     */
    @JsonProperty("DRV_LINE_ID")
    private String drvLineId;
    /**
     * 处理结果
     * 0x00:完成记录
     * 0x01:审核通过,完成记录
     * 0x02:信息错误,未完成记录
     * 0x03:审核未通过,未完成记录
     */
    @JsonProperty("RESULT")
    private String result;
    /**
     * 未通过原因内容长度
     */
    @JsonProperty("REASON_LENGTH")
    private String reasonLength;
    /**
     * 经过GBK编码后的未通过原因
     */
    @JsonProperty("REASON")
    private String reason;
}
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/DOWNBaseMsgDrvLineReq.java
New file
@@ -0,0 +1,34 @@
package com.ruoyi.dataInterchange.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
/**
 * 上报车辆行驶路线请求
 * @author zhibing.pu
 * @Date 2025/3/3 11:15
 */
@Data
public class DOWNBaseMsgDrvLineReq {
    /**
     * 车牌号
     */
    @JsonProperty("VEHICLE_NO")
    private String vehicleNo;
    /**
     * 车牌颜色
     */
    @JsonProperty("VEHICLE_COLOR")
    private String vehicleColor;
    /**
     * 子业务类型标识
     */
    @JsonProperty("DATA_TYPE")
    private String dataType;
    /**
     * 后续数据长度
     */
    @JsonProperty("DATA_LENGTH")
    private Integer dataLength;
}
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/DOWNBaseMsgVehicleAdded.java
New file
@@ -0,0 +1,33 @@
package com.ruoyi.dataInterchange.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
/**
 * 补报车辆静态信息请求
 * @author zhibing.pu
 * @Date 2025/3/3 17:24
 */
@Data
public class DOWNBaseMsgVehicleAdded {
    /**
     * 车牌号码
     */
    @JsonProperty("VEHICLE_NO")
    private String vehicleNo;
    /**
     * 车牌颜色
     */
    @JsonProperty("VEHICLE_COLOR")
    private String vehicleColor;
    /**
     * 子业务类型标识
     */
    @JsonProperty("DATA_TYPE")
    private String dataType;
    /**
     * 后续数据长度
     */
    @JsonProperty("DATA_LENGTH")
    private String dataLength;
}
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/DOWNConnectReq.java
@@ -1,10 +1,13 @@
package com.ruoyi.dataInterchange.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufUtil;
import io.netty.buffer.Unpooled;
import lombok.Data;
/**
 * 从链路登录请求
 *
 * @author zhibing.pu
 * @Date 2025/2/24 11:05
 */
@@ -13,6 +16,13 @@
    /**
     * 校验码
     */
    @JsonProperty("VERIFY_CODE")
    private String verifyCode;
    private int verifyCode;
    public byte[] encode() {
        ByteBuf byteBuf = Unpooled.buffer(1);
        byteBuf.writeInt(this.getVerifyCode());
        byte[] bytes = ByteBufUtil.getBytes(byteBuf);
        byteBuf.release();
        return bytes;
    }
}
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/DOWNConnectRsp.java
@@ -1,6 +1,7 @@
package com.ruoyi.dataInterchange.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.netty.buffer.ByteBuf;
import lombok.Data;
/**
@@ -17,6 +18,15 @@
     * 0x02:资源紧张,稍后再连接(已经占用)
     * 0xFF:其他
     */
    @JsonProperty("VERIFY_CODE")
    private String verifyCode;
    private int verifyCode;
    /**
     * 解析报文
     */
    public DOWNConnectRsp decode(ByteBuf byteBuf) {
        this.verifyCode = byteBuf.readByte();
        return this;
    }
}
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/DOWNCtrlMsgEmergencyMonitoringReq.java
New file
@@ -0,0 +1,73 @@
package com.ruoyi.dataInterchange.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
/**
 * 车辆应急接入监管平台请求
 * @author zhibing.pu
 * @Date 2025/3/3 17:10
 */
@Data
public class DOWNCtrlMsgEmergencyMonitoringReq {
    /**
     * 车牌号码
     */
    @JsonProperty("VEHICLE_NO")
    private String vehicleNo;
    /**
     * 车牌颜色
     */
    @JsonProperty("VEHICLE_COLOR")
    private String vehicleColor;
    /**
     * 子业务类型标识
     */
    @JsonProperty("DATA_TYPE")
    private String dataType;
    /**
     * 后续数据长度
     */
    @JsonProperty("DATA_LENGTH")
    private String dataLength;
    /**
     * 监管平台下发的鉴权码,用于车载终端连接到监管平台鉴权时使用
     */
    @JsonProperty("AUTHENTICATION_CODE")
    private String authenticationCode;
    /**
     * 拨号点名称
     */
    @JsonProperty("ACCESS_POINT_NAME")
    private String accessPointName;
    /**
     * 拨号用户名
     */
    @JsonProperty("USERNAME")
    private String username;
    /**
     * 拨号密码
     */
    @JsonProperty("PASSWORD")
    private String password;
    /**
     * 地址
     */
    @JsonProperty("SERVER_IP")
    private String serverIp;
    /**
     * 服务器TCP端口
     */
    @JsonProperty("TCP_PORT")
    private String tcpPort;
    /**
     * 服务器UDP端口
     */
    @JsonProperty("UDP_PORT")
    private String udpPort;
    /**
     * 结束时间
     */
    @JsonProperty("END_TIME")
    private String endTime;
}
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/DOWNCtrlMsgMonitorVehicleReq.java
New file
@@ -0,0 +1,38 @@
package com.ruoyi.dataInterchange.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
/**
 * 车辆单向监听请求
 * @author zhibing.pu
 * @Date 2025/3/3 16:42
 */
@Data
public class DOWNCtrlMsgMonitorVehicleReq {
    /**
     * 车牌号码
     */
    @JsonProperty("VEHICLE_NO")
    private String vehicleNo;
    /**
     * 车牌颜色
     */
    @JsonProperty("VEHICLE_COLOR")
    private String vehicleColor;
    /**
     * 子业务类型标识
     */
    @JsonProperty("DATA_TYPE")
    private String dataType;
    /**
     * 后续数据长度
     */
    @JsonProperty("DATA_LENGTH")
    private String dataLength;
    /**
     * 回拨电话号码
     */
    @JsonProperty("MONITOR_TEL")
    private String monitorTel;
}
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/DOWNCtrlMsgTakePhotoReq.java
New file
@@ -0,0 +1,51 @@
package com.ruoyi.dataInterchange.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
/**
 * 车辆牌照请求消息
 * @author zhibing.pu
 * @Date 2025/3/3 16:53
 */
@Data
public class DOWNCtrlMsgTakePhotoReq {
    /**
     * 车牌号码
     */
    @JsonProperty("VEHICLE_NO")
    private String vehicleNo;
    /**
     * 车牌颜色
     */
    @JsonProperty("VEHICLE_COLOR")
    private String vehicleColor;
    /**
     * 子业务类型标识
     */
    @JsonProperty("DATA_TYPE")
    private String dataType;
    /**
     * 后续数据长度
     */
    @JsonProperty("DATA_LENGTH")
    private String dataLength;
    /**
     * 镜头ID
     */
    @JsonProperty("LENS_ID")
    private String lensId;
    /**
     * 图片大小
     * 0x01: 320 x 240
     * 0x02: 640 x 48
     * 0x03: 800 x 600
     * 0x04: 1024 x 768
     * 0x05: 176 x 144
     * 0x06: 352 x 288
     * 0x07: 704 x 288
     * 0x08: 704 x 576
     */
    @JsonProperty("SIZE")
    private String size;
}
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/DOWNCtrlMsgTakeTravelReq.java
New file
@@ -0,0 +1,48 @@
package com.ruoyi.dataInterchange.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
/**
 * 上报车辆行驶记录请求
 * @author zhibing.pu
 * @Date 2025/3/3 17:06
 */
@Data
public class DOWNCtrlMsgTakeTravelReq {
    /**
     * 车牌号码
     */
    @JsonProperty("VEHICLE_NO")
    private String vehicleNo;
    /**
     * 车牌颜色
     */
    @JsonProperty("VEHICLE_COLOR")
    private String vehicleColor;
    /**
     * 子业务类型标识
     */
    @JsonProperty("DATA_TYPE")
    private String dataType;
    /**
     * 后续数据长度
     */
    @JsonProperty("DATA_LENGTH")
    private String dataLength;
    /**
     * 开始时间
     */
    @JsonProperty("START_TIME")
    private String startTime;
    /**
     * 结束时间
     */
    @JsonProperty("END_TIME")
    private String endTime;
    /**
     * 命令字
     */
    @JsonProperty("COMMAND_TYPE")
    private String commandType;
}
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/DOWNCtrlMsgTextReq.java
New file
@@ -0,0 +1,50 @@
package com.ruoyi.dataInterchange.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
/**
 * 下发车辆报文请求
 * @author zhibing.pu
 * @Date 2025/3/3 16:55
 */
@Data
public class DOWNCtrlMsgTextReq {
    /**
     * 车牌号码
     */
    @JsonProperty("VEHICLE_NO")
    private String vehicleNo;
    /**
     * 车牌颜色
     */
    @JsonProperty("VEHICLE_COLOR")
    private String vehicleColor;
    /**
     * 子业务类型标识
     */
    @JsonProperty("DATA_TYPE")
    private String dataType;
    /**
     * 后续数据长度
     */
    @JsonProperty("DATA_LENGTH")
    private String dataLength;
    /**
     * 报文优先级
     * 0x00: 紧急
     * 0x01: 一般
     */
    @JsonProperty("MSG_PRIORITY")
    private String msgPriority;
    /**
     * 报文信息长度
     */
    @JsonProperty("MSG_LENGTH")
    private String msgLength;
    /**
     * 报文信息内容
     */
    @JsonProperty("MSG_CONTENT")
    private String msgContent;
}
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/DOWNDisconnectInform.java
@@ -1,6 +1,9 @@
package com.ruoyi.dataInterchange.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufUtil;
import io.netty.buffer.Unpooled;
import lombok.Data;
/**
@@ -16,6 +19,14 @@
     * 0x01:上级平台客户端与下级平台服务端断开
     * 0xFF:其他错误
     */
    @JsonProperty("ERROR_CODE")
    private String errorCode;
    private int errorCode;
    public byte[] encode() {
        ByteBuf byteBuf = Unpooled.buffer(1);
        byteBuf.writeInt(this.getErrorCode());
        byte[] bytes = ByteBufUtil.getBytes(byteBuf);
        byteBuf.release();
        return bytes;
    }
}
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/DOWNExgMsgApplyForMonitorEndAck.java
New file
@@ -0,0 +1,52 @@
package com.ruoyi.dataInterchange.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
/**
 * 取消申请交换指定车辆定位信息应答
 * @author zhibing.pu
 * @Date 2025/3/3 10:47
 */
@Data
public class DOWNExgMsgApplyForMonitorEndAck {
    /**
     * 车牌号
     */
    @JsonProperty("VEHICLE_NO")
    private String vehicleNo;
    /**
     * 车牌颜色
     */
    @JsonProperty("VEHICLE_COLOR")
    private String vehicleColor;
    /**
     * 子业务类型标识
     */
    @JsonProperty("DATA_TYPE")
    private String dataType;
    /**
     * 后续数据长度
     */
    @JsonProperty("DATA_LENGTH")
    private Integer dataLength;
    /**
     * 对应取消申请交换指定车辆定位信息请求信息源子业务类型标识
     */
    @JsonProperty("SOURCE_DATA_TYPE")
    private String sourceDataType;
    /**
     * 对应取消申请交换指定车辆定位信息请求信息源报文序号
     */
    @JsonProperty("SOURCE_MSG_SN")
    private String sourceMsgSn;
    /**
     * 取消申请交换指定车辆定位信息结果
     * 0x00:取消申请成功
     * 0x01:之前没有对应申请信息
     * 0xFF:其他
     */
    @JsonProperty("RESULT")
    private String result;
}
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/DOWNExgMsgApplyForMonitorStartupAck.java
New file
@@ -0,0 +1,51 @@
package com.ruoyi.dataInterchange.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data; /**
 * 申请交换指定车辆定位信息应答
 * @author zhibing.pu
 * @Date 2025/3/3 10:47
 */
@Data
public class DOWNExgMsgApplyForMonitorStartupAck {
    /**
     * 车牌号
     */
    @JsonProperty("VEHICLE_NO")
    private String vehicleNo;
    /**
     * 车牌颜色
     */
    @JsonProperty("VEHICLE_COLOR")
    private String vehicleColor;
    /**
     * 子业务类型标识
     */
    @JsonProperty("DATA_TYPE")
    private String dataType;
    /**
     * 后续数据长度
     */
    @JsonProperty("DATA_LENGTH")
    private Integer dataLength;
    /**
     * 对应申请交换指定车辆定位信息请求信息源子业务类型标识
     */
    @JsonProperty("SOURCE_DATA_TYPE")
    private String sourceDataType;
    /**
     * 对应申请交换指定车辆定位信息请求信息源报文序号
     */
    @JsonProperty("SOURCE_MSG_SN")
    private String sourceMsgSn;
    /**
     * 申请交换指定车辆定位信息结果
     * 0x00:申请成功
     * 0x01:上级平台没有该车辆数据
     * 0x02:申请时间段错误
     * 0xFF:其他
     */
    @JsonProperty("RESULT")
    private String result;
}
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/DOWNExgMsgApplyHisgnssDataAck.java
New file
@@ -0,0 +1,51 @@
package com.ruoyi.dataInterchange.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data; /**
 * 补发车辆定位信息应答
 * @author zhibing.pu
 * @Date 2025/3/3 10:57
 */
@Data
public class DOWNExgMsgApplyHisgnssDataAck {
    /**
     * 车牌号
     */
    @JsonProperty("VEHICLE_NO")
    private String vehicleNo;
    /**
     * 车牌颜色
     */
    @JsonProperty("VEHICLE_COLOR")
    private String vehicleColor;
    /**
     * 子业务类型标识
     */
    @JsonProperty("DATA_TYPE")
    private String dataType;
    /**
     * 后续数据长度
     */
    @JsonProperty("DATA_LENGTH")
    private Integer dataLength;
    /**
     * 对应补发车辆定位信息请求信息源子业务类型标识
     */
    @JsonProperty("SOURCE_DATA_TYPE")
    private String sourceDataType;
    /**
     * 对应补发车辆定位信息请求信息源报文序列号
     */
    @JsonProperty("SOURCE_MSG_SN")
    private String sourceMsgSn;
    /**
     * 补发车辆定位信息应答结果
     * 0x00:成功,上级平台即刻补发
     * 0x01:成功,上级平台择机补发
     * 0x02:失败、上级平台无对应申请的定位数据
     * 0x03:失败、申请内容不正确
     * 0xFF:其他
     */
    @JsonProperty("RESULT")
    private String result;
}
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/DOWNExgMsgReportDriverInfo.java
New file
@@ -0,0 +1,50 @@
package com.ruoyi.dataInterchange.model;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufUtil;
import io.netty.buffer.Unpooled;
import lombok.Data;
/**
 * 上报驾驶员身份信息请求
 *
 * @author zhibing.pu
 * @Date 2025/3/3 11:02
 */
@Data
public class DOWNExgMsgReportDriverInfo {
    /**
     * 车牌号
     */
    private String vehicleNo;
    /**
     * 车牌颜色
     */
    private int vehicleColor;
    /**
     * 子业务类型标识
     */
    private int dataType;
    /**
     * 后续数据长度
     */
    private int dataLength;
    /**
     * 编码报文
     */
    public byte[] encode() {
        ByteBuf byteBuf = Unpooled.buffer(28);
        byte[] bytes1 = this.getVehicleNo().getBytes();
        for (byte b : bytes1) {
            byteBuf.writeByte(b);
        }
        byteBuf.writeByte(this.getVehicleColor());
        byteBuf.writeByte(this.getDataType());
        byteBuf.writeInt(this.getDataLength());
        byte[] bytes = ByteBufUtil.getBytes(byteBuf);
        byteBuf.release();
        return bytes;
    }
}
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/DOWNExgMsgTakeEwaybillReq.java
New file
@@ -0,0 +1,49 @@
package com.ruoyi.dataInterchange.model;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufUtil;
import io.netty.buffer.Unpooled;
import lombok.Data;
/**
 * 上报车辆电子运单请求
 * @author zhibing.pu
 * @Date 2025/3/3 11:06
 */
@Data
public class DOWNExgMsgTakeEwaybillReq {
    /**
     * 车牌号
     */
    private String vehicleNo;
    /**
     * 车牌颜色
     */
    private int vehicleColor;
    /**
     * 子业务类型标识
     */
    private int dataType;
    /**
     * 后续数据长度
     */
    private int dataLength;
    /**
     * 编码报文
     */
    public byte[] encode() {
        ByteBuf byteBuf = Unpooled.buffer(28);
        byte[] bytes1 = this.getVehicleNo().getBytes();
        for (byte b : bytes1) {
            byteBuf.writeByte(b);
        }
        byteBuf.writeByte(this.getVehicleColor());
        byteBuf.writeByte(this.getDataType());
        byteBuf.writeInt(this.getDataLength());
        byte[] bytes = ByteBufUtil.getBytes(byteBuf);
        byteBuf.release();
        return bytes;
    }
}
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/DOWNPlatformMsgInfoReq.java
New file
@@ -0,0 +1,49 @@
package com.ruoyi.dataInterchange.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
/**
 * 下发平台间报文请求
 * @author zhibing.pu
 * @Date 2025/3/3 14:24
 */
@Data
public class DOWNPlatformMsgInfoReq {
    /**
     * 子业务类型标识
     */
    @JsonProperty("DATA_TYPE")
    private String dataType;
    /**
     * 后续数据长度
     */
    @JsonProperty("DATA_LENGTH")
    private String dataLength;
    /**
     * 下发报文对象类型
     */
    @JsonProperty("OBJECT_TYPE")
    private String objectType;
    /**
     * 下发报文对象的ID,长度不足时后补0x00
     */
    @JsonProperty("OBJECT_ID")
    private String objectId;
    /**
     * 信誉ID
     */
    @JsonProperty("INFO_ID")
    private String infoId;
    /**
     * 信息长度
     */
    @JsonProperty("INFO_LENGTH")
    private String infoLength;
    /**
     * 信息内容
     */
    @JsonProperty("INFO_CONTENT")
    private String infoContent;
}
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/DOWNPlatformMsgPostQueryReq.java
New file
@@ -0,0 +1,55 @@
package com.ruoyi.dataInterchange.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
/**
 * 平台查岗请求
 * @author zhibing.pu
 * @Date 2025/3/3 14:16
 */
@Data
public class DOWNPlatformMsgPostQueryReq {
    /**
     * 子业务类型标识
     */
    @JsonProperty("DATA_TYPE")
    private String dataType;
    /**
     * 后续数据长度
     */
    @JsonProperty("DATA_LENGTH")
    private String dataLength;
    /**
     * 查岗对象类型
     */
    @JsonProperty("OBJECT_TYPE")
    private String objectType;
    /**
     * 查岗对象的ID,长度不足时后补0x00
     * 对象类型为平台时,由平台行政区划代码和平台唯一码组成
     * 对象类型为业户时,为业户经营许可证号
     */
    @JsonProperty("OBJECT_ID")
    private String objectId;
    /**
     * 查岗应答时限
     */
    @JsonProperty("ANSWER_TIME")
    private String answerTime;
    /**
     * 信息ID
     */
    @JsonProperty("INFO_ID")
    private String infoId;
    /**
     * 数据长度
     */
    @JsonProperty("INFO_LENGTH")
    private String infoLength;
    /**
     * 应答内容
     */
    @JsonProperty("INFO_CONTENT")
    private String infoContent;
}
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/DOWNPlatformMsgRetranReq.java
New file
@@ -0,0 +1,44 @@
package com.ruoyi.dataInterchange.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
/**
 * 下发平台间信息补传请求
 * @author zhibing.pu
 * @Date 2025/3/3 14:38
 */
@Data
public class DOWNPlatformMsgRetranReq {
    /**
     * 子业务类型标识
     */
    @JsonProperty("DATA_TYPE")
    private String dataType;
    /**
     * 后续数据长度
     */
    @JsonProperty("DATA_LENGTH")
    private String dataLength;
    /**
     * 对应需要重传消息的子业务类型标识
     */
    @JsonProperty("RETRAN_DATA_TYPE")
    private String retranDataType;
    /**
     * 重传消息总数
     */
    @JsonProperty("SERIAL_TOTAL")
    private String serialTotal;
    /**
     * 需要重传消息的起始报文序列号和结束的报文序列号
     */
    @JsonProperty("SERIAL_LIST")
    private Integer serialList;
    /**
     * 重传起始系统UTC时间
     */
    @JsonProperty("TIME")
    private String time;
}
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/DOWNWarnMsgExgInform.java
New file
@@ -0,0 +1,73 @@
package com.ruoyi.dataInterchange.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
/**
 * 实时交换报警信息
 * @author zhibing.pu
 * @Date 2025/3/3 15:35
 */
@Data
public class DOWNWarnMsgExgInform {
    /**
     * 子业务类型标识
     */
    @JsonProperty("DATA_TYPE")
    private String dataType;
    /**
     * 后续数据长度
     */
    @JsonProperty("DATA_LENGTH")
    private String dataLength;
    /**
     * 发起报警平台唯一编码
     */
    @JsonProperty("PLATFORM_ID")
    private String platformId;
    /**
     * 报警类型
     */
    @JsonProperty("WARN_TYPE")
    private String warnType;
    /**
     * 报警时间
     */
    @JsonProperty("WARN_TIME")
    private String warnTime;
    /**
     * 事件开始时间
     */
    @JsonProperty("START_TIME")
    private String startTime;
    /**
     * 事件结束时间
     */
    @JsonProperty("END_TIME")
    private String endTime;
    /**
     * 车牌号码
     */
    @JsonProperty("VEHICLE_NO")
    private String vehicleNo;
    /**
     * 车牌颜色
     */
    @JsonProperty("VEHICLE_COLOR")
    private String vehicleColor;
    /**
     * 线路ID
     */
    @JsonProperty("DRV_LINE_ID")
    private String drvLineId;
    /**
     * 上报报警信息内容长度
     */
    @JsonProperty("WARN_LENGTH")
    private String warnLength;
    /**
     * 报警信息
     */
    @JsonProperty("WARN_CONTENT")
    private String warnContent;
}
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/DOWNWarnMsgInformTips.java
New file
@@ -0,0 +1,78 @@
package com.ruoyi.dataInterchange.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
/**
 * 下发报警预警消息
 * @author zhibing.pu
 * @Date 2025/3/3 15:26
 */
@Data
public class DOWNWarnMsgInformTips {
    /**
     * 子业务类型标识
     */
    @JsonProperty("DATA_TYPE")
    private String dataType;
    /**
     * 后续数据长度
     */
    @JsonProperty("DATA_LENGTH")
    private String dataLength;
    /**
     * 发起报警平台唯一编码,由平台所在地行政区划代码和平台编号组成
     */
    @JsonProperty("PLATFORM_ID")
    private String platformId;
    /**
     * 报警类型
     */
    @JsonProperty("WARN_TYPE")
    private String warnType;
    /**
     * 报警时间
     */
    @JsonProperty("WARN_TIME")
    private String warnTime;
    /**
     * 事件开始时间
     */
    @JsonProperty("START_TIME")
    private String startTime;
    /**
     * 事件结束时间
     */
    @JsonProperty("END_TIME")
    private String endTime;
    /**
     * 车牌号码
     */
    @JsonProperty("VEHICLE_NO")
    private String vehicleNo;
    /**
     * 车牌颜色
     */
    @JsonProperty("VEHICLE_COLOR")
    private String vehicleColor;
    /**
     * 被报警平台唯一编码,由平台所在地行政区划代码和平台编号组成。非平台相关报警全0
     */
    @JsonProperty("PLATFORM_ID1")
    private String platformId1;
    /**
     * 线路ID
     */
    @JsonProperty("DRV_LINE_ID")
    private String drvLineId;
    /**
     * 报警信息内容长度
     */
    @JsonProperty("WARN_LENGTH")
    private String warnLength;
    /**
     * 报警描述
     */
    @JsonProperty("WARN_CONTENT")
    private String warnContent;
}
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/DOWNWarnMsgUrgeTodoReq.java
New file
@@ -0,0 +1,131 @@
package com.ruoyi.dataInterchange.model;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufUtil;
import io.netty.buffer.Unpooled;
import lombok.Data;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
/**
 * 报警督办请求
 *
 * @author zhibing.pu
 * @Date 2025/3/3 15:14
 */
@Data
public class DOWNWarnMsgUrgeTodoReq {
    /**
     * 车牌号
     */
    private String vehicleNo;
    /**
     * 车牌颜色
     */
    private int vehicleColor;
    /**
     * 子业务类型标识
     */
    private int dataType;
    /**
     * 后续数据长度
     */
    private int dataLength;
    /**
     * 报警信息来源
     * 0x01: 车载终端
     * 0x02: 企业监控平台
     * 0x03: 政府监管平台
     * 0x09: 其他
     */
    private int warnSrc;
    /**
     * 报警类型
     */
    private int warnType;
    /**
     * 报警时间
     */
    private long warnTime;
    /**
     * 报警督办ID
     */
    private int supervisionId;
    /**
     * 督办截止时间
     */
    private long supervisionEndTime;
    /**
     * 督办级别
     * 0x00: 紧急
     * 0x01: 一般
     */
    private int supervisionLevel;
    /**
     * 督办人
     */
    private String supervisor;
    /**
     * 督办联系电话
     */
    private String supervisorTel;
    /**
     * 督办联系电子邮件
     */
    private String supervisorEmail;
    public DOWNWarnMsgUrgeTodoReq build(UPWarnMsgAdptInfo upWarnMsgAdptInfo) {
        this.vehicleNo = upWarnMsgAdptInfo.getVehicleNo();
        this.vehicleColor = upWarnMsgAdptInfo.getVehicleColor();
        this.dataType = upWarnMsgAdptInfo.getDataType();
        this.dataLength = upWarnMsgAdptInfo.getDataLength();
        this.warnSrc = upWarnMsgAdptInfo.getWarnSrc();
        this.warnType = upWarnMsgAdptInfo.getWarnType();
        this.warnTime = upWarnMsgAdptInfo.getWarnTime();
        this.supervisionId = upWarnMsgAdptInfo.getInfoId();
        this.supervisionEndTime = LocalDateTime.now().plusDays(7).toEpochSecond(ZoneOffset.UTC);
        this.supervisionLevel = 0x01;
        this.supervisor = "admin";
        this.supervisorTel = "";
        this.supervisorEmail = "";
        return this;
    }
    /**
     * 编码报文
     */
    public byte[] encode() {
        ByteBuf byteBuf = Unpooled.buffer(120);
        byte[] bytes1 = this.getVehicleNo().getBytes();
        for (byte b : bytes1) {
            byteBuf.writeByte(b);
        }
        byteBuf.writeByte(this.getVehicleColor());
        byteBuf.writeShort(this.getDataType());
        byteBuf.writeInt(this.getDataLength());
        byteBuf.writeByte(this.getWarnSrc());
        byteBuf.writeShort(this.getWarnType());
        byteBuf.writeLong(this.getWarnTime());
        byteBuf.writeInt(this.getSupervisionId());
        byteBuf.writeLong(this.getSupervisionEndTime());
        byteBuf.writeByte(this.getSupervisionLevel());
        byte[] bytes2 = this.getSupervisor().getBytes();
        for (byte b : bytes2) {
            byteBuf.writeByte(b);
        }
        byte[] bytes3 = this.getSupervisorTel().getBytes();
        for (byte b : bytes3) {
            byteBuf.writeByte(b);
        }
        byte[] bytes4 = this.getSupervisorEmail().getBytes();
        for (byte b : bytes4) {
            byteBuf.writeByte(b);
        }
        byte[] bytes = ByteBufUtil.getBytes(byteBuf);
        byteBuf.release();
        return bytes;
    }
}
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/GnssData.java
@@ -1,10 +1,13 @@
package com.ruoyi.dataInterchange.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.netty.buffer.ByteBuf;
import lombok.Data;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;
/**
 * 车辆定位信息
 *
 * @author zhibing.pu
 * @Date 2025/2/24 11:56
 */
@@ -16,46 +19,85 @@
     * 1:已加密
     * 0:未加密
     */
    @JsonProperty("ENCRYPT")
    private Integer encrypt;
    @Field(type = FieldType.Integer)
    private int encrypt;
    /**
     * 车辆定位信息数据长度
     * 日月年
     */
    @JsonProperty("DATA_LENGTH")
    private Integer dataLength;
    @Field(type = FieldType.Integer)
    private int date;
    /**
     * 车辆定位信息内容
     * 时分秒
     */
    @JsonProperty("GNSS_DATA")
    private Object gnssData;
    @Field(type = FieldType.Integer)
    private int time;
    /**
     * 监控平台唯一编码,由平台所在地行政区划代码和平台编号组成
     * 经度
     */
    @JsonProperty("PLATFORM_ID1")
    private String platformId1;
    @Field(type = FieldType.Integer)
    private int lon;
    /**
     * 报警状态,二进制表示,0表示正常,1表示报警
     * 纬度
     */
    @JsonProperty("ALARM1")
    private Integer alarm1;
    @Field(type = FieldType.Integer)
    private int lat;
    /**
     * 市级监管平台唯一编码,由平台所在地行政区划代码和平台编号组成;未填写时,全填0;无市级平台应由省级平台全填1
     * 速度
     */
    @JsonProperty("PLATFORM_ID2")
    private String platformId2;
    @Field(type = FieldType.Integer)
    private int vec1;
    /**
     * 报警状态,二进制表示,0表示正常,1表示报警
     * 行驶记录速度
     */
    @JsonProperty("ALARM2")
    private Integer alarm2;
    @Field(type = FieldType.Integer)
    private int vec2;
    /**
     * 省级监管平台唯一编码,由平台所在地行政区划代码和平台编号组成;未填写时,全填0
     * 车辆当前总里程数
     */
    @JsonProperty("PLATFORM_ID3")
    private String platformId3;
    @Field(type = FieldType.Integer)
    private int vec3;
    /**
     * 报警状态,二进制表示,0表示正常,1表示报警
     * 方向
     */
    @JsonProperty("ALARM3")
    private Integer alarm3;
    @Field(type = FieldType.Integer)
    private int direction;
    /**
     * 海拔高度
     */
    @Field(type = FieldType.Integer)
    private int altitude;
    /**
     * 车辆状态
     */
    @Field(type = FieldType.Integer)
    private int state;
    /**
     * 报警状态
     */
    @Field(type = FieldType.Integer)
    private int alarm;
    /**
     * 解析报文
     */
    public GnssData decode(ByteBuf byteBuf) {
        this.encrypt = byteBuf.readByte();
        this.date = byteBuf.readInt();
        ByteBuf byteBuf1 = byteBuf.readBytes(3);
        StringBuilder t = new StringBuilder();
        for (int i = 0; i < 3; i++) {
            t.append(byteBuf1.getByte(i));
        }
        this.time = Integer.valueOf(t.toString());
        this.lon = byteBuf.readInt();
        this.lat = byteBuf.readInt();
        this.vec1 = byteBuf.readShort();
        this.vec2 = byteBuf.readShort();
        this.vec3 = byteBuf.readInt();
        this.direction = byteBuf.readShort();
        this.altitude = byteBuf.readShort();
        this.state = byteBuf.readInt();
        this.alarm = byteBuf.readInt();
        return this;
    }
}
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/Message.java
New file
@@ -0,0 +1,33 @@
package com.ruoyi.dataInterchange.model;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
 * @author zhibing.pu
 * @Date 2025/3/5 20:41
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Message {
    private int headFlag;
    private MessageHead msgHead;
    private byte[] msgBody;
    private byte[] crcCode;
    private int endFlag;
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    public static final class MessageHead {
        private int msgLength;
        private int msgSn;
        private short msgId;
        private int msgGnssCenterId;
        private byte[] versionFlag;
        private int encryptFlag;
        private int encryptKey;
    }
}
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/UPBaseMsgDrvLineAddedReq.java
New file
@@ -0,0 +1,38 @@
package com.ruoyi.dataInterchange.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
/**
 * 补报车辆行驶路线信息应答
 * @author zhibing.pu
 * @Date 2025/3/3 17:17
 */
@Data
public class UPBaseMsgDrvLineAddedReq {
    /**
     * 车牌号码
     */
    @JsonProperty("VEHICLE_NO")
    private String vehicleNo;
    /**
     * 车牌颜色
     */
    @JsonProperty("VEHICLE_COLOR")
    private String vehicleColor;
    /**
     * 子业务类型标识
     */
    @JsonProperty("DATA_TYPE")
    private String dataType;
    /**
     * 后续数据长度
     */
    @JsonProperty("DATA_LENGTH")
    private String dataLength;
    /**
     * 线路信息
     */
    @JsonProperty("DRV_LINE")
    private String drvLine;
}
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/UPBaseMsgVehicleAddedAck.java
New file
@@ -0,0 +1,48 @@
package com.ruoyi.dataInterchange.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
/**
 * 补报车辆静态信息应答消息
 * @author zhibing.pu
 * @Date 2025/3/3 17:19
 */
@Data
public class UPBaseMsgVehicleAddedAck {
    /**
     * 车牌号码
     */
    @JsonProperty("VEHICLE_NO")
    private String vehicleNo;
    /**
     * 车牌颜色
     */
    @JsonProperty("VEHICLE_COLOR")
    private String vehicleColor;
    /**
     * 子业务类型标识
     */
    @JsonProperty("DATA_TYPE")
    private String dataType;
    /**
     * 后续数据长度
     */
    @JsonProperty("DATA_LENGTH")
    private String dataLength;
    /**
     * 对应补报车辆静态信息请求消息源子业务类型标识
     */
    @JsonProperty("SOURCE_DATE_TYPE")
    private String sourceDateType;
    /**
     * 对应补报车辆静态信息请求消息源报文序列号
     */
    @JsonProperty("SOURCE_MSG_SN")
    private String sourceMsgSn;
    /**
     * 车辆信息
     */
    @JsonProperty("CAR_INFO")
    private String carInfo;
}
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/UPCloseLinkInform.java
@@ -1,6 +1,6 @@
package com.ruoyi.dataInterchange.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.netty.buffer.ByteBuf;
import lombok.Data;
/**
@@ -15,6 +15,14 @@
     * 0x00:从链路断开
     * 0x01:其他
     */
    @JsonProperty("REASON_CODE")
    private String reasonCode;
    private int reasonCode;
    /**
     * 解析报文
     */
    public UPCloseLinkInform decode(ByteBuf byteBuf) {
        this.reasonCode = byteBuf.readByte();
        return this;
    }
}
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/UPConnectReq.java
@@ -1,10 +1,12 @@
package com.ruoyi.dataInterchange.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.ruoyi.dataInterchange.util.jtt809.common.Jtt809Util;
import io.netty.buffer.ByteBuf;
import lombok.Data;
/**
 * 住链路登录请求
 * 主链路登录请求
 *
 * @author zhibing.pu
 * @Date 2025/2/24 10:43
 */
@@ -13,26 +15,31 @@
    /**
     * 用户名
     */
    @JsonProperty("USERID")
    private String userId;
    private int userId;
    /**
     * 密码
     */
    @JsonProperty("PASSWORD")
    private String password;
    /**
     * 下级平台接入码,上级平台给下级平台分配的唯一标识号
     */
    @JsonProperty("MSG_GNSSCENTERID")
    private String msgGnsscenterid;
    /**
     * 下级平台提供对应的从链路服务端IP地址
     */
    @JsonProperty("DOWN_LINK_IP")
    private String downLinkIp;
    /**
     * 下级平台提供对应的从链路服务端端口号
     */
    @JsonProperty("DOWN_LINK_PORT")
    private String downLinkPort;
    private int downLinkPort;
    /**
     * 解析登录报文
     */
    public UPConnectReq decode(ByteBuf byteBuf) {
        this.userId = byteBuf.readInt();
        this.password = Jtt809Util.readGBKString(byteBuf, 8);
        this.downLinkIp = Jtt809Util.readGBKString(byteBuf, 32);
        this.downLinkPort = byteBuf.readShort();
        return this;
    }
}
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/UPConnectRsp.java
@@ -1,10 +1,13 @@
package com.ruoyi.dataInterchange.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufUtil;
import io.netty.buffer.Unpooled;
import lombok.Data;
/**
 * 住链路登录应答消息
 * 主链路登录应答
 *
 * @author zhibing.pu
 * @Date 2025/2/24 10:47
 */
@@ -20,11 +23,21 @@
     * 0x05:资源紧张,超厚再连接(已经占用)
     * 0xFF::其他
     */
    @JsonProperty("RESULT")
    private String result;
    private int result;
    /**
     * 校验码
     */
    @JsonProperty("VERIFY_CODE")
    private String verifyCode;
    private int verifyCode;
    /**
     * 编码登录回复报文
     */
    public byte[] encode() {
        ByteBuf byteBuf = Unpooled.buffer(5);
        byteBuf.writeByte(this.getResult());
        byteBuf.writeInt(this.getVerifyCode());
        byte[] bytes = ByteBufUtil.getBytes(byteBuf);
        byteBuf.release();
        return bytes;
    }
}
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/UPCtrlMsgEmergencyMonitoringAck.java
New file
@@ -0,0 +1,50 @@
package com.ruoyi.dataInterchange.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
/**
 * 车辆应急接入监管平台应答消息
 * @author zhibing.pu
 * @Date 2025/3/3 16:37
 */
@Data
public class UPCtrlMsgEmergencyMonitoringAck {
    /**
     * 车牌号码
     */
    @JsonProperty("VEHICLE_NO")
    private String vehicleNo;
    /**
     * 车牌颜色
     */
    @JsonProperty("VEHICLE_COLOR")
    private String vehicleColor;
    /**
     * 子业务类型标识
     */
    @JsonProperty("DATA_TYPE")
    private String dataType;
    /**
     * 后续数据长度
     */
    @JsonProperty("DATA_LENGTH")
    private String dataLength;
    /**
     * 对应车辆应急接入监管瓶体请求消息源子业务类型标识
     */
    @JsonProperty("SOURCE_DATA_TYPE")
    private String sourceDataType;
    /**
     * 对应车辆应急接入监管瓶体请求消息源报文序列号
     */
    @JsonProperty("SOURCE_MSG_SN")
    private String sourceMsgSn;
    /**
     * 0x00: 车载终端成功收到该命令
     * 0x01: 无该车辆
     * 0x02: 其他
     */
    @JsonProperty("RESULT")
    private String result;
}
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/UPCtrlMsgMonitorVehicleAck.java
New file
@@ -0,0 +1,50 @@
package com.ruoyi.dataInterchange.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
/**
 * 车辆单向监听应答消息
 * @author zhibing.pu
 * @Date 2025/3/3 16:05
 */
@Data
public class UPCtrlMsgMonitorVehicleAck {
    /**
     * 车牌号码
     */
    @JsonProperty("VEHICLE_NO")
    private String vehicleNo;
    /**
     * 车牌颜色
     */
    @JsonProperty("VEHICLE_COLOR")
    private String vehicleColor;
    /**
     * 子业务类型标识
     */
    @JsonProperty("DATA_TYPE")
    private String dataType;
    /**
     * 后续数据长度
     */
    @JsonProperty("DATA_LENGTH")
    private String dataLength;
    /**
     * 对应车辆单向监听请求消息源子业务类型标识
     */
    @JsonProperty("SOURCE_DATA_TYPE")
    private String sourceDataType;
    /**
     * 对应车辆单向监听请求消息源报文序列号
     */
    @JsonProperty("SOURCE_MSG_SN")
    private String sourceMsgSn;
    /**
     * 车辆单向监听应答结果
     * 0x00: 监听成功
     * 0x01: 监听失败
     */
    @JsonProperty("RESULT")
    private String result;
}
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/UPCtrlMsgTakePhotoAck.java
New file
@@ -0,0 +1,98 @@
package com.ruoyi.dataInterchange.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
/**
 * 车辆牌照应答消息
 * @author zhibing.pu
 * @Date 2025/3/3 16:13
 */
@Data
public class UPCtrlMsgTakePhotoAck {
    /**
     * 车牌号码
     */
    @JsonProperty("VEHICLE_NO")
    private String vehicleNo;
    /**
     * 车牌颜色
     */
    @JsonProperty("VEHICLE_COLOR")
    private String vehicleColor;
    /**
     * 子业务类型标识
     */
    @JsonProperty("DATA_TYPE")
    private String dataType;
    /**
     * 后续数据长度
     */
    @JsonProperty("DATA_LENGTH")
    private String dataLength;
    /**
     * 对应车辆牌照请求消息源子业务类型标识
     */
    @JsonProperty("SOURCE_DATA_TYPE")
    private String sourceDataType;
    /**
     * 对应车辆牌照请求消息源报文序列号
     */
    @JsonProperty("SOURCE_MSG_SN")
    private String sourceMsgSn;
    /**
     * 牌照应答标识
     * 0x00: 不支持牌照
     * 0x01: 完成拍照
     * 0x02: 完成拍照、照片数据稍后传送
     * 0x03: 未拍照(不在线)
     * 0x04: 未拍照(无法使用指定镜头)
     * 0x05: 未拍照(其他)
     * 0x09: 车牌号码错误
     */
    @JsonProperty("PHOTO_RSP_FLAG")
    private String photoRspFlag;
    /**
     * 牌照位置地点
     */
    @JsonProperty("GNSS_DATA")
    private String gnssData;
    /**
     * 镜头ID
     */
    @JsonProperty("LENS_ID")
    private String lensId;
    /**
     * 图片长度
     */
    @JsonProperty("PHOTO_LEN")
    private String photoLen;
    /**
     * 图片大小
     * 0x01: 320 x 240
     * 0x02: 640 x 48
     * 0x03: 800 x 600
     * 0x04: 1024 x 768
     * 0x05: 176 x 144
     * 0x06: 352 x 288
     * 0x07: 704 x 288
     * 0x08: 704 x 576
     */
    @JsonProperty("SIZE_TYPE")
    private String sizeType;
    /**
     * 图像格式
     * 0x01: jpg
     * 0x02: gif
     * 0x03: tiff
     * 0x04: png
     */
    @JsonProperty("TYPE")
    private String type;
    /**
     * 图片内容
     */
    @JsonProperty("PHOTO")
    private String photo;
}
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/UPCtrlMsgTakeTravelAck.java
New file
@@ -0,0 +1,58 @@
package com.ruoyi.dataInterchange.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
/**
 * 上报车辆行驶记录应答消息
 * @author zhibing.pu
 * @Date 2025/3/3 16:32
 */
@Data
public class UPCtrlMsgTakeTravelAck {
    /**
     * 车牌号码
     */
    @JsonProperty("VEHICLE_NO")
    private String vehicleNo;
    /**
     * 车牌颜色
     */
    @JsonProperty("VEHICLE_COLOR")
    private String vehicleColor;
    /**
     * 子业务类型标识
     */
    @JsonProperty("DATA_TYPE")
    private String dataType;
    /**
     * 后续数据长度
     */
    @JsonProperty("DATA_LENGTH")
    private String dataLength;
    /**
     * 对应上报车辆行驶记录请求消息源子业务类型标识
     */
    @JsonProperty("SOURCE_DATA_TYPE")
    private String sourceDataType;
    /**
     * 对对应上报车辆行驶记录请求消息源报文序列号
     */
    @JsonProperty("SOURCE_MSG_SN")
    private String sourceMsgSn;
    /**
     * 命令字
     */
    @JsonProperty("COMMAND_TYPE")
    private String commandType;
    /**
     * 车辆行驶记录数据体长度
     */
    @JsonProperty("TRAVELDATA_LENGTH")
    private String travelDataLength;
    /**
     * 车辆行驶记录信息
     */
    @JsonProperty("TRAVELDATA_INFO")
    private String travelDataInfo;
}
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/UPCtrlMsgTextInfoAck.java
New file
@@ -0,0 +1,51 @@
package com.ruoyi.dataInterchange.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
/**
 * 下发车辆报文应答消息
 * @author zhibing.pu
 * @Date 2025/3/3 16:29
 */
@Data
public class UPCtrlMsgTextInfoAck {
    /**
     * 车牌号码
     */
    @JsonProperty("VEHICLE_NO")
    private String vehicleNo;
    /**
     * 车牌颜色
     */
    @JsonProperty("VEHICLE_COLOR")
    private String vehicleColor;
    /**
     * 子业务类型标识
     */
    @JsonProperty("DATA_TYPE")
    private String dataType;
    /**
     * 后续数据长度
     */
    @JsonProperty("DATA_LENGTH")
    private String dataLength;
    /**
     * 对应下发车辆报文请求消息源子业务类型标识
     */
    @JsonProperty("SOURCE_DATA_TYPE")
    private String sourceDataType;
    /**
     * 对应下发车辆报文请求消息源报文序列号
     */
    @JsonProperty("SOURCE_MSG_SN")
    private String sourceMsgSn;
    /**
     * 下发车辆报文应答结果
     * 0x00: 下发成功
     * 0x01: 下发失败
     */
    @JsonProperty("RESULT")
    private String result;
}
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/UPDisconnectInform.java
@@ -1,10 +1,12 @@
package com.ruoyi.dataInterchange.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.ruoyi.dataInterchange.util.jtt809.common.Jtt809Util;
import io.netty.buffer.ByteBuf;
import lombok.Data;
/**
 * 住链路断开通知
 * 主链路断开通知
 * @author zhibing.pu
 * @Date 2025/2/24 10:59
 */
@@ -15,6 +17,13 @@
     * 0x00:主链路断开
     * 0x01:其他
     */
    @JsonProperty("ERROR_CODE")
    private String errorCode;
    private int errorCode;
    /**
     * 解析报文
     */
    public UPDisconnectInform decode(ByteBuf byteBuf) {
        this.errorCode = byteBuf.readByte();
        return this;
    }
}
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/UPDisconnectReq.java
@@ -1,10 +1,12 @@
package com.ruoyi.dataInterchange.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.ruoyi.dataInterchange.util.jtt809.common.Jtt809Util;
import io.netty.buffer.ByteBuf;
import lombok.Data;
/**
 * 住链路注销请求
 * 主链路注销请求
 *
 * @author zhibing.pu
 * @Date 2025/2/24 10:53
 */
@@ -13,11 +15,19 @@
    /**
     * 用户名
     */
    @JsonProperty("USERID")
    private String userId;
    private int userId;
    /**
     * 密码
     */
    @JsonProperty("PASSWORD")
    private String password;
    /**
     * 解析报文
     */
    public UPDisconnectReq decode(ByteBuf byteBuf) {
        this.userId = byteBuf.readInt();
        this.password = Jtt809Util.readGBKString(byteBuf, 12);
        return this;
    }
}
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/UPExgMsg.java
@@ -13,26 +13,21 @@
    /**
     * 车牌号
     */
    @JsonProperty("VEHICLE_NO")
    private String vehicleNo;
    /**
     * 车牌颜色
     */
    @JsonProperty("VEHICLE_COLOR")
    private String vehicleColor;
    private int vehicleColor;
    /**
     * 子业务类型标识
     */
    @JsonProperty("DATA_TYPE")
    private String dataType;
    private int dataType;
    /**
     * 后续数据长度
     */
    @JsonProperty("DATA_LENGTH")
    private Integer dataLength;
    private int dataLength;
    /**
     * 数据部分
     */
    @JsonProperty("DATA")
    private Object data;
    private byte[] data;
}
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/UPExgMsgHistoryLocation.java
@@ -1,40 +1,73 @@
package com.ruoyi.dataInterchange.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.ruoyi.dataInterchange.pojo.BaseModel;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import lombok.Data;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;
import java.util.ArrayList;
import java.util.List;
/**
 * 车辆定位信息自动补报请求
 *
 * @author zhibing.pu
 * @Date 2025/2/24 13:40
 */
@Data
public class UPExgMsgHistoryLocation {
@Document(indexName = "up_exg_msg_history_location")
public class UPExgMsgHistoryLocation extends BaseModel {
    /**
     * 车牌号
     */
    @JsonProperty("VEHICLE_NO")
    @Field(type = FieldType.Text)
    private String vehicleNo;
    /**
     * 车牌颜色
     */
    @JsonProperty("VEHICLE_COLOR")
    private String vehicleColor;
    @Field(type = FieldType.Integer)
    private int vehicleColor;
    /**
     * 子业务类型标识
     */
    @JsonProperty("DATA_TYPE")
    private String dataType;
    @Field(type = FieldType.Integer)
    private int dataType;
    /**
     * 后续数据长度
     */
    @JsonProperty("DATA_LENGTH")
    private Integer dataLength;
    @Field(type = FieldType.Integer)
    private int dataLength;
    /**
     * 改数据包里包含的卫星定位数据个数
     */
    @Field(type = FieldType.Integer)
    private int gnssCnt;
    /**
     * GNSS定位数据
     */
    @JsonProperty("GNSS_CNT")
    private List<GnssData> gnssCnt;
    @Field(type = FieldType.Object)
    private List<GnssData> gnssData;
    /**
     * 解析报文
     */
    public UPExgMsgHistoryLocation decode(UPExgMsg exgMsg) {
        byte[] data = exgMsg.getData();
        ByteBuf byteBuf = Unpooled.wrappedBuffer(data);
        this.vehicleNo = exgMsg.getVehicleNo();
        this.vehicleColor = exgMsg.getVehicleColor();
        this.dataType = exgMsg.getDataType();
        this.dataLength = exgMsg.getDataLength();
        this.gnssCnt = byteBuf.readByte();
        List<GnssData> gnssData = new ArrayList<>();
        for (int i = 0; i < this.gnssCnt; i++) {
            gnssData.add(new GnssData().decode(byteBuf));
        }
        this.gnssData = gnssData;
        return this;
    }
}
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/UPExgMsgRealLocation.java
@@ -1,38 +1,60 @@
package com.ruoyi.dataInterchange.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.ruoyi.dataInterchange.pojo.BaseModel;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import lombok.Data;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;
/**
 * 上传车辆实时定位信息
 *
 * @author zhibing.pu
 * @Date 2025/2/24 11:53
 */
@Data
public class UPExgMsgRealLocation {
@Document(indexName = "up_exg_msg_real_location")
public class UPExgMsgRealLocation extends BaseModel {
    /**
     * 车牌号
     */
    @JsonProperty("VEHICLE_NO")
    @Field(type = FieldType.Text)
    private String vehicleNo;
    /**
     * 车牌颜色
     */
    @JsonProperty("VEHICLE_COLOR")
    private String vehicleColor;
    @Field(type = FieldType.Integer)
    private int vehicleColor;
    /**
     * 子业务类型标识
     */
    @JsonProperty("DATA_TYPE")
    private String dataType;
    @Field(type = FieldType.Integer)
    private int dataType;
    /**
     * 后续数据长度
     */
    @JsonProperty("DATA_LENGTH")
    private Integer dataLength;
    @Field(type = FieldType.Integer)
    private int dataLength;
    /**
     * 车辆定位信息
     * 定位数据
     */
    @JsonProperty("GNSS_DATA")
    @Field(type = FieldType.Object)
    private GnssData gnssData;
    /**
     * 解析报文
     */
    public UPExgMsgRealLocation decode(UPExgMsg exgMsg) {
        byte[] data = exgMsg.getData();
        ByteBuf byteBuf = Unpooled.wrappedBuffer(data);
        this.vehicleNo = exgMsg.getVehicleNo();
        this.vehicleColor = exgMsg.getVehicleColor();
        this.dataType = exgMsg.getDataType();
        this.dataLength = exgMsg.getDataLength();
        this.gnssData = new GnssData().decode(byteBuf);
        return this;
    }
}
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/UPExgMsgRegister.java
@@ -1,63 +1,91 @@
package com.ruoyi.dataInterchange.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.ruoyi.dataInterchange.pojo.BaseModel;
import com.ruoyi.dataInterchange.util.jtt809.common.Jtt809Util;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import lombok.Data;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;
/**
 * 上传车辆注册信息
 *
 * @author zhibing.pu
 * @Date 2025/2/24 11:47
 */
@Data
public class UPExgMsgRegister {
@Document(indexName = "up_exg_msg_register")
public class UPExgMsgRegister extends BaseModel {
    /**
     * 车牌号
     */
    @JsonProperty("VEHICLE_NO")
    @Field(type = FieldType.Text)
    private String vehicleNo;
    /**
     * 车牌颜色
     */
    @JsonProperty("VEHICLE_COLOR")
    private String vehicleColor;
    @Field(type = FieldType.Integer)
    private int vehicleColor;
    /**
     * 子业务类型标识
     */
    @JsonProperty("DATA_TYPE")
    private String dataType;
    @Field(type = FieldType.Integer)
    private int dataType;
    /**
     * 后续数据长度
     */
    @JsonProperty("DATA_LENGTH")
    @Field(type = FieldType.Integer)
    private Integer dataLength;
    /**
     * 平台唯一编号,由平台所在地行政区划代码和平台编号组成
     */
    @JsonProperty("PLATFORM_ID")
    @Field(type = FieldType.Text)
    private String platformId;
    /**
     * 车载终端厂商唯一编码,由车载终端厂商所在地行政区划代码和厂商ID组成
     */
    @JsonProperty("PRODUCER_ID")
    @Field(type = FieldType.Text)
    private String producerId;
    /**
     * 车载终端型号
     */
    @JsonProperty("TERMINAL_MODEL_TYPE")
    @Field(type = FieldType.Text)
    private String terminalModelType;
    /**
     * 车载终端通讯模块IMEI码
     */
    @JsonProperty("IMEI_ID")
    private String imeiId;
    /**
     * 车载终端编号
     */
    @JsonProperty("TERMINAL_ID")
    @Field(type = FieldType.Text)
    private String terminalId;
    /**
     * 车载终端SIM卡电话号码
     */
    @JsonProperty("TERMINAL_SIMCODE")
    private String terminalSimcode;
    @Field(type = FieldType.Text)
    private String terminalSIMCode;
    /**
     * 解析报文
     */
    public UPExgMsgRegister decode(UPExgMsg exgMsg) {
        byte[] data = exgMsg.getData();
        ByteBuf byteBuf = Unpooled.wrappedBuffer(data);
        this.vehicleNo = exgMsg.getVehicleNo();
        this.vehicleColor = exgMsg.getVehicleColor();
        this.dataType = exgMsg.getDataType();
        this.dataLength = exgMsg.getDataLength();
        //平台唯一编码
        this.platformId = Jtt809Util.readGBKString(byteBuf, 11);
        //车载终端厂商唯一编码
        this.producerId = Jtt809Util.readGBKString(byteBuf, 11);
        //车载终端型号
        this.terminalModelType = Jtt809Util.readGBKString(byteBuf, 8);
        //车载终端编号
        this.terminalId = Jtt809Util.readGBKString(byteBuf, 7);
        //车载终端SIM卡电话号码
        this.terminalSIMCode = Jtt809Util.readGBKString(byteBuf, 12);
        return this;
    }
}
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/UPExgMsgReportDriverInfoAck.java
@@ -1,68 +1,79 @@
package com.ruoyi.dataInterchange.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.ruoyi.dataInterchange.pojo.BaseModel;
import com.ruoyi.dataInterchange.util.jtt809.common.Jtt809Util;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import lombok.Data;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;
/**
 * 上报驾驶员身份信息应答
 *
 * @author zhibing.pu
 * @Date 2025/2/24 15:14
 */
@Data
public class UPExgMsgReportDriverInfoAck {
@Document(indexName = "up_exg_msg_report_driver_info_ack")
public class UPExgMsgReportDriverInfoAck extends BaseModel {
    /**
     * 车牌号
     */
    @JsonProperty("VEHICLE_NO")
    @Field(type = FieldType.Text)
    private String vehicleNo;
    /**
     * 车牌颜色
     */
    @JsonProperty("VEHICLE_COLOR")
    private String vehicleColor;
    @Field(type = FieldType.Integer)
    private int vehicleColor;
    /**
     * 子业务类型标识
     */
    @JsonProperty("DATA_TYPE")
    private String dataType;
    @Field(type = FieldType.Integer)
    private int dataType;
    /**
     * 后续数据长度
     */
    @JsonProperty("DATA_LENGTH")
    private Integer dataLength;
    /**
     * 对应上报驾驶员身份请求消息源子业务类型标识
     */
    @JsonProperty("SOURCE_DATA_TYPE")
    private Integer sourceDataType;
    /**
     * 对应上报驾驶员身份请求消息源报文序列号
     */
    @JsonProperty("SOURCE_MSG_SN")
    private Integer sourceMsgSn;
    @Field(type = FieldType.Integer)
    private int dataLength;
    /**
     * 驾驶员姓名
     */
    @JsonProperty("DRIVER_NAME")
    @Field(type = FieldType.Text)
    private String driverName;
    /**
     * 驾驶证编号
     */
    @JsonProperty("DRIVER_ID")
    @Field(type = FieldType.Text)
    private String driverId;
    /**
     * 从业资格证号
     */
    @JsonProperty("LICENCE")
    @Field(type = FieldType.Text)
    private String licence;
    /**
     * 发证机构名称
     */
    @JsonProperty("ORG_NAME")
    @Field(type = FieldType.Text)
    private String orgName;
    /**
     * 证件有效期,时分秒均用0表示
     * 解析报文
     */
    @JsonProperty("VALID_TIME")
    private String validTime;
    public UPExgMsgReportDriverInfoAck decode(UPExgMsg exgMsg) {
        byte[] data = exgMsg.getData();
        ByteBuf byteBuf = Unpooled.wrappedBuffer(data);
        this.vehicleNo = exgMsg.getVehicleNo();
        this.vehicleColor = exgMsg.getVehicleColor();
        this.dataType = exgMsg.getDataType();
        this.dataLength = exgMsg.getDataLength();
        this.driverName = Jtt809Util.readGBKString(byteBuf, 16);
        this.driverId = Jtt809Util.readGBKString(byteBuf, 20);
        this.licence = Jtt809Util.readGBKString(byteBuf, 40);
        this.orgName = Jtt809Util.readGBKString(byteBuf, 200);
        return this;
    }
}
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/UPExgMsgTakeEwayBillAck.java
@@ -1,53 +1,67 @@
package com.ruoyi.dataInterchange.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.ruoyi.dataInterchange.pojo.BaseModel;
import com.ruoyi.dataInterchange.util.jtt809.common.Jtt809Util;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import lombok.Data;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;
/**
 * 上报车辆电子运单应答消息
 *
 * @author zhibing.pu
 * @Date 2025/2/24 15:20
 */
@Data
public class UPExgMsgTakeEwayBillAck {
@Document(indexName = "up_exg_msg_take_ewaybill_ack")
public class UPExgMsgTakeEwayBillAck extends BaseModel {
    /**
     * 车牌号
     */
    @JsonProperty("VEHICLE_NO")
    @Field(type = FieldType.Text)
    private String vehicleNo;
    /**
     * 车牌颜色
     */
    @JsonProperty("VEHICLE_COLOR")
    private String vehicleColor;
    @Field(type = FieldType.Integer)
    private int vehicleColor;
    /**
     * 子业务类型标识
     */
    @JsonProperty("DATA_TYPE")
    private String dataType;
    @Field(type = FieldType.Integer)
    private int dataType;
    /**
     * 后续数据长度
     */
    @JsonProperty("DATA_LENGTH")
    private Integer dataLength;
    /**
     * 对应上报车辆电子运单请求消息源子业务类型标识
     */
    @JsonProperty("SOURCE_DATA_TYPE")
    private Integer sourceDataType;
    /**
     * 对应上报车辆电子运单请求消息源报文序列号
     */
    @JsonProperty("SOURCE_MSG_SN")
    private Integer sourceMsgSn;
    @Field(type = FieldType.Integer)
    private int dataLength;
    /**
     * 电子运单数据体长度
     */
    @JsonProperty("EWAYBILL_LENGTH")
    private Integer ewaybillLength;
    @Field(type = FieldType.Integer)
    private int ewayBillLength;
    /**
     * 电子运单数据内容
     */
    @JsonProperty("EWAYBILL_INFO")
    private Object ewaybillInfo;
    @Field(type = FieldType.Text)
    private String ewayBillInfo;
    /**
     * 解析报文
     */
    public UPExgMsgTakeEwayBillAck decode(UPExgMsg exgMsg) {
        byte[] data = exgMsg.getData();
        ByteBuf byteBuf = Unpooled.wrappedBuffer(data);
        this.vehicleNo = exgMsg.getVehicleNo();
        this.vehicleColor = exgMsg.getVehicleColor();
        this.dataType = exgMsg.getDataType();
        this.dataLength = exgMsg.getDataLength();
        this.ewayBillLength = byteBuf.readInt();
        this.ewayBillInfo = Jtt809Util.readGBKString(byteBuf, this.ewayBillLength);
        return this;
    }
}
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/UPPlatformMsg.java
New file
@@ -0,0 +1,24 @@
package com.ruoyi.dataInterchange.model;
import lombok.Data;
/**
 * @author zhibing.pu
 * @Date 2025/3/6 20:18
 */
@Data
public class UPPlatformMsg {
    /**
     * 子业务类型标识
     */
    private int dataType;
    /**
     * 后续数据长度
     */
    private int dataLength;
    /**
     * 数据包
     */
    private byte[] data;
}
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/UPPlatformMsgInfoAck.java
New file
@@ -0,0 +1,31 @@
package com.ruoyi.dataInterchange.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data; /**
 * 下发平台间报文应答消息
 * @author zhibing.pu
 * @Date 2025/3/3 11:47
 */
@Data
public class UPPlatformMsgInfoAck {
    /**
     * 子业务类型标识
     */
    @JsonProperty("DATA_TYPE")
    private String dataType;
    /**
     * 后续数据长度
     */
    @JsonProperty("DATA_LENGTH")
    private String dataLength;
    /**
     * 对应下发平台间报文请求消息源子业务类型标识
     */
    @JsonProperty("SOURCE_DATE_TYPE")
    private String sourceDateType;
    /**
     * 对应下发平台间报文请求消息源报文序列号
     */
    @JsonProperty("SOURCE_MSG_SN")
    private String sourceMsgSn;
}
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/UPPlatformMsgPostQueryAck.java
New file
@@ -0,0 +1,63 @@
package com.ruoyi.dataInterchange.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data; /**
 * 平台查岗应答消息
 * @author zhibing.pu
 * @Date 2025/3/3 11:25
 */
@Data
public class UPPlatformMsgPostQueryAck {
    /**
     * 子业务类型标识
     */
    @JsonProperty("DATA_TYPE")
    private String dataType;
    /**
     * 后续数据长度
     */
    @JsonProperty("DATA_LENGTH")
    private String dataLength;
    /**
     * 查岗对象类型
     */
    @JsonProperty("OBJECT_TYPE")
    private String objectType;
    /**
     * 查岗应答人姓名
     */
    @JsonProperty("RESPONDER")
    private String responder;
    /**
     * 查岗应答人联系电话
     */
    @JsonProperty("RESPONDER_TEL")
    private String responderTel;
    /**
     * 查岗对象的ID,长度不足时后补0x00
     * 对象类型为平台时,由平台行政区划代码和平台唯一码组成
     * 对象类型为业户时,为业户经营许可证号
     */
    @JsonProperty("OBJECT_ID")
    private String objectId;
    /**
     * 对应平台查岗请求信息源子业务类型标识
     */
    @JsonProperty("SOURCE_DATA_TYPE")
    private String sourceDataType;
    /**
     * 对应平台查岗请求消息源报文序列号
     */
    @JsonProperty("SOURCE_MSG_SN")
    private String sourceMsgSn;
    /**
     * 数据长度
     */
    @JsonProperty("INFO_LENGTH")
    private String infoLength;
    /**
     * 应答内容
     */
    @JsonProperty("INFO_CONTENT")
    private String infoContent;
}
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/UPPlatformMsgRetranReq.java
New file
@@ -0,0 +1,43 @@
package com.ruoyi.dataInterchange.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
/**
 * 上传平台间消息补传请求
 * @author zhibing.pu
 * @Date 2025/3/3 14:10
 */
@Data
public class UPPlatformMsgRetranReq {
    /**
     * 子业务类型标识
     */
    @JsonProperty("DATA_TYPE")
    private String dataType;
    /**
     * 后续数据长度
     */
    @JsonProperty("DATA_LENGTH")
    private String dataLength;
    /**
     * 对应需要重传消息的子业务类型标识
     */
    @JsonProperty("RETRAN_DATA_TYPE")
    private String retranDataType;
    /**
     * 重传消息总数
     */
    @JsonProperty("SERIAL_TOTAL")
    private String serialTotal;
    /**
     * 需要重传消息的起始报文序列号和结束的报文序列号
     */
    @JsonProperty("SERIAL_LIST")
    private Integer serialList;
    /**
     * 重传起始系统UTC时间
     */
    @JsonProperty("TIME")
    private String time;
}
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/UPWarnMsgAdptInfo.java
New file
@@ -0,0 +1,113 @@
package com.ruoyi.dataInterchange.model;
import com.ruoyi.common.core.utils.DateUtils;
import com.ruoyi.dataInterchange.pojo.BaseModel;
import com.ruoyi.dataInterchange.util.jtt809.common.Jtt809Util;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import lombok.Data;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;
import java.text.ParseException;
/**
 * 上报报警信息
 *
 * @author zhibing.pu
 * @Date 2025/3/3 14:50
 */
@Data
@Document(indexName = "up_warn_msg_adpt_info")
public class UPWarnMsgAdptInfo extends BaseModel {
    /**
     * 车牌号
     */
    @Field(type = FieldType.Text)
    private String vehicleNo;
    /**
     * 车牌颜色
     */
    @Field(type = FieldType.Integer)
    private int vehicleColor;
    /**
     * 子业务类型标识
     */
    @Field(type = FieldType.Integer)
    private int dataType;
    /**
     * 后续数据长度
     */
    @Field(type = FieldType.Integer)
    private int dataLength;
    /**
     * 报警信息来源
     * 0x01: 车载终端
     * 0x02: 企业监控平台
     * 0x03: 政府监管平台
     * 0x09: 其他
     */
    @Field(type = FieldType.Integer)
    private int warnSrc;
    /**
     * 报警类型
     */
    @Field(type = FieldType.Integer)
    private int warnType;
    /**
     * 报警时间
     */
    @Field(type = FieldType.Integer)
    private long warnTime;
    /**
     * 信息ID
     */
    @Field(type = FieldType.Integer)
    private int infoId;
    /**
     * 报警数据长度
     */
    @Field(type = FieldType.Integer)
    private int infoLength;
    /**
     * 上报报警信息内容
     */
    @Field(type = FieldType.Text)
    private String infoContent;
    /**
     * 解析报文
     */
    public UPWarnMsgAdptInfo decode(WarnMsg warnMsg) {
        byte[] data = warnMsg.getData();
        ByteBuf byteBuf = Unpooled.wrappedBuffer(data);
        this.vehicleNo = warnMsg.getVehicleNo();
        this.vehicleColor = warnMsg.getVehicleColor();
        this.dataType = warnMsg.getDataType();
        this.dataLength = warnMsg.getDataLength();
        //报警信息来源
        this.warnSrc = byteBuf.readByte();
        //报警类型
        this.warnType = byteBuf.readShort();
        String date = byteBuf.readByte() + "-" + byteBuf.readByte() + "-" + byteBuf.readShort() + " " +
                byteBuf.readByte() + ":" + byteBuf.readByte() + ":" + byteBuf.readByte();
        long time = 0;
        try {
            time = DateUtils.parseDate(date, "dd-MM-yyyy HH:mm:ss").getTime();
        } catch (ParseException e) {
            e.printStackTrace();
        }
        //报警时间
        this.warnTime = time;
        //信息ID
        this.infoId = byteBuf.readInt();
        //报警数据长度
        this.infoLength = byteBuf.readInt();
        //上报报警信息内容
        this.infoContent = Jtt809Util.readGBKString(byteBuf, this.infoLength);
        return this;
    }
}
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/UPWarnMsgAdptTodoInfo.java
New file
@@ -0,0 +1,42 @@
package com.ruoyi.dataInterchange.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
/**
 * 主动上报报警处理结果
 * @author zhibing.pu
 * @Date 2025/3/3 15:04
 */
@Data
public class UPWarnMsgAdptTodoInfo {
    /**
     * 子业务类型标识
     */
    @JsonProperty("DATA_TYPE")
    private String dataType;
    /**
     * 后续数据长度
     */
    @JsonProperty("DATA_LENGTH")
    private String dataLength;
    /**
     * 对应报警信息源子业务类型标识
     */
    @JsonProperty("SOURCE_DATE_TYPE")
    private String sourceDateType;
    /**
     * 对应报警信息消息源报文序列号或车辆定位罅隙源报文序列号
     */
    @JsonProperty("SOURCE_MSG_SN")
    private String sourceMsgSn;
    /**
     * 报警处理结果
     * 0x00: 处理中
     * 0x01: 已处理完毕
     * 0x02: 不作处理
     * 0x03: 将来处理
     */
    @JsonProperty("RESULT")
    private String result;
}
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/UPWarnMsgInformTips.java
New file
@@ -0,0 +1,74 @@
package com.ruoyi.dataInterchange.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
/**
 * 上报报警预警信息
 * @author zhibing.pu
 * @Date 2025/3/3 15:45
 */
@Data
public class UPWarnMsgInformTips {
    /**
     * 子业务类型标识
     */
    @JsonProperty("DATA_TYPE")
    private String dataType;
    /**
     * 后续数据长度
     */
    @JsonProperty("DATA_LENGTH")
    private String dataLength;
    /**
     * 发起报警平台唯一编码
     */
    @JsonProperty("PLATFORM_ID")
    private String platformId;
    /**
     * 报警类型
     */
    @JsonProperty("WARN_TYPE")
    private String warnType;
    /**
     * 报警时间
     */
    @JsonProperty("WARN_TIME")
    private String warnTime;
    /**
     * 事件开始时间
     */
    @JsonProperty("START_TIME")
    private String startTime;
    /**
     * 事件结束时间
     */
    @JsonProperty("END_TIME")
    private String endTime;
    /**
     * 车牌号码
     */
    @JsonProperty("VEHICLE_NO")
    private String vehicleNo;
    /**
     * 车牌颜色
     */
    @JsonProperty("VEHICLE_COLOR")
    private String vehicleColor;
    /**
     * 线路ID
     */
    @JsonProperty("DRV_LINE_ID")
    private String drvLineId;
    /**
     * 上报报警信息内容长度
     */
    @JsonProperty("WARN_LENGTH")
    private String warnLength;
    /**
     * 报警描述
     */
    @JsonProperty("WARN_CONTENT")
    private String warnContent;
}
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/UPWarnMsgUrgeTodoAck.java
New file
@@ -0,0 +1,73 @@
package com.ruoyi.dataInterchange.model;
import com.ruoyi.dataInterchange.pojo.BaseModel;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import lombok.Data;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;
/**
 * 报警督办应答消息
 *
 * @author zhibing.pu
 * @Date 2025/3/3 14:44
 */
@Data
@Document(indexName = "up_warn_msg_urge_todo_ack")
public class UPWarnMsgUrgeTodoAck extends BaseModel {
    /**
     * 车牌号
     */
    @Field(type = FieldType.Text)
    private String vehicleNo;
    /**
     * 车牌颜色
     */
    @Field(type = FieldType.Integer)
    private int vehicleColor;
    /**
     * 子业务类型标识
     */
    @Field(type = FieldType.Integer)
    private int dataType;
    /**
     * 后续数据长度
     */
    @Field(type = FieldType.Integer)
    private int dataLength;
    /**
     * 报警督办ID
     */
    @Field(type = FieldType.Integer)
    private int supervisionId;
    /**
     * 报警处理结果
     * 0x00:处理中
     * 0x01:已处理完毕
     * 0x02:不作处理
     * 0x03:将来处理
     */
    @Field(type = FieldType.Integer)
    private int result;
    /**
     * 解析报文
     */
    public UPWarnMsgUrgeTodoAck decode(WarnMsg warnMsg) {
        byte[] data = warnMsg.getData();
        ByteBuf byteBuf = Unpooled.wrappedBuffer(data);
        this.vehicleNo = warnMsg.getVehicleNo();
        this.vehicleColor = warnMsg.getVehicleColor();
        this.dataType = warnMsg.getDataType();
        this.dataLength = warnMsg.getDataLength();
        //报警督办ID
        this.supervisionId = byteBuf.readInt();
        //报警处理结果
        this.result = byteBuf.readByte();
        return this;
    }
}
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/UPWarnMsgUrgeTodoAckInfo.java
New file
@@ -0,0 +1,43 @@
package com.ruoyi.dataInterchange.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
/**
 * 上报报警督办应答消息
 * @author zhibing.pu
 * @Date 2025/3/3 15:08
 */
@Data
public class UPWarnMsgUrgeTodoAckInfo {
    /**
     * 子业务类型标识
     */
    @JsonProperty("DATA_TYPE")
    private String dataType;
    /**
     * 后续数据长度
     */
    @JsonProperty("DATA_LENGTH")
    private String dataLength;
    /**
     * 对应报警信息源子业务类型标识
     */
    @JsonProperty("SOURCE_DATE_TYPE")
    private String sourceDateType;
    /**
     * 对应报警信息消息源报文序列号或车辆定位罅隙源报文序列号
     */
    @JsonProperty("SOURCE_MSG_SN")
    private String sourceMsgSn;
    /**
     * 报警处理结果
     * 0x00: 处理中
     * 0x01: 已处理完毕
     * 0x02: 不作处理
     * 0x03: 将来处理
     */
    @JsonProperty("RESULT")
    private String result;
}
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/UPWarnMsgUrgeTodoReqInfo.java
New file
@@ -0,0 +1,71 @@
package com.ruoyi.dataInterchange.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
/**
 * 上报报警督办请求
 * @author zhibing.pu
 * @Date 2025/3/3 15:52
 */
@Data
public class UPWarnMsgUrgeTodoReqInfo {
    /**
     * 子业务类型标识
     */
    @JsonProperty("DATA_TYPE")
    private String dataType;
    /**
     * 后续数据长度
     */
    @JsonProperty("DATA_LENGTH")
    private String dataLength;
    /**
     * 发起报警平台唯一编码
     */
    @JsonProperty("PLATFORM_ID")
    private String platformId;
    /**
     * 报警时间
     */
    @JsonProperty("WARN_TIME")
    private String warnTime;
    /**
     * 对应报警消息源子业务类型标识
     */
    @JsonProperty("SOURCE_DATA_TYPE")
    private String sourceDataType;
    /**
     * 对应报警督办请求消息源报文序号
     */
    @JsonProperty("SOURCE_MSG_SN")
    private String sourceMsgSn;
    /**
     * 督办截止时间
     */
    @JsonProperty("SUPERVISION_ENDTIME")
    private String supervisionEndTime;
    /**
     * 督办级别
     * 0x00: 紧急
     * 0x01: 一般
     */
    @JsonProperty("SUPERVISION_LEVEL")
    private String supervisionLevel;
    /**
     * 督办人
     */
    @JsonProperty("SUPERVISOR")
    private String supervisor;
    /**
     * 督办联系电话
     */
    @JsonProperty("SUPERVISOR_TEL")
    private String supervisorTel;
    /**
     * 督办联系电子邮件
     */
    @JsonProperty("SUPERVISOR_EMAIL")
    private String supervisorEmail;
}
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/WarnMsg.java
New file
@@ -0,0 +1,31 @@
package com.ruoyi.dataInterchange.model;
import lombok.Data;
/**
 * @author zhibing.pu
 * @Date 2025/3/6 20:26
 */
@Data
public class WarnMsg {
    /**
     * 车牌号
     */
    private String vehicleNo;
    /**
     * 车牌颜色
     */
    private int vehicleColor;
    /**
     * 子业务类型标识
     */
    private int dataType;
    /**
     * 后续数据长度
     */
    private int dataLength;
    /**
     * 数据部分
     */
    private byte[] data;
}
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/enu/DataType.java
@@ -9,61 +9,115 @@
 */
@Getter
public enum DataType {
    UP_CONNECT_REQ("UP_CONNECT_REQ", "主链路登录请求"),
    UP_CONNECT_RSP("UP_CONNECT_RSP", "主链路登录应答"),
    UP_DISCONNECT_REQ("UP_DISCONNECT_REQ", "主链路注销请求"),
    UP_DISCONNECT_RSP("UP_DISCONNECT_RSP", "主链路注销应答"),
    UP_LINKTEST_REQ("UP_LINKTEST_REQ", "主链路连接保持请求"),
    UP_LINKTEST_RSP("UP_LINKTEST_RSP", "主链路连接保持应答"),
    UP_DISCONNECT_INFORM("UP_DISCONNECT_INFORM", "主链路断开通知"),
    UP_CLOSELINK_INFORM("UP_CLOSELINK_INFORM", "下级平台主动关闭主从链路通知"),
    DOWN_CONNECT_REQ("DOWN_CONNECT_REQ", "从链路连接请求"),
    DOWN_CONNECT_RSP("DOWN_CONNECT_RSP", "从链路连接应答"),
    DOWN_DISCONNECT_REQ("DOWN_DISCONNECT_REQ", "从链路注销请求"),
    DOWN_DISCONNECT_RSP("DOWN_DISCONNECT_RSP", "从链路注销应答"),
    DOWN_LINKTEST_REQ("DOWN_LINKTEST_REQ", "从链路连接保持请求"),
    DOWN_LINKTEST_RSP("DOWN_LINKTEST_RSP", "从链路连接保持应答"),
    DOWN_DISCONNECT_INFORM("DOWN_DISCONNECT_INFORM", "从链路断开通知"),
    DOWN_CLOSELINK_INFORM("DOWN_CLOSELINK_INFORM", "上级平台主动关闭主从链路通知"),
    UP_MANAGE_TOTAL_RECV_BACK_MSG("UP_MANAGE_TOTAL_RECV_BACK_MSG", "发送车辆定位信息数量通知"),
    DOWN_MANAGE_MSG_REQ("DOWN_MANAGE_MSG_REQ", "平台链路连接情况与车辆定位消息"),
    DOWN_MANAGE_MSG_RSP("DOWN_MANAGE_MSG_RSP", "平台链路连接情况与车辆定位消息应答"),
    UP_MANAGE_MSG_SN_INFORM("UP_MANAGE_MSG_SN_INFORM", "上传平台间消息序列号通知"),
    DOWN_MANAGE_MSG_SN_INFORM("DOWN_MANAGE_MSG_SN_INFORM", "下发平台间消息序列号通知"),
    UP_EXG_MSG("UP_EXG_MSG", "主链路车辆动态信息交换"),
    UP_EXG_MSG_REGISTER("UP_EXG_MSG_REGISTER", "上传车辆注册信息"),
    UP_EXG_MSG_REAL_LOCATION("UP_EXG_MSG_REAL_LOCATION", "上传车辆实时定位信息"),
    UP_EXG_MSG_HISTORY_LOCATION("UP_EXG_MSG_HISTORY_LOCATION", "车辆定位信息自动补报请求"),
    UP_EXG_MSG_RETURN_STARTUP_ACK("UP_EXG_MSG_RETURN_STARTUP_ACK", "启动车辆定位信息交换应答"),
    UP_EXG_MSG_RETURN_END_ACK("UP_EXG_MSG_RETURN_END_ACK", "结束车辆定位信息交换应答"),
    UP_EXG_MSG_APPLY_FOR_MONITOR_STARTUP("UP_EXG_MSG_APPLY_FOR_MONITOR_STARTUP", "申请交换指定车辆定位信息请求"),
    UP_EXG_MSG_APPLY_FOR_MONITOR_END("UP_EXG_MSG_APPLY_FOR_MONITOR_END", "取消交换指定车辆定位信息请求"),
    UP_EXG_MSG_APPLY_HISGNSSDATA_REQ("UP_EXG_MSG_APPLY_HISGNSSDATA_REQ", "车辆定位信息补发请求"),
    UP_EXG_MSG_REPORT_DRIVER_INFO_ACK("UP_EXG_MSG_REPORT_DRIVER_INFO_ACK", "上报驾驶员身份信息应答"),
    UP_EXG_MSG_TAKE_EWAYBILL_ACK("UP_EXG_MSG_TAKE_EWAYBILL_ACK", "上报车辆电子运单应答消息"),
    UP_EXG_MSG_REPORT_DRIVER_INFO("UP_EXG_MSG_REPORT_DRIVER_INFO", "主动上报驾驶员身份信息"),
    UP_EXG_MSG_REPORT_EWAYBILL_INFO("UP_EXG_MSG_REPORT_EWAYBILL_INFO", "主动上报车辆电子运单信息"),
    UP_BASE_MSG_DRVLINE_INFO("UP_BASE_MSG_DRVLINE_INFO", "主动上报车辆行驶路线信息"),
    DOWN_EXG_MSG("DOWN_EXG_MSG", "从链路车辆动态信息交换"),
    DOWN_EXG_MSG_REGISTER_ACK("DOWN_EXG_MSG_REGISTER_ACK", "车辆注册信息应答"),
    DOWN_EXG_MSG_CAR_LOCATION("DOWN_EXG_MSG_CAR_LOCATION", "交换车辆定位信息"),
    DOWN_EXG_MSG_HISTORY_ARCOSSAREA("DOWN_EXG_MSG_HISTORY_ARCOSSAREA", "车辆定位信息交换补发"),
    DOWN_EXG_MSG_DRVLINE_INFO("DOWN_EXG_MSG_DRVLINE_INFO", "交换车辆行驶线路信息"),
    DOWN_EXG_MSG_CAR_INFO("DOWN_EXG_MSG_CAR_INFO", "交换车辆静态信息"),
    DOWN_EXG_MSG_RETURN_STARTUP("DOWN_EXG_MSG_RETURN_STARTUP", "启动车辆定位信息交换"),
    DOWN_EXG_MSG_RETURN_END("DOWN_EXG_MSG_RETURN_END", "结束车辆定位信息交换"),
    UP_CONNECT_REQ(0x1001, "主链路登录请求"),
    UP_CONNECT_RSP(0x1002, "主链路登录应答"),
    UP_DISCONNECT_REQ(0x1003, "主链路注销请求"),
    UP_DISCONNECT_RSP(0x1004, "主链路注销应答"),
    UP_LINKTEST_REQ(0x1005, "主链路连接保持请求"),
    UP_LINKTEST_RSP(0x1006, "主链路连接保持应答"),
    UP_DISCONNECT_INFORM(0x1007, "主链路断开通知"),
    UP_CLOSELINK_INFORM(0x1008, "下级平台主动关闭主从链路通知"),
    DOWN_CONNECT_REQ(0x9001, "从链路连接请求"),
    DOWN_CONNECT_RSP(0x9002, "从链路连接应答"),
    DOWN_DISCONNECT_REQ(0x9003, "从链路注销请求"),
    DOWN_DISCONNECT_RSP(0x9004, "从链路注销应答"),
    DOWN_LINKTEST_REQ(0x9005, "从链路连接保持请求"),
    DOWN_LINKTEST_RSP(0x9006, "从链路连接保持应答"),
    DOWN_DISCONNECT_INFORM(0x9007, "从链路断开通知"),
    DOWN_CLOSELINK_INFORM(0x9008, "上级平台主动关闭主从链路通知"),
    UP_MANAGE_TOTAL_RECV_BACK_MSG(0x9101, "发送车辆定位信息数量通知"),
    DOWN_MANAGE_MSG_REQ(0x9102, "平台链路连接情况与车辆定位消息"),
    UP_MANAGE_MSG_RSP(0x1102, "平台链路连接情况与车辆定位消息传输情况上报应答消息"),
    UP_MANAGE_MSG_SN_INFORM(0x1103, "上传平台间消息序列号通知"),
    DOWN_MANAGE_MSG_SN_INFORM(0x9103, "下发平台间消息序列号通知"),
    UP_EXG_MSG(0x1200, "主链路车辆动态信息交换"),
    UP_EXG_MSG_REGISTER(0x1201, "上传车辆注册信息"),
    UP_EXG_MSG_REAL_LOCATION(0x1202, "上传车辆实时定位信息"),
    UP_EXG_MSG_HISTORY_LOCATION(0x1203, "车辆定位信息自动补报请求"),
    UP_EXG_MSG_RETURN_STARTUP_ACK(0x1205, "启动车辆定位信息交换应答"),
    UP_EXG_MSG_RETURN_END_ACK(0x1206, "结束车辆定位信息交换应答"),
    UP_EXG_MSG_APPLY_FOR_MONITOR_STARTUP(0x1207, "申请交换指定车辆定位信息请求"),
    UP_EXG_MSG_APPLY_FOR_MONITOR_END(0x1208, "取消交换指定车辆定位信息请求"),
    UP_EXG_MSG_APPLY_HISGNSSDATA_REQ(0x1209, "车辆定位信息补发请求"),
    UP_EXG_MSG_REPORT_DRIVER_INFO_ACK(0x120A, "上报驾驶员身份信息应答"),
    UP_EXG_MSG_TAKE_EWAYBILL_ACK(0x120B, "上报车辆电子运单应答消息"),
    UP_EXG_MSG_REPORT_DRIVER_INFO(0x120C, "主动上报驾驶员身份信息"),
    UP_EXG_MSG_REPORT_EWAYBILL_INFO(0x120D, "主动上报车辆电子运单信息"),
    UP_BASE_MSG_DRVLINE_INFO(0x120E, "主动上报车辆行驶路线信息"),
    DOWN_EXG_MSG(0x9200, "从链路车辆动态信息交换"),
    DOWN_EXG_MSG_REGISTER_ACK(0x9201, "车辆注册信息应答"),
    DOWN_EXG_MSG_CAR_LOCATION(0x9202, "交换车辆定位信息"),
    DOWN_EXG_MSG_HISTORY_ARCOSSAREA(0x9203, "车辆定位信息交换补发"),
    DOWN_BASE_MSG_DRVLINE_INFO(0x9602, "交换车辆行驶线路信息"),
    DOWN_EXG_MSG_CAR_INFO(0x9204, "交换车辆静态信息"),
    DOWN_EXG_MSG_RETURN_STARTUP(0x9205, "启动车辆定位信息交换"),
    DOWN_EXG_MSG_RETURN_END(0x9206, "结束车辆定位信息交换"),
    DOWN_EXG_MSG_APPLY_FOR_MONITOR_STARTUP_ACK(0x9207, "申请交换指定车辆定位信息应答"),
    DOWN_EXG_MSG_APPLY_FOR_MONITOR_END_ACK(0x9208, "取消申请交换指定车辆定位信息应答"),
    DOWN_EXG_MSG_APPLY_HISGNSSDATA_ACK(0x9209, "补发车辆定位信息应答"),
    DOWN_EXG_MSG_REPORT_DRIVER_INFO(0x920A, "上报驾驶员身份信息请求"),
    DOWN_EXG_MSG_TAKE_EWAYBILL_REQ(0x920B, "上报车辆电子运单请求"),
    DOWN_BASE_MSG_DRVLINE_REQ(0x920C, "上报车辆行驶路线请求"),
    DOWN_BASE_MSG_DRVLINE_ACK(0x920D, "车辆行驶路线应答消息"),
    UP_PLATFORM_MSG(0x1300, "主链路平台间信息交互"),
    UP_PLATFORM_MSG_POST_QUERY_ACK(0x1301, "平台查岗应答消息"),
    UP_PLATFORM_MSG_INFO_ACK(0x1302, "下发平台间报文应答消息"),
    UP_PLATFORM_MSG_RETRAN_REQ(0x1303, "上传平台间消息补传请求"),
    DOWN_PLATFORM_MSG(0x9300, "从链路平台间信息交互"),
    DOWN_PLATFORM_MSG_POST_QUERY_REQ(0x9301, "平台查岗请求"),
    DOWN_PLATFORM_MSG_INFO_REQ(0x9302, "下发平台间报文请求"),
    DOWN_PLATFORM_MSG_RETRAN_REQ(0x9303, "下发平台间信息补传请求"),
    UP_WARN_MSG(0x1400, "报警信息交互"),
    UP_WARN_MSG_URGE_TODO_ACK(0x1401, "报警督办应答消息"),
    UP_WARN_MSG_ADPT_INFO(0x1402, "上报报警信息"),
    UP_WARN_MSG_ADPT_TODO_INFO(0x1412, "主动上报报警处理结果"),
    UP_WARN_MSG_URGE_TODO_ACK_INFO(0x1411, "上报报警督办应答消息"),
    DOWN_WARN_MSG(0x9400, "从链路报警信息"),
    DOWN_WARN_MSG_URGE_TODO_REQ(0x9401, "报警督办请求"),
    DOWN_WARN_MSG_INFORM_TIPS(0x9402, "下发报警预警消息"),
    DOWN_WARN_MSG_EXG_INFORM(0x9403, "实时交换报警信息"),
    UP_WARN_MSG_INFORM_TIPS(0x1403, "上报报警预警信息"),
    UP_WARN_MSG_URGE_TODO_REQ_INFO(0x1413, "上报报警督办请求"),
    UP_CTRL_MSG(0x1500, "车辆监管业务"),
    UP_CTRL_MSG_MONITOR_VEHICLE_ACK(0x1501, "车辆单向监听应答消息"),
    UP_CTRL_MSG_TAKE_PHOTO_ACK(0x1502, "车辆牌照应答消息"),
    UP_CTRL_MSG_TEXT_INFO_ACK(0x1503, "下发车辆报文应答消息"),
    UP_CTRL_MSG_TAKE_TRAVEL_ACK(0x1504, "上报车辆行驶记录应答消息"),
    UP_CTRL_MSG_EMERGENCY_MONITORING_ACK(0x1505, "车辆应急接入监管平台应答消息"),
    DOWN_CTRL_MSG(0x9500, "从链路车辆监管业务"),
    DOWN_CTRL_MSG_MONITOR_VEHICLE_REQ(0x9501, "车辆单向监听请求"),
    DOWN_CTRL_MSG_TAKE_PHOTO_REQ(0x9502, "车辆牌照请求消息"),
    DOWN_CTRL_MSG_TEXT_REQ(0x9503, "下发车辆报文请求"),
    DOWN_CTRL_MSG_TAKE_TRAVEL_REQ(0x9504, "上报车辆行驶记录请求"),
    DOWN_CTRL_MSG_EMERGENCY_MONITORING_REQ(0x9505, "车辆应急接入监管平台请求"),
    UP_BASE_MSG(0x1600, "车辆静态信息交换业务"),
    UP_BASE_MSG_DRVLINE_ADDED_REQ(0x1602, "补报车辆行驶路线信息应答"),
    UP_BASE_MSG_VEHICLE_ADDED_ACK(0x1601, "补报车辆静态信息应答消息"),
    DOWN_BASE_MSG(0x9600, "从链路车辆静态信息交换业务"),
    DOWN_BASE_MSG_VEHICLE_ADDED(0x9601, "补报车辆静态信息请求"),
    
    
    ;
    
    
    private String code;
    private int code;
    private String name;
    
    DataType(String code, String name) {
    DataType(int code, String name) {
        this.code = code;
        this.name = name;
    }
    
    
    public static DataType getDataType(int code){
        for (DataType value : DataType.values()) {
            if(code == value.getCode()){
                return value;
            }
        }
        return null;
    }
}
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/enu/NonPositionAlarm.java
New file
@@ -0,0 +1,33 @@
package com.ruoyi.dataInterchange.model.enu;
/**
 * 非位置相关报警类型
 * @author zhibing.pu
 * @Date 2025/3/3 18:45
 */
public enum NonPositionAlarm {
    OVERTIME_PARKING(0xA001, "超时停车"),
    THE_REPORTING_INTERVAL_OF_VEHICLE_LOCATION_INFORMATION_IS_ABNORMAL(0xA002, "车辆定位信息上报时间间隔异常"),
    THE_DISTANCE_BETWEEN_VEHICLE_LOCATION_INFORMATION_REPORTS_IS_ABNORMAL(0xA003, "车辆定位信息上报距离间隔异常"),
    THE_LOWER_LEVEL_PLATFORM_IS_DISCONNECTED_ABNORMALLY(0xA004, "下级平台异常断线"),
    DATA_TRANSMISSION_ON_THE_LOWER_LEVEL_PLATFORM_IS_ABNORMAL(0xA005, "下级平台数据传输异常"),
    ROAD_BLOCKING_ALARM(0xA006, "路段堵塞报警"),
    DANGEROUS_ROAD_WARNING(0xA007, "危险路段报警"),
    RAIN_AND_SNOW_WARNING(0xA008, "雨雪天气报警"),
    ABNORMAL_DRIVER_IDENTIFICATION(0xA009, "驾驶员身份识别异常"),
    TERMINAL_EXCEPTION(0xA00A, "终端异常(含线路连接异常)"),
    PLATFORM_ACCESS_EXCEPTION(0xA00B, "平台接入异常"),
    CORE_DATA_EXCEPTION(0xA00C, "核心数据异常"),
    OTHER_ALARM(0x00FF, "其他报警"),
    ;
    private Integer code;
    private String name;
    NonPositionAlarm(Integer code, String name) {
        this.code = code;
        this.name = name;
    }
}
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/enu/PositionAlarm.java
New file
@@ -0,0 +1,37 @@
package com.ruoyi.dataInterchange.model.enu;
/**
 * 位置相关报警类型
 * @author zhibing.pu
 * @Date 2025/3/3 18:45
 */
public enum PositionAlarm {
    OVERSPEED_ALARM(0x0001, "超速报警"),
    FATIGUE_DRIVING_ALARM(0x0002, "疲劳驾驶报警"),
    EMERGENCY_ALARM(0x0003, "紧急报警"),
    ENTER_THE_DESIGNATED_AREA_TO_ALERT(0x0004, "进入指定区域报警"),
    LEAVE_THE_DESIGNATED_AREA_TO_CALL_THE_POLICE(0x0005, "离开指定区域报警"),
    CROSSING_ALARM(0x0008, "越界报警"),
    BURGLAR_ALARM(0x0009, "盗警"),
    ROBBERY_POLICE(0x000A, "劫警"),
    OFF_COURSE_ALARM(0x000B, "偏离路线报警"),
    VEHICLE_MOVEMENT_ALARM(0x000C, "车辆移动报警"),
    OVERTIME_DRIVING_ALARM(0x000D, "超时驾驶报警"),
    ILLEGAL_DRIVING_ALARM(0x0010, "违规行驶报警"),
    FORWARD_COLLISION_ALARM(0x0011, "前撞报警"),
    LANE_DEPARTURE_WARNING(0x0012, "车道偏离报警"),
    ABNORMAL_TIRE_PRESSURE_ALARM(0x0013, "胎压异常报警"),
    DYNAMIC_INFORMATION_ABNORMAL_ALARM(0x0014, "动态信息异常报警"),
    OTHER_ALARM(0x00FF, "其他报警"),
    ;
    private Integer code;
    private String name;
    PositionAlarm(Integer code, String name) {
        this.code = code;
        this.name = name;
    }
}
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/netty/client/ChannelMap.java
New file
@@ -0,0 +1,118 @@
package com.ruoyi.dataInterchange.netty.client;
import com.ruoyi.dataInterchange.wapper.UPConnect;
import io.netty.channel.Channel;
import io.netty.channel.ChannelId;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.util.concurrent.GlobalEventExecutor;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
 * @author zhibing.pu
 * @Date 2025/3/4 19:17
 */
public class ChannelMap {
    //存储主链路通道
    private static final ChannelGroup SERVER_GROUP = new DefaultChannelGroup("Jtt809Server", GlobalEventExecutor.INSTANCE);
    //存储主链路ID
    private static final Map<Integer, ChannelId> SERVER_ID_MAP = new ConcurrentHashMap<>();
    //存储从链路通道
    private static final ChannelGroup CLIENT_GROUP = new DefaultChannelGroup("Jtt809Client", GlobalEventExecutor.INSTANCE);
    //存储从链路ID
    private static final Map<Integer, ChannelId> CLIENT_ID_MAP = new ConcurrentHashMap<>();
    //存储从链路连接地址和端口号
    private static final Map<Integer, UPConnect> IP_PORT = new ConcurrentHashMap<>();
    //存储从链路连接重试次数
    private static final Map<Integer, Integer> TIMES = new ConcurrentHashMap<>();
    /**
     * 保存通道
     *
     * @param key
     * @param channel
     */
    public static void addClientChannel(int key, ChannelId channel) {
        CLIENT_ID_MAP.put(key, channel);
    }
    /**
     * 获取通道
     *
     * @param key
     * @return
     */
    public static Channel getClientChannel(int key) {
        ChannelId channelId = CLIENT_ID_MAP.get(key);
        Channel channel = CLIENT_GROUP.find(channelId);
        return channel;
    }
    /**
     * 保存通道
     *
     * @param key
     * @param channel
     */
    public static void addServerChannel(int key, ChannelId channel) {
        SERVER_ID_MAP.put(key, channel);
    }
    /**
     * 获取通道
     *
     * @param key
     * @return
     */
    public static Channel getServerChannel(int key) {
        ChannelId channelId = SERVER_ID_MAP.get(key);
        Channel channel = SERVER_GROUP.find(channelId);
        return channel;
    }
    /**
     * 缓存从链路的IP地址和端口号
     *
     * @param key
     * @param req
     */
    public static void addIpAndPort(int key, UPConnect req) {
        IP_PORT.put(key, req);
    }
    /**
     * 获取从链路的IP地址和端口号
     *
     * @param key
     */
    public static UPConnect getIpAndPort(int key) {
        return IP_PORT.get(key);
    }
    /**
     * 获取从链路连接重试次数
     *
     * @param key
     * @return
     */
    public static int getTimes(int key) {
        return TIMES.get(key);
    }
    /**
     * 保存从链路连接重试次数
     *
     * @param key
     * @return
     */
    public static int saveTimes(int key, int t) {
        return TIMES.put(key, t);
    }
}
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/netty/client/NettyClient.java
New file
@@ -0,0 +1,89 @@
package com.ruoyi.dataInterchange.netty.client;
import com.ruoyi.dataInterchange.netty.server.NettyHandle;
import com.ruoyi.dataInterchange.util.jtt809.decoder.Jtt809Decoder;
import com.ruoyi.dataInterchange.util.jtt809.encoder.Jtt809Encoder;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.timeout.IdleStateHandler;
import java.net.InetSocketAddress;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
/**
 * @author zhibing.pu
 * @Date 2025/3/3 20:11
 */
public class NettyClient {
    /**
     * 连接IP
     */
    private String host;
    /**
     * 连接端口号
     */
    private int port;
    public NettyClient(String host, int port) {
        this.host = host;
        this.port = port;
    }
    /**
     * 执行启动连接
     * @throws Exception
     */
    public void start(int code) throws Exception {
        EventLoopGroup nioEventLoopGroup = null;
        try {
            //创建Bootstrap对象用来引导启动客户端
            Bootstrap bootstrap = new Bootstrap();
            //创建EventLoopGroup对象并设置到Bootstrap中,EventLoopGroup可以理解为是一个线程池,这个线程池用来处理连接、接受数据、发送数据
            nioEventLoopGroup = new NioEventLoopGroup();
            //创建InetSocketAddress并设置到Bootstrap中,InetSocketAddress是指定连接的服务器地址
            bootstrap.group(nioEventLoopGroup).channel(NioSocketChannel.class).remoteAddress(new InetSocketAddress(host, port))
                    .handler(new ChannelInitializer<SocketChannel>() {
                        //添加一个ChannelHandler,客户端成功连接服务器后就会被执行
                        @Override
                        protected void initChannel(SocketChannel socketChannel)
                                throws Exception {
                            ChannelPipeline pipeline = socketChannel.pipeline();
                            // 解码器
                            pipeline.addLast("decoder", new Jtt809Decoder());
                            // 编码器
                            pipeline.addLast("encoder", new Jtt809Encoder());
                            //  空闲检测处理器 触发空闲状态事件            读空闲:5秒      写空闲:7秒  读写空闲:10秒
                            pipeline.addLast(new IdleStateHandler(5,7,3, TimeUnit.SECONDS));
                            // 处理器
                            pipeline.addLast("handler", new NettyHandle());
                        }
                    });
            // • 调用Bootstrap.connect()来连接服务器
            ChannelFuture f = bootstrap.connect().sync();
            //将通道添加到缓存中,便于后期直接使用
            Channel channel = f.channel();
            ChannelMap.addClientChannel(code, channel.id());
            // • 最后关闭EventLoopGroup来释放资源
            f.channel().closeFuture().sync();
        } finally {
            nioEventLoopGroup.shutdownGracefully().sync();
        }
    }
    public static void main(String[] args) {
        try {
            new NettyClient("221.182.45.100", 1000).start(1);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/netty/client/NettyClientHandler.java
New file
@@ -0,0 +1,73 @@
package com.ruoyi.dataInterchange.netty.client;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.util.CharsetUtil;
import java.util.ArrayList;
import java.util.List;
/**
 * @author zhibing.pu
 * @Date 2025/3/3 20:13
 */
public class NettyClientHandler extends ChannelInboundHandlerAdapter {
    public static List<ChannelHandlerContext> cts = new ArrayList<ChannelHandlerContext>();
    /**
     * 向服务端发送数据
     */
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        System.err.println("客户端和服务端已建立连接");
    }
    public void write(ChannelHandlerContext ctx , String mess) throws Exception {
        String sendInfo = mess;
        ctx.writeAndFlush(Unpooled.copiedBuffer(sendInfo, CharsetUtil.UTF_8)); // 必须有flush
        ctx.flush();
    }
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        //读取数据
        //读取数据
        ByteBuf buf1 = (ByteBuf) msg;
        byte[] req = readClientData((ByteBuf) msg);
        String body = new String(req, "UTF-8"); //获取到的值
        System.out.println("客户端的数据------>"+body);
        //写数据
        write(ctx,"wits写的数据");
    }
    //将netty的数据装换为字节数组
    private byte[] readClientData(ByteBuf msg) {
        ByteBuf buf = msg;
        byte[] req = new byte[buf.readableBytes()];
        buf.readBytes(req);
        buf.release();
        return req;
    }
    /**
     * channelInactive
     * channel 通道 Inactive 不活跃的
     * 当客户端主动断开服务端的链接后,这个通道就是不活跃的。也就是说客户端与服务端的关闭了通信通道并且不可以传输数据
     */
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        System.out.println("客户端与服务端通道-关闭:" + ctx.channel().localAddress() + "channelInactive");
    }
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        cts.remove(ctx);
        ctx.close();
        System.out.println("异常退出:" + cause.getMessage());
    }
}
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/netty/server/NettyConfig.java
New file
@@ -0,0 +1,57 @@
package com.ruoyi.dataInterchange.netty.server;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelOption;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
 * @author zhibing.pu
 * @Date 2025/3/3 19:24
 */
@Configuration
public class NettyConfig {
    /**
     * 用户线程数
     */
    private Integer bossThread = 5;
    /**
     * 工作线程数
     */
    private int workThread = 10;
    /**
     * 心跳
     */
    private Boolean keepAlive = true;
    @Autowired
    private NettyInitalizer nettyInitalizer;
    @Bean(name = "bossGroup", destroyMethod = "shutdownGracefully")
    public NioEventLoopGroup bossGroup() {
        return new NioEventLoopGroup(bossThread);
    }
    @Bean(name = "workerGroup", destroyMethod = "shutdownGracefully")
    public NioEventLoopGroup workerGroup() {
        return new NioEventLoopGroup(workThread);
    }
    // 定义
    @Bean(name = "serverBootstrap")
    public ServerBootstrap bootstrap(){
        ServerBootstrap bootstrap = new ServerBootstrap();
        bootstrap.group(bossGroup(), workerGroup())
                .channel(NioServerSocketChannel.class)
                .childHandler(nettyInitalizer);
        bootstrap.option(ChannelOption.SO_KEEPALIVE, keepAlive); // 是否使用TCP的心跳机制
        bootstrap.option(ChannelOption.SO_BACKLOG, 1024); // backLog的队列大小
        // 通过TCP_NODELAY禁用NAGLE,使消息立即发出去,不用等待到一定的数据量才发出去
        bootstrap.option(ChannelOption.TCP_NODELAY, true);
        return bootstrap;
    }
}
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/netty/server/NettyHandle.java
New file
@@ -0,0 +1,192 @@
package com.ruoyi.dataInterchange.netty.server;
import com.ruoyi.common.core.utils.SpringUtils;
import com.ruoyi.dataInterchange.model.enu.DataType;
import com.ruoyi.dataInterchange.server.*;
import com.ruoyi.dataInterchange.util.jtt809.packet.common.OuterPacket;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
/**
 * 自定义handler
 * @author zhibing.pu
 * @Date 2025/3/3 19:30
 */
@Slf4j
@Component
public class NettyHandle extends SimpleChannelInboundHandler<String> {
    @Resource
    private ConnectReqService connectReqService = SpringUtils.getBean(ConnectReqService.class);
    @Resource
    private UPDisconnectReqService upDisconnectReqService = SpringUtils.getBean(UPDisconnectReqService.class);
    @Resource
    private UPLinkTestReqService upLinkTestReqService = SpringUtils.getBean(UPLinkTestReqService.class);
    @Resource
    private UPDisconnectInformService upDisconnectInformService = SpringUtils.getBean(UPDisconnectInformService.class);
    @Resource
    private UPCloseLinkInformService upCloseLinkInformService = SpringUtils.getBean(UPCloseLinkInformService.class);
    @Resource
    private DOWNConnectRspService downConnectRspService = SpringUtils.getBean(DOWNConnectRspService.class);
    @Resource
    private ExgMsgService exgMsgService = SpringUtils.getBean(ExgMsgService.class);
    @Resource
    private PlatformMsgService platformMsgService = SpringUtils.getBean(PlatformMsgService.class);
    @Resource
    private WarnMsgService warnMsgService = SpringUtils.getBean(WarnMsgService.class);
    @Resource
    private CtrlMsgService ctrlMsgService = SpringUtils.getBean(CtrlMsgService.class);
    @Resource
    private BaseMsgService baseMsgService = SpringUtils.getBean(BaseMsgService.class);
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object object) throws Exception {
        OuterPacket outerPacket = (OuterPacket) object;
        int id = outerPacket.getId();
        serviceRouting(DataType.getDataType(id), ctx, outerPacket);
    }
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {
        log.info("收到客户端发送消息:{}", msg);
        //数据转义
        msg = msg.replaceAll("5a01", "5b");
        msg = msg.replaceAll("5a02", "5a");
        msg = msg.replaceAll("5e01", "5d");
        msg = msg.replaceAll("5e02", "5e");
        log.info("转义后的数据包:{}", msg);
        //数据头
        String head = msg.substring(0, 2); //--头标识
        String tail = msg.substring(msg.length() - 2);
        String datalength= msg.substring(2, 10);//--数据头->数据长度
        String dataSeqNo = msg.substring(10, 18);// --数据头->报文序列号
        String bizdata = msg.substring(18, 22);// --数据头->业务数据类型
        String code = msg.substring(22, 30); //--数据头->下级平台接入码,上级平台给下级平台分配唯一标识码
        String version = msg.substring(30, 36); //--数据头->协议版本号标识
        String entryFlag = msg.substring(36, 38);//--数据头->报文加密标识位
        String key = msg.substring(38, 46);//--数据头->数据加密的密匙
        String time = msg.substring(46, 62);//--数据头->系统时间
        //数据体
        String body = msg.substring(62, msg.length() - 2);
    }
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        log.info("Netty客户端链接成功");
        super.channelActive(ctx);
    }
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        log.info("Netty客户端连链接常关闭");
        cause.printStackTrace();
        ctx.close();
    }
    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        log.info("Netty客户端离线");
        super.channelInactive(ctx);
    }
    /**
     * 业务路由
     * @param dataType
     * @param ctx
     * @param out
     */
    public void serviceRouting(DataType dataType, ChannelHandlerContext ctx, OuterPacket out){
        switch (dataType){
            case UP_CONNECT_REQ:
                log.info("主链路登录请求({}):{}", DataType.UP_CONNECT_REQ.getCode(), out);
                connectReqService.connect(ctx, out);
                break;
            case UP_DISCONNECT_REQ:
                log.info("主链路注销请求({}):{}", DataType.UP_DISCONNECT_REQ.getCode(), out);
                upDisconnectReqService.disconnect(ctx, out);
                break;
            case UP_LINKTEST_REQ:
                log.info("主链路连接保持请求({}):{}", DataType.UP_LINKTEST_REQ.getCode(), out);
                upLinkTestReqService.linkTest(ctx, out);
                break;
            case UP_DISCONNECT_INFORM:
                log.info("主链路断开通知请求({}):{}", DataType.UP_DISCONNECT_INFORM.getCode(), out);
                upDisconnectInformService.disconnect(ctx, out);
                break;
            case UP_CLOSELINK_INFORM:
                log.info("下级平台主动关闭主从链路通知({}):{}", DataType.UP_CLOSELINK_INFORM.getCode(), out);
                upCloseLinkInformService.closeLinkInform(ctx, out);
                break;
            case DOWN_CONNECT_RSP:
                log.info("从链路连接应答({}):{}", DataType.DOWN_CONNECT_RSP.getCode(), out);
                downConnectRspService.connectRsp(ctx, out);
                break;
            case DOWN_DISCONNECT_RSP:
                log.info("从链路注销应答({}):{}", DataType.DOWN_DISCONNECT_RSP.getCode(), out);
                break;
            case DOWN_LINKTEST_RSP:
                log.info("从链路连接保持应答({}):{}", DataType.DOWN_LINKTEST_RSP.getCode(), out);
                break;
            case UP_MANAGE_TOTAL_RECV_BACK_MSG:
                log.info("发送车辆定位信息数量通知({}):{}", DataType.UP_MANAGE_TOTAL_RECV_BACK_MSG.getCode(), out);
                break;
            case UP_MANAGE_MSG_RSP:
                log.info("平台链路连接情况与车辆定位消息传输情况上报应答消息({}):{}", DataType.UP_MANAGE_MSG_RSP.getCode(), out);
                break;
            case UP_MANAGE_MSG_SN_INFORM:
                log.info("上传平台间消息序列号通知({}):{}", DataType.UP_MANAGE_MSG_SN_INFORM.getCode(), out);
                break;
            case UP_EXG_MSG:
                log.info("主链路车辆动态信息交换({}):{}", DataType.UP_EXG_MSG.getCode(), out);
                exgMsgService.up_exg_msg(ctx, out);
                break;
            case UP_PLATFORM_MSG:
                log.info("主链路平台间信息交互({}):{}", DataType.UP_PLATFORM_MSG.getCode(), out);
                platformMsgService.up_platform_msg(ctx, out);
                break;
            case UP_WARN_MSG:
                log.info("报警信息交互({}):{}", DataType.UP_WARN_MSG.getCode(), out);
                warnMsgService.up_warn_msg(ctx, out);
                break;
            case UP_CTRL_MSG:
                log.info("车辆监管业务({}):{}", DataType.UP_CTRL_MSG.getCode(), out);
                ctrlMsgService.up_ctrl_msg(ctx, out);
                break;
            case UP_BASE_MSG:
                log.info("车辆静态信息交换业务({}):{}", DataType.UP_BASE_MSG.getCode(), out);
                baseMsgService.up_base_msg(ctx, out);
                break;
            default:
                break;
        }
    }
}
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/netty/server/NettyInitalizer.java
New file
@@ -0,0 +1,46 @@
package com.ruoyi.dataInterchange.netty.server;
import com.ruoyi.dataInterchange.util.jtt809.decoder.Jtt809Decoder;
import com.ruoyi.dataInterchange.util.jtt809.encoder.Jtt809Encoder;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
import io.netty.handler.timeout.IdleStateHandler;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.concurrent.TimeUnit;
/**
 * @author zhibing.pu
 * @Date 2025/3/3 19:26
 */
@Component
@ChannelHandler.Sharable
public class NettyInitalizer extends ChannelInitializer<SocketChannel> {
    @Override
    protected void initChannel(SocketChannel socketChannel) throws Exception {
        ChannelPipeline pipeline = socketChannel.pipeline();
        // 解码器
        pipeline.addLast("decoder", new Jtt809Decoder());
        // 编码器
        pipeline.addLast("encoder", new Jtt809Encoder());
        //  空闲检测处理器 触发空闲状态事件            读空闲:5秒      写空闲:7秒  读写空闲:10秒
        pipeline.addLast(new IdleStateHandler(5,7,3, TimeUnit.SECONDS));
        // 处理器
        pipeline.addLast("handler", new NettyHandle());
        // 如果后期处理拆包粘包可以在这里处理
        /** LineBasedFrameDecoder:以行为单位进行数据包的解码,使用换行符\n或者\r\n作为依据遇
         到\n或者\r\n都认为是一条完整的消息。
         DelimiterBasedFrameDecoder:以特殊的符号作为分隔来进行数据包的解码。
         FixedLengthFrameDecoder:以固定长度进行数据包的解码。
         LenghtFieldBasedFrameDecode:适用于消息头包含消息长度的协议(最常用)。
         */
        pipeline.addLast(new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE, 0, 4, 0, 4));
    }
}
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/netty/server/NettyStart.java
New file
@@ -0,0 +1,31 @@
package com.ruoyi.dataInterchange.netty.server;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
/**
 * @author zhibing.pu
 * @Date 2025/3/3 20:06
 */
@Slf4j
@Component
public class NettyStart {
    @Autowired
    private ServerBootstrap serverBootstrap;
    private int nettyPort = 1000;
    private ChannelFuture serverChannelFuture;
    @PostConstruct
    public void start() throws Exception {
        log.info("Netty服务启动成功:" + nettyPort);
        serverChannelFuture = serverBootstrap.bind(nettyPort).sync();
    }
}
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/pojo/BaseModel.java
New file
@@ -0,0 +1,29 @@
package com.ruoyi.dataInterchange.pojo;
import lombok.Data;
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;
import java.time.LocalDateTime;
/**
 * @author zhibing.pu
 * @Date 2025/3/7 16:22
 */
@Data
public class BaseModel {
    @Id
    @Field(type = FieldType.Auto)
    private Long id;
    /**
     * 下级平台唯一标识
     */
    @Field(type = FieldType.Integer)
    private Integer inferiorPlatformId;
    /**
     * 添加时间
     */
    @Field(type = FieldType.Date)
    private LocalDateTime createTime;
}
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/server/BaseMsgService.java
New file
@@ -0,0 +1,28 @@
package com.ruoyi.dataInterchange.server;
import com.ruoyi.dataInterchange.model.enu.DataType;
import com.ruoyi.dataInterchange.util.jtt809.packet.common.OuterPacket;
import io.netty.channel.ChannelHandlerContext;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
/**
 * @author zhibing.pu
 * @Date 2025/3/4 21:01
 */
@Slf4j
@Component
public class BaseMsgService {
    public void up_base_msg(ChannelHandlerContext ctx, OuterPacket out){
        DataType dataType = DataType.getDataType(out.getId());
        switch (dataType){
            case UP_BASE_MSG_VEHICLE_ADDED_ACK:
                log.info("补报车辆静态信息应答消息({}):{}", DataType.UP_BASE_MSG_VEHICLE_ADDED_ACK.getCode(), out);
                break;
            default:
                break;
        }
    }
}
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/server/ConnectReqService.java
New file
@@ -0,0 +1,197 @@
package com.ruoyi.dataInterchange.server;
import com.alibaba.fastjson.JSON;
import com.ruoyi.dataInterchange.model.DOWNConnectReq;
import com.ruoyi.dataInterchange.model.DOWNDisconnectInform;
import com.ruoyi.dataInterchange.model.UPConnectReq;
import com.ruoyi.dataInterchange.model.UPConnectRsp;
import com.ruoyi.dataInterchange.model.enu.DataType;
import com.ruoyi.dataInterchange.netty.client.ChannelMap;
import com.ruoyi.dataInterchange.netty.client.NettyClient;
import com.ruoyi.dataInterchange.util.jtt809.packet.common.OuterPacket;
import com.ruoyi.dataInterchange.wapper.UPConnect;
import com.ruoyi.system.api.feignClient.EnterpriseClient;
import com.ruoyi.system.api.model.Enterprise;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.Random;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
/**
 * @author zhibing.pu
 * @Date 2025/3/4 18:40
 */
@Slf4j
@Component
public class ConnectReqService {
    @Resource
    private EnterpriseClient enterpriseClient;
    /**
     * 主链路登录请求业务逻辑
     *
     * @param ctx
     */
    public void connect(ChannelHandlerContext ctx, OuterPacket outerPacket) {
        ByteBuf byteBuf = Unpooled.wrappedBuffer(outerPacket.getBody());
        //解析封装原元数据
        UPConnectReq upConnectReq = new UPConnectReq().decode(byteBuf);
        Enterprise data = enterpriseClient.getEnterprise(upConnectReq.getUserId() + "").getData();
        UPConnectRsp upConnectRsp = new UPConnectRsp();
        if (null == data) {
            //用户没有注册
            upConnectRsp.setResult(0x03);
        } else {
            //IP地址不对
            if (!upConnectReq.getDownLinkIp().equals(data.getIpWhitelist())) {
                upConnectRsp.setResult(0x01);
            } else if (!data.getPassword().equals(upConnectReq.getPassword())) {
                upConnectRsp.setResult(0x04);
            } else if (outerPacket.getGnsscenterId() != Integer.valueOf(data.getCode())) {
                upConnectRsp.setResult(0x02);
            } else {
                upConnectRsp.setResult(0x00);
            }
        }
        // 随机一个校验码
        int verifyCode = new Random().nextInt(9999);
        upConnectRsp.setVerifyCode(verifyCode);
        //主链路登录应答
        log.info("主链路登录应答({}):{}", DataType.UP_CONNECT_RSP.getCode(), JSON.toJSONString(upConnectRsp));
        byte[] body = upConnectRsp.encode();
        OuterPacket out = new OuterPacket(DataType.UP_CONNECT_RSP.getCode(), body);
        ctx.writeAndFlush(out);
        ctx.flush();
        if (upConnectRsp.getResult() == 0x00) {
            //保存链路
            ChannelMap.addServerChannel(outerPacket.getGnsscenterId(), ctx.channel().id());
            //从链路连接
            downConnect(ctx, outerPacket.getGnsscenterId(), upConnectReq.getDownLinkIp(), upConnectReq.getDownLinkPort(), verifyCode);
        } else {
            ctx.close();
        }
    }
    /**
     * 从链路连接
     *
     * @param inferiorPlatformId 企业唯一标识
     * @param host               连接IP
     * @param port               连接端口
     */
    public void downConnect(ChannelHandlerContext ctx, int inferiorPlatformId, String host, int port, int verifyCode) {
        try {
            boolean b = downConnect(inferiorPlatformId, host, port, verifyCode);
            if (b) {
                downLinkTest(inferiorPlatformId);
            }
        } catch (Exception e) {
            downDisconnectInform(ctx, 0x00);
            throw new RuntimeException(e);
        }
    }
    /**
     * 从链路连接
     *
     * @param inferiorPlatformId 企业唯一标识
     * @param host               连接IP
     * @param port               连接端口
     */
    public boolean downConnect(int inferiorPlatformId, String host, int port, int verifyCode) {
        try {
            new NettyClient(host, port).start(inferiorPlatformId);
            //构建从链路请求
            DOWNConnectReq downConnectReq = new DOWNConnectReq();
            downConnectReq.setVerifyCode(verifyCode);
            //获取从链路通道
            Channel channel = ChannelMap.getClientChannel(inferiorPlatformId);
            if (null != channel && channel.isActive()) {
                log.info("从链路连接请求({}):{}", DataType.DOWN_CONNECT_REQ.getCode(), JSON.toJSONString(downConnectReq));
                byte[] body = downConnectReq.encode();
                OuterPacket out = new OuterPacket(DataType.DOWN_CONNECT_REQ.getCode(), body);
                channel.writeAndFlush(out);
                channel.flush();
                //缓存从链路地址
                UPConnect upConnect = new UPConnect();
                upConnect.setDownLinkIp(host);
                upConnect.setDownLinkPort(port);
                upConnect.setVerifyCode(verifyCode);
                ChannelMap.addIpAndPort(inferiorPlatformId, upConnect);
                return true;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }
    /**
     * 从链路连接保持请求
     *
     * @param inferiorPlatformId
     */
    public void downLinkTest(int inferiorPlatformId) {
        //创建定时任务间隔发送链接保持请求
        ScheduledExecutorService scheduledExecutorService = new ScheduledThreadPoolExecutor(1);
        scheduledExecutorService.scheduleAtFixedRate(new Runnable() {
            @Override
            public void run() {
                //获取从链路通道
                Channel channel = ChannelMap.getClientChannel(inferiorPlatformId);
                if (null != channel && channel.isActive()) {
                    log.info("从链路连接保持请求({}):{}", DataType.DOWN_LINKTEST_REQ.getCode(), "");
                    OuterPacket out = new OuterPacket(DataType.DOWN_LINKTEST_REQ.getCode(), null);
                    channel.writeAndFlush(out);
                    channel.flush();
                } else {
                    //记录失败次数,然后再重新连接
                    int times = ChannelMap.getTimes(inferiorPlatformId);
                    if (times >= 18) {
                        UPConnect ipAndPort = ChannelMap.getIpAndPort(inferiorPlatformId);
                        boolean b = downConnect(inferiorPlatformId, ipAndPort.getDownLinkIp(), ipAndPort.getDownLinkPort(), ipAndPort.getVerifyCode());
                        if (b) {
                            times = 0;
                        } else {
                            times++;
                        }
                    } else {
                        times++;
                    }
                    ChannelMap.saveTimes(inferiorPlatformId, times);
                }
            }
        }, 10, 10, TimeUnit.SECONDS);
    }
    /**
     * 从链路断开通知
     *
     * @param ctx
     * @param errorCode
     */
    public void downDisconnectInform(ChannelHandlerContext ctx, int errorCode) {
        DOWNDisconnectInform downDisconnectInform = new DOWNDisconnectInform();
        downDisconnectInform.setErrorCode(errorCode);
        log.info("从链路断开通知({}):{}", DataType.DOWN_DISCONNECT_INFORM.getCode(), JSON.toJSONString(downDisconnectInform));
        byte[] body = downDisconnectInform.encode();
        OuterPacket out = new OuterPacket(DataType.DOWN_CONNECT_REQ.getCode(), body);
        ctx.writeAndFlush(out);
        ctx.flush();
    }
}
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/server/CtrlMsgService.java
New file
@@ -0,0 +1,74 @@
package com.ruoyi.dataInterchange.server;
import com.ruoyi.dataInterchange.model.CtrlMag;
import com.ruoyi.dataInterchange.model.WarnMsg;
import com.ruoyi.dataInterchange.model.enu.DataType;
import com.ruoyi.dataInterchange.util.jtt809.common.Jtt809Util;
import com.ruoyi.dataInterchange.util.jtt809.packet.common.OuterPacket;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
/**
 * @author zhibing.pu
 * @Date 2025/3/4 20:55
 */
@Slf4j
@Component
public class CtrlMsgService {
    public void up_ctrl_msg(ChannelHandlerContext ctx, OuterPacket out){
        CtrlMag ctrlMsg = getCtrlMsg(out);
        DataType dataType = DataType.getDataType(ctrlMsg.getDataType());
        switch (dataType){
            case UP_CTRL_MSG_MONITOR_VEHICLE_ACK:
                log.info("车辆单向监听应答消息({}):{}", DataType.UP_CTRL_MSG_MONITOR_VEHICLE_ACK.getCode(), out);
                break;
            case UP_CTRL_MSG_TAKE_PHOTO_ACK:
                log.info("车辆牌照应答消息({}):{}", DataType.UP_CTRL_MSG_TAKE_PHOTO_ACK.getCode(), out);
                break;
            case UP_CTRL_MSG_TEXT_INFO_ACK:
                log.info("下发车辆报文应答消息({}):{}", DataType.UP_CTRL_MSG_TEXT_INFO_ACK.getCode(), out);
                break;
            case UP_CTRL_MSG_TAKE_TRAVEL_ACK:
                log.info("上报车辆行驶记录应答消息({}):{}", DataType.UP_CTRL_MSG_TAKE_TRAVEL_ACK.getCode(), out);
                break;
            case UP_CTRL_MSG_EMERGENCY_MONITORING_ACK:
                log.info("车辆应急接入监管平台应答消息({}):{}", DataType.UP_CTRL_MSG_EMERGENCY_MONITORING_ACK.getCode(), out);
                break;
            default:
                break;
        }
    }
    /**
     * 解析子业务数据
     * @param out
     * @return
     */
    public CtrlMag getCtrlMsg(OuterPacket out) {
        byte[] body = out.getBody();
        ByteBuf byteBuf = Unpooled.wrappedBuffer(body);
        //车牌号
        String vehicleNo = Jtt809Util.readGBKString(byteBuf, 21);
        //车牌颜色
        byte vehicleColor = byteBuf.readByte();
        //子业务类型标识
        int dataType = byteBuf.readUnsignedShort();
        //后续数据长度
        int dataLength = byteBuf.readInt();
        //子业务数据包
        byte[] data = new byte[byteBuf.readableBytes()];
        byteBuf.readBytes(data);
        CtrlMag ctrlMag = new CtrlMag();
        ctrlMag.setVehicleNo(vehicleNo);
        ctrlMag.setVehicleColor(vehicleColor);
        ctrlMag.setDataType(dataType);
        ctrlMag.setDataLength(dataLength);
        ctrlMag.setData(data);
        return ctrlMag;
    }
}
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/server/DOWNConnectRspService.java
New file
@@ -0,0 +1,32 @@
package com.ruoyi.dataInterchange.server;
import com.ruoyi.dataInterchange.model.DOWNConnectRsp;import com.ruoyi.dataInterchange.model.UPConnectReq;
import com.ruoyi.dataInterchange.util.jtt809.packet.common.OuterPacket;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
/**
 * 从链路连接应答
 * @author zhibing.pu
 * @Date 2025/3/6 16:11
 */
@Slf4j
@Component
public class DOWNConnectRspService {
    /**
     * 从链路连接应答
     * @param ctx
     * @param outerPacket
     */
    public void connectRsp(ChannelHandlerContext ctx, OuterPacket outerPacket){
        ByteBuf byteBuf = Unpooled.wrappedBuffer(outerPacket.getBody());
        DOWNConnectRsp downConnectRsp = new DOWNConnectRsp().decode(byteBuf);
    }
}
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/server/DOWNTotalRecvBackMsgService.java
New file
@@ -0,0 +1,17 @@
package com.ruoyi.dataInterchange.server;
import org.springframework.stereotype.Service;
/**
 * @author zhibing.pu
 * @Date 2025/3/7 16:00
 */
@Service
public class DOWNTotalRecvBackMsgService {
    public void taskTotalRecvBack() {
        // todo 查询车辆定位信息
    }
}
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/server/ExgMsgService.java
New file
@@ -0,0 +1,261 @@
package com.ruoyi.dataInterchange.server;
import com.alibaba.fastjson.JSON;
import com.ruoyi.dataInterchange.dao.*;
import com.ruoyi.dataInterchange.model.*;
import com.ruoyi.dataInterchange.model.enu.DataType;
import com.ruoyi.dataInterchange.netty.client.ChannelMap;
import com.ruoyi.dataInterchange.util.jtt809.common.Jtt809Util;
import com.ruoyi.dataInterchange.util.jtt809.packet.common.OuterPacket;
import com.ruoyi.dataInterchange.wapper.UPConnect;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.Iterator;
/**
 * @author zhibing.pu
 * @Date 2025/3/4 19:42
 */
@Slf4j
@Service
public class ExgMsgService {
    @Resource
    private ConnectReqService connectReqService;
    @Resource
    private UPExgMsgRegisterDao upExgMsgRegisterDao;
    @Resource
    private UPExgMsgRealLocationDao upExgMsgRealLocationDao;
    @Resource
    private UPExgMsgHistoryLocationDao upExgMsgHistoryLocationDao;
    @Resource
    private UPExgMsgReportDriverInfoAckDao upExgMsgReportDriverInfoAckDao;
    @Resource
    private UPExgMsgTakeEwayBillAckDao upExgMsgTakeEwayBillAckDao;
    public void up_exg_msg(ChannelHandlerContext ctx, OuterPacket out) {
        UPExgMsg exgMsg = getExgMsg(out);
        DataType dataType = DataType.getDataType(exgMsg.getDataType());
        switch (dataType) {
            case UP_EXG_MSG_REGISTER:
                log.info("上传车辆注册信息({}):{}", DataType.UP_EXG_MSG_REGISTER.getCode(), out);
                up_exg_msg_register(ctx, out.getGnsscenterId(), exgMsg);
                break;
            case UP_EXG_MSG_REAL_LOCATION:
                log.info("上传车辆实时定位信息({}):{}", DataType.UP_EXG_MSG_REAL_LOCATION.getCode(), out);
                up_exg_msg_real_location(ctx, out.getGnsscenterId(), exgMsg);
                break;
            case UP_EXG_MSG_HISTORY_LOCATION:
                log.info("车辆定位信息自动补报请求({}):{}", DataType.UP_EXG_MSG_HISTORY_LOCATION.getCode(), out);
                up_exg_msg_history_location(ctx, out.getGnsscenterId(), exgMsg);
                break;
            case UP_EXG_MSG_RETURN_STARTUP_ACK:
                log.info("启动车辆定位信息交换应答({}):{}", DataType.UP_EXG_MSG_RETURN_STARTUP_ACK.getCode(), out);
                break;
            case UP_EXG_MSG_RETURN_END_ACK:
                log.info("结束车辆定位信息交换应答({}):{}", DataType.UP_EXG_MSG_RETURN_END_ACK.getCode(), out);
                break;
            case UP_EXG_MSG_APPLY_FOR_MONITOR_STARTUP:
                log.info("申请交换指定车辆定位信息请求({}):{}", DataType.UP_EXG_MSG_APPLY_FOR_MONITOR_STARTUP.getCode(), out);
                break;
            case UP_EXG_MSG_APPLY_FOR_MONITOR_END:
                log.info("取消交换指定车辆定位信息请求({}):{}", DataType.UP_EXG_MSG_APPLY_FOR_MONITOR_END.getCode(), out);
                break;
            case UP_EXG_MSG_APPLY_HISGNSSDATA_REQ:
                log.info("车辆定位信息补发请求({}):{}", DataType.UP_EXG_MSG_APPLY_HISGNSSDATA_REQ.getCode(), out);
                break;
            case UP_EXG_MSG_REPORT_DRIVER_INFO_ACK:
                log.info("上报驾驶员身份信息应答({}):{}", DataType.UP_EXG_MSG_REPORT_DRIVER_INFO_ACK.getCode(), out);
                up_exg_msg_report_driver_info_ack(ctx, out.getGnsscenterId(), exgMsg);
                break;
            case UP_EXG_MSG_TAKE_EWAYBILL_ACK:
                log.info("上报车辆电子运单应答消息({}):{}", DataType.UP_EXG_MSG_TAKE_EWAYBILL_ACK.getCode(), out);
                up_exg_msg_take_ewaybill_ack(ctx, out.getGnsscenterId(), exgMsg);
                break;
            default:
                break;
        }
    }
    /**
     * 解析子业务数据
     *
     * @param out
     * @return
     */
    public UPExgMsg getExgMsg(OuterPacket out) {
        byte[] body = out.getBody();
        ByteBuf byteBuf = Unpooled.wrappedBuffer(body);
        //车牌号
        String vehicleNo = Jtt809Util.readGBKString(byteBuf, 21);
        //车牌颜色
        byte vehicleColor = byteBuf.readByte();
        //子业务类型标识
        int dataType = byteBuf.readUnsignedShort();
        //后续数据长度
        int dataLength = byteBuf.readInt();
        //子业务数据包
        byte[] data = new byte[byteBuf.readableBytes()];
        byteBuf.readBytes(data);
        UPExgMsg upExgMsg = new UPExgMsg();
        upExgMsg.setVehicleNo(vehicleNo);
        upExgMsg.setVehicleColor(vehicleColor);
        upExgMsg.setDataType(dataType);
        upExgMsg.setDataLength(dataLength);
        upExgMsg.setData(data);
        return upExgMsg;
    }
    /**
     * 上传车辆注册信息
     *
     * @param ctx
     */
    public void up_exg_msg_register(ChannelHandlerContext ctx, int inferiorPlatformId, UPExgMsg exgMsg) {
        UPExgMsgRegister upExgMsgRegister = new UPExgMsgRegister().decode(exgMsg);
        upExgMsgRegister.setInferiorPlatformId(inferiorPlatformId);
        upExgMsgRegister.setCreateTime(LocalDateTime.now());
        upExgMsgRegisterDao.save(upExgMsgRegister);
        //上报驾驶员身份识别信息请求
        down_exg_msg_report_driver_info(ctx, inferiorPlatformId, upExgMsgRegister.getVehicleNo(), upExgMsgRegister.getVehicleColor());
    }
    /**
     * 上报驾驶员身份识别信息请求
     *
     * @param ctx
     */
    public void down_exg_msg_report_driver_info(ChannelHandlerContext ctx, int inferiorPlatformId, String vehicleNo, int VehicleColor) {
        DOWNExgMsgReportDriverInfo downExgMsgReportDriverInfo = new DOWNExgMsgReportDriverInfo();
        downExgMsgReportDriverInfo.setVehicleNo(vehicleNo);
        downExgMsgReportDriverInfo.setVehicleColor(VehicleColor);
        downExgMsgReportDriverInfo.setDataType(DataType.DOWN_EXG_MSG_REPORT_DRIVER_INFO.getCode());
        downExgMsgReportDriverInfo.setDataLength(0);
        log.info("上报驾驶员身份识别信息请求({}):{}", DataType.DOWN_EXG_MSG_REPORT_DRIVER_INFO.getCode(), JSON.toJSONString(downExgMsgReportDriverInfo));
        byte[] body = downExgMsgReportDriverInfo.encode();
        OuterPacket out = new OuterPacket(DataType.DOWN_EXG_MSG_REPORT_DRIVER_INFO.getCode(), body);
        //获取从链路通道
        Channel channel = ChannelMap.getClientChannel(inferiorPlatformId);
        if (null != channel && channel.isActive()) {
            channel.writeAndFlush(out);
            channel.flush();
        } else {
            ctx.writeAndFlush(out);
            ctx.flush();
        }
    }
    /**
     * 上传车辆实时定位信息
     *
     * @param ctx
     */
    public void up_exg_msg_real_location(ChannelHandlerContext ctx, int inferiorPlatformId, UPExgMsg exgMsg) {
        UPExgMsgRealLocation upExgMsgRealLocation = new UPExgMsgRealLocation().decode(exgMsg);
        upExgMsgRealLocation.setInferiorPlatformId(inferiorPlatformId);
        upExgMsgRealLocation.setCreateTime(LocalDateTime.now());
        upExgMsgRealLocationDao.save(upExgMsgRealLocation);
    }
    /**
     * 定时任务获取车辆运单信息
     */
    public void takeEwaybill() {
        Iterator<UPExgMsgRegister> iterator = upExgMsgRegisterDao.findAll().iterator();
        while (iterator.hasNext()) {
            UPExgMsgRegister pojo = iterator.next();
            down_exg_msg_take_ewaybill_req(pojo.getInferiorPlatformId(), pojo.getVehicleNo(), pojo.getVehicleColor());
        }
    }
    /**
     * 上报车辆电子运单请求
     *
     * @param inferiorPlatformId
     */
    public void down_exg_msg_take_ewaybill_req(int inferiorPlatformId, String vehicleNo, int VehicleColor) {
        DOWNExgMsgTakeEwaybillReq downExgMsgTakeEwaybillReq = new DOWNExgMsgTakeEwaybillReq();
        downExgMsgTakeEwaybillReq.setVehicleNo(vehicleNo);
        downExgMsgTakeEwaybillReq.setVehicleColor(VehicleColor);
        downExgMsgTakeEwaybillReq.setDataType(DataType.DOWN_EXG_MSG_REPORT_DRIVER_INFO.getCode());
        downExgMsgTakeEwaybillReq.setDataLength(0);
        log.info("上报车辆电子运单请求({}):{}", DataType.DOWN_EXG_MSG_TAKE_EWAYBILL_REQ.getCode(), JSON.toJSONString(downExgMsgTakeEwaybillReq));
        byte[] body = downExgMsgTakeEwaybillReq.encode();
        OuterPacket out = new OuterPacket(DataType.DOWN_EXG_MSG_TAKE_EWAYBILL_REQ.getCode(), body);
        //获取从链路通道
        Channel channel = ChannelMap.getClientChannel(inferiorPlatformId);
        if (null != channel && channel.isActive()) {
            channel.writeAndFlush(out);
            channel.flush();
        } else {
            //重新连接从链路
            UPConnect ipAndPort = ChannelMap.getIpAndPort(inferiorPlatformId);
            connectReqService.downConnect(inferiorPlatformId, ipAndPort.getDownLinkIp(), ipAndPort.getDownLinkPort(), ipAndPort.getVerifyCode());
        }
    }
    /**
     * 车辆定位信息自动补报请求
     *
     * @param ctx
     * @param inferiorPlatformId
     * @param exgMsg
     */
    public void up_exg_msg_history_location(ChannelHandlerContext ctx, int inferiorPlatformId, UPExgMsg exgMsg) {
        UPExgMsgHistoryLocation upExgMsgHistoryLocation = new UPExgMsgHistoryLocation().decode(exgMsg);
        upExgMsgHistoryLocation.setInferiorPlatformId(inferiorPlatformId);
        upExgMsgHistoryLocation.setCreateTime(LocalDateTime.now());
        upExgMsgHistoryLocationDao.save(upExgMsgHistoryLocation);
    }
    /**
     * 上报驾驶员身份识别信息应答
     *
     * @param ctx
     * @param inferiorPlatformId
     * @param exgMsg
     */
    public void up_exg_msg_report_driver_info_ack(ChannelHandlerContext ctx, int inferiorPlatformId, UPExgMsg exgMsg) {
        UPExgMsgReportDriverInfoAck upExgMsgReportDriverInfoAck = new UPExgMsgReportDriverInfoAck().decode(exgMsg);
        upExgMsgReportDriverInfoAck.setInferiorPlatformId(inferiorPlatformId);
        upExgMsgReportDriverInfoAck.setCreateTime(LocalDateTime.now());
        upExgMsgReportDriverInfoAckDao.save(upExgMsgReportDriverInfoAck);
    }
    /**
     * 上报车辆电子运单应答
     *
     * @param ctx
     * @param inferiorPlatformId
     * @param exgMsg
     */
    public void up_exg_msg_take_ewaybill_ack(ChannelHandlerContext ctx, int inferiorPlatformId, UPExgMsg exgMsg) {
        UPExgMsgTakeEwayBillAck upExgMsgTakeEwayBillAck = new UPExgMsgTakeEwayBillAck().decode(exgMsg);
        upExgMsgTakeEwayBillAck.setInferiorPlatformId(inferiorPlatformId);
        upExgMsgTakeEwayBillAck.setCreateTime(LocalDateTime.now());
        upExgMsgTakeEwayBillAckDao.save(upExgMsgTakeEwayBillAck);
    }
}
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/server/PlatformMsgService.java
New file
@@ -0,0 +1,64 @@
package com.ruoyi.dataInterchange.server;
import com.ruoyi.dataInterchange.model.UPExgMsg;
import com.ruoyi.dataInterchange.model.UPPlatformMsg;
import com.ruoyi.dataInterchange.model.UPPlatformMsgInfoAck;
import com.ruoyi.dataInterchange.model.enu.DataType;
import com.ruoyi.dataInterchange.util.jtt809.common.Jtt809Util;
import com.ruoyi.dataInterchange.util.jtt809.packet.common.OuterPacket;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
/**
 * @author zhibing.pu
 * @Date 2025/3/4 20:41
 */
@Slf4j
@Component
public class PlatformMsgService {
    public void up_platform_msg(ChannelHandlerContext ctx, OuterPacket out){
        UPPlatformMsg platformMsg = getPlatformMsg(out);
        DataType dataType = DataType.getDataType(platformMsg.getDataType());
        switch (dataType){
            case UP_PLATFORM_MSG_POST_QUERY_ACK:
                log.info("平台查岗应答消息({}):{}", DataType.UP_PLATFORM_MSG_POST_QUERY_ACK.getCode(), platformMsg);
                break;
            case UP_PLATFORM_MSG_INFO_ACK:
                log.info("下发平台间报文应答消息({}):{}", DataType.UP_PLATFORM_MSG_INFO_ACK.getCode(), platformMsg);
                break;
            case UP_PLATFORM_MSG_RETRAN_REQ:
                log.info("上传平台间消息补传请求({}):{}", DataType.UP_PLATFORM_MSG_RETRAN_REQ.getCode(), platformMsg);
                break;
            default:
                break;
        }
    }
    /**
     * 解析子业务数据
     * @param out
     * @return
     */
    public UPPlatformMsg getPlatformMsg(OuterPacket out) {
        byte[] body = out.getBody();
        ByteBuf byteBuf = Unpooled.wrappedBuffer(body);
        //子业务类型标识
        int dataType = byteBuf.readShort();
        //后续数据长度
        int dataLength = byteBuf.readInt();
        //子业务数据包
        byte[] data = new byte[byteBuf.readableBytes()];
        byteBuf.readBytes(data);
        UPPlatformMsg platformMsg = new UPPlatformMsg();
        platformMsg.setDataType(dataType);
        platformMsg.setDataLength(dataLength);
        platformMsg.setData(data);
        return platformMsg;
    }
}
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/server/UPCloseLinkInformService.java
New file
@@ -0,0 +1,30 @@
package com.ruoyi.dataInterchange.server;
import com.ruoyi.dataInterchange.model.UPCloseLinkInform;import com.ruoyi.dataInterchange.model.UPDisconnectInform;
import com.ruoyi.dataInterchange.util.jtt809.packet.common.OuterPacket;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
/**
 * @author zhibing.pu
 * @Date 2025/3/6 16:02
 */
@Slf4j
@Component
public class UPCloseLinkInformService {
    /**
     * 下级平台主动关闭主从链路通知
     * @param ctx
     * @param out
     */
    public void closeLinkInform(ChannelHandlerContext ctx, OuterPacket out){
        ByteBuf byteBuf = Unpooled.wrappedBuffer(out.getBody());
        UPCloseLinkInform upCloseLinkInform = new UPCloseLinkInform().decode(byteBuf);
    }
}
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/server/UPDisconnectInformService.java
New file
@@ -0,0 +1,28 @@
package com.ruoyi.dataInterchange.server;
import com.ruoyi.dataInterchange.model.UPDisconnectInform;
import com.ruoyi.dataInterchange.model.UPDisconnectReq;
import com.ruoyi.dataInterchange.util.jtt809.packet.common.OuterPacket;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component; /**
 * @author zhibing.pu
 * @Date 2025/3/6 15:55
 */
@Slf4j
@Component
public class UPDisconnectInformService {
    /**
     * 主链路断开通知
     * @param ctx
     * @param out
     */
    public void disconnect(ChannelHandlerContext ctx, OuterPacket out){
        ByteBuf byteBuf = Unpooled.wrappedBuffer(out.getBody());
        UPDisconnectInform upDisconnectInform = new UPDisconnectInform().decode(byteBuf);
    }
}
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/server/UPDisconnectReqService.java
New file
@@ -0,0 +1,52 @@
package com.ruoyi.dataInterchange.server;
import com.alibaba.fastjson.JSON;
import com.ruoyi.dataInterchange.model.UPDisconnectReq;
import com.ruoyi.dataInterchange.model.enu.DataType;
import com.ruoyi.dataInterchange.netty.client.ChannelMap;
import com.ruoyi.dataInterchange.util.jtt809.packet.common.OuterPacket;
import com.ruoyi.system.api.feignClient.EnterpriseClient;
import com.ruoyi.system.api.model.Enterprise;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
/**
 * @author zhibing.pu
 * @Date 2025/3/6 15:34
 */
@Slf4j
@Component
public class UPDisconnectReqService {
    @Resource
    private EnterpriseClient enterpriseClient;
    /**
     * 主链路注销
     * @param ctx
     * @param out
     */
    public void disconnect(ChannelHandlerContext ctx, OuterPacket out){
        ByteBuf byteBuf = Unpooled.wrappedBuffer(out.getBody());
        UPDisconnectReq disconnectReq = new UPDisconnectReq().decode(byteBuf);
        Enterprise data = enterpriseClient.getEnterprise(disconnectReq.getUserId() + "").getData();
        if(null != data){
            if(!data.getPassword().equals(disconnectReq.getPassword())){
                ctx.close();
                return;
            }
            OuterPacket rep = new OuterPacket(DataType.UP_DISCONNECT_RSP.getCode(), null);
            log.info("主链路注销应答({}):{}", DataType.UP_DISCONNECT_RSP.getCode(), JSON.toJSONString(rep));
            ctx.writeAndFlush(rep);
            ctx.flush();
        }
    }
}
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/server/UPLinkTestReqService.java
New file
@@ -0,0 +1,34 @@
package com.ruoyi.dataInterchange.server;
import com.alibaba.fastjson.JSON;
import com.ruoyi.dataInterchange.model.enu.DataType;
import com.ruoyi.dataInterchange.netty.client.ChannelMap;
import com.ruoyi.dataInterchange.util.jtt809.packet.common.OuterPacket;
import io.netty.channel.ChannelHandlerContext;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
/**
 * @author zhibing.pu
 * @Date 2025/3/6 15:46
 */
@Slf4j
@Component
public class UPLinkTestReqService {
    /**
     * 住链路连接保持
     * @param ctx
     * @param out
     */
    public void linkTest(ChannelHandlerContext ctx, OuterPacket out){
        int gnsscenterId = out.getGnsscenterId();
        ChannelMap.addServerChannel(gnsscenterId, ctx.channel().id());
        OuterPacket rep = new OuterPacket(DataType.UP_LINKTEST_RSP.getCode(), null);
        log.info("住链路连接保持应答({}):{}", DataType.UP_LINKTEST_RSP.getCode(), JSON.toJSONString(rep));
        ctx.writeAndFlush(rep);
        ctx.flush();
    }
}
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/server/WarnMsgService.java
New file
@@ -0,0 +1,167 @@
package com.ruoyi.dataInterchange.server;
import com.alibaba.fastjson.JSON;
import com.ruoyi.dataInterchange.dao.UPWarnMsgAdptInfoDao;
import com.ruoyi.dataInterchange.dao.UPWarnMsgUrgeTodoAckDao;
import com.ruoyi.dataInterchange.model.DOWNWarnMsgUrgeTodoReq;
import com.ruoyi.dataInterchange.model.UPWarnMsgAdptInfo;
import com.ruoyi.dataInterchange.model.UPWarnMsgUrgeTodoAck;
import com.ruoyi.dataInterchange.model.WarnMsg;
import com.ruoyi.dataInterchange.model.enu.DataType;
import com.ruoyi.dataInterchange.netty.client.ChannelMap;
import com.ruoyi.dataInterchange.util.jtt809.common.Jtt809Util;
import com.ruoyi.dataInterchange.util.jtt809.packet.common.OuterPacket;
import com.ruoyi.dataInterchange.wapper.UPConnect;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
/**
 * @author zhibing.pu
 * @Date 2025/3/4 20:45
 */
@Slf4j
@Component
public class WarnMsgService {
    @Resource
    private ConnectReqService connectReqService;
    @Resource
    private UPWarnMsgUrgeTodoAckDao upWarnMsgUrgeTodoAckDao;
    @Resource
    private UPWarnMsgAdptInfoDao upWarnMsgAdptInfoDao;
    public void up_warn_msg(ChannelHandlerContext ctx, OuterPacket out) {
        WarnMsg warnMsg = getWarnMsg(out);
        DataType dataType = DataType.getDataType(warnMsg.getDataType());
        switch (dataType) {
            case UP_WARN_MSG_URGE_TODO_ACK:
                log.info("报警督办应答消息({}):{}", DataType.UP_WARN_MSG_URGE_TODO_ACK.getCode(), out);
                up_warn_msg_urge_todo_ack(ctx, out.getGnsscenterId(), warnMsg);
                break;
            case UP_WARN_MSG_ADPT_INFO:
                log.info("上报报警信息({}):{}", DataType.UP_WARN_MSG_ADPT_INFO.getCode(), out);
                up_warn_msg_adpt_info(ctx, out.getGnsscenterId(), warnMsg);
                break;
            case UP_CTRL_MSG_MONITOR_VEHICLE_ACK:
                log.info("车辆单向监听应答消息({}):{}", DataType.UP_CTRL_MSG_MONITOR_VEHICLE_ACK.getCode(), out);
                break;
            case UP_CTRL_MSG_TAKE_PHOTO_ACK:
                log.info("车辆牌照应答消息({}):{}", DataType.UP_CTRL_MSG_TAKE_PHOTO_ACK.getCode(), out);
                break;
            case UP_CTRL_MSG_TEXT_INFO_ACK:
                log.info("下发车辆报文应答消息({}):{}", DataType.UP_CTRL_MSG_TEXT_INFO_ACK.getCode(), out);
                break;
            case UP_CTRL_MSG_EMERGENCY_MONITORING_ACK:
                log.info("车辆应急接入监管平台应答消息({}):{}", DataType.UP_CTRL_MSG_EMERGENCY_MONITORING_ACK.getCode(), out);
                break;
            default:
                break;
        }
    }
    /**
     * 解析子业务数据
     *
     * @param out
     * @return
     */
    public WarnMsg getWarnMsg(OuterPacket out) {
        byte[] body = out.getBody();
        ByteBuf byteBuf = Unpooled.wrappedBuffer(body);
        //车牌号
        String vehicleNo = Jtt809Util.readGBKString(byteBuf, 21);
        //车牌颜色
        byte vehicleColor = byteBuf.readByte();
        //子业务类型标识
        int dataType = byteBuf.readUnsignedShort();
        //后续数据长度
        int dataLength = byteBuf.readInt();
        //子业务数据包
        byte[] data = new byte[byteBuf.readableBytes()];
        byteBuf.readBytes(data);
        WarnMsg warnMsg = new WarnMsg();
        warnMsg.setVehicleNo(vehicleNo);
        warnMsg.setVehicleColor(vehicleColor);
        warnMsg.setDataType(dataType);
        warnMsg.setDataLength(dataLength);
        warnMsg.setData(data);
        return warnMsg;
    }
    /**
     * 报警督办应答消息
     *
     * @param ctx
     * @param inferiorPlatformId
     * @param warnMsg
     */
    public void up_warn_msg_urge_todo_ack(ChannelHandlerContext ctx, int inferiorPlatformId, WarnMsg warnMsg) {
        UPWarnMsgUrgeTodoAck upWarnMsgUrgeTodoAck = new UPWarnMsgUrgeTodoAck().decode(warnMsg);
        upWarnMsgUrgeTodoAck.setInferiorPlatformId(inferiorPlatformId);
        upWarnMsgUrgeTodoAck.setCreateTime(LocalDateTime.now());
        upWarnMsgUrgeTodoAckDao.save(upWarnMsgUrgeTodoAck);
    }
    /**
     * 上报报警信息
     *
     * @param ctx
     * @param inferiorPlatformId
     * @param warnMsg
     */
    public void up_warn_msg_adpt_info(ChannelHandlerContext ctx, int inferiorPlatformId, WarnMsg warnMsg) {
        UPWarnMsgAdptInfo upWarnMsgAdptInfo = new UPWarnMsgAdptInfo().decode(warnMsg);
        upWarnMsgAdptInfo.setInferiorPlatformId(inferiorPlatformId);
        upWarnMsgAdptInfo.setCreateTime(LocalDateTime.now());
        upWarnMsgAdptInfoDao.save(upWarnMsgAdptInfo);
    }
    /**
     * 定时任务督办报警请求
     */
    public void taskUrgeTodo() {
        upWarnMsgAdptInfoDao.findAll()
        List<UPWarnMsgAdptInfo> list = new ArrayList<>();
        for (UPWarnMsgAdptInfo upWarnMsgAdptInfo : list) {
            down_warn_msg_urge_todo_req(upWarnMsgAdptInfo);
        }
    }
    /**
     * 报警督办请求
     */
    public void down_warn_msg_urge_todo_req(UPWarnMsgAdptInfo upWarnMsgAdptInfo) {
        int inferiorPlatformId = upWarnMsgAdptInfo.getInferiorPlatformId();
        DOWNWarnMsgUrgeTodoReq downWarnMsgUrgeTodoReq = new DOWNWarnMsgUrgeTodoReq().build(upWarnMsgAdptInfo);
        log.info("报警督办请求({}):{}", DataType.DOWN_WARN_MSG_URGE_TODO_REQ.getCode(), JSON.toJSONString(downWarnMsgUrgeTodoReq));
        byte[] body = downWarnMsgUrgeTodoReq.encode();
        OuterPacket out = new OuterPacket(DataType.DOWN_WARN_MSG_URGE_TODO_REQ.getCode(), body);
        //获取从链路通道
        Channel channel = ChannelMap.getClientChannel(inferiorPlatformId);
        if (null != channel && channel.isActive()) {
            channel.writeAndFlush(out);
            channel.flush();
        } else {
            //重新连接从链路
            UPConnect ipAndPort = ChannelMap.getIpAndPort(inferiorPlatformId);
            connectReqService.downConnect(inferiorPlatformId, ipAndPort.getDownLinkIp(), ipAndPort.getDownLinkPort(), ipAndPort.getVerifyCode());
        }
    }
}
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/util/EncryptUtil.java
File was deleted
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/util/TaskUtil.java
New file
@@ -0,0 +1,54 @@
package com.ruoyi.dataInterchange.util;
import com.ruoyi.dataInterchange.server.DOWNTotalRecvBackMsgService;
import com.ruoyi.dataInterchange.server.ExgMsgService;
import com.ruoyi.dataInterchange.server.WarnMsgService;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
/**
 * @author zhibing.pu
 * @Date 2025/3/6 19:39
 */
@Component
public class TaskUtil {
    @Resource
    private ExgMsgService exgMsgService;
    @Resource
    private WarnMsgService warnMsgService;
    @Resource
    private DOWNTotalRecvBackMsgService downTotalRecvBackMsgService;
    /**
     * 接收车辆定位信息数据通知消息
     */
    @Scheduled(fixedRate = 1000 * 60)
    public void taskTotalRecvBack() {
        downTotalRecvBackMsgService.taskTotalRecvBack();
    }
    /**
     * 定时任务获取电子运单信息
     */
    @Scheduled(fixedRate = 1000 * 60)
    public void takeEwaybill() {
        exgMsgService.takeEwaybill();
    }
    /**
     * 报警督办请求
     */
    @Scheduled(fixedRate = 1000 * 60)
    public void taskUrgeTodo() {
        warnMsgService.taskUrgeTodo();
    }
}
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/util/jtt809/common/ByteArrayUtil.java
New file
@@ -0,0 +1,343 @@
package com.ruoyi.dataInterchange.util.jtt809.common;
import java.nio.charset.Charset;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
 * @author choice
 * @description:
 * @date 2018-12-27 17:27
 *
 */
public class ByteArrayUtil {
    /**
     * byte数组拼接
     * @param first
     * @param back
     * @return
     */
    public static byte[] append(byte[] first, byte[] back) {
        if(null == first || null == back){
            return null;
        }
        int length = first.length + back.length;
        byte[] res = new byte[length];
        System.arraycopy(first, 0, res, 0, first.length);
        System.arraycopy(back, 0, res, first.length, back.length);
        return res;
    }
    /**
     * sub byte
     * @param data
     * @param off
     * @param length
     * @return
     */
    public static byte[] subBytes(byte[] data,int off,int length){
        byte[] res = new byte[length];
        System.arraycopy(data, off, res, 0, length);
        return res;
    }
    /**
     * short转换为byte[]
     * @param number
     * @return byte[]
     */
    public static byte[] short2Bytes(short number) {
        byte[] b = new byte[2];
        b[0] = (byte) (number >> 8);
        b[1] = (byte) (number & 0xFF);
        return b;
    }
    /**
     * byte[]转换为short
     * @param bytes
     * @return short
     */
    public static short bytes2Short(byte[] bytes){
        short z = (short)((bytes[0] << 8) | (bytes[1] & 0xFF));
        return z;
    }
    /**
     * byte to int
     *
     * @param data
     * @return
     */
    public static int bytes2int(byte[] data) {
        int mask = 0xff;
        int temp = 0;
        int n = 0;
        for (int i = 0; i < data.length; i++) {
            n <<= 8;
            temp = data[i] & mask;
            n |= temp;
        }
        return n;
    }
    /**
     * int to bytes
     *
     * @param n
     * @return
     */
    public static byte[] int2bytes(int n) {
        byte[] b = new byte[4];
        for (int i = 0; i < 4; i++) {
            b[i] = (byte) (n >> (24 - i * 8));
        }
        return b;
    }
    /**
     * byte[] 转换为 GBK 编码的 字符串
     * @param byteArray
     * @return
     */
    public static String bytes2gbkString(byte[] byteArray) {
        return bytes2string(byteArray,"GBK");
    }
    /**
     * byte[] 转换为 string
     * @param byteArray
     * @param charset
     * @return
     */
    public static String bytes2string(byte[] byteArray, String charset) {
        if (byteArray.length == 0) {
            return "";
        }
        return new String(byteArray, Charset.forName(charset));
    }
    /**
     * byte[] 转换为 string
     * @param byteArray
     * @return
     */
    public static String bytes2string(byte[] byteArray) {
        if (byteArray.length == 0) {
            return "";
        }
        return new String(byteArray, Charset.defaultCharset());
    }
    /**
     * byte[] to float
     * @param floatArray
     * @return
     */
    public static float bytes2float(byte[] floatArray){
        int accum = 0;
        for(int i = 0,j = 0; i < floatArray.length; i ++){
            accum = accum|(floatArray[i] & 0xff) << j;
            j += 8;
        }
        return Float.intBitsToFloat(accum);
    }
    /**
     * byte[] to double
     * @param doubleArray
     * @return
     */
    public static double bytes2double(byte[] doubleArray) {
        long value = 0;
        for (int i = 0; i < doubleArray.length; i++) {
            value |= ((long) (doubleArray[i] & 0xff)) << (8 * i);
        }
        return Double.longBitsToDouble(value);
    }
    /**
     * 数组转换成十六进制字符串
     * @param array
     * @return HexString
     */
    public static String bytes2HexStr(byte[] array) {
        StringBuffer sb = new StringBuffer(array.length);
        String sTemp;
        for (int i = 0; i < array.length; i++) {
            sTemp = Integer.toHexString(0xFF & array[i]);
            if (sTemp.length() < 2){
                sb.append(0);
            }
            sb.append(sTemp.toUpperCase());
        }
        return sb.toString();
    }
    /**
     * 数组转换成带0x的十六进制字符串
     * @param array
     * @return HexString
     */
    public static String bytes2FullHexStr(byte[] array) {
        StringBuffer sb = new StringBuffer(array.length);
        sb.append("0x");
        String sTemp;
        for (int i = 0; i < array.length; i++) {
            sTemp = Integer.toHexString(0xFF & array[i]);
            if (sTemp.length() < 2){
                sb.append(0);
            }
            sb.append(sTemp);
            if(i < array.length-1){
                sb.append("0x");
            }
        }
        return sb.toString().toLowerCase();
    }
    /**
     * short to 16进制字符串
     * @param num
     * @return
     */
    public static String short2HexStr(short num){
        return Integer.toHexString(num);
    }
    /**
     * 把16进制字符串转换成字节数组
     * @param hex
     * @return byte[]
     */
    public static byte[] hexStr2Bytes(String hex) {
        int len = (hex.length() / 2);
        byte[] result = new byte[len];
        char[] achar = hex.toCharArray();
        for (int i = 0; i < len; i++) {
            int pos = i * 2;
            result[i] = (byte) (toByte(achar[pos]) << 4 | toByte(achar[pos + 1]));
        }
        return result;
    }
    /**
     * 把带0x的16进制字符串转换成字节数组
     * @param hex
     * @return byte[]
     */
    public static byte[] fullHexStr2Bytes(String hex){
        hex = hex.toLowerCase().replaceAll("0x","").trim().toUpperCase();
        return hexStr2Bytes(hex);
    }
    private static int toByte(char c) {
        byte b = (byte) "0123456789ABCDEF".indexOf(c);
        return b;
    }
    /**
     * byte数组转时间字符串 格式 yyMMddHHmmss
     * @return
     */
    public static String bytes2timeStr(byte[] array){
        StringBuilder stringBuilder = new StringBuilder();
        for(int i = 0; i < array.length; i ++){
            int timeUnit = byte2UnsignedInt(array[i]);
            if(timeUnit < 10){
                stringBuilder.append(0);
            }
            stringBuilder.append(timeUnit);
        }
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        return  sdf.format(new Date()).substring(0,2) + stringBuilder.toString();
    }
    /**
     * byte转无符号整数
     * @param value
     * @return
     */
    public static int byte2UnsignedInt(byte value) {
        return Byte.toUnsignedInt(value);
    }
    /**
     *
     *
     * @描述 将一个long转换成8位的byte[]
     * @param num
     *     long值
     * @return
     * 长度是8的byte[]
     * @throws Exception
     */
    public static byte[] longToBytes(long num) {
        byte[] b = new byte[8];
        for (int i = 0; i < 8; i++) {
            b[i] = (byte) (num >>> (56 - i * 8));
        }
        return b;
    }
    /**
     *
     *
     * @描述 将一个数组转换成一个long值
     * @param b
     *  长度是8的byte[]
     * @return
     *     long值
     * @throws Exception
     */
    public static long bytesToLong(byte[] b) {
        int mask = 0xff;
        long temp = 0;
        long res = 0;
        for (int i = 0; i < 8; i++) {
            res <<= 8;
            temp = b[i] & mask;
            res |= temp;
        }
        return res;
    }
    /**
     *  将一个byte数组转换成二进制字符串
     * @param bytes
     * @return 二进制字符串
     */
    public static String bytes2bitStr(byte[] bytes){
        StringBuilder stringBuilder = new StringBuilder();
        for (byte b : bytes) {
            stringBuilder.append(byte2bitStr(b));
        }
        return stringBuilder.toString();
    }
    /**
     *  将一个byte转换成二进制字符串
     * @param b
     * @return 二进制字符串
     */
    public static String byte2bitStr(byte b) {
        return "" + (byte) ((b >> 7) & 0x1) + (byte) ((b >> 6) & 0x1)
                + (byte) ((b >> 5) & 0x1) + (byte) ((b >> 4) & 0x1)
                + (byte) ((b >> 3) & 0x1) + (byte) ((b >> 2) & 0x1)
                + (byte) ((b >> 1) & 0x1) + (byte) ((b >> 0) & 0x1);
    }
}
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/util/jtt809/common/CRC16CCITT.java
New file
@@ -0,0 +1,29 @@
package com.ruoyi.dataInterchange.util.jtt809.common;
/**
 * @author tucke
 */
public class CRC16CCITT {
    public static int crc16(byte[] bytes){
        int crc = 0xFFFF;
        for (byte aByte : bytes) {
            crc = ((crc >>> 8) | (crc << 8)) & 0xFFFF;
            // byte to int, trunc sign
            crc ^= (aByte & 0xFF);
            crc ^= ((crc & 0xFF) >> 4);
            crc ^= (crc << 12) & 0xFFFF;
            crc ^= ((crc & 0xFF) << 5) & 0xFFFF;
        }
        crc &= 0xFFFF;
        return crc;
    }
    public static void main(String[] args) {
        String hex = "000000480000096C1001010A66F801000100000000000000149A35394A484E7379313130312E3230362E3231312E3635000000000000000000000000000000000000000107";
        byte[] bytes = ByteArrayUtil.hexStr2Bytes(hex);
        int i = crc16(bytes);
        System.err.println(i);
    }
}
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/util/jtt809/common/Jtt809Constant.java
New file
@@ -0,0 +1,343 @@
package com.ruoyi.dataInterchange.util.jtt809.common;
import io.netty.util.AttributeKey;
/**
 * @author tucke
 */
public class Jtt809Constant {
    public static final String SERVER_NAME = "JT/T 809";
    public static final byte PACKET_HEAD_FLAG = 0x5B;
    public static final byte PACKET_END_FLAG = 0x5D;
    public static final class NettyAttribute {
        public static final AttributeKey<String> GNSS_CENTER_ID = AttributeKey.valueOf("GNSS_CENTER_ID");
    }
    /**
     * 业务数据类型标识
     * <p>
     * a) 上级平台向下级平台发送的请求消息,一般以 DOWN_ 开头,以后缀 _REQ 结尾;而下级平台向上级平台发送的请求消息一般以 UP_ 开头,以后缀 _REQ 结尾;
     * b) 当上下级平台之间有应答消息情况下,应答消息可继续沿用对应的请求消息开头标识符,而通过后缀 RSP 来标识结尾。
     */
    @SuppressWarnings({"SpellCheckingInspection", "unused"})
    public static class DataType {
        /**
         * 主链路登录请求消息
         */
        public final static int UP_CONNECT_REQ = 0x1001;
        /**
         * 主链路登录应答消息
         */
        public final static int UP_CONNECT_RSP = 0x1002;
        /**
         * 主链路注销请求消息
         */
        public final static int UP_DICONNECE_REQ = 0x1003;
        /**
         * 主链路注销应答消息
         */
        public final static int UP_DISCONNECT_RSP = 0x1004;
        /**
         * 主链路连接保持请求消息
         */
        public final static int UP_LINKTEST_REQ = 0x1005;
        /**
         * 主链路连接保持应答消息
         */
        public final static int UP_LINKTEST_RSP = 0x1006;
        /**
         * 主链路断开通知
         */
        public final static int UP_DISCONNECT_INFORM = 0x1007;
        /**
         * 下级平台主动关闭从链路通知
         */
        public final static int UP_CLOSELINK_INFORM = 0x1008;
        /**
         * 主链路登录请求消息
         */
        public final static int DOWN_CONNECT_REQ = 0x9001;
        /**
         * 从链路登录应答消息
         */
        public final static int DOWN_CONNECT_RSP = 0x9002;
        /**
         * 从链路注销请求消息
         */
        public final static int DOWN_DISCONNECT_REQ = 0x9003;
        /**
         * 从链路注销应答消息
         */
        public final static int DOWN_DISCONNECT_RSP = 0x9004;
        /**
         * 从链路连接保持请求消息
         */
        public final static int DOWN_LINKTEST_REQ = 0x9005;
        /**
         * 从链路连接保持应答消息
         */
        public final static int DOWN_LINKTEST_RSP = 0x9006;
        /**
         * 从链路链路断开通知
         */
        public final static int DOWN_DISCONNECT_INFORM = 0x9007;
        /**
         * 上级平台主动关闭从链路通知
         */
        public final static int DOWN_CLOSELINK_INFORM = 0x9008;
        /**
         * 接受定位信息数量通知
         */
        public final static int DOWN_TOTAL_RECV_BACK_MSG = 0x9101;
        /**
         * 主链路动态信息交换消息
         */
        public final static int UP_EXG_MSG = 0x1200;
        /**
         * 从链路动态信息交换
         */
        public final static int DOWN_EXG_MSG = 0x9200;
        /**
         * 主链路平台间信息交互
         */
        public final static int UP_PLATFORM_MSG = 0x1300;
        /**
         * 从链路平台间信息交互
         */
        public final static int DOWN_PLATFORM_MSG = 0x9300;
        /**
         * 主链路报警信息交互
         */
        public final static int UP_WARN_MSG = 0x1400;
        /**
         * 从链路报警信息交互
         */
        public final static int DOWN_WARN_MSG = 0x9400;
        /**
         * 主链路车辆监管消息
         */
        public final static int UP_CTRL_MSG = 0x1500;
        /**
         * 从链路车辆监管消息
         */
        public final static int DOWN_CTRL_MSG = 0x9500;
        /**
         * 主链路静态信息交换
         */
        public final static int UP_BASE_MSG = 0x1600;
        /**
         * 从链路静态信息交换
         */
        public final static int DOWN_BASE_MSG = 0x9600;
    }
    /**
     * 子业务类型标识
     * <p>
     * a) 对应于业务数据类型下的子业务标识头继续遵循原有归属业务数据类型的标识头,例如业务数据类型 UP_EXG_MSG 下的子业务类型标识头均以 UP_EXG_MSG 开始;
     * b) 子业务类型名称标识的主从链路方向遵循原有归属业务数据类型的主从链路方向。
     */
    @SuppressWarnings({"SpellCheckingInspection", "unused"})
    public static class SubDataType {
        /**
         * 上传车辆注册信息
         */
        public final static int UP_EXG_MSG_REGISTER = 0x1201;
        /**
         * 实时上传车辆定位信息
         */
        public final static int UP_EXG_MSG_REAL_LOCATION = 0x1202;
        /**
         * 车辆定位信息自动补报
         */
        public final static int UP_EXG_MSG_HISTORY_LOCATION = 0x1203;
        /**
         * 启动车辆定位信息交换应答
         */
        public final static int UP_EXG_MSG_RETURE_STARTUP_ACK = 0x1205;
        /**
         * 结束车辆定位信息交换应答
         */
        public final static int UP_EXG_MSG_RETURE_END_ACK = 0x1206;
        /**
         * 申请交换指定车辆定位信息请求
         */
        public final static int UP_EXG_MSG_APPLE_FOR_MONITOR_STAR_TUP = 0x1207;
        /**
         * 取消交换制定车辆定位信息请求
         */
        public final static int UP_EXG_MSG_APPLE_FOR_MONITOR_END = 0x1208;
        /**
         * 补发车辆定位信息请求
         */
        public final static int UP_EXG_MSG_APPLE_HISGNSSDATA_REQ = 0x1209;
        /**
         * 上报车辆驾驶员身份识别信息应答
         */
        public final static int UP_EXG_MSG_REPORT_DRIVER_INFO_ACK = 0x120A;
        /**
         * 上报车辆电子运单应答
         */
        public final static int UP_EXG_MSG_TAKE_EWAYBILL_ACK = 0x120B;
        /**
         * 车辆定位信息交换
         */
        public final static int DOWN_EXG_MSG_CAR_LOCATION = 0x9202;
        /**
         * 车辆定位信息交换补发
         */
        public final static int DOWN_EXG_MSG_HISTORY_ARCOSSAREL = 0x9203;
        /**
         * 车辆静态信息交换
         */
        public final static int DOWN_EXG_MSG_CAR_INFO = 0x9204;
        /**
         * 启动车辆定位信息交换请求
         */
        public final static int DOWN_EXG_MSG_RETURN_STARTUP = 0x9205;
        /**
         * 关闭车辆定位信息交换请求
         */
        public final static int DOWN_EXG_MSG_RETURN_END = 0x9206;
        /**
         * 申请交换制定车辆定位信息
         */
        public final static int DOWN_EXG_MSG_APPLY_FOR_MONITOR_STARTUP_ACK = 0x9207;
        /**
         * 取消交换制定车辆定位信息
         */
        public final static int DOWN_EXG_MSG_APPLY_FOR_MONITOR_END_ACK = 0x9208;
        /**
         * 补发车辆定位信息应答
         */
        public final static int DOWN_EXG_MSG_APPLY_HISGNSSDATA_ACK = 0x9209;
        /**
         * 上报车辆驾驶员身份识别信息请求
         */
        public final static int DOWN_EXG_MSG_REPORT_DRIVER_INFO = 0x920A;
        /**
         * 上报车辆电子运单请求
         */
        public final static int DOWN_EXG_MSG_TAKE_EWAYBILL_REQ = 0x920B;
        /**
         * 平台查岗应答
         */
        public final static int UP_PLATFORM_MSG_POST_QUERY_ACK = 0x1301;
        /**
         * 下发平台间报文应答
         */
        public final static int UP_PLATFORM_MSG_INFO_ACK = 0x1302;
        /**
         * 平台查岗应答
         */
        public final static int DOWN_PLATFORM_MSG_POST_QUERY_REQ = 0x9301;
        /**
         * 下发平台间报文应答
         */
        public final static int DOWN_PLATFORM_MSG_INFO_REQ = 0x9302;
        /**
         * 报警督办应答
         */
        public final static int UP_WARN_MSG_URGE_TODO_ACK = 0x1401;
        /**
         * 上报报警信息
         */
        public final static int UP_WARN_MSG_ADPT_INFO = 0x1402;
        /**
         * 报警督办请求
         */
        public final static int DOWN_WARN_MSG_URGE_TODO_REQ = 0x9401;
        /**
         * 报警预警
         */
        public final static int DOWN_WARN_MSG_INFORM_TIPS = 0x9402;
        /**
         * 实时交换报警信息
         */
        public final static int DOWN_WARN_MSG_EXG_INFORM = 0x9403;
        /**
         * 车辆单向监听应答
         */
        public final static int UP_CTRL_MSG_MONITOR_VEHICLE_ACK = 0x1501;
        /**
         * 车辆牌照应答
         */
        public final static int UP_CTRL_MSG_TAKE_PHOTO_ACK = 0x1502;
        /**
         * 下发车辆报文应答
         */
        public final static int UP_CTRL_MSG_TEXT_INFO_ACK = 0x1503;
        /**
         * 上报车辆形式记录应答
         */
        public final static int UP_CTRL_MSG_TAKE_TRAVEL_ACK = 0x1504;
        /**
         * 车辆应急接入监管平台应答
         */
        public final static int UP_CTRL_MSG_EMERGENCY_MONITORING_ACK = 0x1505;
        /**
         * 车辆单向监听请求
         */
        public final static int DOWN_CTRL_MSG_MONITOR_VEHICLE_REQ = 0x9501;
        /**
         * 车辆牌照请求
         */
        public final static int DOWN_CTRL_MSG_TAKE_PHOTO_REQ = 0x9502;
        /**
         * 下发车辆报文请求
         */
        public final static int DOWN_CTRL_MSG_TEXT_INFO_REQ = 0x9503;
        /**
         * 上报车辆形式记录请求
         */
        public final static int DOWN_CTRL_MSG_TAKE_TRAVEL_REQ = 0x9504;
        /**
         * 车辆应急接入监管平台请求
         */
        public final static int UP_CTRL_MSG_EMERGENCY_MONITORING_REQ = 0x9505;
        /**
         * 补报车辆静态信息应答
         */
        public final static int UP_BASE_MSG_VEHICLE_ADDED_ACK = 0x1601;
        /**
         * 补报车辆静态信息请求
         */
        public final static int DOWN_BASE_MSG_VEHICLE_ADDED = 0x9601;
    }
}
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/util/jtt809/common/Jtt809Util.java
New file
@@ -0,0 +1,177 @@
package com.ruoyi.dataInterchange.util.jtt809.common;
import io.netty.buffer.ByteBuf;
import lombok.extern.slf4j.Slf4j;
import java.nio.charset.Charset;
import java.util.Arrays;
/**
 * @author tucke
 */
@Slf4j
public class Jtt809Util {
    /**
     * 0x5B, 0x5A, 0x5D, 0x5E 转义处理
     */
    public static byte[] escape(byte[] bytes) {
        // 最极端情况,每个byte都需要转义,所以使用2倍长度
        byte[] result = new byte[bytes.length * 2];
        int i = 0;
        for (byte b : bytes) {
            switch (b) {
                case 0x5B:
                    result[i++] = 0x5A;
                    result[i++] = 0x01;
                    break;
                case 0x5A:
                    result[i++] = 0x5A;
                    result[i++] = 0x02;
                    break;
                case 0x5D:
                    result[i++] = 0x5E;
                    result[i++] = 0x01;
                    break;
                case 0x5E:
                    result[i++] = 0x5E;
                    result[i++] = 0x02;
                    break;
                default:
                    result[i++] = b;
            }
        }
        // 截取转义后的数据并返回
        return Arrays.copyOf(result, i);
    }
    /**
     * 0x5B, 0x5A, 0x5D, 0x5E 反转义处理
     */
    public static byte[] unescape(byte[] bytes) {
        if (bytes == null || bytes.length <= 1) {
            return bytes;
        }
        // 最极端情况,每个byte都不需要反转义,所以使用1倍长度
        byte[] result = new byte[bytes.length];
        int ii = 0;
        for (int i = 0; i < bytes.length; i++) {
            // 当前循环的 byte 数据
            byte curr = bytes[i];
            // 若最后一条 byte 数据还能进入循环,则它必定不满足反转义
            if (i == bytes.length - 1) {
                result[ii++] = curr;
                break;
            }
            // 下一条 byte 数据
            byte next = bytes[i + 1];
            if (curr == 0x5A) {
                // 将 0x5A 0x01 反转义为 0x5B,且下一条数据 0x01 不需要参与循环
                if (next == 0x01) {
                    result[ii++] = 0x5B;
                    i++;
                    continue;
                }
                // 0x5A 0x02 反转义结果就是 0x5A,且下一条数据 0x02 不需要参与循环
                if (next == 0x02) {
                    i++;
                }
            }
            if (curr == 0x5E) {
                // 将 0x5E 0x01 反转义为 0x5D,且下一条数据 0x01 不需要参与循环
                if (next == 0x01) {
                    result[ii++] = 0x5D;
                    i++;
                    continue;
                }
                // 0x5E 0x02 反转义结果就是 0x5E,且下一条数据 0x02 不需要参与循环
                if (next == 0x02) {
                    i++;
                }
            }
            result[ii++] = curr;
        }
        // 截取反转义后的数据并返回
        return Arrays.copyOf(result, ii);
    }
    /**
     * 消息校验
     */
    public static boolean validate(ByteBuf byteBuf) {
        int len = byteBuf.readableBytes();
        byte[] bytes = new byte[len - 2];
        byteBuf.getBytes(2, bytes);
        int calc = CRC16CCITT.crc16(bytes);
        int code = byteBuf.getUnsignedShort(len - 2);
        boolean result = calc == code;
        if (!result) {
            log.warn("CRC校验失败!计算结果为:{}, 传入值为:{}", calc, code);
        }
        return result;
    }
    /**
     * 加密
     */
    public static byte[] encrypt(int m1, int ia1, int ic1, long key, byte[] bytes) {
        if (bytes == null) {
            return null;
        }
        if (key == 0) {
            key = 1;
        }
        for (int i = 0; i < bytes.length; i++) {
            key = ia1 * (key % m1) + ic1;
            bytes[i] ^= ((key >> 20) & 0xFF);
        }
        return bytes;
    }
    /**
     * 解密
     */
    public static byte[] decrypt(int m1, int ia1, int ic1, long key, byte[] bytes) {
        return encrypt(m1, ia1, ic1, key, bytes);
    }
    /**
     * 解析字符串
     *
     * @param complement 是否考虑右边补零的情况
     */
    public static String readString(ByteBuf byteBuf, int length, Charset charset, boolean complement) {
        // 是否考虑右补十六进制 0x00
        if (complement) {
            byte[] bytes = new byte[length];
            byteBuf.readBytes(bytes);
            int len = 0;
            for (int i = bytes.length; i > 0; i--) {
                if (bytes[i - 1] != 0x00) {
                    len = i;
                    break;
                }
            }
            return new String(Arrays.copyOf(bytes, len), charset);
        } else {
            return byteBuf.readBytes(length).toString(charset);
        }
    }
    /**
     * 解析GBK字符串
     *
     * @param complement 是否考虑右边补零的情况
     */
    public static String readGBKString(ByteBuf byteBuf, int length, boolean complement) {
        return readString(byteBuf, length, Charset.forName("GBK"), complement);
    }
    /**
     * 解析GBK字符串
     */
    public static String readGBKString(ByteBuf byteBuf, int length) {
        return readGBKString(byteBuf, length, true);
    }
}
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/util/jtt809/decoder/Jtt809Decoder.java
New file
@@ -0,0 +1,100 @@
package com.ruoyi.dataInterchange.util.jtt809.decoder;
import com.ruoyi.dataInterchange.util.jtt809.common.ByteArrayUtil;
import com.ruoyi.dataInterchange.util.jtt809.common.Jtt809Constant;
import com.ruoyi.dataInterchange.util.jtt809.common.Jtt809Util;
import com.ruoyi.dataInterchange.util.jtt809.gnsscenter.GnssCenterService;
import com.ruoyi.dataInterchange.util.jtt809.packet.common.OuterPacket;import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufUtil;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToMessageDecoder;
import io.netty.util.ReferenceCountUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.time.DateUtils;
import java.text.ParseException;
import java.util.List;
/**
 * @author tucke
 */
@Slf4j
public class Jtt809Decoder extends MessageToMessageDecoder<ByteBuf> {
    @Override
    protected void decode(ChannelHandlerContext ctx, ByteBuf msg, List<Object> out) throws Exception {
        // 写个判断,线上环境就不需要执行 ByteBufUtil.hexDump
        if (log.isDebugEnabled()) {
            log.debug("收到一条消息:{}5d", ByteBufUtil.hexDump(msg));
        }
        byte[] readableBytes = new byte[msg.readableBytes()];
        msg.readBytes(readableBytes);
        log.info("接收到数据包, packetLen : {}, packet : {}", readableBytes.length, ByteArrayUtil.bytes2HexStr(readableBytes));
        // 反转义处理
        byte[] bytes = Jtt809Util.unescape(readableBytes);
        ByteBuf byteBuf = Unpooled.wrappedBuffer(bytes);
        log.info("反转义后数据包, packetLen : {}, packet : {}", bytes.length, ByteArrayUtil.bytes2HexStr(bytes));
        // 判断包头
        if (byteBuf.readByte() != Jtt809Constant.PACKET_HEAD_FLAG) {
            byteBuf.resetReaderIndex();
            log.warn("消息包头错误: {}5d", ByteBufUtil.hexDump(byteBuf));
            return;
        }
        // crc校验
//        if (!Jtt809Util.validate(byteBuf)) {
//            return;
//        }
        /* 解析外层包 */
        // 长度
        long length = byteBuf.readUnsignedInt();
        // 长度校验, 反转义之后数组加上包头和包尾长度与解析出来的长度对比;
        // 因为数据长度不包含校验码,而此时解析出来的数据不包含头尾标识,刚好都是2个字节,所以两个长度应该相等
        if (length != bytes.length) {
            log.warn("消息长度校验错误,报文解析出来长度为 {}, 实际可解析的长度为 {}", length, bytes.length);
            return;
        }
        // 报文序列号
        long sn = byteBuf.readUnsignedInt();
        // 业务数据类型
        int id = byteBuf.readUnsignedShort();
        // 下级平台接入码
        int gnsscenterId = byteBuf.readInt();
        ctx.channel().attr(Jtt809Constant.NettyAttribute.GNSS_CENTER_ID).setIfAbsent(String.valueOf(gnsscenterId));
        // 协议版本号标识
        String version = "v" + byteBuf.readByte() + "." + byteBuf.readByte() + "." + byteBuf.readByte();
        // 报文加密标识位
        byte encryptFlag = byteBuf.readByte();
        // 数据加密解密的密匙
        long encryptKey = byteBuf.readUnsignedInt();
        // 2019版
//        String date = byteBuf.readByte() + "-" + byteBuf.readByte() + "-" + byteBuf.readShort() + " " +
//                byteBuf.readByte() + ":" + byteBuf.readByte() + ":" + byteBuf.readByte();
//        long time = 0;
//        try {
//            time = DateUtils.parseDate(date, "dd-MM-yyyy HH:mm:ss").getTime();
//        } catch (ParseException e) {
//            log.warn("日期 [{}] 解析错误", date);
//        }
        // 消息体
        byte[] body;
        if (encryptFlag == 1) {
            byte[] encryptedBytes = new byte[byteBuf.readableBytes() - 2];
            byteBuf.readBytes(encryptedBytes);
            // 解密
            int[] param = GnssCenterService.getInstance().getDecryptParam(gnsscenterId);
            Jtt809Util.decrypt(param[0], param[1], param[2], encryptKey, encryptedBytes);
            body = encryptedBytes;
        } else {
            body = new byte[byteBuf.readableBytes() - 2];
            byteBuf.readBytes(body);
        }
        // 校验码
        int crcCode = byteBuf.readUnsignedShort();
        ReferenceCountUtil.release(byteBuf);
        out.add(new OuterPacket(length, sn, id, gnsscenterId, version, encryptFlag, encryptKey, body, crcCode));
    }
}
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/util/jtt809/encoder/Jtt809Encoder.java
New file
@@ -0,0 +1,78 @@
package com.ruoyi.dataInterchange.util.jtt809.encoder;
import com.ruoyi.dataInterchange.util.jtt809.common.CRC16CCITT;
import com.ruoyi.dataInterchange.util.jtt809.common.Jtt809Constant;
import com.ruoyi.dataInterchange.util.jtt809.common.Jtt809Util;
import com.ruoyi.dataInterchange.util.jtt809.gnsscenter.GnssCenterService;
import com.ruoyi.dataInterchange.util.jtt809.packet.common.OuterPacket;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToByteEncoder;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
/**
 * @author tucke
 */
public class Jtt809Encoder extends MessageToByteEncoder<OuterPacket> {
    @Override
    protected void encode(ChannelHandlerContext ctx, OuterPacket packet, ByteBuf out) throws Exception {
        if (packet == null) {
            return;
        }
        int gnsscenterId;
        if (ctx.channel().hasAttr(Jtt809Constant.NettyAttribute.GNSS_CENTER_ID)) {
            gnsscenterId = Integer.parseInt(ctx.channel().attr(Jtt809Constant.NettyAttribute.GNSS_CENTER_ID).get());
        } else {
            gnsscenterId = packet.getGnsscenterId();
        }
        byte[] body = packet.getBody();
        if (body == null) {
            body = new byte[0];
        }
        // 32 = 头标识[1] + 数据头[30 = 长度[4] + 序列号[4] + 数据类型[2] + 接入码[4] + 版本号[3] + 加密标识[1] + 密钥[4]] + 时间[8] + 尾标识[1]
        int len = body.length + 32;
        out.markReaderIndex();
        // 数据长度
        out.writeInt(len);
        // 序列号
        out.writeInt(GnssCenterService.getInstance().serialNo(gnsscenterId));
        // 业务数据类型
        out.writeShort(packet.getId());
        // 下级平台接入码
        out.writeInt(gnsscenterId);
        // 版本号
        out.writeByte(1);
        out.writeByte(0);
        out.writeByte(0);
        // 报文加密标识位
        out.writeByte(0);
        // 数据加密的密钥
        out.writeInt(0);
        // 数据体
        out.writeBytes(body);
        // 校验码
        byte[] crcBytes = new byte[out.readableBytes()];
        out.readBytes(crcBytes);
        out.writeShort(CRC16CCITT.crc16(crcBytes));
        // 转义
        out.resetReaderIndex();
        byte[] escapeBytes = new byte[out.readableBytes()];
        out.readBytes(escapeBytes);
        // 重置下标
        out.setIndex(0, 0);
        // 包头标识
        out.writeByte(Jtt809Constant.PACKET_HEAD_FLAG);
        // 数据内容
        out.writeBytes(Jtt809Util.escape(escapeBytes));
        // 包尾标识
        out.writeByte(Jtt809Constant.PACKET_END_FLAG);
    }
}
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/util/jtt809/gnsscenter/GnssCenterService.java
New file
@@ -0,0 +1,91 @@
package com.ruoyi.dataInterchange.util.jtt809.gnsscenter;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
 * 下级平台配置服务
 *
 * @author tucke
 */
public class GnssCenterService {
    private final Lock lock = new ReentrantLock();
    private final Map<Integer, AtomicInteger> SERIAL_NUMBER_MAP = new ConcurrentHashMap<>();
    private volatile static GnssCenterService instance;
    private GnssCenterService() {
    }
    public static GnssCenterService getInstance() {
        if (instance == null) {
            synchronized (GnssCenterService.class) {
                if (instance == null) {
                    instance = new GnssCenterService();
                }
            }
        }
        return instance;
    }
    public void start() throws Exception {
    }
    /**
     * 获取加密的参数
     *
     * @param gnsscenterId 下级平台接入码
     * @return {M1, IA1, IC1}
     */
    public int[] getEncryptParam(int gnsscenterId) {
        return new int[]{1, 2, 3};
    }
    /**
     * 获取解密的参数
     *
     * @param gnsscenterId 下级平台接入码
     * @return {M1, IA1, IC1}
     */
    public int[] getDecryptParam(int gnsscenterId) {
        return getEncryptParam(gnsscenterId);
    }
    /**
     * 获取序列号
     * 1 - 同一个下级平台的序列号保证连续
     * 2 - 不同下级平台的序列号保证互不干扰
     * 3 - 序列号达到最大值后,需要清零
     *
     * @param gnsscenterId 下级平台接入码
     * @return 序列号
     */
    public int serialNo(int gnsscenterId) {
        int serialNumber;
        lock.lock();
        try {
            if (!SERIAL_NUMBER_MAP.containsKey(gnsscenterId)) {
                if (!SERIAL_NUMBER_MAP.containsKey(gnsscenterId)) {
                    SERIAL_NUMBER_MAP.put(gnsscenterId, new AtomicInteger());
                }
            }
            serialNumber = SERIAL_NUMBER_MAP.get(gnsscenterId).getAndIncrement();
            if (serialNumber == Integer.MAX_VALUE) {
                SERIAL_NUMBER_MAP.get(gnsscenterId).set(0);
            }
        } finally {
            lock.unlock();
        }
        return serialNumber;
    }
    public void stop() {
    }
}
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/util/jtt809/packet/DownTotalReceivePacket.java
New file
@@ -0,0 +1,31 @@
package com.ruoyi.dataInterchange.util.jtt809.packet;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufUtil;
import io.netty.buffer.Unpooled;
import lombok.Data;
/**
 * @author tucke
 */
@Data
public class DownTotalReceivePacket {
    private Integer dynamicInfoTotal;
    private Long startTime;
    private Long endTime;
    /**
     * 编码登录回复报文
     */
    public static byte[] encode(DownTotalReceivePacket packet) {
        ByteBuf byteBuf = Unpooled.buffer(5);
        byteBuf.writeInt(packet.getDynamicInfoTotal());
        byteBuf.writeLong(packet.getStartTime());
        byteBuf.writeLong(packet.getEndTime());
        byte[] bytes = ByteBufUtil.getBytes(byteBuf);
        byteBuf.release();
        return bytes;
    }
}
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/util/jtt809/packet/common/OuterPacket.java
New file
@@ -0,0 +1,73 @@
package com.ruoyi.dataInterchange.util.jtt809.packet.common;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
/**
 * @author tucke
 */
@SuppressWarnings("SpellCheckingInspection")
@AllArgsConstructor
@NoArgsConstructor
@Data
public class OuterPacket implements Serializable {
    private static final long serialVersionUID = 1L;
    /**
     * 数据长度(包括头标识、数据头、数据体和尾标识)
     */
    private long length;
    /**
     * 报文序列号
     * 占用四个字节,为发送信息的序列号,用于接收方检测是否有信息的丢失,上级平台和下级平台接自己发送数据包的个数计数,互不影响。
     * 程序开始运行时等于零,发送第一帧数据时开始计数,到最大数后自动归零
     */
    private long sn;
    /**
     * 业务数据类型
     */
    private int id;
    /**
     * 下级平台接入码,上级平台给下级平台分配唯一标识码
     */
    private int gnsscenterId;
    /**
     * 协议版本号标识,上下级平台之间采用的标准协议版编号
     * 长度为 3 个字节来表示,0x01 0x02 0x0F 表示的版本号是 v1.2.15,以此类推
     */
    private String version;
    /**
     * 报文加密标识位
     * 0 - 报文不加密
     * 1 - 报文加密, 后继相应业务的数据体采用 ENCRYPT_KEY 对应的密钥进行加密处理
     */
    private byte encryptFlag;
    /**
     * 数据加密解密的密匙,长度为 4 个字节
     */
    private long encryptKey;
    /**
     * 消息体
     */
    private byte[] body;
    /**
     * 数据 CRC 校验码
     */
    private int crcCode;
    public OuterPacket(int id, byte[] body) {
        this.id = id;
        this.body = body;
    }
    public OuterPacket(int id, int gnsscenterId, byte[] body) {
        this.id = id;
        this.gnsscenterId = gnsscenterId;
        this.body = body;
    }
}
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/util/jtt809/packet/upexg/UpExgHistoryPacket.java
New file
@@ -0,0 +1,34 @@
package com.ruoyi.dataInterchange.util.jtt809.packet.upexg;
import io.netty.buffer.ByteBuf;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import java.util.ArrayList;
import java.util.List;
/**
 * @author tucke
 */
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
@Data
public class UpExgHistoryPacket extends UpExgPacket {
    private byte cnt;
    private List<UpExgRealLocationPacket> locations;
    public static UpExgHistoryPacket decode(ByteBuf byteBuf) {
        UpExgHistoryPacket packet = new UpExgHistoryPacket();
        byte cnt = byteBuf.readByte();
        packet.setCnt(byteBuf.readByte());
        List<UpExgRealLocationPacket> locations = new ArrayList<>();
        for (int i = cnt; i > 0; i--) {
            locations.add(UpExgRealLocationPacket.decode(byteBuf));
        }
        packet.setLocations(locations);
        return packet;
    }
}
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/util/jtt809/packet/upexg/UpExgPacket.java
New file
@@ -0,0 +1,23 @@
package com.ruoyi.dataInterchange.util.jtt809.packet.upexg;
import io.netty.buffer.ByteBuf;
import lombok.Data;
/**
 * @author tucke
 */
@Data
public class UpExgPacket {
    private String vehicleNo;
    private byte vehicleColor;
    private short dataType;
    private int dataLength;
    private ByteBuf data;
    public void complete(String vehicleNo, Byte vehicleColor) {
        this.setVehicleNo(vehicleNo);
        this.setVehicleColor(vehicleColor);
    }
}
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/util/jtt809/packet/upexg/UpExgRealLocationPacket.java
New file
@@ -0,0 +1,66 @@
package com.ruoyi.dataInterchange.util.jtt809.packet.upexg;
import io.netty.buffer.ByteBuf;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.time.DateUtils;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.ParseException;
/**
 * @author tucke
 */
@Slf4j
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
@Data
public class UpExgRealLocationPacket extends UpExgPacket {
    private static final BigDecimal LAT_LON_DIVISOR = new BigDecimal(1000000);
    private byte encrypt;
    private long timestamp;
    private double lon;
    private double lat;
    private short vec1;
    private short vec2;
    private int vec3;
    private short direction;
    private short altitude;
    private int state;
    private int alarm;
    public static UpExgRealLocationPacket decode(ByteBuf byteBuf) {
        UpExgRealLocationPacket packet = new UpExgRealLocationPacket();
        packet.setEncrypt(byteBuf.readByte());
        String date = byteBuf.readByte() + "-" + byteBuf.readByte() + "-" + byteBuf.readShort() + " " +
                byteBuf.readByte() + ":" + byteBuf.readByte() + ":" + byteBuf.readByte();
        try {
            long time = DateUtils.parseDate(date, "dd-MM-yyyy HH:mm:ss").getTime();
            packet.setTimestamp(time);
        } catch (ParseException e) {
            log.warn("日期 [{}] 解析错误", date);
        }
        BigDecimal lon = new BigDecimal(String.valueOf(byteBuf.readInt()));
        BigDecimal lat = new BigDecimal(String.valueOf(byteBuf.readInt()));
        try {
            packet.setLon(lon.divide(LAT_LON_DIVISOR, 6, RoundingMode.UNNECESSARY).doubleValue());
            packet.setLat(lat.divide(LAT_LON_DIVISOR, 6, RoundingMode.UNNECESSARY).doubleValue());
        } catch (ArithmeticException e) {
            log.warn("经纬度 [{}, {}] 解析错误", lon, lat);
        }
        packet.setVec1(byteBuf.readShort());
        packet.setVec2(byteBuf.readShort());
        packet.setVec3(byteBuf.readInt());
        packet.setDirection(byteBuf.readShort());
        packet.setAltitude(byteBuf.readShort());
        packet.setState(byteBuf.readInt());
        packet.setAlarm(byteBuf.readInt());
        return packet;
    }
}
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/wapper/UPConnect.java
New file
@@ -0,0 +1,23 @@
package com.ruoyi.dataInterchange.wapper;
import lombok.Data;
/**
 * @author zhibing.pu
 * @Date 2025/3/7 15:54
 */
@Data
public class UPConnect {
    /**
     * 下级平台提供对应的从链路服务端IP地址
     */
    private String downLinkIp;
    /**
     * 下级平台提供对应的从链路服务端端口号
     */
    private int downLinkPort;
    /**
     * 登录验证码
     */
    private int verifyCode;
}