ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/dao/UPWarnMsgOperationInfoDao.java
@@ -2,10 +2,12 @@ import com.ruoyi.dataInterchange.model.UPWarnMsgOperationInfo; import org.springframework.data.elasticsearch.repository.ElasticsearchRepository; import org.springframework.stereotype.Repository; /** * @author zhibing.pu * @Date 2025/6/3 17:25 */ @Repository public interface UPWarnMsgOperationInfoDao extends ElasticsearchRepository<UPWarnMsgOperationInfo, String> { } ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/dao/UpWarnMsgFileListAckDao.java
New file @@ -0,0 +1,13 @@ package com.ruoyi.dataInterchange.dao; import com.ruoyi.dataInterchange.model.UpWarnMsgFileListAck; import org.springframework.data.elasticsearch.repository.ElasticsearchRepository; import org.springframework.stereotype.Repository; /** * @author zhibing.pu * @Date 2025/6/4 15:17 */ @Repository public interface UpWarnMsgFileListAckDao extends ElasticsearchRepository<UpWarnMsgFileListAck, String> { } ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/DOWNWarnMsgFileListReq.java
New file @@ -0,0 +1,77 @@ 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.io.UnsupportedEncodingException; /** * 报警附件目录请求消息 * @author zhibing.pu * @Date 2025/6/4 14:42 */ @Data public class DOWNWarnMsgFileListReq { /** * 车牌号 */ private String vehicleNo; /** * 车牌颜色 */ private int vehicleColor; /** * 子业务类型标识 */ private int dataType; /** * 后续数据长度 */ private int dataLength; /** * 报警信息ID */ private String infoId; /** * 编码报文 */ public byte[] encode() { ByteBuf byteBuf = Unpooled.buffer(120); byte[] bytes1 = new byte[0]; try { bytes1 = this.getVehicleNo().getBytes("GBK"); } catch (UnsupportedEncodingException e) { throw new RuntimeException(e); } for (int i = 0; i < 21; i++) { if (i < bytes1.length) { byteBuf.writeByte(bytes1[i]); } else { byteBuf.writeByte(0x00); } } byteBuf.writeByte(this.getVehicleColor()); byteBuf.writeShort(this.getDataType()); byteBuf.writeInt(this.getDataLength()); byte[] bytes2 = new byte[0]; try { bytes2 = this.getInfoId().getBytes("GBK"); } catch (UnsupportedEncodingException e) { throw new RuntimeException(e); } for (int i = 0; i < this.getDataLength(); i++) { if (i < bytes2.length) { byteBuf.writeByte(bytes2[i]); } else { byteBuf.writeByte(0x00); } } byte[] bytes = ByteBufUtil.getBytes(byteBuf); byteBuf.release(); return bytes; } } ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/File.java
New file @@ -0,0 +1,74 @@ package com.ruoyi.dataInterchange.model; import com.ruoyi.dataInterchange.util.jtt809.common.Jtt809Util; 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/6/4 15:11 */ @Data public class File { /** * 文件名称长度 */ @Field(type = FieldType.Integer) private int fileNameLength; /** * 文件名称 */ @Field(type = FieldType.Text) private String fileName; /** * 文件类型 * 0x00: 图片 * 0x01: 音频 * 0x02: 视频 * 0x03: 记录文件 * 0x04: 其他 */ @Field(type = FieldType.Integer) private int fileType; /** * 文件大小 */ @Field(type = FieldType.Integer) private int fileSize; /** * 文件URL的长度 */ @Field(type = FieldType.Integer) private int fileUrlLength; /** * 文件URL */ @Field(type = FieldType.Text) private String fileUrl; /** * 解析报文 */ public File decode(ByteBuf byteBuf) { try { //文件名称长度 this.fileNameLength = byteBuf.readByte(); //文件名称 this.fileName = Jtt809Util.readGBKString(byteBuf,fileNameLength); //文件类型 this.fileType = byteBuf.readByte(); //文件大小 this.fileSize = byteBuf.readInt(); //文件URL的长度 this.fileUrlLength = byteBuf.readByte(); //文件URL this.fileUrl = Jtt809Util.readGBKString(byteBuf,fileUrlLength); }catch (Exception e){ e.printStackTrace(); } return this; } } ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/UpWarnMsgFileListAck.java
New file @@ -0,0 +1,135 @@ package com.ruoyi.dataInterchange.model; 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.util.ArrayList; import java.util.List; /** * 报警附件目录请求应答 * @author zhibing.pu * @Date 2025/6/4 15:05 */ @Data @Document(indexName = "up_warn_msg_filelist_ack") public class UpWarnMsgFileListAck 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.Text) private String infoId; /** * 附件服务器地址长度 */ @Field(type = FieldType.Integer) private int serverLength; /** * 附件服务器IP或域名 */ @Field(type = FieldType.Text) private String server; /** * 附件服务器FTP协议端口号 */ @Field(type = FieldType.Integer) private int port; /** * 用户名长度 */ @Field(type = FieldType.Integer) private int userNameLength; /** * 附件服务器用户名 */ @Field(type = FieldType.Text) private String userName; /** * 密码长度 */ @Field(type = FieldType.Integer) private int passwordLength; /** * 附件服务器密码 */ @Field(type = FieldType.Text) private String password; /** * 附件数量 */ @Field(type = FieldType.Integer) private int fileCount; /** * 附件列表数据 */ @Field(type = FieldType.Object) private List<File> fileList; /** * 解析报文 */ public UpWarnMsgFileListAck decode(WarnMsg warnMsg) { try { 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.infoId = Jtt809Util.readGBKString(byteBuf,32); //附件服务器地址长度 this.serverLength = byteBuf.readByte(); //附件服务器IP或域名 this.server = Jtt809Util.readGBKString(byteBuf,serverLength); //附件服务器FTP协议端口号 this.port = byteBuf.readShort(); //用户名长度 this.userNameLength = byteBuf.readByte(); //附件服务器用户名 this.userName = Jtt809Util.readGBKString(byteBuf,userNameLength); //密码长度 this.passwordLength = byteBuf.readByte(); //附件服务器密码 this.password = Jtt809Util.readGBKString(byteBuf,passwordLength); //附件数量 this.fileCount = byteBuf.readByte(); List<File> list = new ArrayList<>(); for (int i = 0; i < this.fileCount; i++) { list.add(new File().decode(byteBuf)); } this.fileList = list; }catch (Exception e){ e.printStackTrace(); } return this; } } ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/enu/DataType.java
@@ -71,13 +71,15 @@ UP_WARN_MSG(0x1400, "报警信息交互"), UP_WARN_MSG_URGE_TODO_ACK(0x1401, "报警督办应答消息"), UP_WARN_MSG_ADPT_INFO(0x1402, "上报报警信息"), UP_WARN_MSG_OPERATION_INFO(0x1402, "主动上报报警处理消息"), UP_WARN_MSG_OPERATION_INFO(0x1403, "主动上报报警处理消息"), UP_WARN_MSG_FILELIST_ACK(0x1404, "报警附件目录请求应答"), 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, "实时交换报警信息"), DOWN_WARN_MSG_FILELIST_REQ(0x9404, "报警附件目录请消息"), UP_WARN_MSG_INFORM_TIPS(0x1403, "上报报警预警信息"), UP_WARN_MSG_URGE_TODO_REQ_INFO(0x1413, "上报报警督办请求"), UP_CTRL_MSG(0x1500, "车辆监管业务"), ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/server/WarnMsgService.java
@@ -1,17 +1,16 @@ package com.ruoyi.dataInterchange.server; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson2.JSONArray; import com.alibaba.fastjson2.JSONObject; import com.ruoyi.dataInterchange.dao.UPExgMsgRealLocationDao; import com.ruoyi.dataInterchange.dao.UPWarnMsgAdptInfoDao; import com.ruoyi.dataInterchange.dao.UPWarnMsgOperationInfoDao; import com.ruoyi.dataInterchange.dao.UPWarnMsgUrgeTodoAckDao; 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.haikang.Artemis; import com.ruoyi.dataInterchange.util.haikang.model.Alarm; import com.ruoyi.dataInterchange.util.haikang.model.AlarmPic; import com.ruoyi.dataInterchange.util.haikang.model.Event; import com.ruoyi.dataInterchange.util.haikang.model.FindPicturesByAlarmIdRequest; import com.ruoyi.dataInterchange.util.haikang.model.SubscriptionEvent; import com.ruoyi.dataInterchange.util.jtt809.common.Jtt809Util; import com.ruoyi.dataInterchange.util.jtt809.packet.common.OuterPacket; @@ -30,6 +29,7 @@ import java.time.format.DateTimeFormatter; import java.util.Arrays; import java.util.List; import java.util.StringJoiner; /** * @author zhibing.pu @@ -50,6 +50,9 @@ @Resource private UPWarnMsgOperationInfoDao upWarnMsgOperationInfoDao; @Resource private UpWarnMsgFileListAckDao upWarnMsgFileListAckDao; @Resource private RedisTemplate redisTemplate; @@ -82,6 +85,10 @@ case UP_WARN_MSG_OPERATION_INFO: log.info("上报报警处理信息({}):{}", DataType.UP_WARN_MSG_OPERATION_INFO.getCode(), out); up_warn_msg_operation_info(ctx, out.getGnsscenterId(), warnMsg); break; case UP_WARN_MSG_FILELIST_ACK: log.info("报警附件目录请求应答({}):{}", DataType.UP_WARN_MSG_FILELIST_ACK.getCode(), out); up_warn_msg_filelist_ack(ctx, out.getGnsscenterId(), warnMsg); break; default: break; @@ -156,6 +163,24 @@ } } upWarnMsgAdptInfoDao.save(upWarnMsgAdptInfo); //请求报警附件(川标协议) if(enterprise.contains(inferiorPlatformId)){ DOWNWarnMsgFileListReq downWarnMsgFileListReq = new DOWNWarnMsgFileListReq(); downWarnMsgFileListReq.setVehicleNo(upWarnMsgAdptInfo.getVehicleNo()); downWarnMsgFileListReq.setVehicleColor(upWarnMsgAdptInfo.getVehicleColor()); downWarnMsgFileListReq.setDataType(DataType.DOWN_WARN_MSG_FILELIST_REQ.getCode()); downWarnMsgFileListReq.setDataLength(32); downWarnMsgFileListReq.setInfoId(upWarnMsgAdptInfo.getInfoId()); byte[] body = downWarnMsgFileListReq.encode(); OuterPacket out = new OuterPacket(DataType.DOWN_WARN_MSG.getCode(), inferiorPlatformId, body); //获取从链路通道 Channel channel = ChannelMap.getClientChannel(inferiorPlatformId); if (null != channel && channel.isActive()) { channel.writeAndFlush(out); log.info("报警附件目录请求({}):{}", DataType.DOWN_WARN_MSG_FILELIST_REQ.getCode(), JSON.toJSONString(downWarnMsgFileListReq)); } } } @@ -178,11 +203,71 @@ /** * 报警附件目录请求应答 * @param ctx * @param inferiorPlatformId * @param warnMsg */ public void up_warn_msg_filelist_ack(ChannelHandlerContext ctx, int inferiorPlatformId, WarnMsg warnMsg){ UpWarnMsgFileListAck upWarnMsgFileListAck = new UpWarnMsgFileListAck().decode(warnMsg).decode(warnMsg); upWarnMsgFileListAck.setInferiorPlatformId(inferiorPlatformId); upWarnMsgFileListAck.setCreateTime(LocalDateTime.now().toEpochSecond(ZoneOffset.ofHours(8))); upWarnMsgFileListAckDao.save(upWarnMsgFileListAck); //修改报警处理结果 UPWarnMsgAdptInfo upWarnMsgAdptInfo = upWarnMsgAdptInfoDao.findByInfoIdIs(upWarnMsgFileListAck.getInfoId()); StringJoiner joiner = new StringJoiner(","); upWarnMsgFileListAck.getFileList().forEach(file->{ if(file.getFileType() == 0x00){ joiner.add(file.getFileUrl()); } }); upWarnMsgAdptInfo.setPicUrl(joiner.toString()); upWarnMsgAdptInfoDao.save(upWarnMsgAdptInfo); } /** * 定时任务督办报警请求 */ public void taskUrgeTodo() { List<UPWarnMsgAdptInfo> list = upWarnMsgAdptInfoDao.findByResultIsAndLevelNotNullAndPushTimeBefore(0x00, LocalDateTime.now().toEpochSecond(ZoneOffset.ofHours(8))); for (UPWarnMsgAdptInfo upWarnMsgAdptInfo : list) { Integer inferiorPlatformId = upWarnMsgAdptInfo.getInferiorPlatformId(); //海康威视直接走接口 if(25439966 == inferiorPlatformId){ try { if("***".equals(upWarnMsgAdptInfo.getPicUrl())){ FindPicturesByAlarmIdRequest findPicturesByAlarmIdRequest = new FindPicturesByAlarmIdRequest(); findPicturesByAlarmIdRequest.setAlarmId(upWarnMsgAdptInfo.getInfoId()); long warnTime = upWarnMsgAdptInfo.getWarnTime(); findPicturesByAlarmIdRequest.setAlarmTime(LocalDateTime.ofEpochSecond(warnTime, 0, ZoneOffset.ofHours(8)).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))); String pictures = Artemis.findPicturesByAlarmId(findPicturesByAlarmIdRequest); JSONObject jsonObject = JSONObject.parseObject(pictures); Integer code = jsonObject.getInteger("code"); if(0 == code){ JSONArray data = jsonObject.getJSONArray("data"); StringJoiner joiner = new StringJoiner(","); for (int i = 0; i < data.size(); i++) { JSONObject jsonObject1 = data.getJSONObject(0); String url = jsonObject1.getString("url"); joiner.add(url); } upWarnMsgAdptInfo.setPicUrl(joiner.toString()); upWarnMsgAdptInfoDao.save(upWarnMsgAdptInfo); } } }catch (Exception e){ e.printStackTrace(); } } down_warn_msg_urge_todo_req(upWarnMsgAdptInfo); } } @@ -266,7 +351,30 @@ if(!warnType.contains(upWarnMsgAdptInfo.getWarnType())){ return; } upWarnMsgAdptInfo.setResult(0x00); //获取报警抓拍图片 if(data.getPicNum() > 0){ upWarnMsgAdptInfo.setPicUrl("***"); FindPicturesByAlarmIdRequest findPicturesByAlarmIdRequest = new FindPicturesByAlarmIdRequest(); findPicturesByAlarmIdRequest.setAlarmId(data.getAlarmId()); findPicturesByAlarmIdRequest.setAlarmTime(data.getAlarmTime()); String pictures = Artemis.findPicturesByAlarmId(findPicturesByAlarmIdRequest); JSONObject jsonObject1 = JSONObject.parseObject(pictures); Integer code = jsonObject1.getInteger("code"); if(0 == code){ JSONArray data1 = jsonObject1.getJSONArray("data"); StringJoiner joiner = new StringJoiner(","); for (int i = 0; i < data1.size(); i++) { JSONObject jsonObject2 = data1.getJSONObject(0); String url = jsonObject2.getString("url"); joiner.add(url); } upWarnMsgAdptInfo.setPicUrl(joiner.toString()); } } upWarnMsgAdptInfoDao.save(upWarnMsgAdptInfo); }catch (Exception e){ e.printStackTrace(); } @@ -439,29 +547,6 @@ return 0; } } /** * 存储mqtt协议报警图片信息 */ public void saveWarnMsgPicService(JSONObject jsonObject) { SubscriptionEvent subscriptionEvent = jsonObject.getObject("", SubscriptionEvent.class); List<Event> events = subscriptionEvent.getEvents(); events.forEach(event -> { AlarmPic data = JSONObject.parseObject(event.getData(), AlarmPic.class); if(StringUtils.hasLength(data.getAlarmId())){ UPWarnMsgAdptInfo upWarnMsgAdptInfo = upWarnMsgAdptInfoDao.findByInfoIdIs(data.getAlarmId()); if(null != upWarnMsgAdptInfo){ upWarnMsgAdptInfo.setPicUrl(data.getUrl()); upWarnMsgAdptInfoDao.save(upWarnMsgAdptInfo); }else{ upWarnMsgAdptInfo = new UPWarnMsgAdptInfo(); upWarnMsgAdptInfo.setInfoId(data.getAlarmId()); upWarnMsgAdptInfoDao.save(upWarnMsgAdptInfo); } } }); } } ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/util/haikang/Artemis.java
@@ -213,4 +213,18 @@ String result =ArtemisHttpUtil.doPostStringArtemis(artemisConfig,path,body,null,null,"application/json"); return result; } //根据报警ID获取关联图片信息 public static String findPicturesByAlarmId(FindPicturesByAlarmIdRequest findPicturesByAlarmIdRequest) throws Exception { String findPicturesByAlarmIdDataApi = ARTEMIS_PATH +"/api/rtsm/v1/multimedia/findPicturesByAlarmId"; Map<String,String> path = new HashMap<String,String>(2){ { put("https://",findPicturesByAlarmIdDataApi); } }; String body=JSON.toJSONString(findPicturesByAlarmIdRequest); String result =ArtemisHttpUtil.doPostStringArtemis(artemisConfig,path,body,null,null,"application/json"); return result; } } ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/util/haikang/model/FindPicturesByAlarmIdRequest.java
New file @@ -0,0 +1,22 @@ package com.ruoyi.dataInterchange.util.haikang.model; public class FindPicturesByAlarmIdRequest { private String alarmId; private String alarmTime; public String getAlarmId() { return alarmId; } public void setAlarmId(String alarmId) { this.alarmId = alarmId; } public String getAlarmTime() { return alarmTime; } public void setAlarmTime(String alarmTime) { this.alarmTime = alarmTime; } } ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/util/mqtt/MqttReceiverMessageHandler.java
@@ -37,9 +37,6 @@ case "event_msa_alarm": warnMsgService.saveWarnMsgService(jsonObject); break; case "event_msa_pic": warnMsgService.saveWarnMsgPicService(jsonObject); break; } } }