diff --git a/sql/2.6.6-2.6.7更新.sql b/sql/2.6.6-2.6.7更新.sql new file mode 100755 index 00000000..df595a81 --- /dev/null +++ b/sql/2.6.6-2.6.7更新.sql @@ -0,0 +1,6 @@ +alter table device + add asMessageChannel int default 0; + +alter table parent_platform + add asMessageChannel int default 0; + diff --git a/src/main/resources/db/migration/V2.6.7_20230201__初始化.sql b/sql/初始化.sql similarity index 99% rename from src/main/resources/db/migration/V2.6.7_20230201__初始化.sql rename to sql/初始化.sql index 7a15f905..a8dfaff1 100644 --- a/src/main/resources/db/migration/V2.6.7_20230201__初始化.sql +++ b/sql/初始化.sql @@ -47,6 +47,7 @@ CREATE TABLE `device` ( `mobilePositionSubmissionInterval` int DEFAULT '5', `subscribeCycleForAlarm` int DEFAULT NULL, `ssrcCheck` int DEFAULT '0', + `asMessageChannel` int DEFAULT '0', `geoCoordSys` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `treeType` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `custom_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, @@ -329,6 +330,7 @@ CREATE TABLE `parent_platform` ( `catalogId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `ptz` int DEFAULT NULL, `rtcp` int DEFAULT NULL, + `asMessageChannel` int DEFAULT '0', `status` bit(1) DEFAULT NULL, `startOfflinePush` int DEFAULT '0', `administrativeDivision` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, diff --git a/src/main/java/com/genersoft/iot/vmp/conf/UserSetting.java b/src/main/java/com/genersoft/iot/vmp/conf/UserSetting.java index 1e7fd368..b413d88f 100644 --- a/src/main/java/com/genersoft/iot/vmp/conf/UserSetting.java +++ b/src/main/java/com/genersoft/iot/vmp/conf/UserSetting.java @@ -48,6 +48,7 @@ public class UserSetting { private Boolean syncChannelOnDeviceOnline = Boolean.FALSE; private Boolean sipLog = Boolean.FALSE; + private Boolean sendToPlatformsWhenIdLost = Boolean.FALSE; private String serverId = "000000"; @@ -218,4 +219,12 @@ public class UserSetting { public void setSipLog(Boolean sipLog) { this.sipLog = sipLog; } + + public Boolean getSendToPlatformsWhenIdLost() { + return sendToPlatformsWhenIdLost; + } + + public void setSendToPlatformsWhenIdLost(Boolean sendToPlatformsWhenIdLost) { + this.sendToPlatformsWhenIdLost = sendToPlatformsWhenIdLost; + } } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/Device.java b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/Device.java index e454896e..83b9c6af 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/Device.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/Device.java @@ -188,6 +188,9 @@ public class Device { @Schema(description = "SIP交互IP(设备访问平台的IP)") private String localIp; + @Schema(description = "是否作为消息通道") + private boolean asMessageChannel; + public String getDeviceId() { return deviceId; @@ -428,4 +431,12 @@ public class Device { public void setKeepaliveIntervalTime(int keepaliveIntervalTime) { this.keepaliveIntervalTime = keepaliveIntervalTime; } + + public boolean isAsMessageChannel() { + return asMessageChannel; + } + + public void setAsMessageChannel(boolean asMessageChannel) { + this.asMessageChannel = asMessageChannel; + } } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/ParentPlatform.java b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/ParentPlatform.java index b056cc71..01a11eb6 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/ParentPlatform.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/ParentPlatform.java @@ -189,6 +189,9 @@ public class ParentPlatform { @Schema(description = "树类型 国标规定了两种树的展现方式 行政区划 CivilCode 和业务分组:BusinessGrou") private String treeType; + @Schema(description = "是否作为消息通道") + private boolean asMessageChannel; + public Integer getId() { return id; } @@ -428,4 +431,12 @@ public class ParentPlatform { public void setTreeType(String treeType) { this.treeType = treeType; } + + public boolean isAsMessageChannel() { + return asMessageChannel; + } + + public void setAsMessageChannel(boolean asMessageChannel) { + this.asMessageChannel = asMessageChannel; + } } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/RecordInfo.java b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/RecordInfo.java index 41aebf5d..7ff52830 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/RecordInfo.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/RecordInfo.java @@ -1,6 +1,8 @@ package com.genersoft.iot.vmp.gb28181.bean; +import io.swagger.v3.oas.annotations.media.Schema; + import java.time.Instant; import java.util.List; @@ -9,22 +11,29 @@ import java.util.List; * @author: swwheihei * @date: 2020年5月8日 下午2:05:56 */ +@Schema(description = "设备录像查询结果信息") public class RecordInfo { + @Schema(description = "设备编号") private String deviceId; + @Schema(description = "通道编号") private String channelId; + @Schema(description = "命令序列号") private String sn; + @Schema(description = "设备名称") private String name; - + + @Schema(description = "列表总数") private int sumNum; private int count; private Instant lastTime; - + + @Schema(description = "") private List recordList; public String getDeviceId() { diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/RecordItem.java b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/RecordItem.java index a47147a1..07e559c8 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/RecordItem.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/RecordItem.java @@ -2,9 +2,9 @@ package com.genersoft.iot.vmp.gb28181.bean; import com.genersoft.iot.vmp.utils.DateUtil; +import io.swagger.v3.oas.annotations.media.Schema; import org.jetbrains.annotations.NotNull; -import java.text.ParseException; import java.time.Instant; import java.time.temporal.TemporalAccessor; @@ -13,26 +13,37 @@ import java.time.temporal.TemporalAccessor; * @author: swwheihei * @date: 2020年5月8日 下午2:06:54 */ +@Schema(description = "设备录像详情") public class RecordItem implements Comparable{ + @Schema(description = "设备编号") private String deviceId; - + + @Schema(description = "名称") private String name; - + + @Schema(description = "文件路径名 (可选)") private String filePath; + @Schema(description = "录像文件大小,单位:Byte(可选)") private String fileSize; + @Schema(description = "录像地址(可选)") private String address; - + + @Schema(description = "录像开始时间(可选)") private String startTime; - + + @Schema(description = "录像结束时间(可选)") private String endTime; - + + @Schema(description = "保密属性(必选)缺省为0;0:不涉密,1:涉密") private int secrecy; - + + @Schema(description = "录像产生类型(可选)time或alarm 或 manua") private String type; - + + @Schema(description = "录像触发者ID(可选)") private String recorderId; public String getDeviceId() { diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java index dabe1c87..740e8376 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java @@ -1376,7 +1376,7 @@ public class SIPCommander implements ISIPCommander { if (device == null) { return; } - logger.info("[发送 报警通知] {}/{}->{},{}", device.getDeviceId(), deviceAlarm.getChannelId(), + logger.info("[发送报警通知]设备: {}/{}->{},{}", device.getDeviceId(), deviceAlarm.getChannelId(), deviceAlarm.getLongitude(), deviceAlarm.getLatitude()); String characterSet = device.getCharset(); diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java index 64152415..b9d2c4cf 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java @@ -402,7 +402,7 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { if (parentPlatform == null) { return; } - logger.info("[发送报警通知] {}/{}->{},{}: {}", parentPlatform.getServerGBId(), deviceAlarm.getChannelId(), + logger.info("[发送报警通知]平台: {}/{}->{},{}: {}", parentPlatform.getServerGBId(), deviceAlarm.getChannelId(), deviceAlarm.getLongitude(), deviceAlarm.getLatitude(), JSON.toJSONString(deviceAlarm)); String characterSet = parentPlatform.getCharacterSet(); StringBuffer deviceStatusXml = new StringBuffer(600); diff --git a/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisAlarmMsgListener.java b/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisAlarmMsgListener.java index 1cc754d2..43528ecc 100644 --- a/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisAlarmMsgListener.java +++ b/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisAlarmMsgListener.java @@ -1,6 +1,7 @@ package com.genersoft.iot.vmp.service.redisMsg; import com.alibaba.fastjson2.JSON; +import com.genersoft.iot.vmp.conf.UserSetting; import com.genersoft.iot.vmp.gb28181.bean.*; import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander; import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; @@ -44,8 +45,12 @@ public class RedisAlarmMsgListener implements MessageListener { @Autowired private ThreadPoolTaskExecutor taskExecutor; + @Autowired + private UserSetting userSetting; + @Override public void onMessage(@NotNull Message message, byte[] bytes) { + // 消息示例: PUBLISH alarm_receive '{ "gbId": "", "alarmSn": 1, "alarmType": "111", "alarmDescription": "222", }' logger.info("收到来自REDIS的ALARM通知: {}", new String(message.getBody())); boolean isEmpty = taskQueue.isEmpty(); taskQueue.offer(message); @@ -74,17 +79,44 @@ public class RedisAlarmMsgListener implements MessageListener { deviceAlarm.setLatitude(0); if (ObjectUtils.isEmpty(gbId)) { - // 发送给所有的上级 - List parentPlatforms = storage.queryEnableParentPlatformList(true); - if (parentPlatforms.size() > 0) { - for (ParentPlatform parentPlatform : parentPlatforms) { + if (userSetting.getSendToPlatformsWhenIdLost()) { + // 发送给所有的上级 + List parentPlatforms = storage.queryEnableParentPlatformList(true); + if (parentPlatforms.size() > 0) { + for (ParentPlatform parentPlatform : parentPlatforms) { + try { + commanderForPlatform.sendAlarmMessage(parentPlatform, deviceAlarm); + } catch (SipException | InvalidArgumentException | ParseException e) { + logger.error("[命令发送失败] 国标级联 发送报警: {}", e.getMessage()); + } + } + } + }else { + // 获取开启了消息推送的设备和平台 + List parentPlatforms = storage.queryEnablePlatformListWithAsMessageChannel(); + if (parentPlatforms.size() > 0) { + for (ParentPlatform parentPlatform : parentPlatforms) { + try { + commanderForPlatform.sendAlarmMessage(parentPlatform, deviceAlarm); + } catch (SipException | InvalidArgumentException | ParseException e) { + logger.error("[命令发送失败] 国标级联 发送报警: {}", e.getMessage()); + } + } + } + + } + // 获取开启了消息推送的设备和平台 + List devices = storage.queryDeviceWithAsMessageChannel(); + if (devices.size() > 0) { + for (Device device : devices) { try { - commanderForPlatform.sendAlarmMessage(parentPlatform, deviceAlarm); - } catch (SipException | InvalidArgumentException | ParseException e) { - logger.error("[命令发送失败] 国标级联 发送报警: {}", e.getMessage()); + commander.sendAlarmMessage(device, deviceAlarm); + } catch (InvalidArgumentException | SipException | ParseException e) { + logger.error("[命令发送失败] 发送报警: {}", e.getMessage()); } } } + }else { Device device = storage.queryVideoDevice(gbId); ParentPlatform platform = storage.queryParentPlatByServerGBId(gbId); diff --git a/src/main/java/com/genersoft/iot/vmp/storager/IVideoManagerStorage.java b/src/main/java/com/genersoft/iot/vmp/storager/IVideoManagerStorage.java index 5965678e..b53c2d31 100644 --- a/src/main/java/com/genersoft/iot/vmp/storager/IVideoManagerStorage.java +++ b/src/main/java/com/genersoft/iot/vmp/storager/IVideoManagerStorage.java @@ -378,4 +378,7 @@ public interface IVideoManagerStorage { List queryChannelsByDeviceId(String serial, List channelIds, Boolean online); + List queryEnablePlatformListWithAsMessageChannel(); + + List queryDeviceWithAsMessageChannel(); } diff --git a/src/main/java/com/genersoft/iot/vmp/storager/dao/DeviceMapper.java b/src/main/java/com/genersoft/iot/vmp/storager/dao/DeviceMapper.java index 0aed8207..8f158e29 100644 --- a/src/main/java/com/genersoft/iot/vmp/storager/dao/DeviceMapper.java +++ b/src/main/java/com/genersoft/iot/vmp/storager/dao/DeviceMapper.java @@ -39,6 +39,7 @@ public interface DeviceMapper { "mobilePositionSubmissionInterval," + "subscribeCycleForAlarm," + "ssrcCheck," + + "asMessageChannel," + "geoCoordSys," + "treeType," + "online" + @@ -70,6 +71,7 @@ public interface DeviceMapper { "mobilePositionSubmissionInterval," + "subscribeCycleForAlarm," + "ssrcCheck," + + "asMessageChannel," + "geoCoordSys," + "treeType," + "online" + @@ -98,6 +100,7 @@ public interface DeviceMapper { "#{mobilePositionSubmissionInterval}," + "#{subscribeCycleForAlarm}," + "#{ssrcCheck}," + + "#{asMessageChannel}," + "#{geoCoordSys}," + "#{treeType}," + "#{online}" + @@ -152,6 +155,7 @@ public interface DeviceMapper { "mobilePositionSubmissionInterval," + "subscribeCycleForAlarm," + "ssrcCheck," + + "asMessageChannel," + "geoCoordSys," + "treeType," + "online," + @@ -192,6 +196,7 @@ public interface DeviceMapper { "mobilePositionSubmissionInterval," + "subscribeCycleForAlarm," + "ssrcCheck," + + "asMessageChannel," + "geoCoordSys," + "treeType," + "online " + @@ -222,6 +227,7 @@ public interface DeviceMapper { "mobilePositionSubmissionInterval," + "subscribeCycleForAlarm," + "ssrcCheck," + + "asMessageChannel," + "geoCoordSys," + "treeType," + "online" + @@ -243,6 +249,7 @@ public interface DeviceMapper { ", mobilePositionSubmissionInterval=#{mobilePositionSubmissionInterval}" + ", subscribeCycleForAlarm=#{subscribeCycleForAlarm}" + ", ssrcCheck=#{ssrcCheck}" + + ", asMessageChannel=#{asMessageChannel}" + ", geoCoordSys=#{geoCoordSys}" + ", treeType=#{treeType}" + ", mediaServerId=#{mediaServerId}" + @@ -259,6 +266,7 @@ public interface DeviceMapper { "updateTime," + "charset," + "ssrcCheck," + + "asMessageChannel," + "geoCoordSys," + "treeType," + "online" + @@ -271,6 +279,7 @@ public interface DeviceMapper { "#{updateTime}," + "#{charset}," + "#{ssrcCheck}," + + "#{asMessageChannel}," + "#{geoCoordSys}," + "#{treeType}," + "#{online}" + @@ -282,4 +291,7 @@ public interface DeviceMapper { @Select("select * from device") List getAll(); + + @Select("select * from device where asMessageChannel = 1") + List queryDeviceWithAsMessageChannel(); } diff --git a/src/main/java/com/genersoft/iot/vmp/storager/dao/ParentPlatformMapper.java b/src/main/java/com/genersoft/iot/vmp/storager/dao/ParentPlatformMapper.java index 52025eb5..89ebd69f 100644 --- a/src/main/java/com/genersoft/iot/vmp/storager/dao/ParentPlatformMapper.java +++ b/src/main/java/com/genersoft/iot/vmp/storager/dao/ParentPlatformMapper.java @@ -15,10 +15,10 @@ import java.util.List; public interface ParentPlatformMapper { @Insert("INSERT INTO parent_platform (enable, name, serverGBId, serverGBDomain, serverIP, serverPort, deviceGBId, deviceIp, " + - " devicePort, username, password, expires, keepTimeout, transport, characterSet, ptz, rtcp, " + + " devicePort, username, password, expires, keepTimeout, transport, characterSet, ptz, rtcp, asMessageChannel, " + " status, startOfflinePush, catalogId, administrativeDivision, catalogGroup, createTime, updateTime, treeType) " + " VALUES (#{enable}, #{name}, #{serverGBId}, #{serverGBDomain}, #{serverIP}, #{serverPort}, #{deviceGBId}, #{deviceIp}, " + - " #{devicePort}, #{username}, #{password}, #{expires}, #{keepTimeout}, #{transport}, #{characterSet}, #{ptz}, #{rtcp}, " + + " #{devicePort}, #{username}, #{password}, #{expires}, #{keepTimeout}, #{transport}, #{characterSet}, #{ptz}, #{rtcp}, #{asMessageChannel}, " + " #{status}, #{startOfflinePush}, #{catalogId}, #{administrativeDivision}, #{catalogGroup}, #{createTime}, #{updateTime}, #{treeType})") int addParentPlatform(ParentPlatform parentPlatform); @@ -40,6 +40,7 @@ public interface ParentPlatformMapper { "characterSet=#{characterSet}, " + "ptz=#{ptz}, " + "rtcp=#{rtcp}, " + + "asMessageChannel=#{asMessageChannel}, " + "status=#{status}, " + "startOfflinePush=#{startOfflinePush}, " + "catalogGroup=#{catalogGroup}, " + @@ -68,9 +69,12 @@ public interface ParentPlatformMapper { "FROM parent_platform pp ") List getParentPlatformList(); - @Select("SELECT * FROM parent_platform WHERE enable=#{enable}") + @Select("SELECT * FROM parent_platform WHERE enable=#{enable} ") List getEnableParentPlatformList(boolean enable); + @Select("SELECT * FROM parent_platform WHERE enable=1 and asMessageChannel = 1") + List queryEnablePlatformListWithAsMessageChannel(); + @Select("SELECT * FROM parent_platform WHERE serverGBId=#{platformGbId}") ParentPlatform getParentPlatByServerGBId(String platformGbId); diff --git a/src/main/java/com/genersoft/iot/vmp/storager/impl/VideoManagerStorageImpl.java b/src/main/java/com/genersoft/iot/vmp/storager/impl/VideoManagerStorageImpl.java index 9475abcd..3920fc7e 100644 --- a/src/main/java/com/genersoft/iot/vmp/storager/impl/VideoManagerStorageImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/storager/impl/VideoManagerStorageImpl.java @@ -524,6 +524,16 @@ public class VideoManagerStorageImpl implements IVideoManagerStorage { return platformMapper.getEnableParentPlatformList(enable); } + @Override + public List queryEnablePlatformListWithAsMessageChannel() { + return platformMapper.queryEnablePlatformListWithAsMessageChannel(); + } + + @Override + public List queryDeviceWithAsMessageChannel() { + return deviceMapper.queryDeviceWithAsMessageChannel(); + } + @Override public void outlineForAllParentPlatform() { platformMapper.outlineForAllParentPlatform(); diff --git a/src/main/resources/all-application.yml b/src/main/resources/all-application.yml index 3908019f..89da5e07 100644 --- a/src/main/resources/all-application.yml +++ b/src/main/resources/all-application.yml @@ -199,8 +199,8 @@ user-settings: sip-use-source-ip-as-remote-address: false # 是否开启sip日志 sip-log: true - # 自动数据库升级,保证表结构完整 - sync-db: true + # 消息通道功能-缺少国标ID是否给所有上级发送消息 + send-to-platforms-when-id-lost: true # 关闭在线文档(生产环境建议关闭) springdoc: diff --git a/web_src/index.html b/web_src/index.html index 778591ed..bd66d392 100644 --- a/web_src/index.html +++ b/web_src/index.html @@ -15,5 +15,6 @@
+ diff --git a/web_src/src/components/dialog/deviceEdit.vue b/web_src/src/components/dialog/deviceEdit.vue index 8a5f9d13..7597c102 100644 --- a/web_src/src/components/dialog/deviceEdit.vue +++ b/web_src/src/components/dialog/deviceEdit.vue @@ -66,6 +66,7 @@ +
diff --git a/web_src/src/components/dialog/platformEdit.vue b/web_src/src/components/dialog/platformEdit.vue index 76382324..2844fccb 100644 --- a/web_src/src/components/dialog/platformEdit.vue +++ b/web_src/src/components/dialog/platformEdit.vue @@ -96,9 +96,10 @@ - + + {{ @@ -145,6 +146,7 @@ export default { enable: true, ptz: true, rtcp: false, + asMessageChannel: false, name: null, serverGBId: null, serverGBDomain: null, @@ -213,6 +215,7 @@ export default { this.platform.enable = platform.enable; this.platform.ptz = platform.ptz; this.platform.rtcp = platform.rtcp; + this.platform.rtcpasMessageChannel = platform.asMessageChannel; this.platform.name = platform.name; this.platform.serverGBId = platform.serverGBId; this.platform.serverGBDomain = platform.serverGBDomain; @@ -290,6 +293,7 @@ export default { enable: true, ptz: true, rtcp: false, + asMessageChannel: false, name: null, serverGBId: null, administrativeDivision: null,