Commit 8d87741dea3d174f098269073429a0f6b982baa1

Authored by mrjackwang
Committed by GitHub
2 parents 5e724cc0 a51b4111

Merge branch '648540858:wvp-28181-2.0' into wvp-28181-2.0

Showing 95 changed files with 2973 additions and 1154 deletions
sql/mysql.sql
... ... @@ -50,7 +50,7 @@ CREATE TABLE `device` (
50 50 `treeType` varchar(50) COLLATE utf8mb4_general_ci NOT NULL,
51 51 PRIMARY KEY (`id`) USING BTREE,
52 52 UNIQUE KEY `device_deviceId_uindex` (`deviceId`) USING BTREE
53   -) ENGINE=InnoDB AUTO_INCREMENT=37 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC;
  53 +) ENGINE=InnoDB AUTO_INCREMENT=45 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC;
54 54 /*!40101 SET character_set_client = @saved_cs_client */;
55 55  
56 56 --
... ... @@ -142,7 +142,7 @@ CREATE TABLE `device_channel` (
142 142 PRIMARY KEY (`id`) USING BTREE,
143 143 UNIQUE KEY `device_channel_id_uindex` (`id`) USING BTREE,
144 144 UNIQUE KEY `device_channel_pk` (`channelId`,`deviceId`) USING BTREE
145   -) ENGINE=InnoDB AUTO_INCREMENT=19324 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC;
  145 +) ENGINE=InnoDB AUTO_INCREMENT=19336 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC;
146 146 /*!40101 SET character_set_client = @saved_cs_client */;
147 147  
148 148 --
... ... @@ -179,7 +179,7 @@ CREATE TABLE `device_mobile_position` (
179 179 `latitudeWgs84` double DEFAULT NULL,
180 180 `createTime` varchar(50) COLLATE utf8mb4_general_ci DEFAULT NULL,
181 181 PRIMARY KEY (`id`) USING BTREE
182   -) ENGINE=InnoDB AUTO_INCREMENT=5649 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC;
  182 +) ENGINE=InnoDB AUTO_INCREMENT=6751 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC;
183 183 /*!40101 SET character_set_client = @saved_cs_client */;
184 184  
185 185 --
... ... @@ -208,13 +208,12 @@ CREATE TABLE `gb_stream` (
208 208 `latitude` double DEFAULT NULL,
209 209 `streamType` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,
210 210 `mediaServerId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,
211   - `status` int DEFAULT NULL,
212 211 `createTime` varchar(50) COLLATE utf8mb4_general_ci DEFAULT NULL,
213 212 `gpsTime` varchar(50) COLLATE utf8mb4_general_ci DEFAULT NULL,
214 213 PRIMARY KEY (`gbStreamId`) USING BTREE,
215 214 UNIQUE KEY `app` (`app`,`stream`) USING BTREE,
216 215 UNIQUE KEY `gbId` (`gbId`) USING BTREE
217   -) ENGINE=InnoDB AUTO_INCREMENT=301681 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC;
  216 +) ENGINE=InnoDB AUTO_INCREMENT=301740 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC;
218 217 /*!40101 SET character_set_client = @saved_cs_client */;
219 218  
220 219 --
... ... @@ -244,7 +243,7 @@ CREATE TABLE `log` (
244 243 `username` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
245 244 `createTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
246 245 PRIMARY KEY (`id`) USING BTREE
247   -) ENGINE=InnoDB AUTO_INCREMENT=29943 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC;
  246 +) ENGINE=InnoDB AUTO_INCREMENT=37760 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC;
248 247 /*!40101 SET character_set_client = @saved_cs_client */;
249 248  
250 249 --
... ... @@ -329,16 +328,16 @@ CREATE TABLE `parent_platform` (
329 328 `ptz` int DEFAULT NULL,
330 329 `rtcp` int DEFAULT NULL,
331 330 `status` bit(1) DEFAULT NULL,
332   - `shareAllLiveStream` int DEFAULT NULL,
333 331 `startOfflinePush` int DEFAULT '0',
334 332 `administrativeDivision` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
335 333 `catalogGroup` int DEFAULT '1',
336 334 `createTime` varchar(50) COLLATE utf8mb4_general_ci DEFAULT NULL,
337 335 `updateTime` varchar(50) COLLATE utf8mb4_general_ci DEFAULT NULL,
  336 + `treeType` varchar(50) COLLATE utf8mb4_general_ci NOT NULL,
338 337 PRIMARY KEY (`id`) USING BTREE,
339 338 UNIQUE KEY `parent_platform_id_uindex` (`id`) USING BTREE,
340 339 UNIQUE KEY `parent_platform_pk` (`serverGBId`) USING BTREE
341   -) ENGINE=InnoDB AUTO_INCREMENT=33 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC;
  340 +) ENGINE=InnoDB AUTO_INCREMENT=35 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC;
342 341 /*!40101 SET character_set_client = @saved_cs_client */;
343 342  
344 343 --
... ... @@ -362,6 +361,8 @@ CREATE TABLE `platform_catalog` (
362 361 `platformId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
363 362 `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
364 363 `parentId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,
  364 + `civilCode` varchar(50) COLLATE utf8mb4_general_ci DEFAULT NULL,
  365 + `businessGroupId` varchar(50) COLLATE utf8mb4_general_ci DEFAULT NULL,
365 366 PRIMARY KEY (`id`) USING BTREE
366 367 ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC;
367 368 /*!40101 SET character_set_client = @saved_cs_client */;
... ... @@ -388,7 +389,7 @@ CREATE TABLE `platform_gb_channel` (
388 389 `catalogId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
389 390 `deviceChannelId` int NOT NULL,
390 391 PRIMARY KEY (`id`) USING BTREE
391   -) ENGINE=InnoDB AUTO_INCREMENT=4889 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC;
  392 +) ENGINE=InnoDB AUTO_INCREMENT=4912 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC;
392 393 /*!40101 SET character_set_client = @saved_cs_client */;
393 394  
394 395 --
... ... @@ -414,7 +415,7 @@ CREATE TABLE `platform_gb_stream` (
414 415 `id` int NOT NULL AUTO_INCREMENT,
415 416 PRIMARY KEY (`id`) USING BTREE,
416 417 UNIQUE KEY `platform_gb_stream_pk` (`platformId`,`catalogId`,`gbStreamId`) USING BTREE
417   -) ENGINE=InnoDB AUTO_INCREMENT=302077 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC;
  418 +) ENGINE=InnoDB AUTO_INCREMENT=302134 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC;
418 419 /*!40101 SET character_set_client = @saved_cs_client */;
419 420  
420 421 --
... ... @@ -455,7 +456,7 @@ CREATE TABLE `stream_proxy` (
455 456 `updateTime` varchar(50) COLLATE utf8mb4_general_ci DEFAULT NULL,
456 457 PRIMARY KEY (`id`) USING BTREE,
457 458 UNIQUE KEY `stream_proxy_pk` (`app`,`stream`) USING BTREE
458   -) ENGINE=InnoDB AUTO_INCREMENT=65 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC;
  459 +) ENGINE=InnoDB AUTO_INCREMENT=66 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC;
459 460 /*!40101 SET character_set_client = @saved_cs_client */;
460 461  
461 462 --
... ... @@ -487,9 +488,10 @@ CREATE TABLE `stream_push` (
487 488 `serverId` varchar(50) COLLATE utf8mb4_general_ci NOT NULL,
488 489 `pushTime` varchar(50) COLLATE utf8mb4_general_ci DEFAULT NULL,
489 490 `updateTime` varchar(50) COLLATE utf8mb4_general_ci DEFAULT NULL,
  491 + `status` int DEFAULT NULL,
490 492 PRIMARY KEY (`id`) USING BTREE,
491 493 UNIQUE KEY `stream_push_pk` (`app`,`stream`) USING BTREE
492   -) ENGINE=InnoDB AUTO_INCREMENT=305304 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC;
  494 +) ENGINE=InnoDB AUTO_INCREMENT=305390 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC;
493 495 /*!40101 SET character_set_client = @saved_cs_client */;
494 496  
495 497 --
... ... @@ -515,6 +517,7 @@ CREATE TABLE `user` (
515 517 `roleId` int NOT NULL,
516 518 `createTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
517 519 `updateTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
  520 + `pushKey` varchar(50) COLLATE utf8mb4_general_ci DEFAULT NULL,
518 521 PRIMARY KEY (`id`) USING BTREE,
519 522 UNIQUE KEY `user_username_uindex` (`username`) USING BTREE
520 523 ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC;
... ... @@ -526,7 +529,7 @@ CREATE TABLE `user` (
526 529  
527 530 LOCK TABLES `user` WRITE;
528 531 /*!40000 ALTER TABLE `user` DISABLE KEYS */;
529   -INSERT INTO `user` VALUES (1,'admin','21232f297a57a5a743894a0e4a801fc3',1,'2021 - 04 - 13 14:14:57','2021 - 04 - 13 14:14:57');
  532 +INSERT INTO `user` VALUES (1,'admin','21232f297a57a5a743894a0e4a801fc3',1,'2021 - 04 - 13 14:14:57','2021 - 04 - 13 14:14:57','453df297a57a5a7438934sda801fc3');
530 533 /*!40000 ALTER TABLE `user` ENABLE KEYS */;
531 534 UNLOCK TABLES;
532 535  
... ... @@ -566,4 +569,4 @@ UNLOCK TABLES;
566 569 /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
567 570 /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
568 571  
569   --- Dump completed on 2022-07-06 9:43:54
  572 +-- Dump completed on 2022-07-17 23:15:09
... ...
sql/update.sql
... ... @@ -52,9 +52,30 @@ alter table stream_proxy
52 52 alter table stream_push
53 53 add pushTime varchar(50) default null;
54 54 alter table stream_push
  55 + add status int DEFAULT NULL;
  56 +alter table stream_push
55 57 add updateTime varchar(50) default null;
56 58 alter table stream_push
  59 + add pushIng int DEFAULT NULL;
  60 +alter table stream_push
57 61 change createStamp createTime varchar(50) default null;
58 62  
  63 +alter table gb_stream
  64 + drop column status;
  65 +
  66 +alter table user
  67 + add pushKey varchar(50) default null;
  68 +update user set pushKey='453df297a57a5a7438934sda801fc3' where id=1;
  69 +
  70 +alter table parent_platform
  71 + add treeType varchar(50) not null;
  72 +update parent_platform set parent_platform.treeType='BusinessGroup';
  73 +alter table parent_platform drop shareAllLiveStream;
  74 +
  75 +alter table platform_catalog
  76 + add civilCode varchar(50) default null;
  77 +alter table platform_catalog
  78 + add businessGroupId varchar(50) default null;
  79 +
59 80  
60 81  
... ...
src/main/java/com/genersoft/iot/vmp/VManageBootstrap.java
... ... @@ -11,7 +11,7 @@ import org.springframework.scheduling.annotation.EnableScheduling;
11 11 import springfox.documentation.oas.annotations.EnableOpenApi;
12 12  
13 13 /**
14   - *
  14 + * 启动类
15 15 */
16 16 @ServletComponentScan("com.genersoft.iot.vmp.conf")
17 17 @SpringBootApplication
... ...
src/main/java/com/genersoft/iot/vmp/common/StreamInfo.java
... ... @@ -9,6 +9,9 @@ public class StreamInfo {
9 9 private String deviceID;
10 10 private String channelId;
11 11 private String flv;
  12 +
  13 + private String ip;
  14 +
12 15 private String https_flv;
13 16 private String ws_flv;
14 17 private String wss_flv;
... ... @@ -292,4 +295,12 @@ public class StreamInfo {
292 295 public void setProgress(double progress) {
293 296 this.progress = progress;
294 297 }
  298 +
  299 + public String getIp() {
  300 + return ip;
  301 + }
  302 +
  303 + public void setIp(String ip) {
  304 + this.ip = ip;
  305 + }
295 306 }
... ...
src/main/java/com/genersoft/iot/vmp/common/VideoManagerConstants.java
... ... @@ -58,6 +58,8 @@ public class VideoManagerConstants {
58 58  
59 59 public static final String MEDIA_TRANSACTION_USED_PREFIX = "VMP_MEDIA_TRANSACTION_";
60 60  
  61 + public static final String MEDIA_STREAM_AUTHORITY = "MEDIA_STREAM_AUTHORITY_";
  62 +
61 63 public static final String SIP_CSEQ_PREFIX = "VMP_SIP_CSEQ_";
62 64  
63 65 public static final String SIP_SN_PREFIX = "VMP_SIP_SN_";
... ... @@ -71,6 +73,8 @@ public class VideoManagerConstants {
71 73 public static final String SYSTEM_INFO_NET_PREFIX = "VMP_SYSTEM_INFO_NET_";
72 74  
73 75  
  76 +
  77 +
74 78 //************************** redis 消息*********************************
75 79  
76 80 // 流变化的通知
... ... @@ -79,9 +83,15 @@ public class VideoManagerConstants {
79 83 // 接收推流设备的GPS变化通知
80 84 public static final String VM_MSG_GPS = "VM_MSG_GPS";
81 85  
  86 + // 接收推流设备的GPS变化通知
  87 + public static final String VM_MSG_PUSH_STREAM_STATUS_CHANGE = "VM_MSG_PUSH_STREAM_STATUS_CHANGE";
  88 +
82 89 // redis 消息通知设备推流到平台
83 90 public static final String VM_MSG_STREAM_PUSH_REQUESTED = "VM_MSG_STREAM_PUSH_REQUESTED";
84 91  
  92 + // redis 消息请求所有的在线通道
  93 + public static final String VM_MSG_GET_ALL_ONLINE_REQUESTED = "VM_MSG_GET_ALL_ONLINE_REQUESTED";
  94 +
85 95 // 移动位置订阅通知
86 96 public static final String VM_MSG_SUBSCRIBE_MOBILE_POSITION = "mobileposition";
87 97  
... ... @@ -94,6 +104,10 @@ public class VideoManagerConstants {
94 104 // 设备状态订阅的通知
95 105 public static final String VM_MSG_SUBSCRIBE_DEVICE_STATUS = "device";
96 106  
  107 +
  108 +
  109 +
  110 +
97 111 //************************** 第三方 ****************************************
98 112 public static final String WVP_STREAM_GB_ID_PREFIX = "memberNo_";
99 113 public static final String WVP_STREAM_GPS_MSG_PREFIX = "WVP_STREAM_GPS_MSG_";
... ...
src/main/java/com/genersoft/iot/vmp/conf/DynamicTask.java
... ... @@ -5,6 +5,7 @@ import org.slf4j.Logger;
5 5 import org.slf4j.LoggerFactory;
6 6 import org.springframework.beans.factory.annotation.Autowired;
7 7 import org.springframework.context.annotation.Bean;
  8 +import org.springframework.scheduling.annotation.Scheduled;
8 9 import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
9 10 import org.springframework.stereotype.Component;
10 11  
... ... @@ -103,12 +104,9 @@ public class DynamicTask {
103 104  
104 105 public void stop(String key) {
105 106 if (futureMap.get(key) != null && !futureMap.get(key).isCancelled()) {
106   -// Runnable runnable = runnableMap.get(key);
107   -// if (runnable instanceof ISubscribeTask) {
108   -// ISubscribeTask subscribeTask = (ISubscribeTask) runnable;
109   -// subscribeTask.stop();
110   -// }
111 107 futureMap.get(key).cancel(false);
  108 + futureMap.remove(key);
  109 + runnableMap.remove(key);
112 110 }
113 111 }
114 112  
... ... @@ -123,4 +121,19 @@ public class DynamicTask {
123 121 public Runnable get(String key) {
124 122 return runnableMap.get(key);
125 123 }
  124 +
  125 + /**
  126 + * 每五分钟检查失效的任务,并移除
  127 + */
  128 + @Scheduled(cron="0 0/5 * * * ?")
  129 + public void execute(){
  130 + if (futureMap.size() > 0) {
  131 + for (String key : futureMap.keySet()) {
  132 + if (futureMap.get(key).isDone()) {
  133 + futureMap.remove(key);
  134 + runnableMap.remove(key);
  135 + }
  136 + }
  137 + }
  138 + }
126 139 }
... ...
src/main/java/com/genersoft/iot/vmp/conf/RedisConfig.java
1 1 package com.genersoft.iot.vmp.conf;
2 2  
3 3 import com.genersoft.iot.vmp.common.VideoManagerConstants;
4   -import com.genersoft.iot.vmp.service.impl.RedisAlarmMsgListener;
5   -import com.genersoft.iot.vmp.service.impl.RedisGpsMsgListener;
6   -import com.genersoft.iot.vmp.service.impl.RedisGbPlayMsgListener;
7   -import com.genersoft.iot.vmp.service.impl.RedisStreamMsgListener;
  4 +import com.genersoft.iot.vmp.service.impl.*;
8 5 import org.apache.commons.lang3.StringUtils;
9 6 import org.springframework.beans.factory.annotation.Autowired;
10 7 import org.springframework.beans.factory.annotation.Value;
... ... @@ -60,6 +57,9 @@ public class RedisConfig extends CachingConfigurerSupport {
60 57 @Autowired
61 58 private RedisGbPlayMsgListener redisGbPlayMsgListener;
62 59  
  60 + @Autowired
  61 + private RedisPushStreamStatusMsgListener redisPushStreamStatusMsgListener;
  62 +
63 63 @Bean
64 64 public JedisPool jedisPool() {
65 65 if (StringUtils.isBlank(password)) {
... ... @@ -108,6 +108,7 @@ public class RedisConfig extends CachingConfigurerSupport {
108 108 container.addMessageListener(redisAlarmMsgListener, new PatternTopic(VideoManagerConstants.VM_MSG_SUBSCRIBE_ALARM_RECEIVE));
109 109 container.addMessageListener(redisStreamMsgListener, new PatternTopic(VideoManagerConstants.WVP_MSG_STREAM_CHANGE_PREFIX + "PUSH"));
110 110 container.addMessageListener(redisGbPlayMsgListener, new PatternTopic(RedisGbPlayMsgListener.WVP_PUSH_STREAM_KEY));
  111 + container.addMessageListener(redisPushStreamStatusMsgListener, new PatternTopic(VideoManagerConstants.VM_MSG_PUSH_STREAM_STATUS_CHANGE));
111 112 return container;
112 113 }
113 114  
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/bean/ParentPlatform.java
... ... @@ -105,11 +105,6 @@ public class ParentPlatform {
105 105 private int channelCount;
106 106  
107 107 /**
108   - * 共享所有的直播流
109   - */
110   - private boolean shareAllLiveStream;
111   -
112   - /**
113 108 * 默认目录Id,自动添加的通道多放在这个目录下
114 109 */
115 110 private String catalogId;
... ... @@ -154,6 +149,11 @@ public class ParentPlatform {
154 149 */
155 150 private String createTime;
156 151  
  152 + /**
  153 + * 树类型 国标规定了两种树的展现方式 行政区划 CivilCode 和业务分组:BusinessGroup
  154 + */
  155 + private String treeType;
  156 +
157 157 public Integer getId() {
158 158 return id;
159 159 }
... ... @@ -314,15 +314,6 @@ public class ParentPlatform {
314 314 this.channelCount = channelCount;
315 315 }
316 316  
317   -
318   - public boolean isShareAllLiveStream() {
319   - return shareAllLiveStream;
320   - }
321   -
322   - public void setShareAllLiveStream(boolean shareAllLiveStream) {
323   - this.shareAllLiveStream = shareAllLiveStream;
324   - }
325   -
326 317 public String getCatalogId() {
327 318 return catalogId;
328 319 }
... ... @@ -394,4 +385,12 @@ public class ParentPlatform {
394 385 public void setCreateTime(String createTime) {
395 386 this.createTime = createTime;
396 387 }
  388 +
  389 + public String getTreeType() {
  390 + return treeType;
  391 + }
  392 +
  393 + public void setTreeType(String treeType) {
  394 + this.treeType = treeType;
  395 + }
397 396 }
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/bean/PlatformCatalog.java
1 1 package com.genersoft.iot.vmp.gb28181.bean;
2 2  
  3 +/**
  4 + * 国标级联-目录
  5 + * @author lin
  6 + */
3 7 public class PlatformCatalog {
4 8 private String id;
5 9 private String name;
6 10 private String platformId;
7 11 private String parentId;
8   - private int childrenCount; // 子节点数
9   - private int type; // 0 目录, 1 国标通道, 2 直播流
  12 +
  13 + private String civilCode;
  14 +
  15 + private String businessGroupId;
  16 +
  17 + /**
  18 + * 子节点数
  19 + */
  20 + private int childrenCount;
  21 +
  22 + /**
  23 + * 0 目录, 1 国标通道, 2 直播流
  24 + */
  25 + private int type;
10 26  
11 27 public String getId() {
12 28 return id;
... ... @@ -68,4 +84,19 @@ public class PlatformCatalog {
68 84 this.type = 2;
69 85 }
70 86  
  87 + public String getCivilCode() {
  88 + return civilCode;
  89 + }
  90 +
  91 + public void setCivilCode(String civilCode) {
  92 + this.civilCode = civilCode;
  93 + }
  94 +
  95 + public String getBusinessGroupId() {
  96 + return businessGroupId;
  97 + }
  98 +
  99 + public void setBusinessGroupId(String businessGroupId) {
  100 + this.businessGroupId = businessGroupId;
  101 + }
71 102 }
... ...
src/main/java/com/genersoft/iot/vmp/domain/req/PresetQuerySipReq.java renamed to src/main/java/com/genersoft/iot/vmp/gb28181/bean/PresetQuerySipReq.java
1   -package com.genersoft.iot.vmp.domain.req;
  1 +package com.genersoft.iot.vmp.gb28181.bean;
2 2  
3 3  
4 4 /**
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/bean/TreeType.java 0 → 100644
  1 +package com.genersoft.iot.vmp.gb28181.bean;
  2 +
  3 +/**
  4 + * 目录结构类型
  5 + * @author lin
  6 + */
  7 +public class TreeType {
  8 + public static final String BUSINESS_GROUP = "BusinessGroup";
  9 + public static final String CIVIL_CODE = "CivilCode";
  10 +}
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/event/platformNotRegister/PlatformNotRegisterEventLister.java
... ... @@ -65,7 +65,6 @@ public class PlatformNotRegisterEventLister implements ApplicationListener<Platf
65 65 }
66 66 // 查询是否有推流, 如果有则都停止
67 67 List<SendRtpItem> sendRtpItems = redisCatchStorage.querySendRTPServer(event.getPlatformGbID());
68   - logger.info("[ 平台未注册事件 ] 停止[ {} ]的所有推流size", sendRtpItems.size());
69 68 if (sendRtpItems != null && sendRtpItems.size() > 0) {
70 69 logger.info("[ 平台未注册事件 ] 停止[ {} ]的所有推流", event.getPlatformGbID());
71 70 for (SendRtpItem sendRtpItem : sendRtpItems) {
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/event/subscribe/catalog/CatalogEvent.java
... ... @@ -11,13 +11,40 @@ public class CatalogEvent extends ApplicationEvent {
11 11 super(source);
12 12 }
13 13  
14   - public static final String ON = "ON"; // 上线
15   - public static final String OFF = "OFF"; // 离线
16   - public static final String VLOST = "VLOST"; // 视频丢失
17   - public static final String DEFECT = "DEFECT"; // 故障
18   - public static final String ADD = "ADD"; // 增加
19   - public static final String DEL = "DEL"; // 删除
20   - public static final String UPDATE = "UPDATE"; // 更新
  14 + /**
  15 + * 上线
  16 + */
  17 + public static final String ON = "ON";
  18 +
  19 + /**
  20 + * 离线
  21 + */
  22 + public static final String OFF = "OFF";
  23 +
  24 + /**
  25 + * 视频丢失
  26 + */
  27 + public static final String VLOST = "VLOST";
  28 +
  29 + /**
  30 + * 故障
  31 + */
  32 + public static final String DEFECT = "DEFECT";
  33 +
  34 + /**
  35 + * 增加
  36 + */
  37 + public static final String ADD = "ADD";
  38 +
  39 + /**
  40 + * 删除
  41 + */
  42 + public static final String DEL = "DEL";
  43 +
  44 + /**
  45 + * 更新
  46 + */
  47 + public static final String UPDATE = "UPDATE";
21 48  
22 49 private List<DeviceChannel> deviceChannels;
23 50 private List<GbStream> gbStreams;
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/event/subscribe/catalog/CatalogEventLister.java
... ... @@ -58,17 +58,16 @@ public class CatalogEventLister implements ApplicationListener&lt;CatalogEvent&gt; {
58 58 ParentPlatform parentPlatform = null;
59 59  
60 60 Map<String, List<ParentPlatform>> parentPlatformMap = new HashMap<>();
61   - if (event.getPlatformId() != null) {
  61 + if (!StringUtils.isEmpty(event.getPlatformId())) {
  62 + subscribe = subscribeHolder.getCatalogSubscribe(event.getPlatformId());
  63 + if (subscribe == null) {
  64 + return;
  65 + }
62 66 parentPlatform = storager.queryParentPlatByServerGBId(event.getPlatformId());
63 67 if (parentPlatform != null && !parentPlatform.isStatus()) {
64 68 return;
65 69 }
66   - subscribe = subscribeHolder.getCatalogSubscribe(event.getPlatformId());
67 70  
68   - if (subscribe == null) {
69   - logger.info("发送订阅消息时发现订阅信息已经不存在: {}", event.getPlatformId());
70   - return;
71   - }
72 71 }else {
73 72 // 获取所用订阅
74 73 List<String> platforms = subscribeHolder.getAllCatalogSubscribePlatform();
... ... @@ -144,11 +143,8 @@ public class CatalogEventLister implements ApplicationListener&lt;CatalogEvent&gt; {
144 143 }
145 144 if (event.getGbStreams() != null && event.getGbStreams().size() > 0){
146 145 for (GbStream gbStream : event.getGbStreams()) {
147   - DeviceChannel deviceChannelByStream = gbStreamService.getDeviceChannelListByStream(gbStream, gbStream.getCatalogId(), parentPlatform);
148   - if (deviceChannelByStream.getParentId().length() <= 10) { // 父节点是行政区划,则设置CivilCode使用此行政区划
149   - deviceChannelByStream.setCivilCode(deviceChannelByStream.getParentId());
150   - }
151   - deviceChannelList.add(deviceChannelByStream);
  146 + deviceChannelList.add(
  147 + gbStreamService.getDeviceChannelListByStream(gbStream, gbStream.getCatalogId(), parentPlatform));
152 148 }
153 149 }
154 150 if (deviceChannelList.size() > 0) {
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/task/impl/MobilePositionSubscribeHandlerTask.java
... ... @@ -57,23 +57,17 @@ public class MobilePositionSubscribeHandlerTask implements ISubscribeTask {
57 57 SubscribeInfo subscribe = subscribeHolder.getMobilePositionSubscribe(platform.getServerGBId());
58 58 if (subscribe != null) {
59 59  
60   -// if (!parentPlatform.isStatus()) {
61   -// logger.info("发送订阅时发现平台已经离线:{}", platformId);
62   -// return;
63   -// }
64 60 // TODO 暂时只处理视频流的回复,后续增加对国标设备的支持
65   - List<GbStream> gbStreams = storager.queryGbStreamListInPlatform(platform.getServerGBId());
  61 + List<DeviceChannel> gbStreams = storager.queryGbStreamListInPlatform(platform.getServerGBId());
66 62 if (gbStreams.size() == 0) {
67 63 logger.info("发送订阅时发现平台已经没有关联的直播流:{}", platform.getServerGBId());
68 64 return;
69 65 }
70   - for (GbStream gbStream : gbStreams) {
71   - String gbId = gbStream.getGbId();
  66 + for (DeviceChannel deviceChannel : gbStreams) {
  67 + String gbId = deviceChannel.getChannelId();
72 68 GPSMsgInfo gpsMsgInfo = redisCatchStorage.getGpsMsgInfo(gbId);
73   - if (gpsMsgInfo != null) { // 无最新位置不发送
74   - if (logger.isDebugEnabled()) {
75   - logger.debug("无最新位置不发送");
76   - }
  69 + // 无最新位置不发送
  70 + if (gpsMsgInfo != null) {
77 71 // 经纬度都为0不发送
78 72 if (gpsMsgInfo.getLng() == 0 && gpsMsgInfo.getLat() == 0) {
79 73 continue;
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java
... ... @@ -257,37 +257,37 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
257 257 catalogXml.append("<DeviceList Num=\"" + channels.size() +"\">\r\n");
258 258 if (channels.size() > 0) {
259 259 for (DeviceChannel channel : channels) {
  260 + if (parentPlatform.getServerGBId().equals(channel.getParentId())) {
  261 + channel.setParentId(parentPlatform.getDeviceGBId());
  262 + }
260 263 catalogXml.append("<Item>\r\n");
  264 + // 行政区划分组只需要这两项就可以
261 265 catalogXml.append("<DeviceID>" + channel.getChannelId() + "</DeviceID>\r\n");
262 266 catalogXml.append("<Name>" + channel.getName() + "</Name>\r\n");
263   - catalogXml.append("<Parental>" + channel.getParental() + "</Parental>\r\n");
264 267 if (channel.getParentId() != null) {
  268 + // 业务分组加上这一项即可,提高兼容性,
265 269 catalogXml.append("<ParentID>" + channel.getParentId() + "</ParentID>\r\n");
266 270 }
267   - if (channel.getChannelId().length() == 20) {
268   - if (Integer.parseInt(channel.getChannelId().substring(10, 13)) == 216) { // 虚拟组织增加BusinessGroupID字段
269   - catalogXml.append("<BusinessGroupID>" + channel.getParentId() + "</BusinessGroupID>\r\n");
270   - }
  271 + if (channel.getChannelId().length() == 20 && Integer.parseInt(channel.getChannelId().substring(10, 13)) == 216) {
  272 + // 虚拟组织增加BusinessGroupID字段
  273 + catalogXml.append("<BusinessGroupID>" + channel.getParentId() + "</BusinessGroupID>\r\n");
  274 + }
  275 + catalogXml.append("<Parental>" + channel.getParental() + "</Parental>\r\n");
  276 + if (channel.getParental() == 0) {
  277 + // 通道项
271 278 catalogXml.append("<Manufacturer>" + channel.getManufacture() + "</Manufacturer>\r\n");
  279 + catalogXml.append("<Secrecy>" + channel.getSecrecy() + "</Secrecy>\r\n");
272 280 catalogXml.append("<RegisterWay>" + channel.getRegisterWay() + "</RegisterWay>\r\n");
273   - catalogXml.append("<Status>" + (channel.getStatus() == 0?"OFF":"ON") + "</Status>\r\n");
274   - if (channel.getChannelType() != 2) { // 业务分组/虚拟组织/行政区划 不设置以下字段
275   - catalogXml.append("<Secrecy>" + channel.getSecrecy() + "</Secrecy>\r\n");
  281 + catalogXml.append("<Status>" + (channel.getStatus() == 0 ? "OFF" : "ON") + "</Status>\r\n");
  282 +
  283 + if (channel.getChannelType() != 2) { // 业务分组/虚拟组织/行政区划 不设置以下属性
276 284 catalogXml.append("<Model>" + channel.getModel() + "</Model>\r\n");
277   - catalogXml.append("<Owner>" + channel.getOwner() + "</Owner>\r\n");
  285 + catalogXml.append("<Owner> " + channel.getOwner()+ "</Owner>\r\n");
278 286 catalogXml.append("<CivilCode>" + channel.getCivilCode() + "</CivilCode>\r\n");
279 287 catalogXml.append("<Address>" + channel.getAddress() + "</Address>\r\n");
280   - catalogXml.append("<Longitude>" + channel.getLongitudeWgs84() + "</Longitude>\r\n");
281   - catalogXml.append("<Latitude>" + channel.getLatitudeWgs84() + "</Latitude>\r\n");
282   - catalogXml.append("<IPAddress>" + channel.getIpAddress() + "</IPAddress>\r\n");
283   - catalogXml.append("<Port>" + channel.getPort() + "</Port>\r\n");
284   - catalogXml.append("<Info>\r\n");
285   - catalogXml.append("<PTZType>" + channel.getPTZType() + "</PTZType>\r\n");
286   - catalogXml.append("</Info>\r\n");
287 288 }
288   - }
289   -
290 289  
  290 + }
291 291 catalogXml.append("</Item>\r\n");
292 292 }
293 293 }
... ... @@ -592,27 +592,35 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
592 592 channel.setParentId(parentPlatform.getDeviceGBId());
593 593 }
594 594 catalogXml.append("<Item>\r\n");
  595 + // 行政区划分组只需要这两项就可以
595 596 catalogXml.append("<DeviceID>" + channel.getChannelId() + "</DeviceID>\r\n");
596 597 catalogXml.append("<Name>" + channel.getName() + "</Name>\r\n");
597   - catalogXml.append("<Manufacturer>" + channel.getManufacture() + "</Manufacturer>\r\n");
598   - catalogXml.append("<Parental>" + channel.getParental() + "</Parental>\r\n");
599 598 if (channel.getParentId() != null) {
  599 + // 业务分组加上这一项即可,提高兼容性,
600 600 catalogXml.append("<ParentID>" + channel.getParentId() + "</ParentID>\r\n");
601 601 }
602   - catalogXml.append("<Secrecy>" + channel.getSecrecy() + "</Secrecy>\r\n");
603   - catalogXml.append("<RegisterWay>" + channel.getRegisterWay() + "</RegisterWay>\r\n");
604   - catalogXml.append("<Status>" + (channel.getStatus() == 0 ? "OFF" : "ON") + "</Status>\r\n");
605   - if (channel.getChannelId().length() == 20 && Integer.parseInt(channel.getChannelId().substring(10, 13)) == 216) { // 虚拟组织增加BusinessGroupID字段
  602 + if (channel.getChannelId().length() == 20 && Integer.parseInt(channel.getChannelId().substring(10, 13)) == 216) {
  603 + // 虚拟组织增加BusinessGroupID字段
606 604 catalogXml.append("<BusinessGroupID>" + channel.getParentId() + "</BusinessGroupID>\r\n");
607 605 }
608   - if (channel.getChannelType() == 2) { // 业务分组/虚拟组织/行政区划 不设置以下属性
609   - catalogXml.append("<Model>" + channel.getModel() + "</Model>\r\n");
610   - catalogXml.append("<Owner>0</Owner>\r\n");
611   - catalogXml.append("<CivilCode>CivilCode</CivilCode>\r\n");
612   - catalogXml.append("<Address>" + channel.getAddress() + "</Address>\r\n");
613   - }
614   - if (!"presence".equals(subscribeInfo.getEventType())) {
615   - catalogXml.append("<Event>" + type + "</Event>\r\n");
  606 + catalogXml.append("<Parental>" + channel.getParental() + "</Parental>\r\n");
  607 + if (channel.getParental() == 0) {
  608 + // 通道项
  609 + catalogXml.append("<Manufacturer>" + channel.getManufacture() + "</Manufacturer>\r\n");
  610 + catalogXml.append("<Secrecy>" + channel.getSecrecy() + "</Secrecy>\r\n");
  611 + catalogXml.append("<RegisterWay>" + channel.getRegisterWay() + "</RegisterWay>\r\n");
  612 + catalogXml.append("<Status>" + (channel.getStatus() == 0 ? "OFF" : "ON") + "</Status>\r\n");
  613 +
  614 + if (channel.getChannelType() != 2) { // 业务分组/虚拟组织/行政区划 不设置以下属性
  615 + catalogXml.append("<Model>" + channel.getModel() + "</Model>\r\n");
  616 + catalogXml.append("<Owner> " + channel.getOwner()+ "</Owner>\r\n");
  617 + catalogXml.append("<CivilCode>" + channel.getCivilCode() + "</CivilCode>\r\n");
  618 + catalogXml.append("<Address>" + channel.getAddress() + "</Address>\r\n");
  619 + }
  620 + if (!"presence".equals(subscribeInfo.getEventType())) {
  621 + catalogXml.append("<Event>" + type + "</Event>\r\n");
  622 + }
  623 +
616 624 }
617 625 catalogXml.append("</Item>\r\n");
618 626 }
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/NotifyRequestProcessor.java
... ... @@ -15,6 +15,7 @@ import com.genersoft.iot.vmp.gb28181.utils.Coordtransform;
15 15 import com.genersoft.iot.vmp.gb28181.utils.NumericUtil;
16 16 import com.genersoft.iot.vmp.gb28181.utils.SipUtils;
17 17 import com.genersoft.iot.vmp.gb28181.utils.XmlUtil;
  18 +import com.genersoft.iot.vmp.service.IDeviceChannelService;
18 19 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
19 20 import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
20 21 import com.genersoft.iot.vmp.utils.DateUtil;
... ... @@ -71,6 +72,9 @@ public class NotifyRequestProcessor extends SIPRequestProcessorParent implements
71 72 @Autowired
72 73 private SIPProcessorObserver sipProcessorObserver;
73 74  
  75 + @Autowired
  76 + private IDeviceChannelService deviceChannelService;
  77 +
74 78 private boolean taskQueueHandlerRun = false;
75 79  
76 80 private final ConcurrentLinkedQueue<HandlerCatchData> taskQueue = new ConcurrentLinkedQueue<>();
... ... @@ -173,28 +177,7 @@ public class NotifyRequestProcessor extends SIPRequestProcessorParent implements
173 177 logger.info("[收到 移动位置订阅]:{}/{}->{}.{}", mobilePosition.getDeviceId(), mobilePosition.getChannelId(),
174 178 mobilePosition.getLongitude(), mobilePosition.getLatitude());
175 179 mobilePosition.setReportSource("Mobile Position");
176   - // 默认来源坐标系为WGS-84处理
177   - if ("WGS84".equals(device.getGeoCoordSys())) {
178   - mobilePosition.setLongitudeWgs84(mobilePosition.getLongitude());
179   - mobilePosition.setLatitudeWgs84(mobilePosition.getLatitude());
180   - Double[] position = Coordtransform.WGS84ToGCJ02(mobilePosition.getLongitude(), mobilePosition.getLatitude());
181   - mobilePosition.setLongitudeGcj02(position[0]);
182   - mobilePosition.setLatitudeGcj02(position[1]);
183   - }else if ("GCJ02".equals(device.getGeoCoordSys())) {
184   - mobilePosition.setLongitudeGcj02(mobilePosition.getLongitude());
185   - mobilePosition.setLatitudeGcj02(mobilePosition.getLatitude());
186   - Double[] position = Coordtransform.GCJ02ToWGS84(mobilePosition.getLongitude(), mobilePosition.getLatitude());
187   - mobilePosition.setLongitudeWgs84(position[0]);
188   - mobilePosition.setLatitudeWgs84(position[1]);
189   - }else {
190   - mobilePosition.setLongitudeGcj02(0.00);
191   - mobilePosition.setLatitudeGcj02(0.00);
192   - mobilePosition.setLongitudeWgs84(0.00);
193   - mobilePosition.setLatitudeWgs84(0.00);
194   - }
195   - if (userSetting.getSavePositionHistory()) {
196   - storager.insertMobilePosition(mobilePosition);
197   - }
  180 +
198 181  
199 182 // 更新device channel 的经纬度
200 183 DeviceChannel deviceChannel = new DeviceChannel();
... ... @@ -202,11 +185,18 @@ public class NotifyRequestProcessor extends SIPRequestProcessorParent implements
202 185 deviceChannel.setChannelId(channelId);
203 186 deviceChannel.setLongitude(mobilePosition.getLongitude());
204 187 deviceChannel.setLatitude(mobilePosition.getLatitude());
205   - deviceChannel.setLongitudeWgs84(mobilePosition.getLongitudeWgs84());
206   - deviceChannel.setLatitudeWgs84(mobilePosition.getLatitudeWgs84());
207   - deviceChannel.setLongitudeGcj02(mobilePosition.getLongitudeGcj02());
208   - deviceChannel.setLatitudeGcj02(mobilePosition.getLatitudeGcj02());
209 188 deviceChannel.setGpsTime(mobilePosition.getTime());
  189 + deviceChannel = deviceChannelService.updateGps(deviceChannel, device);
  190 +
  191 + mobilePosition.setLongitudeWgs84(deviceChannel.getLongitudeWgs84());
  192 + mobilePosition.setLatitudeWgs84(deviceChannel.getLatitudeWgs84());
  193 + mobilePosition.setLongitudeGcj02(deviceChannel.getLongitudeGcj02());
  194 + mobilePosition.setLatitudeGcj02(deviceChannel.getLatitudeGcj02());
  195 +
  196 + if (userSetting.getSavePositionHistory()) {
  197 + storager.insertMobilePosition(mobilePosition);
  198 + }
  199 +
210 200 storager.updateChannelPosition(deviceChannel);
211 201 // 发送redis消息。 通知位置信息的变化
212 202 JSONObject jsonObject = new JSONObject();
... ... @@ -281,38 +271,28 @@ public class NotifyRequestProcessor extends SIPRequestProcessorParent implements
281 271 mobilePosition.setLongitude(deviceAlarm.getLongitude());
282 272 mobilePosition.setLatitude(deviceAlarm.getLatitude());
283 273 mobilePosition.setReportSource("GPS Alarm");
284   - if ("WGS84".equals(device.getGeoCoordSys())) {
285   - mobilePosition.setLongitudeWgs84(mobilePosition.getLongitude());
286   - mobilePosition.setLatitudeWgs84(mobilePosition.getLatitude());
287   - Double[] position = Coordtransform.WGS84ToGCJ02(mobilePosition.getLongitude(), mobilePosition.getLatitude());
288   - mobilePosition.setLongitudeGcj02(position[0]);
289   - mobilePosition.setLatitudeGcj02(position[1]);
290   - }else if ("GCJ02".equals(device.getGeoCoordSys())) {
291   - mobilePosition.setLongitudeGcj02(mobilePosition.getLongitude());
292   - mobilePosition.setLatitudeGcj02(mobilePosition.getLatitude());
293   - Double[] position = Coordtransform.GCJ02ToWGS84(mobilePosition.getLongitude(), mobilePosition.getLatitude());
294   - mobilePosition.setLongitudeWgs84(position[0]);
295   - mobilePosition.setLatitudeWgs84(position[1]);
296   - }else {
297   - mobilePosition.setLongitudeGcj02(0.00);
298   - mobilePosition.setLatitudeGcj02(0.00);
299   - mobilePosition.setLongitudeWgs84(0.00);
300   - mobilePosition.setLatitudeWgs84(0.00);
301   - }
302   - if (userSetting.getSavePositionHistory()) {
303   - storager.insertMobilePosition(mobilePosition);
304   - }
  274 +
  275 +
  276 +
305 277 // 更新device channel 的经纬度
306 278 DeviceChannel deviceChannel = new DeviceChannel();
307 279 deviceChannel.setDeviceId(device.getDeviceId());
308 280 deviceChannel.setChannelId(channelId);
309 281 deviceChannel.setLongitude(mobilePosition.getLongitude());
310 282 deviceChannel.setLatitude(mobilePosition.getLatitude());
311   - deviceChannel.setLongitudeWgs84(mobilePosition.getLongitudeWgs84());
312   - deviceChannel.setLatitudeWgs84(mobilePosition.getLatitudeWgs84());
313   - deviceChannel.setLongitudeGcj02(mobilePosition.getLongitudeGcj02());
314   - deviceChannel.setLatitudeGcj02(mobilePosition.getLatitudeGcj02());
315 283 deviceChannel.setGpsTime(mobilePosition.getTime());
  284 +
  285 + deviceChannel = deviceChannelService.updateGps(deviceChannel, device);
  286 +
  287 + mobilePosition.setLongitudeWgs84(deviceChannel.getLongitudeWgs84());
  288 + mobilePosition.setLatitudeWgs84(deviceChannel.getLatitudeWgs84());
  289 + mobilePosition.setLongitudeGcj02(deviceChannel.getLongitudeGcj02());
  290 + mobilePosition.setLatitudeGcj02(deviceChannel.getLatitudeGcj02());
  291 +
  292 + if (userSetting.getSavePositionHistory()) {
  293 + storager.insertMobilePosition(mobilePosition);
  294 + }
  295 +
316 296 storager.updateChannelPosition(deviceChannel);
317 297 }
318 298 // TODO: 需要实现存储报警信息、报警分类
... ... @@ -364,7 +344,7 @@ public class NotifyRequestProcessor extends SIPRequestProcessorParent implements
364 344 }else {
365 345 event = eventElement.getText().toUpperCase();
366 346 }
367   - DeviceChannel channel = XmlUtil.channelContentHander(itemDevice, device);
  347 + DeviceChannel channel = XmlUtil.channelContentHander(itemDevice, device, event);
368 348 channel.setDeviceId(device.getDeviceId());
369 349 logger.info("[收到 目录订阅]:{}/{}", device.getDeviceId(), channel.getChannelId());
370 350 switch (event) {
... ... @@ -389,7 +369,7 @@ public class NotifyRequestProcessor extends SIPRequestProcessorParent implements
389 369 case CatalogEvent.ADD:
390 370 // 增加
391 371 logger.info("收到来自设备【{}】的增加通道【{}】通知", device.getDeviceId(), channel.getChannelId());
392   - storager.updateChannel(deviceId, channel);
  372 + deviceChannelService.updateChannel(deviceId, channel);
393 373 break;
394 374 case CatalogEvent.DEL:
395 375 // 删除
... ... @@ -399,7 +379,7 @@ public class NotifyRequestProcessor extends SIPRequestProcessorParent implements
399 379 case CatalogEvent.UPDATE:
400 380 // 更新
401 381 logger.info("收到来自设备【{}】的更新通道【{}】通知", device.getDeviceId(), channel.getChannelId());
402   - storager.updateChannel(deviceId, channel);
  382 + deviceChannelService.updateChannel(deviceId, channel);
403 383 break;
404 384 default:
405 385 logger.warn("[ NotifyCatalog ] event not found : {}", event );
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/AlarmNotifyMessageHandler.java
... ... @@ -11,6 +11,7 @@ import com.genersoft.iot.vmp.gb28181.utils.Coordtransform;
11 11 import com.genersoft.iot.vmp.gb28181.utils.NumericUtil;
12 12 import com.genersoft.iot.vmp.gb28181.utils.XmlUtil;
13 13 import com.genersoft.iot.vmp.service.IDeviceAlarmService;
  14 +import com.genersoft.iot.vmp.service.IDeviceChannelService;
14 15 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
15 16 import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
16 17 import com.genersoft.iot.vmp.utils.DateUtil;
... ... @@ -58,6 +59,9 @@ public class AlarmNotifyMessageHandler extends SIPRequestProcessorParent impleme
58 59 @Autowired
59 60 private IDeviceAlarmService deviceAlarmService;
60 61  
  62 + @Autowired
  63 + private IDeviceChannelService deviceChannelService;
  64 +
61 65 @Override
62 66 public void afterPropertiesSet() throws Exception {
63 67 notifyMessageHandler.addHandler(cmdType, this);
... ... @@ -119,38 +123,26 @@ public class AlarmNotifyMessageHandler extends SIPRequestProcessorParent impleme
119 123 mobilePosition.setLongitude(deviceAlarm.getLongitude());
120 124 mobilePosition.setLatitude(deviceAlarm.getLatitude());
121 125 mobilePosition.setReportSource("GPS Alarm");
122   - if ("WGS84".equals(device.getGeoCoordSys())) {
123   - mobilePosition.setLongitudeWgs84(mobilePosition.getLongitude());
124   - mobilePosition.setLatitudeWgs84(mobilePosition.getLatitude());
125   - Double[] position = Coordtransform.WGS84ToGCJ02(mobilePosition.getLongitude(), mobilePosition.getLatitude());
126   - mobilePosition.setLongitudeGcj02(position[0]);
127   - mobilePosition.setLatitudeGcj02(position[1]);
128   - }else if ("GCJ02".equals(device.getGeoCoordSys())) {
129   - mobilePosition.setLongitudeGcj02(mobilePosition.getLongitude());
130   - mobilePosition.setLatitudeGcj02(mobilePosition.getLatitude());
131   - Double[] position = Coordtransform.GCJ02ToWGS84(mobilePosition.getLongitude(), mobilePosition.getLatitude());
132   - mobilePosition.setLongitudeWgs84(position[0]);
133   - mobilePosition.setLatitudeWgs84(position[1]);
134   - }else {
135   - mobilePosition.setLongitudeGcj02(0.00);
136   - mobilePosition.setLatitudeGcj02(0.00);
137   - mobilePosition.setLongitudeWgs84(0.00);
138   - mobilePosition.setLatitudeWgs84(0.00);
139   - }
140   - if (userSetting.getSavePositionHistory()) {
141   - storager.insertMobilePosition(mobilePosition);
142   - }
  126 +
  127 +
143 128 // 更新device channel 的经纬度
144 129 DeviceChannel deviceChannel = new DeviceChannel();
145 130 deviceChannel.setDeviceId(device.getDeviceId());
146 131 deviceChannel.setChannelId(channelId);
147 132 deviceChannel.setLongitude(mobilePosition.getLongitude());
148 133 deviceChannel.setLatitude(mobilePosition.getLatitude());
149   - deviceChannel.setLongitudeWgs84(mobilePosition.getLongitudeWgs84());
150   - deviceChannel.setLatitudeWgs84(mobilePosition.getLatitudeWgs84());
151   - deviceChannel.setLongitudeGcj02(mobilePosition.getLongitudeGcj02());
152   - deviceChannel.setLatitudeGcj02(mobilePosition.getLatitudeGcj02());
153 134 deviceChannel.setGpsTime(mobilePosition.getTime());
  135 +
  136 + deviceChannel = deviceChannelService.updateGps(deviceChannel, device);
  137 +
  138 + mobilePosition.setLongitudeWgs84(deviceChannel.getLongitudeWgs84());
  139 + mobilePosition.setLatitudeWgs84(deviceChannel.getLatitudeWgs84());
  140 + mobilePosition.setLongitudeGcj02(deviceChannel.getLongitudeGcj02());
  141 + mobilePosition.setLatitudeGcj02(deviceChannel.getLatitudeGcj02());
  142 +
  143 + if (userSetting.getSavePositionHistory()) {
  144 + storager.insertMobilePosition(mobilePosition);
  145 + }
154 146 storager.updateChannelPosition(deviceChannel);
155 147 }
156 148 }
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/CatalogNotifyMessageHandler.java
... ... @@ -58,85 +58,21 @@ public class CatalogNotifyMessageHandler extends SIPRequestProcessorParent imple
58 58 // 准备回复通道信息
59 59 List<DeviceChannelInPlatform> deviceChannels = storage.queryChannelListInParentPlatform(parentPlatform.getServerGBId());
60 60 // 查询关联的直播通道
61   - List<GbStream> gbStreams = storage.queryGbStreamListInPlatform(parentPlatform.getServerGBId());
  61 + List<DeviceChannel> gbStreams = storage.queryGbStreamListInPlatform(parentPlatform.getServerGBId());
  62 + // 回复目录信息
  63 + List<DeviceChannel> catalogs = storage.queryCatalogInPlatform(parentPlatform.getServerGBId());
62 64  
63 65 List<DeviceChannel> allChannels = new ArrayList<>();
64   - // 回复目录信息
65   - List<PlatformCatalog> catalogs = storage.queryCatalogInPlatform(parentPlatform.getServerGBId());
66 66 if (catalogs.size() > 0) {
67   - for (PlatformCatalog catalog : catalogs) {
68   - if (catalog.getParentId().equals(catalog.getPlatformId())) {
69   - catalog.setParentId(parentPlatform.getDeviceGBId());
70   - }
71   - DeviceChannel deviceChannel = new DeviceChannel();
72   - deviceChannel.setChannelId(catalog.getId());
73   - deviceChannel.setName(catalog.getName());
74   - deviceChannel.setLongitude(0.0);
75   - deviceChannel.setLatitude(0.0);
76   - deviceChannel.setDeviceId(parentPlatform.getDeviceGBId());
77   - deviceChannel.setManufacture("wvp-pro");
78   - deviceChannel.setStatus(1);
79   - deviceChannel.setParental(1);
80   - deviceChannel.setParentId(catalog.getParentId());
81   - deviceChannel.setRegisterWay(1);
82   - if (catalog.getParentId() != null && catalog.getParentId().length() <= 10) {
83   - deviceChannel.setCivilCode(catalog.getParentId());
84   - }else {
85   - deviceChannel.setCivilCode(parentPlatform.getAdministrativeDivision());
86   - }
87   - deviceChannel.setCivilCode(parentPlatform.getAdministrativeDivision());
88   - deviceChannel.setModel("live");
89   - deviceChannel.setOwner("wvp-pro");
90   - deviceChannel.setSecrecy("0");
91   - allChannels.add(deviceChannel);
92   - }
  67 + allChannels.addAll(catalogs);
93 68 }
94 69 // 回复级联的通道
95 70 if (deviceChannels.size() > 0) {
96   - for (DeviceChannelInPlatform channel : deviceChannels) {
97   - if (channel.getCatalogId().equals(parentPlatform.getServerGBId())) {
98   - channel.setCatalogId(parentPlatform.getDeviceGBId());
99   - }
100   - DeviceChannel deviceChannel = storage.queryChannel(channel.getDeviceId(), channel.getChannelId());
101   - deviceChannel.setParental(0);
102   - deviceChannel.setParentId(channel.getCatalogId());
103   - if (channel.getCatalogId() != null && channel.getCatalogId().length() <= 10) {
104   - channel.setCivilCode(channel.getCatalogId());
105   - }else {
106   - deviceChannel.setCivilCode(parentPlatform.getAdministrativeDivision());
107   - }
108   -
109   - allChannels.add(deviceChannel);
110   - }
  71 + allChannels.addAll(deviceChannels);
111 72 }
112 73 // 回复直播的通道
113 74 if (gbStreams.size() > 0) {
114   - for (GbStream gbStream : gbStreams) {
115   - if (gbStream.getCatalogId().equals(parentPlatform.getServerGBId())) {
116   - gbStream.setCatalogId(null);
117   - }
118   - DeviceChannel deviceChannel = new DeviceChannel();
119   - deviceChannel.setChannelId(gbStream.getGbId());
120   - deviceChannel.setName(gbStream.getName());
121   - deviceChannel.setLongitude(gbStream.getLongitude());
122   - deviceChannel.setLatitude(gbStream.getLatitude());
123   - deviceChannel.setDeviceId(parentPlatform.getDeviceGBId());
124   - deviceChannel.setManufacture("wvp-pro");
125   -// deviceChannel.setStatus(gbStream.isStatus()?1:0);
126   - deviceChannel.setStatus(1);
127   - deviceChannel.setParentId(gbStream.getCatalogId());
128   - deviceChannel.setRegisterWay(1);
129   - if (gbStream.getCatalogId() != null && gbStream.getCatalogId().length() <= 10) {
130   - deviceChannel.setCivilCode(gbStream.getCatalogId());
131   - }else {
132   - deviceChannel.setCivilCode(parentPlatform.getAdministrativeDivision());
133   - }
134   - deviceChannel.setModel("live");
135   - deviceChannel.setOwner("wvp-pro");
136   - deviceChannel.setParental(0);
137   - deviceChannel.setSecrecy("0");
138   - allChannels.add(deviceChannel);
139   - }
  75 + allChannels.addAll(gbStreams);
140 76 }
141 77 if (allChannels.size() > 0) {
142 78 cmderFroPlatform.catalogQuery(allChannels, parentPlatform, sn, fromHeader.getTag());
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/MobilePositionNotifyMessageHandler.java
... ... @@ -7,6 +7,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.IMessag
7 7 import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.notify.NotifyMessageHandler;
8 8 import com.genersoft.iot.vmp.gb28181.utils.Coordtransform;
9 9 import com.genersoft.iot.vmp.gb28181.utils.NumericUtil;
  10 +import com.genersoft.iot.vmp.service.IDeviceChannelService;
10 11 import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
11 12 import com.genersoft.iot.vmp.utils.DateUtil;
12 13 import com.genersoft.iot.vmp.utils.GpsUtil;
... ... @@ -42,6 +43,9 @@ public class MobilePositionNotifyMessageHandler extends SIPRequestProcessorParen
42 43 @Autowired
43 44 private IVideoManagerStorage storager;
44 45  
  46 + @Autowired
  47 + private IDeviceChannelService deviceChannelService;
  48 +
45 49 @Override
46 50 public void afterPropertiesSet() throws Exception {
47 51 notifyMessageHandler.addHandler(cmdType, this);
... ... @@ -79,38 +83,26 @@ public class MobilePositionNotifyMessageHandler extends SIPRequestProcessorParen
79 83 mobilePosition.setAltitude(0.0);
80 84 }
81 85 mobilePosition.setReportSource("Mobile Position");
82   - if ("WGS84".equals(device.getGeoCoordSys())) {
83   - mobilePosition.setLongitudeWgs84(mobilePosition.getLongitude());
84   - mobilePosition.setLatitudeWgs84(mobilePosition.getLatitude());
85   - Double[] position = Coordtransform.WGS84ToGCJ02(mobilePosition.getLongitude(), mobilePosition.getLatitude());
86   - mobilePosition.setLongitudeGcj02(position[0]);
87   - mobilePosition.setLatitudeGcj02(position[1]);
88   - }else if ("GCJ02".equals(device.getGeoCoordSys())) {
89   - mobilePosition.setLongitudeGcj02(mobilePosition.getLongitude());
90   - mobilePosition.setLatitudeGcj02(mobilePosition.getLatitude());
91   - Double[] position = Coordtransform.GCJ02ToWGS84(mobilePosition.getLongitude(), mobilePosition.getLatitude());
92   - mobilePosition.setLongitudeWgs84(position[0]);
93   - mobilePosition.setLatitudeWgs84(position[1]);
94   - }else {
95   - mobilePosition.setLongitudeGcj02(0.00);
96   - mobilePosition.setLatitudeGcj02(0.00);
97   - mobilePosition.setLongitudeWgs84(0.00);
98   - mobilePosition.setLatitudeWgs84(0.00);
99   - }
100   - if (userSetting.getSavePositionHistory()) {
101   - storager.insertMobilePosition(mobilePosition);
102   - }
  86 +
  87 +
103 88 // 更新device channel 的经纬度
104 89 DeviceChannel deviceChannel = new DeviceChannel();
105 90 deviceChannel.setDeviceId(device.getDeviceId());
106 91 deviceChannel.setChannelId(mobilePosition.getChannelId());
107 92 deviceChannel.setLongitude(mobilePosition.getLongitude());
108 93 deviceChannel.setLatitude(mobilePosition.getLatitude());
109   - deviceChannel.setLongitudeWgs84(mobilePosition.getLongitudeWgs84());
110   - deviceChannel.setLatitudeWgs84(mobilePosition.getLatitudeWgs84());
111   - deviceChannel.setLongitudeGcj02(mobilePosition.getLongitudeGcj02());
112   - deviceChannel.setLatitudeGcj02(mobilePosition.getLatitudeGcj02());
113 94 deviceChannel.setGpsTime(mobilePosition.getTime());
  95 +
  96 + deviceChannel = deviceChannelService.updateGps(deviceChannel, device);
  97 +
  98 + mobilePosition.setLongitudeWgs84(deviceChannel.getLongitudeWgs84());
  99 + mobilePosition.setLatitudeWgs84(deviceChannel.getLatitudeWgs84());
  100 + mobilePosition.setLongitudeGcj02(deviceChannel.getLongitudeGcj02());
  101 + mobilePosition.setLatitudeGcj02(deviceChannel.getLatitudeGcj02());
  102 +
  103 + if (userSetting.getSavePositionHistory()) {
  104 + storager.insertMobilePosition(mobilePosition);
  105 + }
114 106 storager.updateChannelPosition(deviceChannel);
115 107 //回复 200 OK
116 108 responseAck(evt, Response.OK);
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/query/cmd/CatalogQueryMessageHandler.java
... ... @@ -70,86 +70,24 @@ public class CatalogQueryMessageHandler extends SIPRequestProcessorParent implem
70 70 Element snElement = rootElement.element("SN");
71 71 String sn = snElement.getText();
72 72 // 准备回复通道信息
73   - List<DeviceChannelInPlatform> deviceChannelInPlatforms = storager.queryChannelListInParentPlatform(parentPlatform.getServerGBId());
  73 + List<DeviceChannel> deviceChannelInPlatforms = storager.queryChannelWithCatalog(parentPlatform.getServerGBId());
74 74 // 查询关联的直播通道
75   - List<GbStream> gbStreams = storager.queryGbStreamListInPlatform(parentPlatform.getServerGBId());
  75 + List<DeviceChannel> gbStreams = storager.queryGbStreamListInPlatform(parentPlatform.getServerGBId());
76 76 // 回复目录信息
77   - List<PlatformCatalog> catalogs = storager.queryCatalogInPlatform(parentPlatform.getServerGBId());
  77 + List<DeviceChannel> catalogs = storager.queryCatalogInPlatform(parentPlatform.getServerGBId());
78 78  
79 79 List<DeviceChannel> allChannels = new ArrayList<>();
  80 +
80 81 if (catalogs.size() > 0) {
81   - for (PlatformCatalog catalog : catalogs) {
82   - if (catalog.getParentId().equals(catalog.getPlatformId())) {
83   - catalog.setParentId(parentPlatform.getDeviceGBId());
84   - }
85   - DeviceChannel deviceChannel = new DeviceChannel();
86   - // 通道的类型,0->国标通道 1->直播流通道 2->业务分组/虚拟组织/行政区划
87   - deviceChannel.setChannelType(2);
88   - deviceChannel.setChannelId(catalog.getId());
89   - deviceChannel.setName(catalog.getName());
90   - deviceChannel.setDeviceId(parentPlatform.getDeviceGBId());
91   - deviceChannel.setManufacture("wvp-pro");
92   - deviceChannel.setStatus(1);
93   - deviceChannel.setParental(1);
94   - deviceChannel.setParentId(catalog.getParentId());
95   - deviceChannel.setRegisterWay(1);
96   - if (catalog.getParentId() != null && catalog.getParentId().length() < 10) {
97   - deviceChannel.setCivilCode(catalog.getParentId());
98   - }else {
99   - deviceChannel.setCivilCode(parentPlatform.getAdministrativeDivision());
100   - }
101   - allChannels.add(deviceChannel);
102   - }
  82 + allChannels.addAll(catalogs);
103 83 }
104 84 // 回复级联的通道
105 85 if (deviceChannelInPlatforms.size() > 0) {
106   - for (DeviceChannelInPlatform channel : deviceChannelInPlatforms) {
107   - if (channel.getCatalogId().equals(parentPlatform.getServerGBId())) {
108   - channel.setCatalogId(parentPlatform.getDeviceGBId());
109   - }
110   - DeviceChannel deviceChannel = storage.queryChannel(channel.getDeviceId(), channel.getChannelId());
111   - // 通道的类型,0->国标通道 1->直播流通道 2->业务分组/虚拟组织/行政区划
112   - deviceChannel.setChannelType(0);
113   - deviceChannel.setParental(0);
114   - deviceChannel.setParentId(channel.getCatalogId());
115   - if (channel.getCatalogId() != null && channel.getCatalogId().length() < 10) {
116   - deviceChannel.setCivilCode(channel.getCatalogId());
117   - }else {
118   - deviceChannel.setCivilCode(parentPlatform.getAdministrativeDivision());
119   - }
120   - allChannels.add(deviceChannel);
121   - }
  86 + allChannels.addAll(deviceChannelInPlatforms);
122 87 }
123 88 // 回复直播的通道
124 89 if (gbStreams.size() > 0) {
125   - for (GbStream gbStream : gbStreams) {
126   - if (gbStream.getCatalogId().equals(parentPlatform.getServerGBId())) {
127   - gbStream.setCatalogId(null);
128   - }
129   - DeviceChannel deviceChannel = new DeviceChannel();
130   - // 通道的类型,0->国标通道 1->直播流通道 2->业务分组/虚拟组织/行政区划
131   - deviceChannel.setChannelType(1);
132   - deviceChannel.setChannelId(gbStream.getGbId());
133   - deviceChannel.setName(gbStream.getName());
134   - deviceChannel.setLongitude(gbStream.getLongitude());
135   - deviceChannel.setLatitude(gbStream.getLatitude());
136   - deviceChannel.setDeviceId(parentPlatform.getDeviceGBId());
137   - deviceChannel.setManufacture("wvp-pro");
138   -// deviceChannel.setStatus(gbStream.isStatus()?1:0);
139   - deviceChannel.setStatus(1);
140   - deviceChannel.setParentId(gbStream.getCatalogId());
141   - deviceChannel.setRegisterWay(1);
142   - if (gbStream.getCatalogId() != null && gbStream.getCatalogId().length() < 10) {
143   - deviceChannel.setCivilCode(gbStream.getCatalogId());
144   - }else {
145   - deviceChannel.setCivilCode(parentPlatform.getAdministrativeDivision());
146   - }
147   - deviceChannel.setModel("live");
148   - deviceChannel.setOwner("wvp-pro");
149   - deviceChannel.setParental(0);
150   - deviceChannel.setSecrecy("0");
151   - allChannels.add(deviceChannel);
152   - }
  90 + allChannels.addAll(gbStreams);
153 91 }
154 92 if (allChannels.size() > 0) {
155 93 cmderFroPlatform.catalogQuery(allChannels, parentPlatform, sn, fromHeader.getTag());
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/CatalogResponseMessageHandler.java
... ... @@ -125,11 +125,7 @@ public class CatalogResponseMessageHandler extends SIPRequestProcessorParent imp
125 125 if (channelDeviceElement == null) {
126 126 continue;
127 127 }
128   - //by brewswang
129   - // if (NumericUtil.isDouble(XmlUtil.getText(itemDevice, "Longitude"))) {//如果包含位置信息,就更新一下位置
130   - // processNotifyMobilePosition(evt, itemDevice);
131   - // }
132   - DeviceChannel deviceChannel = XmlUtil.channelContentHander(itemDevice, device);
  128 + DeviceChannel deviceChannel = XmlUtil.channelContentHander(itemDevice, device, null);
133 129 deviceChannel.setDeviceId(take.getDevice().getDeviceId());
134 130  
135 131 channelList.add(deviceChannel);
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/DeviceInfoResponseMessageHandler.java
... ... @@ -87,7 +87,6 @@ public class DeviceInfoResponseMessageHandler extends SIPRequestProcessorParent
87 87 device.setStreamMode("UDP");
88 88 }
89 89 deviceService.updateDevice(device);
90   -// storager.updateDevice(device);
91 90  
92 91 RequestMessage msg = new RequestMessage();
93 92 msg.setKey(key);
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/MobilePositionResponseMessageHandler.java
... ... @@ -7,6 +7,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.IMessag
7 7 import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.response.ResponseMessageHandler;
8 8 import com.genersoft.iot.vmp.gb28181.utils.Coordtransform;
9 9 import com.genersoft.iot.vmp.gb28181.utils.NumericUtil;
  10 +import com.genersoft.iot.vmp.service.IDeviceChannelService;
10 11 import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
11 12 import com.genersoft.iot.vmp.utils.DateUtil;
12 13 import com.genersoft.iot.vmp.utils.GpsUtil;
... ... @@ -42,6 +43,9 @@ public class MobilePositionResponseMessageHandler extends SIPRequestProcessorPar
42 43 @Autowired
43 44 private IVideoManagerStorage storager;
44 45  
  46 + @Autowired
  47 + private IDeviceChannelService deviceChannelService;
  48 +
45 49 @Override
46 50 public void afterPropertiesSet() throws Exception {
47 51 responseMessageHandler.addHandler(cmdType, this);
... ... @@ -79,38 +83,25 @@ public class MobilePositionResponseMessageHandler extends SIPRequestProcessorPar
79 83 mobilePosition.setAltitude(0.0);
80 84 }
81 85 mobilePosition.setReportSource("Mobile Position");
82   - if ("WGS84".equals(device.getGeoCoordSys())) {
83   - mobilePosition.setLongitudeWgs84(mobilePosition.getLongitude());
84   - mobilePosition.setLatitudeWgs84(mobilePosition.getLatitude());
85   - Double[] position = Coordtransform.WGS84ToGCJ02(mobilePosition.getLongitude(), mobilePosition.getLatitude());
86   - mobilePosition.setLongitudeGcj02(position[0]);
87   - mobilePosition.setLatitudeGcj02(position[1]);
88   - }else if ("GCJ02".equals(device.getGeoCoordSys())) {
89   - mobilePosition.setLongitudeGcj02(mobilePosition.getLongitude());
90   - mobilePosition.setLatitudeGcj02(mobilePosition.getLatitude());
91   - Double[] position = Coordtransform.GCJ02ToWGS84(mobilePosition.getLongitude(), mobilePosition.getLatitude());
92   - mobilePosition.setLongitudeWgs84(position[0]);
93   - mobilePosition.setLatitudeWgs84(position[1]);
94   - }else {
95   - mobilePosition.setLongitudeGcj02(0.00);
96   - mobilePosition.setLatitudeGcj02(0.00);
97   - mobilePosition.setLongitudeWgs84(0.00);
98   - mobilePosition.setLatitudeWgs84(0.00);
99   - }
100   - if (userSetting.getSavePositionHistory()) {
101   - storager.insertMobilePosition(mobilePosition);
102   - }
  86 +
103 87 // 更新device channel 的经纬度
104 88 DeviceChannel deviceChannel = new DeviceChannel();
105 89 deviceChannel.setDeviceId(device.getDeviceId());
106 90 deviceChannel.setChannelId(mobilePosition.getChannelId());
107 91 deviceChannel.setLongitude(mobilePosition.getLongitude());
108 92 deviceChannel.setLatitude(mobilePosition.getLatitude());
109   - deviceChannel.setLongitudeWgs84(mobilePosition.getLongitudeWgs84());
110   - deviceChannel.setLatitudeWgs84(mobilePosition.getLatitudeWgs84());
111   - deviceChannel.setLongitudeGcj02(mobilePosition.getLongitudeGcj02());
112   - deviceChannel.setLatitudeGcj02(mobilePosition.getLatitudeGcj02());
113 93 deviceChannel.setGpsTime(mobilePosition.getTime());
  94 +
  95 + deviceChannel = deviceChannelService.updateGps(deviceChannel, device);
  96 +
  97 + mobilePosition.setLongitudeWgs84(deviceChannel.getLongitudeWgs84());
  98 + mobilePosition.setLatitudeWgs84(deviceChannel.getLatitudeWgs84());
  99 + mobilePosition.setLongitudeGcj02(deviceChannel.getLongitudeGcj02());
  100 + mobilePosition.setLatitudeGcj02(deviceChannel.getLatitudeGcj02());
  101 +
  102 + if (userSetting.getSavePositionHistory()) {
  103 + storager.insertMobilePosition(mobilePosition);
  104 + }
114 105 storager.updateChannelPosition(deviceChannel);
115 106 //回复 200 OK
116 107 responseAck(evt, Response.OK);
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/PresetQueryResponseMessageHandler.java
1 1 package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.response.cmd;
2 2  
3   -import com.genersoft.iot.vmp.domain.req.PresetQuerySipReq;
  3 +import com.genersoft.iot.vmp.gb28181.bean.PresetQuerySipReq;
4 4 import com.genersoft.iot.vmp.gb28181.bean.*;
5 5 import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder;
6 6 import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage;
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/utils/XmlUtil.java
... ... @@ -4,6 +4,8 @@ import com.alibaba.fastjson.JSONArray;
4 4 import com.alibaba.fastjson.JSONObject;
5 5 import com.genersoft.iot.vmp.gb28181.bean.Device;
6 6 import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
  7 +import com.genersoft.iot.vmp.gb28181.bean.TreeType;
  8 +import com.genersoft.iot.vmp.gb28181.event.subscribe.catalog.CatalogEvent;
7 9 import com.genersoft.iot.vmp.utils.DateUtil;
8 10 import org.dom4j.Attribute;
9 11 import org.dom4j.Document;
... ... @@ -29,7 +31,7 @@ public class XmlUtil {
29 31 /**
30 32 * 日志服务
31 33 */
32   - private static Logger LOG = LoggerFactory.getLogger(XmlUtil.class);
  34 + private static Logger logger = LoggerFactory.getLogger(XmlUtil.class);
33 35  
34 36 /**
35 37 * 解析XML为Document对象
... ... @@ -46,7 +48,7 @@ public class XmlUtil {
46 48 try {
47 49 document = saxReader.read(sr);
48 50 } catch (DocumentException e) {
49   - LOG.error("解析失败", e);
  51 + logger.error("解析失败", e);
50 52 }
51 53 return null == document ? null : document.getRootElement();
52 54 }
... ... @@ -182,47 +184,69 @@ public class XmlUtil {
182 184 return xml.getRootElement();
183 185 }
184 186  
185   - public static DeviceChannel channelContentHander(Element itemDevice, Device device){
186   - Element channdelNameElement = itemDevice.element("Name");
187   - String channelName = channdelNameElement != null ? channdelNameElement.getTextTrim().toString() : "";
188   - Element statusElement = itemDevice.element("Status");
189   - String status = statusElement != null ? statusElement.getTextTrim().toString() : "ON";
  187 + private enum ChannelType{
  188 + CivilCode, BusinessGroup,VirtualOrganization,Other
  189 + }
  190 +
  191 + public static DeviceChannel channelContentHander(Element itemDevice, Device device, String event){
190 192 DeviceChannel deviceChannel = new DeviceChannel();
191   - deviceChannel.setName(channelName);
  193 + deviceChannel.setDeviceId(device.getDeviceId());
192 194 Element channdelIdElement = itemDevice.element("DeviceID");
193   - String channelId = channdelIdElement != null ? channdelIdElement.getTextTrim().toString() : "";
  195 + if (channdelIdElement == null) {
  196 + logger.warn("解析Catalog消息时发现缺少 DeviceID");
  197 + return null;
  198 + }
  199 + String channelId = channdelIdElement.getTextTrim();
  200 + if (StringUtils.isEmpty(channelId)) {
  201 + logger.warn("解析Catalog消息时发现缺少 DeviceID");
  202 + return null;
  203 + }
194 204 deviceChannel.setChannelId(channelId);
195   - // ONLINE OFFLINE HIKVISION DS-7716N-E4 NVR的兼容性处理
196   - if (status.equals("ON") || status.equals("On") || status.equals("ONLINE") || status.equals("OK")) {
197   - deviceChannel.setStatus(1);
  205 + if (event != null && !event.equals(CatalogEvent.ADD) && !event.equals(CatalogEvent.UPDATE)) {
  206 + // 除了ADD和update情况下需要识别全部内容,
  207 + return deviceChannel;
198 208 }
199   - if (status.equals("OFF") || status.equals("Off") || status.equals("OFFLINE")) {
200   - deviceChannel.setStatus(0);
  209 +
  210 + ChannelType channelType = ChannelType.Other;
  211 + if (channelId.length() <= 8) {
  212 + channelType = ChannelType.CivilCode;
  213 + }else {
  214 + if (channelId.length() == 20) {
  215 + int code = Integer.parseInt(channelId.substring(10, 13));
  216 + switch (code){
  217 + case 215:
  218 + channelType = ChannelType.BusinessGroup;
  219 + break;
  220 + case 216:
  221 + channelType = ChannelType.VirtualOrganization;
  222 + break;
  223 + default:
  224 + break;
  225 +
  226 + }
  227 + }
201 228 }
202 229  
203   - deviceChannel.setManufacture(XmlUtil.getText(itemDevice, "Manufacturer"));
204   - deviceChannel.setModel(XmlUtil.getText(itemDevice, "Model"));
205   - deviceChannel.setOwner(XmlUtil.getText(itemDevice, "Owner"));
206   - deviceChannel.setCivilCode(XmlUtil.getText(itemDevice, "CivilCode"));
207   - deviceChannel.setBlock(XmlUtil.getText(itemDevice, "Block"));
208   - deviceChannel.setAddress(XmlUtil.getText(itemDevice, "Address"));
209   - String businessGroupID = XmlUtil.getText(itemDevice, "BusinessGroupID");
210   - if (XmlUtil.getText(itemDevice, "Parental") == null
211   - || XmlUtil.getText(itemDevice, "Parental").equals("")) {
212   - if (deviceChannel.getChannelId().length() <= 10
213   - || (deviceChannel.getChannelId().length() == 20 && (
214   - Integer.parseInt(deviceChannel.getChannelId().substring(10, 13)) == 215
215   - || Integer.parseInt(deviceChannel.getChannelId().substring(10, 13)) == 216
216   - )
217   - )
218   - ) {
219   - deviceChannel.setParental(1);
220   - }else {
221   - deviceChannel.setParental(0);
  230 + Element channdelNameElement = itemDevice.element("Name");
  231 + String channelName = channdelNameElement != null ? channdelNameElement.getTextTrim() : "";
  232 + deviceChannel.setName(channelName);
  233 +
  234 + String civilCode = XmlUtil.getText(itemDevice, "CivilCode");
  235 + deviceChannel.setCivilCode(civilCode);
  236 + if (channelType == ChannelType.CivilCode && civilCode == null) {
  237 + deviceChannel.setParental(1);
  238 + // 行政区划如果没有传递具体值,则推测一个
  239 + if (channelId.length() > 2) {
  240 + deviceChannel.setCivilCode(channelId.substring(0, channelId.length() - 2));
222 241 }
223   - } else {
224   - // 由于海康会错误的发送65535作为这里的取值,所以这里除非是0否则认为是1
225   - deviceChannel.setParental(Integer.parseInt(XmlUtil.getText(itemDevice, "Parental")) == 1?1:0);
  242 + }
  243 + if (channelType.equals(ChannelType.CivilCode)) {
  244 + // 行政区划其他字段没必要识别了,默认在线即可
  245 + deviceChannel.setStatus(1);
  246 + deviceChannel.setParental(1);
  247 + deviceChannel.setCreateTime(DateUtil.getNow());
  248 + deviceChannel.setUpdateTime(DateUtil.getNow());
  249 + return deviceChannel;
226 250 }
227 251 /**
228 252 * 行政区划展示设备树与业务分组展示设备树是两种不同的模式
... ... @@ -230,7 +254,17 @@ public class XmlUtil {
230 254 * 河北省
231 255 * --> 石家庄市
232 256 * --> 摄像头
233   - * --> 正定县
  257 + *String parentId = XmlUtil.getText(itemDevice, "ParentID");
  258 + if (parentId != null) {
  259 + if (parentId.contains("/")) {
  260 + String lastParentId = parentId.substring(parentId.lastIndexOf("/") + 1);
  261 + String businessGroup = parentId.substring(0, parentId.indexOf("/"));
  262 + deviceChannel.setParentId(lastParentId);
  263 + }else {
  264 + deviceChannel.setParentId(parentId);
  265 + }
  266 + }
  267 + deviceCh --> 正定县
234 268 * --> 摄像头
235 269 * --> 摄像头
236 270 *
... ... @@ -243,59 +277,88 @@ public class XmlUtil {
243 277 * --> 摄像头
244 278 */
245 279 String parentId = XmlUtil.getText(itemDevice, "ParentID");
  280 + String businessGroupID = XmlUtil.getText(itemDevice, "BusinessGroupID");
246 281 if (parentId != null) {
247 282 if (parentId.contains("/")) {
248 283 String lastParentId = parentId.substring(parentId.lastIndexOf("/") + 1);
  284 + if (businessGroupID == null) {
  285 + businessGroupID = parentId.substring(0, parentId.indexOf("/"));
  286 + }
249 287 deviceChannel.setParentId(lastParentId);
250 288 }else {
251 289 deviceChannel.setParentId(parentId);
252 290 }
253 291 }
254 292 deviceChannel.setBusinessGroupId(businessGroupID);
  293 + if (channelType.equals(ChannelType.BusinessGroup) || channelType.equals(ChannelType.VirtualOrganization)) {
  294 + // 业务分组和虚拟组织 其他字段没必要识别了,默认在线即可
  295 + deviceChannel.setStatus(1);
  296 + deviceChannel.setParental(1);
  297 + deviceChannel.setCreateTime(DateUtil.getNow());
  298 + deviceChannel.setUpdateTime(DateUtil.getNow());
  299 + return deviceChannel;
  300 + }
255 301  
256   -// else {
257   -// if (deviceChannel.getChannelId().length() <= 10) { // 此时为行政区划, 上下级行政区划使用DeviceId关联
258   -// deviceChannel.setParentId(deviceChannel.getChannelId().substring(0, deviceChannel.getChannelId().length() - 2));
259   -// }else if (deviceChannel.getChannelId().length() == 20) {
260   -// if (Integer.parseInt(deviceChannel.getChannelId().substring(10, 13)) == 216) { // 虚拟组织
261   -// deviceChannel.setBusinessGroupId(businessGroupID);
262   -// }else if (Integer.parseInt(device.getDeviceId().substring(10, 13) )== 118) {//NVR 如果上级设备编号是NVR则直接将NVR的编号设置给通道的上级编号
263   -// deviceChannel.setParentId(device.getDeviceId());
264   -// }else if (deviceChannel.getCivilCode() != null) {
265   -// // 设备, 无parentId的20位是使用CivilCode表示上级的设备,
266   -// // 注:215 业务分组是需要有parentId的
267   -// deviceChannel.setParentId(deviceChannel.getCivilCode());
268   -// }
269   -// }else {
270   -// deviceChannel.setParentId(deviceChannel.getDeviceId());
271   -// }
272   -// }
273   -
274   - if (XmlUtil.getText(itemDevice, "SafetyWay") == null
275   - || XmlUtil.getText(itemDevice, "SafetyWay") == "") {
  302 + Element statusElement = itemDevice.element("Status");
  303 +
  304 + if (statusElement != null) {
  305 + String status = statusElement.getTextTrim().trim();
  306 + // ONLINE OFFLINE HIKVISION DS-7716N-E4 NVR的兼容性处理
  307 + if (status.equals("ON") || status.equals("On") || status.equals("ONLINE") || status.equals("OK")) {
  308 + deviceChannel.setStatus(1);
  309 + }
  310 + if (status.equals("OFF") || status.equals("Off") || status.equals("OFFLINE")) {
  311 + deviceChannel.setStatus(0);
  312 + }
  313 + }else {
  314 + deviceChannel.setStatus(1);
  315 + }
  316 + // 识别自带的目录标识
  317 + String parental = XmlUtil.getText(itemDevice, "Parental");
  318 + // 由于海康会错误的发送65535作为这里的取值,所以这里除非是0否则认为是1
  319 + if (!StringUtils.isEmpty(parental) && parental.length() == 1 && Integer.parseInt(parental) == 0) {
  320 + deviceChannel.setParental(0);
  321 + }else {
  322 + deviceChannel.setParental(1);
  323 + }
  324 +
  325 +
  326 + deviceChannel.setManufacture(XmlUtil.getText(itemDevice, "Manufacturer"));
  327 + deviceChannel.setModel(XmlUtil.getText(itemDevice, "Model"));
  328 + deviceChannel.setOwner(XmlUtil.getText(itemDevice, "Owner"));
  329 + deviceChannel.setCertNum(XmlUtil.getText(itemDevice, "CertNum"));
  330 + deviceChannel.setBlock(XmlUtil.getText(itemDevice, "Block"));
  331 + deviceChannel.setAddress(XmlUtil.getText(itemDevice, "Address"));
  332 + deviceChannel.setPassword(XmlUtil.getText(itemDevice, "Password"));
  333 +
  334 + String safetyWay = XmlUtil.getText(itemDevice, "SafetyWay");
  335 + if (StringUtils.isEmpty(safetyWay)) {
276 336 deviceChannel.setSafetyWay(0);
277 337 } else {
278   - deviceChannel.setSafetyWay(Integer.parseInt(XmlUtil.getText(itemDevice, "SafetyWay")));
  338 + deviceChannel.setSafetyWay(Integer.parseInt(safetyWay));
279 339 }
280   - if (XmlUtil.getText(itemDevice, "RegisterWay") == null
281   - || XmlUtil.getText(itemDevice, "RegisterWay") == "") {
  340 +
  341 + String registerWay = XmlUtil.getText(itemDevice, "RegisterWay");
  342 + if (StringUtils.isEmpty(registerWay)) {
282 343 deviceChannel.setRegisterWay(1);
283 344 } else {
284   - deviceChannel.setRegisterWay(Integer.parseInt(XmlUtil.getText(itemDevice, "RegisterWay")));
  345 + deviceChannel.setRegisterWay(Integer.parseInt(registerWay));
285 346 }
286   - deviceChannel.setCertNum(XmlUtil.getText(itemDevice, "CertNum"));
  347 +
287 348 if (XmlUtil.getText(itemDevice, "Certifiable") == null
288 349 || XmlUtil.getText(itemDevice, "Certifiable") == "") {
289 350 deviceChannel.setCertifiable(0);
290 351 } else {
291 352 deviceChannel.setCertifiable(Integer.parseInt(XmlUtil.getText(itemDevice, "Certifiable")));
292 353 }
  354 +
293 355 if (XmlUtil.getText(itemDevice, "ErrCode") == null
294 356 || XmlUtil.getText(itemDevice, "ErrCode") == "") {
295 357 deviceChannel.setErrCode(0);
296 358 } else {
297 359 deviceChannel.setErrCode(Integer.parseInt(XmlUtil.getText(itemDevice, "ErrCode")));
298 360 }
  361 +
299 362 deviceChannel.setEndTime(XmlUtil.getText(itemDevice, "EndTime"));
300 363 deviceChannel.setSecrecy(XmlUtil.getText(itemDevice, "Secrecy"));
301 364 deviceChannel.setIpAddress(XmlUtil.getText(itemDevice, "IPAddress"));
... ... @@ -304,43 +367,23 @@ public class XmlUtil {
304 367 } else {
305 368 deviceChannel.setPort(Integer.parseInt(XmlUtil.getText(itemDevice, "Port")));
306 369 }
307   - deviceChannel.setPassword(XmlUtil.getText(itemDevice, "Password"));
308   - if (NumericUtil.isDouble(XmlUtil.getText(itemDevice, "Longitude"))) {
309   - deviceChannel.setLongitude(Double.parseDouble(XmlUtil.getText(itemDevice, "Longitude")));
  370 +
  371 +
  372 + String longitude = XmlUtil.getText(itemDevice, "Longitude");
  373 + if (NumericUtil.isDouble(longitude)) {
  374 + deviceChannel.setLongitude(Double.parseDouble(longitude));
310 375 } else {
311 376 deviceChannel.setLongitude(0.00);
312 377 }
313   - if (NumericUtil.isDouble(XmlUtil.getText(itemDevice, "Latitude"))) {
314   - deviceChannel.setLatitude(Double.parseDouble(XmlUtil.getText(itemDevice, "Latitude")));
  378 + String latitude = XmlUtil.getText(itemDevice, "Latitude");
  379 + if (NumericUtil.isDouble(latitude)) {
  380 + deviceChannel.setLatitude(Double.parseDouble(latitude));
315 381 } else {
316 382 deviceChannel.setLatitude(0.00);
317 383 }
318 384 deviceChannel.setGpsTime(DateUtil.getNow());
319   - if (deviceChannel.getLongitude()*deviceChannel.getLatitude() > 0) {
320   - if ("WGS84".equals(device.getGeoCoordSys())) {
321   - deviceChannel.setLongitudeWgs84(deviceChannel.getLongitude());
322   - deviceChannel.setLatitudeWgs84(deviceChannel.getLatitude());
323   - Double[] position = Coordtransform.WGS84ToGCJ02(deviceChannel.getLongitude(), deviceChannel.getLatitude());
324   - deviceChannel.setLongitudeGcj02(position[0]);
325   - deviceChannel.setLatitudeGcj02(position[1]);
326   - }else if ("GCJ02".equals(device.getGeoCoordSys())) {
327   - deviceChannel.setLongitudeGcj02(deviceChannel.getLongitude());
328   - deviceChannel.setLatitudeGcj02(deviceChannel.getLatitude());
329   - Double[] position = Coordtransform.GCJ02ToWGS84(deviceChannel.getLongitude(), deviceChannel.getLatitude());
330   - deviceChannel.setLongitudeWgs84(position[0]);
331   - deviceChannel.setLatitudeWgs84(position[1]);
332   - }else {
333   - deviceChannel.setLongitudeGcj02(0.00);
334   - deviceChannel.setLatitudeGcj02(0.00);
335   - deviceChannel.setLongitudeWgs84(0.00);
336   - deviceChannel.setLatitudeWgs84(0.00);
337   - }
338   - }else {
339   - deviceChannel.setLongitudeGcj02(deviceChannel.getLongitude());
340   - deviceChannel.setLatitudeGcj02(deviceChannel.getLatitude());
341   - deviceChannel.setLongitudeWgs84(deviceChannel.getLongitude());
342   - deviceChannel.setLatitudeWgs84(deviceChannel.getLatitude());
343   - }
  385 +
  386 +
344 387 if (XmlUtil.getText(itemDevice, "PTZType") == null || "".equals(XmlUtil.getText(itemDevice, "PTZType"))) {
345 388 //兼容INFO中的信息
346 389 Element info = itemDevice.element("Info");
... ...
src/main/java/com/genersoft/iot/vmp/media/zlm/AssistRESTfulUtils.java
... ... @@ -136,4 +136,12 @@ public class AssistRESTfulUtils {
136 136 return sendGet(mediaServerItem, "api/record/file/duration",param, callback);
137 137 }
138 138  
  139 + public JSONObject addStreamCallInfo(MediaServerItem mediaServerItem, String app, String stream, String callId, RequestCallback callback){
  140 + Map<String, Object> param = new HashMap<>();
  141 + param.put("app",app);
  142 + param.put("stream",stream);
  143 + param.put("callId",callId);
  144 + return sendGet(mediaServerItem, "api/record/addStreamCallInfo",param, callback);
  145 + }
  146 +
139 147 }
... ...
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java
1 1 package com.genersoft.iot.vmp.media.zlm;
2 2  
3   -import java.util.ArrayList;
  3 +import java.util.HashMap;
4 4 import java.util.List;
  5 +import java.util.Map;
5 6  
6 7 import com.alibaba.fastjson.JSON;
7 8 import com.genersoft.iot.vmp.common.StreamInfo;
... ... @@ -21,6 +22,7 @@ import org.slf4j.LoggerFactory;
21 22 import org.springframework.beans.factory.annotation.Autowired;
22 23 import org.springframework.http.HttpStatus;
23 24 import org.springframework.http.ResponseEntity;
  25 +import org.springframework.util.StringUtils;
24 26 import org.springframework.web.bind.annotation.PostMapping;
25 27 import org.springframework.web.bind.annotation.RequestBody;
26 28 import org.springframework.web.bind.annotation.RequestMapping;
... ... @@ -80,8 +82,14 @@ public class ZLMHttpHookListener {
80 82 private UserSetting userSetting;
81 83  
82 84 @Autowired
  85 + private IUserService userService;
  86 +
  87 + @Autowired
83 88 private VideoStreamSessionManager sessionManager;
84 89  
  90 + @Autowired
  91 + private AssistRESTfulUtils assistRESTfulUtils;
  92 +
85 93 /**
86 94 * 服务器定时上报时间,上报间隔可配置,默认10s上报一次
87 95 *
... ... @@ -151,12 +159,14 @@ public class ZLMHttpHookListener {
151 159 */
152 160 @ResponseBody
153 161 @PostMapping(value = "/on_play", produces = "application/json;charset=UTF-8")
154   - public ResponseEntity<String> onPlay(@RequestBody JSONObject json){
155   -
  162 + public ResponseEntity<String> onPlay(@RequestBody OnPlayHookParam param){
  163 +
  164 + JSONObject json = (JSONObject)JSON.toJSON(param);
  165 +
156 166 if (logger.isDebugEnabled()) {
157   - logger.debug("[ ZLM HOOK ]on_play API调用,参数:" + json.toString());
  167 + logger.debug("[ ZLM HOOK ]on_play API调用,参数:" + JSON.toJSONString(param));
158 168 }
159   - String mediaServerId = json.getString("mediaServerId");
  169 + String mediaServerId = param.getMediaServerId();
160 170 ZLMHttpHookSubscribe.Event subscribe = this.subscribe.getSubscribe(ZLMHttpHookSubscribe.HookType.on_play, json);
161 171 if (subscribe != null ) {
162 172 MediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId);
... ... @@ -165,9 +175,20 @@ public class ZLMHttpHookListener {
165 175 }
166 176 }
167 177 JSONObject ret = new JSONObject();
  178 + if (!"rtp".equals(param.getApp())) {
  179 + Map<String, String> paramMap = urlParamToMap(param.getParams());
  180 + StreamAuthorityInfo streamAuthorityInfo = redisCatchStorage.getStreamAuthorityInfo(param.getApp(), param.getStream());
  181 + if (streamAuthorityInfo == null
  182 + || (streamAuthorityInfo.getCallId() != null && !streamAuthorityInfo.getCallId().equals(paramMap.get("callId")))) {
  183 + ret.put("code", 401);
  184 + ret.put("msg", "Unauthorized");
  185 + return new ResponseEntity<>(ret.toString(),HttpStatus.OK);
  186 + }
  187 + }
  188 +
168 189 ret.put("code", 0);
169 190 ret.put("msg", "success");
170   - return new ResponseEntity<String>(ret.toString(),HttpStatus.OK);
  191 + return new ResponseEntity<>(ret.toString(),HttpStatus.OK);
171 192 }
172 193  
173 194 /**
... ... @@ -176,23 +197,61 @@ public class ZLMHttpHookListener {
176 197 */
177 198 @ResponseBody
178 199 @PostMapping(value = "/on_publish", produces = "application/json;charset=UTF-8")
179   - public ResponseEntity<String> onPublish(@RequestBody JSONObject json) {
  200 + public ResponseEntity<String> onPublish(@RequestBody OnPublishHookParam param) {
  201 +
  202 + JSONObject json = (JSONObject) JSON.toJSON(param);
180 203  
181 204 logger.info("[ ZLM HOOK ]on_publish API调用,参数:" + json.toString());
182 205 JSONObject ret = new JSONObject();
  206 + String mediaServerId = json.getString("mediaServerId");
  207 + MediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId);
  208 + if (!"rtp".equals(param.getApp())) {
  209 + // 推流鉴权
  210 + if (param.getParams() == null) {
  211 + logger.info("推流鉴权失败: 缺少不要参数:sign=md5(user表的pushKey)");
  212 + ret.put("code", 401);
  213 + ret.put("msg", "Unauthorized");
  214 + return new ResponseEntity<>(ret.toString(), HttpStatus.OK);
  215 + }
  216 + Map<String, String> paramMap = urlParamToMap(param.getParams());
  217 + String sign = paramMap.get("sign");
  218 + if (sign == null) {
  219 + logger.info("推流鉴权失败: 缺少不要参数:sign=md5(user表的pushKey)");
  220 + ret.put("code", 401);
  221 + ret.put("msg", "Unauthorized");
  222 + return new ResponseEntity<>(ret.toString(), HttpStatus.OK);
  223 + }
  224 + // 推流自定义播放鉴权码
  225 + String callId = paramMap.get("callId");
  226 + // 鉴权配置
  227 + boolean hasAuthority = userService.checkPushAuthority(callId, sign);
  228 + if (!hasAuthority) {
  229 + logger.info("推流鉴权失败: sign 无权限: callId={}. sign={}", callId, sign);
  230 + ret.put("code", 401);
  231 + ret.put("msg", "Unauthorized");
  232 + return new ResponseEntity<>(ret.toString(), HttpStatus.OK);
  233 + }
  234 + StreamAuthorityInfo streamAuthorityInfo = StreamAuthorityInfo.getInstanceByHook(param);
  235 + streamAuthorityInfo.setCallId(callId);
  236 + streamAuthorityInfo.setSign(sign);
  237 + // 鉴权通过
  238 + redisCatchStorage.updateStreamAuthorityInfo(param.getApp(), param.getStream(), streamAuthorityInfo);
  239 + // 通知assist新的callId
  240 + if (mediaInfo != null) {
  241 + assistRESTfulUtils.addStreamCallInfo(mediaInfo, param.getApp(), param.getStream(), callId, null);
  242 + }
  243 + }
  244 +
183 245 ret.put("code", 0);
184 246 ret.put("msg", "success");
185 247 ret.put("enable_hls", true);
186   - if (json.getInteger("originType") == 1
187   - || json.getInteger("originType") == 2
188   - || json.getInteger("originType") == 3) {
  248 + if (!"rtp".equals(param.getApp())) {
189 249 ret.put("enable_audio", true);
190 250 }
191 251  
192   - String mediaServerId = json.getString("mediaServerId");
  252 +
193 253 ZLMHttpHookSubscribe.Event subscribe = this.subscribe.getSubscribe(ZLMHttpHookSubscribe.HookType.on_publish, json);
194 254 if (subscribe != null) {
195   - MediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId);
196 255 if (mediaInfo != null) {
197 256 subscribe.response(mediaInfo, json);
198 257 }else {
... ... @@ -200,14 +259,13 @@ public class ZLMHttpHookListener {
200 259 ret.put("msg", "zlm not register");
201 260 }
202 261 }
203   - String app = json.getString("app");
204   - String stream = json.getString("stream");
205   - if ("rtp".equals(app)) {
  262 +
  263 + if ("rtp".equals(param.getApp())) {
206 264 ret.put("enable_mp4", userSetting.getRecordSip());
207 265 }else {
208 266 ret.put("enable_mp4", userSetting.isRecordPushLive());
209 267 }
210   - List<SsrcTransaction> ssrcTransactionForAll = sessionManager.getSsrcTransactionForAll(null, null, null, stream);
  268 + List<SsrcTransaction> ssrcTransactionForAll = sessionManager.getSsrcTransactionForAll(null, null, null, param.getStream());
211 269 if (ssrcTransactionForAll != null && ssrcTransactionForAll.size() == 1) {
212 270 String deviceId = ssrcTransactionForAll.get(0).getDeviceId();
213 271 String channelId = ssrcTransactionForAll.get(0).getChannelId();
... ... @@ -220,14 +278,17 @@ public class ZLMHttpHookListener {
220 278 ret.put("mp4_max_second", 10);
221 279 ret.put("enable_mp4", true);
222 280 ret.put("enable_audio", true);
223   - }
224 281  
  282 + }
225 283 }
226 284  
227 285  
  286 +
228 287 return new ResponseEntity<String>(ret.toString(), HttpStatus.OK);
229 288 }
230   -
  289 +
  290 +
  291 +
231 292 /**
232 293 * 录制mp4完成后通知事件;此事件对回复不敏感。
233 294 *
... ... @@ -312,9 +373,6 @@ public class ZLMHttpHookListener {
312 373 if (logger.isDebugEnabled()) {
313 374 logger.debug("[ ZLM HOOK ]on_shell_login API调用,参数:" + json.toString());
314 375 }
315   - // TODO 如果是带有rtpstream则开启按需拉流
316   - // String app = json.getString("app");
317   - // String stream = json.getString("stream");
318 376 String mediaServerId = json.getString("mediaServerId");
319 377 ZLMHttpHookSubscribe.Event subscribe = this.subscribe.getSubscribe(ZLMHttpHookSubscribe.HookType.on_shell_login, json);
320 378 if (subscribe != null ) {
... ... @@ -351,12 +409,24 @@ public class ZLMHttpHookListener {
351 409 }
352 410 // 流消失移除redis play
353 411 String app = item.getApp();
354   - String streamId = item.getStream();
  412 + String stream = item.getStream();
355 413 String schema = item.getSchema();
356 414 List<MediaItem.MediaTrack> tracks = item.getTracks();
357 415 boolean regist = item.isRegist();
  416 + if (regist) {
  417 + StreamAuthorityInfo streamAuthorityInfo = redisCatchStorage.getStreamAuthorityInfo(app, stream);
  418 + if (streamAuthorityInfo == null) {
  419 + streamAuthorityInfo = StreamAuthorityInfo.getInstanceByHook(item);
  420 + }else {
  421 + streamAuthorityInfo.setOriginType(item.getOriginType());
  422 + streamAuthorityInfo.setOriginTypeStr(item.getOriginTypeStr());
  423 + }
  424 + redisCatchStorage.updateStreamAuthorityInfo(app, stream, streamAuthorityInfo);
  425 + }else {
  426 + redisCatchStorage.removeStreamAuthorityInfo(app, stream);
  427 + }
358 428 if ("rtmp".equals(schema)){
359   - logger.info("on_stream_changed:注册->{}, app->{}, stream->{}", regist, app, streamId);
  429 + logger.info("on_stream_changed:注册->{}, app->{}, stream->{}", regist, app, stream);
360 430 if (regist) {
361 431 mediaServerService.addCount(mediaServerId);
362 432 }else {
... ... @@ -365,15 +435,15 @@ public class ZLMHttpHookListener {
365 435 if (item.getOriginType() == OriginType.PULL.ordinal()
366 436 || item.getOriginType() == OriginType.FFMPEG_PULL.ordinal()) {
367 437 // 设置拉流代理上线/离线
368   - streamProxyService.updateStatus(regist, app, streamId);
  438 + streamProxyService.updateStatus(regist, app, stream);
369 439 }
370 440 if ("rtp".equals(app) && !regist ) {
371   - StreamInfo streamInfo = redisCatchStorage.queryPlayByStreamId(streamId);
  441 + StreamInfo streamInfo = redisCatchStorage.queryPlayByStreamId(stream);
372 442 if (streamInfo!=null){
373 443 redisCatchStorage.stopPlay(streamInfo);
374 444 storager.stopPlay(streamInfo.getDeviceID(), streamInfo.getChannelId());
375 445 }else{
376   - streamInfo = redisCatchStorage.queryPlayback(null, null, streamId, null);
  446 + streamInfo = redisCatchStorage.queryPlayback(null, null, stream, null);
377 447 if (streamInfo != null) {
378 448 redisCatchStorage.stopPlayback(streamInfo.getDeviceID(), streamInfo.getChannelId(),
379 449 streamInfo.getStream(), null);
... ... @@ -387,10 +457,12 @@ public class ZLMHttpHookListener {
387 457  
388 458 if (mediaServerItem != null){
389 459 if (regist) {
390   - StreamInfo streamInfoByAppAndStream = mediaService.getStreamInfoByAppAndStream(mediaServerItem, app, streamId, tracks);
  460 + StreamAuthorityInfo streamAuthorityInfo = redisCatchStorage.getStreamAuthorityInfo(app, stream);
  461 + StreamInfo streamInfoByAppAndStream = mediaService.getStreamInfoByAppAndStream(mediaServerItem,
  462 + app, stream, tracks, streamAuthorityInfo.getCallId());
391 463 item.setStreamInfo(streamInfoByAppAndStream);
392   -
393   - redisCatchStorage.addStream(mediaServerItem, type, app, streamId, item);
  464 + item.setSeverId(userSetting.getServerId());
  465 + redisCatchStorage.addStream(mediaServerItem, type, app, stream, item);
394 466 if (item.getOriginType() == OriginType.RTSP_PUSH.ordinal()
395 467 || item.getOriginType() == OriginType.RTMP_PUSH.ordinal()
396 468 || item.getOriginType() == OriginType.RTC_PUSH.ordinal() ) {
... ... @@ -413,23 +485,23 @@ public class ZLMHttpHookListener {
413 485  
414 486 }else {
415 487 // 兼容流注销时类型从redis记录获取
416   - MediaItem mediaItem = redisCatchStorage.getStreamInfo(app, streamId, mediaServerId);
  488 + MediaItem mediaItem = redisCatchStorage.getStreamInfo(app, stream, mediaServerId);
417 489 if (mediaItem != null) {
418 490 type = OriginType.values()[mediaItem.getOriginType()].getType();
419   - redisCatchStorage.removeStream(mediaServerItem.getId(), type, app, streamId);
  491 + redisCatchStorage.removeStream(mediaServerItem.getId(), type, app, stream);
420 492 }
421   - GbStream gbStream = storager.getGbStream(app, streamId);
  493 + GbStream gbStream = storager.getGbStream(app, stream);
422 494 if (gbStream != null) {
423 495 // eventPublisher.catalogEventPublishForStream(null, gbStream, CatalogEvent.OFF);
424 496 }
425   - zlmMediaListManager.removeMedia(app, streamId);
  497 + zlmMediaListManager.removeMedia(app, stream);
426 498 }
427 499 if (type != null) {
428 500 // 发送流变化redis消息
429 501 JSONObject jsonObject = new JSONObject();
430 502 jsonObject.put("serverId", userSetting.getServerId());
431 503 jsonObject.put("app", app);
432   - jsonObject.put("stream", streamId);
  504 + jsonObject.put("stream", stream);
433 505 jsonObject.put("register", regist);
434 506 jsonObject.put("mediaServerId", mediaServerId);
435 507 redisCatchStorage.sendStreamChangeMsg(type, jsonObject);
... ... @@ -565,4 +637,22 @@ public class ZLMHttpHookListener {
565 637 ret.put("msg", "success");
566 638 return new ResponseEntity<String>(ret.toString(),HttpStatus.OK);
567 639 }
  640 +
  641 + private Map<String, String> urlParamToMap(String params) {
  642 + HashMap<String, String> map = new HashMap<>();
  643 + if (StringUtils.isEmpty(params)) {
  644 + return map;
  645 + }
  646 + String[] paramsArray = params.split("&");
  647 + if (paramsArray.length == 0) {
  648 + return map;
  649 + }
  650 + for (String param : paramsArray) {
  651 + String[] paramArray = param.split("=");
  652 + if (paramArray.length == 2){
  653 + map.put(paramArray[0], paramArray[1]);
  654 + }
  655 + }
  656 + return map;
  657 + }
568 658 }
... ...
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaListManager.java
... ... @@ -115,64 +115,16 @@ public class ZLMMediaListManager {
115 115 public StreamPushItem addPush(MediaItem mediaItem) {
116 116 // 查找此直播流是否存在redis预设gbId
117 117 StreamPushItem transform = streamPushService.transform(mediaItem);
118   - // 从streamId取出查询关键值
119   - Pattern pattern = Pattern.compile(userSetting.getThirdPartyGBIdReg());
120   - Matcher matcher = pattern.matcher(mediaItem.getStream());// 指定要匹配的字符串
121   - String queryKey = null;
122   - if (matcher.find()) { //此处find()每次被调用后,会偏移到下一个匹配
123   - queryKey = matcher.group();
124   - }
125   - if (queryKey != null) {
126   - ThirdPartyGB thirdPartyGB = redisCatchStorage.queryMemberNoGBId(queryKey);
127   - if (thirdPartyGB != null && !StringUtils.isEmpty(thirdPartyGB.getNationalStandardNo())) {
128   - transform.setGbId(thirdPartyGB.getNationalStandardNo());
129   - transform.setName(thirdPartyGB.getName());
130   - }
131   - }
132   - if (!StringUtils.isEmpty(transform.getGbId())) {
133   - // 如果这个国标ID已经给了其他推流且流已离线,则移除其他推流
134   - List<GbStream> gbStreams = gbStreamMapper.selectByGBId(transform.getGbId());
135   - if (gbStreams.size() > 0) {
136   - for (GbStream gbStream : gbStreams) {
137   - // 出现使用相同国标Id的视频流时,使用新流替换旧流,
138   - if (queryKey != null && gbStream.getApp().equals(mediaItem.getApp())) {
139   - Matcher matcherForStream = pattern.matcher(gbStream.getStream());
140   - String queryKeyForStream = null;
141   - if (matcherForStream.find()) { //此处find()每次被调用后,会偏移到下一个匹配
142   - queryKeyForStream = matcherForStream.group();
143   - }
144   - if (queryKeyForStream == null || !queryKeyForStream.equals(queryKey)) {
145   - // 此时不是同一个流
146   - gbStreamMapper.del(gbStream.getApp(), gbStream.getStream());
147   - if (!gbStream.isStatus()) {
148   - streamPushMapper.del(gbStream.getApp(), gbStream.getStream());
149   - }
150   - }
151   - }
152   - }
153   - }
154   - List<GbStream> gbStreamList = gbStreamMapper.selectByGBId(transform.getGbId());
155   - if (gbStreamList != null && gbStreamList.size() == 1) {
156   - transform.setGbStreamId(gbStreamList.get(0).getGbStreamId());
157   - transform.setPlatformId(gbStreamList.get(0).getPlatformId());
158   - transform.setCatalogId(gbStreamList.get(0).getCatalogId());
159   - transform.setGbId(gbStreamList.get(0).getGbId());
160   - gbStreamMapper.update(transform);
161   - streamPushMapper.del(gbStreamList.get(0).getApp(), gbStreamList.get(0).getStream());
162   - }else {
163   - transform.setCreateTime(DateUtil.getNow());
164   - transform.setUpdateTime(DateUtil.getNow());
165   - gbStreamMapper.add(transform);
166   - }
167   - if (transform != null) {
168   - if (channelOnlineEvents.get(transform.getGbId()) != null) {
169   - channelOnlineEvents.get(transform.getGbId()).run(transform.getApp(), transform.getStream(), transform.getServerId());
170   - channelOnlineEvents.remove(transform.getGbId());
171   - }
172   - }
  118 + StreamPushItem pushInDb = streamPushService.getPush(mediaItem.getApp(), mediaItem.getStream());
  119 + transform.setPushIng(true);
  120 + transform.setUpdateTime(DateUtil.getNow());
  121 + transform.setPushTime(DateUtil.getNow());
  122 + if (pushInDb == null) {
  123 + transform.setCreateTime(DateUtil.getNow());
  124 + streamPushMapper.add(transform);
  125 + }else {
  126 + streamPushMapper.update(transform);
173 127 }
174   -
175   - storager.updateMedia(transform);
176 128 return transform;
177 129 }
178 130  
... ... @@ -206,13 +158,13 @@ public class ZLMMediaListManager {
206 158  
207 159 public int removeMedia(String app, String streamId) {
208 160 // 查找是否关联了国标, 关联了不删除, 置为离线
209   - StreamProxyItem streamProxyItem = gbStreamMapper.selectOne(app, streamId);
210   - int result = 0;
211   - if (streamProxyItem == null) {
  161 + GbStream gbStream = gbStreamMapper.selectOne(app, streamId);
  162 + int result;
  163 + if (gbStream == null) {
212 164 result = storager.removeMedia(app, streamId);
213 165 }else {
214 166 // TODO 暂不设置为离线
215   - result =storager.mediaOutline(app, streamId);
  167 + result =storager.mediaOffline(app, streamId);
216 168 }
217 169 return result;
218 170 }
... ...
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRTPServerFactory.java
... ... @@ -66,7 +66,7 @@ public class ZLMRTPServerFactory {
66 66 String stream = UUID.randomUUID().toString();
67 67 param.put("enable_tcp", 1);
68 68 param.put("stream_id", stream);
69   - param.put("port", 0);
  69 +// param.put("port", 0);
70 70 JSONObject openRtpServerResultJson = zlmresTfulUtils.openRtpServer(mediaServerItem, param);
71 71  
72 72 if (openRtpServerResultJson != null) {
... ... @@ -101,9 +101,10 @@ public class ZLMRTPServerFactory {
101 101 }
102 102  
103 103 Map<String, Object> param = new HashMap<>();
104   - // 推流端口设置0则使用随机端口
  104 +
105 105 param.put("enable_tcp", 1);
106 106 param.put("stream_id", streamId);
  107 + // 推流端口设置0则使用随机端口
107 108 param.put("port", 0);
108 109 param.put("ssrc", ssrc);
109 110 JSONObject openRtpServerResultJson = zlmresTfulUtils.openRtpServer(mediaServerItem, param);
... ... @@ -291,7 +292,7 @@ public class ZLMRTPServerFactory {
291 292 logger.warn("查询流({}/{})是否有其它观看者时得到: {}", app, streamId, mediaInfo.getString("msg"));
292 293 return -1;
293 294 }
294   - if ( code == 0 && ! mediaInfo.getBoolean("online")) {
  295 + if ( code == 0 && mediaInfo.getBoolean("online") != null && !mediaInfo.getBoolean("online")) {
295 296 logger.warn("查询流({}/{})是否有其它观看者时得到: {}", app, streamId, mediaInfo.getString("msg"));
296 297 return -1;
297 298 }
... ...
src/main/java/com/genersoft/iot/vmp/media/zlm/dto/HookParam.java 0 → 100644
  1 +package com.genersoft.iot.vmp.media.zlm.dto;
  2 +
  3 +/**
  4 + * zlm hook事件的参数
  5 + * @author lin
  6 + */
  7 +public class HookParam {
  8 + private String mediaServerId;
  9 +
  10 + public String getMediaServerId() {
  11 + return mediaServerId;
  12 + }
  13 +
  14 + public void setMediaServerId(String mediaServerId) {
  15 + this.mediaServerId = mediaServerId;
  16 + }
  17 +}
... ...
src/main/java/com/genersoft/iot/vmp/media/zlm/dto/MediaItem.java
... ... @@ -4,6 +4,9 @@ import com.genersoft.iot.vmp.common.StreamInfo;
4 4  
5 5 import java.util.List;
6 6  
  7 +/**
  8 + * @author lin
  9 + */
7 10 public class MediaItem {
8 11  
9 12 /**
... ... @@ -22,6 +25,11 @@ public class MediaItem {
22 25 private String stream;
23 26  
24 27 /**
  28 + * 推流鉴权Id
  29 + */
  30 + private String callId;
  31 +
  32 + /**
25 33 * 观看总人数,包括hls/rtsp/rtmp/http-flv/ws-flv
26 34 */
27 35 private String totalReaderCount;
... ... @@ -427,4 +435,12 @@ public class MediaItem {
427 435 public void setSeverId(String severId) {
428 436 this.severId = severId;
429 437 }
  438 +
  439 + public String getCallId() {
  440 + return callId;
  441 + }
  442 +
  443 + public void setCallId(String callId) {
  444 + this.callId = callId;
  445 + }
430 446 }
... ...
src/main/java/com/genersoft/iot/vmp/media/zlm/dto/OnPlayHookParam.java 0 → 100644
  1 +package com.genersoft.iot.vmp.media.zlm.dto;
  2 +
  3 +/**
  4 + * zlm hook事件中的on_play事件的参数
  5 + * @author lin
  6 + */
  7 +public class OnPlayHookParam extends HookParam{
  8 + private String id;
  9 + private String app;
  10 + private String stream;
  11 + private String ip;
  12 + private String params;
  13 + private int port;
  14 + private String schema;
  15 + private String vhost;
  16 +
  17 +
  18 + public String getId() {
  19 + return id;
  20 + }
  21 +
  22 + public void setId(String id) {
  23 + this.id = id;
  24 + }
  25 +
  26 + public String getApp() {
  27 + return app;
  28 + }
  29 +
  30 + public void setApp(String app) {
  31 + this.app = app;
  32 + }
  33 +
  34 + public String getStream() {
  35 + return stream;
  36 + }
  37 +
  38 + public void setStream(String stream) {
  39 + this.stream = stream;
  40 + }
  41 +
  42 + public String getIp() {
  43 + return ip;
  44 + }
  45 +
  46 + public void setIp(String ip) {
  47 + this.ip = ip;
  48 + }
  49 +
  50 + public String getParams() {
  51 + return params;
  52 + }
  53 +
  54 + public void setParams(String params) {
  55 + this.params = params;
  56 + }
  57 +
  58 + public int getPort() {
  59 + return port;
  60 + }
  61 +
  62 + public void setPort(int port) {
  63 + this.port = port;
  64 + }
  65 +
  66 + public String getSchema() {
  67 + return schema;
  68 + }
  69 +
  70 + public void setSchema(String schema) {
  71 + this.schema = schema;
  72 + }
  73 +
  74 + public String getVhost() {
  75 + return vhost;
  76 + }
  77 +
  78 + public void setVhost(String vhost) {
  79 + this.vhost = vhost;
  80 + }
  81 +
  82 +}
... ...
src/main/java/com/genersoft/iot/vmp/media/zlm/dto/OnPublishHookParam.java 0 → 100644
  1 +package com.genersoft.iot.vmp.media.zlm.dto;
  2 +
  3 +/**
  4 + * zlm hook事件中的on_publish事件的参数
  5 + * @author lin
  6 + */
  7 +public class OnPublishHookParam extends HookParam{
  8 + private String id;
  9 + private String app;
  10 + private String stream;
  11 + private String ip;
  12 + private String params;
  13 + private int port;
  14 + private String schema;
  15 + private String vhost;
  16 +
  17 +
  18 + public String getId() {
  19 + return id;
  20 + }
  21 +
  22 + public void setId(String id) {
  23 + this.id = id;
  24 + }
  25 +
  26 + public String getApp() {
  27 + return app;
  28 + }
  29 +
  30 + public void setApp(String app) {
  31 + this.app = app;
  32 + }
  33 +
  34 + public String getStream() {
  35 + return stream;
  36 + }
  37 +
  38 + public void setStream(String stream) {
  39 + this.stream = stream;
  40 + }
  41 +
  42 + public String getIp() {
  43 + return ip;
  44 + }
  45 +
  46 + public void setIp(String ip) {
  47 + this.ip = ip;
  48 + }
  49 +
  50 + public String getParams() {
  51 + return params;
  52 + }
  53 +
  54 + public void setParams(String params) {
  55 + this.params = params;
  56 + }
  57 +
  58 + public int getPort() {
  59 + return port;
  60 + }
  61 +
  62 + public void setPort(int port) {
  63 + this.port = port;
  64 + }
  65 +
  66 + public String getSchema() {
  67 + return schema;
  68 + }
  69 +
  70 + public void setSchema(String schema) {
  71 + this.schema = schema;
  72 + }
  73 +
  74 + public String getVhost() {
  75 + return vhost;
  76 + }
  77 +
  78 + public void setVhost(String vhost) {
  79 + this.vhost = vhost;
  80 + }
  81 +
  82 +}
... ...
src/main/java/com/genersoft/iot/vmp/media/zlm/dto/StreamAuthorityInfo.java 0 → 100644
  1 +package com.genersoft.iot.vmp.media.zlm.dto;
  2 +
  3 +/**
  4 + * 流的鉴权信息
  5 + * @author lin
  6 + */
  7 +public class StreamAuthorityInfo {
  8 +
  9 + private String id;
  10 + private String app;
  11 + private String stream;
  12 +
  13 + /**
  14 + * 产生源类型,
  15 + * unknown = 0,
  16 + * rtmp_push=1,
  17 + * rtsp_push=2,
  18 + * rtp_push=3,
  19 + * pull=4,
  20 + * ffmpeg_pull=5,
  21 + * mp4_vod=6,
  22 + * device_chn=7
  23 + */
  24 + private int originType;
  25 +
  26 + /**
  27 + * 产生源类型的字符串描述
  28 + */
  29 + private String originTypeStr;
  30 +
  31 + /**
  32 + * 推流时自定义的播放鉴权ID
  33 + */
  34 + private String callId;
  35 +
  36 + /**
  37 + * 推流的鉴权签名
  38 + */
  39 + private String sign;
  40 +
  41 + public String getId() {
  42 + return id;
  43 + }
  44 +
  45 + public void setId(String id) {
  46 + this.id = id;
  47 + }
  48 +
  49 + public String getApp() {
  50 + return app;
  51 + }
  52 +
  53 + public void setApp(String app) {
  54 + this.app = app;
  55 + }
  56 +
  57 + public String getStream() {
  58 + return stream;
  59 + }
  60 +
  61 + public void setStream(String stream) {
  62 + this.stream = stream;
  63 + }
  64 +
  65 + public int getOriginType() {
  66 + return originType;
  67 + }
  68 +
  69 + public void setOriginType(int originType) {
  70 + this.originType = originType;
  71 + }
  72 +
  73 + public String getOriginTypeStr() {
  74 + return originTypeStr;
  75 + }
  76 +
  77 + public void setOriginTypeStr(String originTypeStr) {
  78 + this.originTypeStr = originTypeStr;
  79 + }
  80 +
  81 + public String getCallId() {
  82 + return callId;
  83 + }
  84 +
  85 + public void setCallId(String callId) {
  86 + this.callId = callId;
  87 + }
  88 +
  89 + public String getSign() {
  90 + return sign;
  91 + }
  92 +
  93 + public void setSign(String sign) {
  94 + this.sign = sign;
  95 + }
  96 +
  97 + public static StreamAuthorityInfo getInstanceByHook(OnPublishHookParam hookParam) {
  98 + StreamAuthorityInfo streamAuthorityInfo = new StreamAuthorityInfo();
  99 + streamAuthorityInfo.setApp(hookParam.getApp());
  100 + streamAuthorityInfo.setStream(hookParam.getStream());
  101 + streamAuthorityInfo.setId(hookParam.getId());
  102 + return streamAuthorityInfo;
  103 + }
  104 +
  105 + public static StreamAuthorityInfo getInstanceByHook(MediaItem mediaItem) {
  106 + StreamAuthorityInfo streamAuthorityInfo = new StreamAuthorityInfo();
  107 + streamAuthorityInfo.setApp(mediaItem.getApp());
  108 + streamAuthorityInfo.setStream(mediaItem.getStream());
  109 + streamAuthorityInfo.setId(mediaItem.getMediaServerId());
  110 + streamAuthorityInfo.setOriginType(mediaItem.getOriginType());
  111 + streamAuthorityInfo.setOriginTypeStr(mediaItem.getOriginTypeStr());
  112 + return streamAuthorityInfo;
  113 + }
  114 +}
... ...
src/main/java/com/genersoft/iot/vmp/media/zlm/dto/StreamPushItem.java
... ... @@ -103,6 +103,11 @@ public class StreamPushItem extends GbStream implements Comparable&lt;StreamPushIte
103 103 */
104 104 private String createTime;
105 105  
  106 + /**
  107 + * 是否正在推流
  108 + */
  109 + private boolean pushIng;
  110 +
106 111 public String getVhost() {
107 112 return vhost;
108 113 }
... ... @@ -277,5 +282,13 @@ public class StreamPushItem extends GbStream implements Comparable&lt;StreamPushIte
277 282 public void setCreateTime(String createTime) {
278 283 this.createTime = createTime;
279 284 }
  285 +
  286 + public boolean isPushIng() {
  287 + return pushIng;
  288 + }
  289 +
  290 + public void setPushIng(boolean pushIng) {
  291 + this.pushIng = pushIng;
  292 + }
280 293 }
281 294  
... ...
src/main/java/com/genersoft/iot/vmp/service/IDeviceChannelService.java 0 → 100644
  1 +package com.genersoft.iot.vmp.service;
  2 +
  3 +import com.genersoft.iot.vmp.gb28181.bean.Device;
  4 +import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
  5 +
  6 +import java.util.List;
  7 +
  8 +/**
  9 + * 国标通道业务类
  10 + * @author lin
  11 + */
  12 +public interface IDeviceChannelService {
  13 +
  14 + /**
  15 + * 更新gps信息
  16 + */
  17 + DeviceChannel updateGps(DeviceChannel deviceChannel, Device device);
  18 +
  19 + /**
  20 + * 添加设备通道
  21 + *
  22 + * @param deviceId 设备id
  23 + * @param channel 通道
  24 + */
  25 + void updateChannel(String deviceId, DeviceChannel channel);
  26 +
  27 + /**
  28 + * 批量添加设备通道
  29 + *
  30 + * @param deviceId 设备id
  31 + * @param channels 多个通道
  32 + */
  33 + int updateChannels(String deviceId, List<DeviceChannel> channels);
  34 +
  35 +}
... ...
src/main/java/com/genersoft/iot/vmp/service/IGbStreamService.java
... ... @@ -18,7 +18,7 @@ public interface IGbStreamService {
18 18 * @param count
19 19 * @return
20 20 */
21   - PageInfo<GbStream> getAll(Integer page, Integer count, String platFormId, String catalogId,String query,Boolean pushing,String mediaServerId);
  21 + PageInfo<GbStream> getAll(Integer page, Integer count, String platFormId, String catalogId,String query,String mediaServerId);
22 22  
23 23  
24 24 /**
... ...
src/main/java/com/genersoft/iot/vmp/service/IMediaService.java
... ... @@ -15,7 +15,7 @@ public interface IMediaService {
15 15 * @param stream
16 16 * @return
17 17 */
18   - StreamInfo getStreamInfoByAppAndStreamWithCheck(String app, String stream, String mediaServerId,String addr);
  18 + StreamInfo getStreamInfoByAppAndStreamWithCheck(String app, String stream, String mediaServerId,String addr, boolean authority);
19 19  
20 20  
21 21 /**
... ... @@ -24,7 +24,7 @@ public interface IMediaService {
24 24 * @param stream
25 25 * @return
26 26 */
27   - StreamInfo getStreamInfoByAppAndStreamWithCheck(String app, String stream, String mediaServerId);
  27 + StreamInfo getStreamInfoByAppAndStreamWithCheck(String app, String stream, String mediaServerId, boolean authority);
28 28  
29 29 /**
30 30 * 根据应用名和流ID获取播放地址, 只是地址拼接
... ... @@ -32,7 +32,7 @@ public interface IMediaService {
32 32 * @param stream
33 33 * @return
34 34 */
35   - StreamInfo getStreamInfoByAppAndStream(MediaServerItem mediaServerItem, String app, String stream, Object tracks);
  35 + StreamInfo getStreamInfoByAppAndStream(MediaServerItem mediaServerItem, String app, String stream, Object tracks, String callId);
36 36  
37 37 /**
38 38 * 根据应用名和流ID获取播放地址, 只是地址拼接,返回的ip使用远程访问ip,适用与zlm与wvp在一台主机的情况
... ... @@ -40,5 +40,5 @@ public interface IMediaService {
40 40 * @param stream
41 41 * @return
42 42 */
43   - StreamInfo getStreamInfoByAppAndStream(MediaServerItem mediaInfo, String app, String stream, Object tracks, String addr);
  43 + StreamInfo getStreamInfoByAppAndStream(MediaServerItem mediaInfo, String app, String stream, Object tracks, String addr, String callId);
44 44 }
... ...
src/main/java/com/genersoft/iot/vmp/service/IPlatformChannelService.java 0 → 100644
  1 +package com.genersoft.iot.vmp.service;
  2 +
  3 +import com.genersoft.iot.vmp.vmanager.gb28181.platform.bean.ChannelReduce;
  4 +
  5 +import java.util.List;
  6 +
  7 +/**
  8 + * 平台关联通道管理
  9 + * @author lin
  10 + */
  11 +public interface IPlatformChannelService {
  12 +
  13 + /**
  14 + * 更新目录下的通道
  15 + * @param platformId 平台编号
  16 + * @param channelReduces 通道信息
  17 + * @param catalogId 目录编号
  18 + * @return
  19 + */
  20 + int updateChannelForGB(String platformId, List<ChannelReduce> channelReduces, String catalogId);
  21 +
  22 +}
... ...
src/main/java/com/genersoft/iot/vmp/service/IStreamProxyService.java
... ... @@ -101,4 +101,9 @@ public interface IStreamProxyService {
101 101 void zlmServerOffline(String mediaServerId);
102 102  
103 103 void clean();
  104 +
  105 + /**
  106 + * 更新代理流
  107 + */
  108 + boolean updateStreamProxy(StreamProxyItem streamProxyItem);
104 109 }
... ...
src/main/java/com/genersoft/iot/vmp/service/IStreamPushService.java
... ... @@ -5,6 +5,7 @@ import com.genersoft.iot.vmp.media.zlm.ZLMServerConfig;
5 5 import com.genersoft.iot.vmp.media.zlm.dto.MediaItem;
6 6 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
7 7 import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem;
  8 +import com.genersoft.iot.vmp.service.bean.StreamPushItemFromRedis;
8 9 import com.genersoft.iot.vmp.vmanager.bean.StreamPushExcelDto;
9 10 import com.github.pagehelper.PageInfo;
10 11  
... ... @@ -44,31 +45,55 @@ public interface IStreamPushService {
44 45 * 停止一路推流
45 46 * @param app 应用名
46 47 * @param streamId 流ID
47   - * @return
48 48 */
49 49 boolean stop(String app, String streamId);
50 50  
51 51 /**
52 52 * 新的节点加入
53   - * @param mediaServerId
54   - * @return
55 53 */
56 54 void zlmServerOnline(String mediaServerId);
57 55  
58 56 /**
59 57 * 节点离线
60   - * @param mediaServerId
61   - * @return
62 58 */
63 59 void zlmServerOffline(String mediaServerId);
64 60  
  61 + /**
  62 + * 清空
  63 + */
65 64 void clean();
66 65  
  66 +
67 67 boolean saveToRandomGB();
68 68  
  69 + /**
  70 + * 批量添加
  71 + */
69 72 void batchAdd(List<StreamPushItem> streamPushExcelDtoList);
70 73  
  74 + /**
  75 + * 中止多个推流
  76 + */
71 77 boolean batchStop(List<GbStream> streamPushItems);
72 78  
  79 + /**
  80 + * 导入时批量增加
  81 + */
73 82 void batchAddForUpload(List<StreamPushItem> streamPushItems, Map<String, List<String[]>> streamPushItemsForAll);
  83 +
  84 + /**
  85 + * 全部离线
  86 + */
  87 + void allStreamOffline();
  88 +
  89 + /**
  90 + * 推流离线
  91 + */
  92 + void offline(List<StreamPushItemFromRedis> offlineStreams);
  93 +
  94 + /**
  95 + * 推流上线
  96 + */
  97 + void online(List<StreamPushItemFromRedis> onlineStreams);
  98 +
74 99 }
... ...
src/main/java/com/genersoft/iot/vmp/service/IUserService.java
1 1 package com.genersoft.iot.vmp.service;
2 2  
3 3 import com.genersoft.iot.vmp.storager.dao.dto.User;
  4 +import com.github.pagehelper.PageInfo;
4 5  
5 6 import java.util.List;
6 7  
... ... @@ -19,4 +20,10 @@ public interface IUserService {
19 20 List<User> getAllUsers();
20 21  
21 22 int updateUsers(User user);
  23 +
  24 + boolean checkPushAuthority(String callId, String sign);
  25 +
  26 + PageInfo<User> getUsers(int page, int count);
  27 +
  28 + int changePushKey(int id, String pushKey);
22 29 }
... ...
src/main/java/com/genersoft/iot/vmp/service/bean/PushStreamStatusChangeFromRedisDto.java 0 → 100644
  1 +package com.genersoft.iot.vmp.service.bean;
  2 +
  3 +import java.util.List;
  4 +
  5 +/**
  6 + * 收到redis通知修改推流通道状态
  7 + * @author lin
  8 + */
  9 +public class PushStreamStatusChangeFromRedisDto {
  10 +
  11 + private boolean setAllOffline;
  12 +
  13 + private List<StreamPushItemFromRedis> onlineStreams;
  14 +
  15 + private List<StreamPushItemFromRedis> offlineStreams;
  16 +
  17 +
  18 + public boolean isSetAllOffline() {
  19 + return setAllOffline;
  20 + }
  21 +
  22 + public void setSetAllOffline(boolean setAllOffline) {
  23 + this.setAllOffline = setAllOffline;
  24 + }
  25 +
  26 + public List<StreamPushItemFromRedis> getOnlineStreams() {
  27 + return onlineStreams;
  28 + }
  29 +
  30 + public void setOnlineStreams(List<StreamPushItemFromRedis> onlineStreams) {
  31 + this.onlineStreams = onlineStreams;
  32 + }
  33 +
  34 + public List<StreamPushItemFromRedis> getOfflineStreams() {
  35 + return offlineStreams;
  36 + }
  37 +
  38 + public void setOfflineStreams(List<StreamPushItemFromRedis> offlineStreams) {
  39 + this.offlineStreams = offlineStreams;
  40 + }
  41 +}
... ...
src/main/java/com/genersoft/iot/vmp/service/bean/StreamPushItemFromRedis.java 0 → 100644
  1 +package com.genersoft.iot.vmp.service.bean;
  2 +
  3 +
  4 +public class StreamPushItemFromRedis {
  5 + private String app;
  6 + private String stream;
  7 + private long timeStamp;
  8 +
  9 + public String getApp() {
  10 + return app;
  11 + }
  12 +
  13 + public void setApp(String app) {
  14 + this.app = app;
  15 + }
  16 +
  17 + public String getStream() {
  18 + return stream;
  19 + }
  20 +
  21 + public void setStream(String stream) {
  22 + this.stream = stream;
  23 + }
  24 +
  25 + public long getTimeStamp() {
  26 + return timeStamp;
  27 + }
  28 +
  29 + public void setTimeStamp(long timeStamp) {
  30 + this.timeStamp = timeStamp;
  31 + }
  32 +}
  33 +
  34 +
... ...
src/main/java/com/genersoft/iot/vmp/service/impl/DeviceAlarmServiceImpl.java
... ... @@ -17,7 +17,6 @@ public class DeviceAlarmServiceImpl implements IDeviceAlarmService {
17 17 @Autowired
18 18 private DeviceAlarmMapper deviceAlarmMapper;
19 19  
20   -
21 20 @Override
22 21 public PageInfo<DeviceAlarm> getAllAlarm(int page, int count, String deviceId, String alarmPriority, String alarmMethod, String alarmType, String startTime, String endTime) {
23 22 PageHelper.startPage(page, count);
... ...
src/main/java/com/genersoft/iot/vmp/service/impl/DeviceChannelServiceImpl.java 0 → 100644
  1 +package com.genersoft.iot.vmp.service.impl;
  2 +
  3 +import com.genersoft.iot.vmp.common.StreamInfo;
  4 +import com.genersoft.iot.vmp.gb28181.bean.Device;
  5 +import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
  6 +import com.genersoft.iot.vmp.gb28181.utils.Coordtransform;
  7 +import com.genersoft.iot.vmp.service.IDeviceChannelService;
  8 +import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
  9 +import com.genersoft.iot.vmp.storager.dao.DeviceChannelMapper;
  10 +import com.genersoft.iot.vmp.storager.dao.DeviceMapper;
  11 +import com.genersoft.iot.vmp.utils.DateUtil;
  12 +import org.slf4j.Logger;
  13 +import org.slf4j.LoggerFactory;
  14 +import org.springframework.beans.factory.annotation.Autowired;
  15 +import org.springframework.stereotype.Service;
  16 +
  17 +import java.util.ArrayList;
  18 +import java.util.HashMap;
  19 +import java.util.List;
  20 +
  21 +/**
  22 + * @author lin
  23 + */
  24 +@Service
  25 +public class DeviceChannelServiceImpl implements IDeviceChannelService {
  26 +
  27 + private final static Logger logger = LoggerFactory.getLogger(DeviceChannelServiceImpl.class);
  28 +
  29 + @Autowired
  30 + private IRedisCatchStorage redisCatchStorage;
  31 +
  32 + @Autowired
  33 + private DeviceChannelMapper channelMapper;
  34 +
  35 + @Autowired
  36 + private DeviceMapper deviceMapper;
  37 +
  38 + @Override
  39 + public DeviceChannel updateGps(DeviceChannel deviceChannel, Device device) {
  40 + if (deviceChannel.getLongitude()*deviceChannel.getLatitude() > 0) {
  41 + if (device == null) {
  42 + device = deviceMapper.getDeviceByDeviceId(deviceChannel.getDeviceId());
  43 + }
  44 +
  45 + if ("WGS84".equals(device.getGeoCoordSys())) {
  46 + deviceChannel.setLongitudeWgs84(deviceChannel.getLongitude());
  47 + deviceChannel.setLatitudeWgs84(deviceChannel.getLatitude());
  48 + Double[] position = Coordtransform.WGS84ToGCJ02(deviceChannel.getLongitude(), deviceChannel.getLatitude());
  49 + deviceChannel.setLongitudeGcj02(position[0]);
  50 + deviceChannel.setLatitudeGcj02(position[1]);
  51 + }else if ("GCJ02".equals(device.getGeoCoordSys())) {
  52 + deviceChannel.setLongitudeGcj02(deviceChannel.getLongitude());
  53 + deviceChannel.setLatitudeGcj02(deviceChannel.getLatitude());
  54 + Double[] position = Coordtransform.GCJ02ToWGS84(deviceChannel.getLongitude(), deviceChannel.getLatitude());
  55 + deviceChannel.setLongitudeWgs84(position[0]);
  56 + deviceChannel.setLatitudeWgs84(position[1]);
  57 + }else {
  58 + deviceChannel.setLongitudeGcj02(0.00);
  59 + deviceChannel.setLatitudeGcj02(0.00);
  60 + deviceChannel.setLongitudeWgs84(0.00);
  61 + deviceChannel.setLatitudeWgs84(0.00);
  62 + }
  63 + }else {
  64 + deviceChannel.setLongitudeGcj02(deviceChannel.getLongitude());
  65 + deviceChannel.setLatitudeGcj02(deviceChannel.getLatitude());
  66 + deviceChannel.setLongitudeWgs84(deviceChannel.getLongitude());
  67 + deviceChannel.setLatitudeWgs84(deviceChannel.getLatitude());
  68 + }
  69 + return deviceChannel;
  70 + }
  71 +
  72 + @Override
  73 + public void updateChannel(String deviceId, DeviceChannel channel) {
  74 + String channelId = channel.getChannelId();
  75 + channel.setDeviceId(deviceId);
  76 + StreamInfo streamInfo = redisCatchStorage.queryPlayByDevice(deviceId, channelId);
  77 + if (streamInfo != null) {
  78 + channel.setStreamId(streamInfo.getStream());
  79 + }
  80 + String now = DateUtil.getNow();
  81 + channel.setUpdateTime(now);
  82 + DeviceChannel deviceChannel = channelMapper.queryChannel(deviceId, channelId);
  83 + channel = updateGps(channel, null);
  84 + if (deviceChannel == null) {
  85 + channel.setCreateTime(now);
  86 + channelMapper.add(channel);
  87 + }else {
  88 + channelMapper.update(channel);
  89 + }
  90 + channelMapper.updateChannelSubCount(deviceId,channel.getParentId());
  91 + }
  92 +
  93 + @Override
  94 + public int updateChannels(String deviceId, List<DeviceChannel> channels) {
  95 + List<DeviceChannel> addChannels = new ArrayList<>();
  96 + List<DeviceChannel> updateChannels = new ArrayList<>();
  97 + HashMap<String, DeviceChannel> channelsInStore = new HashMap<>();
  98 + Device device = deviceMapper.getDeviceByDeviceId(deviceId);
  99 + if (channels != null && channels.size() > 0) {
  100 + List<DeviceChannel> channelList = channelMapper.queryChannels(deviceId, null, null, null, null);
  101 + if (channelList.size() == 0) {
  102 + for (DeviceChannel channel : channels) {
  103 + channel.setDeviceId(deviceId);
  104 + StreamInfo streamInfo = redisCatchStorage.queryPlayByDevice(deviceId, channel.getChannelId());
  105 + if (streamInfo != null) {
  106 + channel.setStreamId(streamInfo.getStream());
  107 + }
  108 + String now = DateUtil.getNow();
  109 + channel.setUpdateTime(now);
  110 + channel.setCreateTime(now);
  111 + channel = updateGps(channel, device);
  112 + addChannels.add(channel);
  113 + }
  114 + }else {
  115 + for (DeviceChannel deviceChannel : channelList) {
  116 + channelsInStore.put(deviceChannel.getChannelId(), deviceChannel);
  117 + }
  118 + for (DeviceChannel channel : channels) {
  119 + channel.setDeviceId(deviceId);
  120 + StreamInfo streamInfo = redisCatchStorage.queryPlayByDevice(deviceId, channel.getChannelId());
  121 + if (streamInfo != null) {
  122 + channel.setStreamId(streamInfo.getStream());
  123 + }
  124 + String now = DateUtil.getNow();
  125 + channel.setUpdateTime(now);
  126 + channel = updateGps(channel, device);
  127 + if (channelsInStore.get(channel.getChannelId()) != null) {
  128 + updateChannels.add(channel);
  129 + }else {
  130 + addChannels.add(channel);
  131 + channel.setCreateTime(now);
  132 + }
  133 + }
  134 + }
  135 + int limitCount = 300;
  136 + if (addChannels.size() > 0) {
  137 + if (addChannels.size() > limitCount) {
  138 + for (int i = 0; i < addChannels.size(); i += limitCount) {
  139 + int toIndex = i + limitCount;
  140 + if (i + limitCount > addChannels.size()) {
  141 + toIndex = addChannels.size();
  142 + }
  143 + channelMapper.batchAdd(addChannels.subList(i, toIndex));
  144 + }
  145 + }else {
  146 + channelMapper.batchAdd(addChannels);
  147 + }
  148 + }
  149 + if (updateChannels.size() > 0) {
  150 + if (updateChannels.size() > limitCount) {
  151 + for (int i = 0; i < updateChannels.size(); i += limitCount) {
  152 + int toIndex = i + limitCount;
  153 + if (i + limitCount > updateChannels.size()) {
  154 + toIndex = updateChannels.size();
  155 + }
  156 + channelMapper.batchUpdate(updateChannels.subList(i, toIndex));
  157 + }
  158 + }else {
  159 + channelMapper.batchUpdate(updateChannels);
  160 + }
  161 + }
  162 + }
  163 + return addChannels.size() + updateChannels.size();
  164 + }
  165 +}
... ...
src/main/java/com/genersoft/iot/vmp/service/impl/DeviceServiceImpl.java
... ... @@ -7,6 +7,7 @@ import com.genersoft.iot.vmp.gb28181.task.ISubscribeTask;
7 7 import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander;
8 8 import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.response.cmd.CatalogResponseMessageHandler;
9 9 import com.genersoft.iot.vmp.gb28181.utils.Coordtransform;
  10 +import com.genersoft.iot.vmp.service.IDeviceChannelService;
10 11 import com.genersoft.iot.vmp.service.IDeviceService;
11 12 import com.genersoft.iot.vmp.gb28181.task.impl.CatalogSubscribeTask;
12 13 import com.genersoft.iot.vmp.gb28181.task.impl.MobilePositionSubscribeTask;
... ... @@ -56,6 +57,9 @@ public class DeviceServiceImpl implements IDeviceService {
56 57 private DeviceMapper deviceMapper;
57 58  
58 59 @Autowired
  60 + private IDeviceChannelService deviceChannelService;
  61 +
  62 + @Autowired
59 63 private DeviceChannelMapper deviceChannelMapper;
60 64  
61 65 @Autowired
... ... @@ -324,23 +328,12 @@ public class DeviceServiceImpl implements IDeviceService {
324 328 private void updateDeviceChannelGeoCoordSys(Device device) {
325 329 List<DeviceChannel> deviceChannels = deviceChannelMapper.getAllChannelWithCoordinate(device.getDeviceId());
326 330 if (deviceChannels.size() > 0) {
  331 + List<DeviceChannel> deviceChannelsForStore = new ArrayList<>();
327 332 for (DeviceChannel deviceChannel : deviceChannels) {
328   - if ("WGS84".equals(device.getGeoCoordSys())) {
329   - deviceChannel.setLongitudeWgs84(deviceChannel.getLongitude());
330   - deviceChannel.setLatitudeWgs84(deviceChannel.getLatitude());
331   - Double[] position = Coordtransform.WGS84ToGCJ02(deviceChannel.getLongitude(), deviceChannel.getLatitude());
332   - deviceChannel.setLongitudeGcj02(position[0]);
333   - deviceChannel.setLatitudeGcj02(position[1]);
334   - }else if ("GCJ02".equals(device.getGeoCoordSys())) {
335   - deviceChannel.setLongitudeGcj02(deviceChannel.getLongitude());
336   - deviceChannel.setLatitudeGcj02(deviceChannel.getLatitude());
337   - Double[] position = Coordtransform.GCJ02ToWGS84(deviceChannel.getLongitude(), deviceChannel.getLatitude());
338   - deviceChannel.setLongitudeWgs84(position[0]);
339   - deviceChannel.setLatitudeWgs84(position[1]);
340   - }
  333 + deviceChannelsForStore.add(deviceChannelService.updateGps(deviceChannel, device));
341 334 }
  335 + deviceChannelService.updateChannels(device.getDeviceId(), deviceChannelsForStore);
342 336 }
343   - storage.updateChannels(device.getDeviceId(), deviceChannels);
344 337 }
345 338  
346 339  
... ... @@ -352,11 +345,11 @@ public class DeviceServiceImpl implements IDeviceService {
352 345 }
353 346 if (parentId == null || parentId.equals(deviceId)) {
354 347 // 字根节点开始查询
355   - List<DeviceChannel> rootNodes = getRootNodes(deviceId, "CivilCode".equals(device.getTreeType()), true, !onlyCatalog);
  348 + List<DeviceChannel> rootNodes = getRootNodes(deviceId, TreeType.CIVIL_CODE.equals(device.getTreeType()), true, !onlyCatalog);
356 349 return transportChannelsToTree(rootNodes, "");
357 350 }
358 351  
359   - if ("CivilCode".equals(device.getTreeType())) {
  352 + if (TreeType.CIVIL_CODE.equals(device.getTreeType())) {
360 353 if (parentId.length()%2 != 0) {
361 354 return null;
362 355 }
... ... @@ -386,7 +379,7 @@ public class DeviceServiceImpl implements IDeviceService {
386 379  
387 380 }
388 381 // 使用业务分组展示树
389   - if ("BusinessGroup".equals(device.getTreeType())) {
  382 + if (TreeType.BUSINESS_GROUP.equals(device.getTreeType())) {
390 383 if (parentId.length() < 14 ) {
391 384 return null;
392 385 }
... ... @@ -406,11 +399,11 @@ public class DeviceServiceImpl implements IDeviceService {
406 399 }
407 400 if (parentId == null || parentId.equals(deviceId)) {
408 401 // 字根节点开始查询
409   - List<DeviceChannel> rootNodes = getRootNodes(deviceId, "CivilCode".equals(device.getTreeType()), false, true);
  402 + List<DeviceChannel> rootNodes = getRootNodes(deviceId, TreeType.CIVIL_CODE.equals(device.getTreeType()), false, true);
410 403 return rootNodes;
411 404 }
412 405  
413   - if ("CivilCode".equals(device.getTreeType())) {
  406 + if (TreeType.CIVIL_CODE.equals(device.getTreeType())) {
414 407 if (parentId.length()%2 != 0) {
415 408 return null;
416 409 }
... ... @@ -431,7 +424,7 @@ public class DeviceServiceImpl implements IDeviceService {
431 424  
432 425 }
433 426 // 使用业务分组展示树
434   - if ("BusinessGroup".equals(device.getTreeType())) {
  427 + if (TreeType.BUSINESS_GROUP.equals(device.getTreeType())) {
435 428 if (parentId.length() < 14 ) {
436 429 return null;
437 430 }
... ...
src/main/java/com/genersoft/iot/vmp/service/impl/GbStreamServiceImpl.java
1 1 package com.genersoft.iot.vmp.service.impl;
2 2  
3 3 import com.genersoft.iot.vmp.conf.SipConfig;
4   -import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
5   -import com.genersoft.iot.vmp.gb28181.bean.GbStream;
6   -import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
  4 +import com.genersoft.iot.vmp.gb28181.bean.*;
7 5 import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
8 6 import com.genersoft.iot.vmp.gb28181.event.subscribe.catalog.CatalogEvent;
9 7 import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem;
10 8 import com.genersoft.iot.vmp.storager.dao.GbStreamMapper;
11 9 import com.genersoft.iot.vmp.storager.dao.ParentPlatformMapper;
  10 +import com.genersoft.iot.vmp.storager.dao.PlatformCatalogMapper;
12 11 import com.genersoft.iot.vmp.storager.dao.PlatformGbStreamMapper;
13 12 import com.genersoft.iot.vmp.service.IGbStreamService;
14 13 import com.github.pagehelper.PageHelper;
... ... @@ -46,15 +45,15 @@ public class GbStreamServiceImpl implements IGbStreamService {
46 45 private ParentPlatformMapper platformMapper;
47 46  
48 47 @Autowired
49   - private SipConfig sipConfig;
  48 + private PlatformCatalogMapper catalogMapper;
50 49  
51 50 @Autowired
52 51 private EventPublisher eventPublisher;
53 52  
54 53 @Override
55   - public PageInfo<GbStream> getAll(Integer page, Integer count, String platFormId, String catalogId, String query, Boolean pushing, String mediaServerId) {
  54 + public PageInfo<GbStream> getAll(Integer page, Integer count, String platFormId, String catalogId, String query, String mediaServerId) {
56 55 PageHelper.startPage(page, count);
57   - List<GbStream> all = gbStreamMapper.selectAll(platFormId, catalogId, query, pushing, mediaServerId);
  56 + List<GbStream> all = gbStreamMapper.selectAll(platFormId, catalogId, query, mediaServerId);
58 57 return new PageInfo<>(all);
59 58 }
60 59  
... ... @@ -102,16 +101,25 @@ public class GbStreamServiceImpl implements IGbStreamService {
102 101 deviceChannel.setLatitude(gbStream.getLatitude());
103 102 deviceChannel.setDeviceId(platform.getDeviceGBId());
104 103 deviceChannel.setManufacture("wvp-pro");
105   -// deviceChannel.setStatus(gbStream.isStatus()?1:0);
106   - deviceChannel.setStatus(1);
107   - deviceChannel.setParentId(catalogId ==null?gbStream.getCatalogId():catalogId);
  104 + deviceChannel.setStatus(gbStream.isStatus()?1:0);
  105 +
108 106 deviceChannel.setRegisterWay(1);
109   - if (catalogId.length() > 0 && catalogId.length() <= 10) {
110   - // 父节点是行政区划,则设置CivilCode使用此行政区划
  107 + deviceChannel.setCivilCode(platform.getAdministrativeDivision());
  108 +
  109 + if (platform.getTreeType().equals(TreeType.CIVIL_CODE)){
111 110 deviceChannel.setCivilCode(catalogId);
112   - }else {
113   - deviceChannel.setCivilCode(platform.getAdministrativeDivision());
  111 + }else if (platform.getTreeType().equals(TreeType.BUSINESS_GROUP)){
  112 + PlatformCatalog catalog = catalogMapper.select(catalogId);
  113 + if (catalog == null) {
  114 + deviceChannel.setParentId(platform.getDeviceGBId());
  115 + deviceChannel.setBusinessGroupId(null);
  116 + }else {
  117 + deviceChannel.setParentId(catalog.getId());
  118 + deviceChannel.setBusinessGroupId(catalog.getBusinessGroupId());
  119 + }
  120 +
114 121 }
  122 +
115 123 deviceChannel.setModel("live");
116 124 deviceChannel.setOwner("wvp-pro");
117 125 deviceChannel.setParental(0);
... ... @@ -149,9 +157,9 @@ public class GbStreamServiceImpl implements IGbStreamService {
149 157 if (gbStream.getGbId() != null) {
150 158 gbStreams.add(gbStream);
151 159 }else {
152   - StreamProxyItem streamProxyItem = gbStreamMapper.selectOne(gbStream.getApp(), gbStream.getStream());
153   - if (streamProxyItem != null && streamProxyItem.getGbId() != null){
154   - gbStreams.add(streamProxyItem);
  160 + GbStream gbStreamIndb = gbStreamMapper.selectOne(gbStream.getApp(), gbStream.getStream());
  161 + if (gbStreamIndb != null && gbStreamIndb.getGbId() != null){
  162 + gbStreams.add(gbStreamIndb);
155 163 }
156 164 }
157 165 sendCatalogMsgs(gbStreams, type);
... ...
src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java
... ... @@ -7,12 +7,15 @@ import com.genersoft.iot.vmp.common.StreamInfo;
7 7 import com.genersoft.iot.vmp.conf.MediaConfig;
8 8 import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils;
9 9 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
  10 +import com.genersoft.iot.vmp.media.zlm.dto.OnPublishHookParam;
  11 +import com.genersoft.iot.vmp.media.zlm.dto.StreamAuthorityInfo;
10 12 import com.genersoft.iot.vmp.service.IMediaServerService;
11 13 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
12 14 import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
13 15 import com.genersoft.iot.vmp.service.IMediaService;
14 16 import org.springframework.beans.factory.annotation.Autowired;
15 17 import org.springframework.stereotype.Service;
  18 +import org.springframework.util.StringUtils;
16 19  
17 20 @Service
18 21 public class MediaServiceImpl implements IMediaService {
... ... @@ -36,20 +39,24 @@ public class MediaServiceImpl implements IMediaService {
36 39  
37 40  
38 41 @Override
39   - public StreamInfo getStreamInfoByAppAndStream(MediaServerItem mediaInfo, String app, String stream, Object tracks) {
40   - return getStreamInfoByAppAndStream(mediaInfo, app, stream, tracks, null);
  42 + public StreamInfo getStreamInfoByAppAndStream(MediaServerItem mediaInfo, String app, String stream, Object tracks, String callId) {
  43 + return getStreamInfoByAppAndStream(mediaInfo, app, stream, tracks, null, callId);
41 44 }
42 45  
43 46 @Override
44   - public StreamInfo getStreamInfoByAppAndStreamWithCheck(String app, String stream, String mediaServerId, String addr) {
  47 + public StreamInfo getStreamInfoByAppAndStreamWithCheck(String app, String stream, String mediaServerId, String addr, boolean authority) {
45 48 StreamInfo streamInfo = null;
46 49 if (mediaServerId == null) {
47 50 mediaServerId = mediaConfig.getId();
48 51 }
49   - MediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId);;
  52 + MediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId);
50 53 if (mediaInfo == null) {
51 54 return null;
52 55 }
  56 + StreamAuthorityInfo streamAuthorityInfo = redisCatchStorage.getStreamAuthorityInfo(app, stream);
  57 + if (streamAuthorityInfo == null) {
  58 + return null;
  59 + }
53 60 JSONObject mediaList = zlmresTfulUtils.getMediaList(mediaInfo, app, stream);
54 61 if (mediaList != null) {
55 62 if (mediaList.getInteger("code") == 0) {
... ... @@ -59,7 +66,12 @@ public class MediaServiceImpl implements IMediaService {
59 66 }
60 67 JSONObject mediaJSON = JSON.parseObject(JSON.toJSONString(data.get(0)), JSONObject.class);
61 68 JSONArray tracks = mediaJSON.getJSONArray("tracks");
62   - streamInfo = getStreamInfoByAppAndStream(mediaInfo, app, stream, tracks);
  69 + if (authority) {
  70 + streamInfo = getStreamInfoByAppAndStream(mediaInfo, app, stream, tracks, streamAuthorityInfo.getCallId());
  71 + }else {
  72 + streamInfo = getStreamInfoByAppAndStream(mediaInfo, app, stream, tracks, null);
  73 + }
  74 +
63 75 }
64 76 }
65 77 return streamInfo;
... ... @@ -68,46 +80,48 @@ public class MediaServiceImpl implements IMediaService {
68 80  
69 81  
70 82 @Override
71   - public StreamInfo getStreamInfoByAppAndStreamWithCheck(String app, String stream, String mediaServerId) {
72   - return getStreamInfoByAppAndStreamWithCheck(app, stream, mediaServerId, null);
  83 + public StreamInfo getStreamInfoByAppAndStreamWithCheck(String app, String stream, String mediaServerId, boolean authority) {
  84 + return getStreamInfoByAppAndStreamWithCheck(app, stream, mediaServerId, null, authority);
73 85 }
74 86  
75 87 @Override
76   - public StreamInfo getStreamInfoByAppAndStream(MediaServerItem mediaInfo, String app, String stream, Object tracks, String addr) {
  88 + public StreamInfo getStreamInfoByAppAndStream(MediaServerItem mediaInfo, String app, String stream, Object tracks, String addr, String callId) {
77 89 StreamInfo streamInfoResult = new StreamInfo();
78 90 streamInfoResult.setStream(stream);
79 91 streamInfoResult.setApp(app);
80 92 if (addr == null) {
81 93 addr = mediaInfo.getStreamIp();
82 94 }
  95 + streamInfoResult.setIp(addr);
83 96 streamInfoResult.setMediaServerId(mediaInfo.getId());
84   - streamInfoResult.setRtmp(String.format("rtmp://%s:%s/%s/%s", addr, mediaInfo.getRtmpPort(), app, stream));
  97 + String callIdParam = StringUtils.isEmpty(callId)?"":"?callId=" + callId;
  98 + streamInfoResult.setRtmp(String.format("rtmp://%s:%s/%s/%s%s", addr, mediaInfo.getRtmpPort(), app, stream, callIdParam));
85 99 if (mediaInfo.getRtmpSSlPort() != 0) {
86   - streamInfoResult.setRtmps(String.format("rtmps://%s:%s/%s/%s", addr, mediaInfo.getRtmpSSlPort(), app, stream));
  100 + streamInfoResult.setRtmps(String.format("rtmps://%s:%s/%s/%s%s", addr, mediaInfo.getRtmpSSlPort(), app, stream, callIdParam));
87 101 }
88   - streamInfoResult.setRtsp(String.format("rtsp://%s:%s/%s/%s", addr, mediaInfo.getRtspPort(), app, stream));
  102 + streamInfoResult.setRtsp(String.format("rtsp://%s:%s/%s/%s%s", addr, mediaInfo.getRtspPort(), app, stream, callIdParam));
89 103 if (mediaInfo.getRtspSSLPort() != 0) {
90   - streamInfoResult.setRtsps(String.format("rtsps://%s:%s/%s/%s", addr, mediaInfo.getRtspSSLPort(), app, stream));
  104 + streamInfoResult.setRtsps(String.format("rtsps://%s:%s/%s/%s%s", addr, mediaInfo.getRtspSSLPort(), app, stream, callIdParam));
91 105 }
92   - streamInfoResult.setFlv(String.format("http://%s:%s/%s/%s.live.flv", addr, mediaInfo.getHttpPort(), app, stream));
93   - streamInfoResult.setWs_flv(String.format("ws://%s:%s/%s/%s.live.flv", addr, mediaInfo.getHttpPort(), app, stream));
94   - streamInfoResult.setHls(String.format("http://%s:%s/%s/%s/hls.m3u8", addr, mediaInfo.getHttpPort(), app, stream));
95   - streamInfoResult.setWs_hls(String.format("ws://%s:%s/%s/%s/hls.m3u8", addr, mediaInfo.getHttpPort(), app, stream));
96   - streamInfoResult.setFmp4(String.format("http://%s:%s/%s/%s.live.mp4", addr, mediaInfo.getHttpPort(), app, stream));
97   - streamInfoResult.setWs_fmp4(String.format("ws://%s:%s/%s/%s.live.mp4", addr, mediaInfo.getHttpPort(), app, stream));
98   - streamInfoResult.setTs(String.format("http://%s:%s/%s/%s.live.ts", addr, mediaInfo.getHttpPort(), app, stream));
99   - streamInfoResult.setWs_ts(String.format("ws://%s:%s/%s/%s.live.ts", addr, mediaInfo.getHttpPort(), app, stream));
  106 + streamInfoResult.setFlv(String.format("http://%s:%s/%s/%s.live.flv%s", addr, mediaInfo.getHttpPort(), app, stream, callIdParam));
  107 + streamInfoResult.setWs_flv(String.format("ws://%s:%s/%s/%s.live.flv%s", addr, mediaInfo.getHttpPort(), app, stream, callIdParam));
  108 + streamInfoResult.setHls(String.format("http://%s:%s/%s/%s/hls.m3u8%s", addr, mediaInfo.getHttpPort(), app, stream, callIdParam));
  109 + streamInfoResult.setWs_hls(String.format("ws://%s:%s/%s/%s/hls.m3u8%s", addr, mediaInfo.getHttpPort(), app, stream, callIdParam));
  110 + streamInfoResult.setFmp4(String.format("http://%s:%s/%s/%s.live.mp4%s", addr, mediaInfo.getHttpPort(), app, stream, callIdParam));
  111 + streamInfoResult.setWs_fmp4(String.format("ws://%s:%s/%s/%s.live.mp4%s", addr, mediaInfo.getHttpPort(), app, stream, callIdParam));
  112 + streamInfoResult.setTs(String.format("http://%s:%s/%s/%s.live.ts%s", addr, mediaInfo.getHttpPort(), app, stream, callIdParam));
  113 + streamInfoResult.setWs_ts(String.format("ws://%s:%s/%s/%s.live.ts%s", addr, mediaInfo.getHttpPort(), app, stream, callIdParam));
100 114 if (mediaInfo.getHttpSSlPort() != 0) {
101   - streamInfoResult.setHttps_flv(String.format("https://%s:%s/%s/%s.live.flv", addr, mediaInfo.getHttpSSlPort(), app, stream));
102   - streamInfoResult.setWss_flv(String.format("wss://%s:%s/%s/%s.live.flv", addr, mediaInfo.getHttpSSlPort(), app, stream));
103   - streamInfoResult.setHttps_hls(String.format("https://%s:%s/%s/%s/hls.m3u8", addr, mediaInfo.getHttpSSlPort(), app, stream));
104   - streamInfoResult.setWss_hls(String.format("wss://%s:%s/%s/%s/hls.m3u8", addr, mediaInfo.getHttpSSlPort(), app, stream));
105   - streamInfoResult.setHttps_fmp4(String.format("https://%s:%s/%s/%s.live.mp4", addr, mediaInfo.getHttpSSlPort(), app, stream));
106   - streamInfoResult.setWss_fmp4(String.format("wss://%s:%s/%s/%s.live.mp4", addr, mediaInfo.getHttpSSlPort(), app, stream));
107   - streamInfoResult.setHttps_ts(String.format("https://%s:%s/%s/%s.live.ts", addr, mediaInfo.getHttpSSlPort(), app, stream));
108   - streamInfoResult.setWss_ts(String.format("wss://%s:%s/%s/%s.live.ts", addr, mediaInfo.getHttpSSlPort(), app, stream));
109   - streamInfoResult.setWss_ts(String.format("wss://%s:%s/%s/%s.live.ts", addr, mediaInfo.getHttpSSlPort(), app, stream));
110   - streamInfoResult.setRtc(String.format("https://%s:%s/index/api/webrtc?app=%s&stream=%s&type=play", mediaInfo.getStreamIp(), mediaInfo.getHttpSSlPort(), app, stream));
  115 + streamInfoResult.setHttps_flv(String.format("https://%s:%s/%s/%s.live.flv%s", addr, mediaInfo.getHttpSSlPort(), app, stream, callIdParam));
  116 + streamInfoResult.setWss_flv(String.format("wss://%s:%s/%s/%s.live.flv%s", addr, mediaInfo.getHttpSSlPort(), app, stream, callIdParam));
  117 + streamInfoResult.setHttps_hls(String.format("https://%s:%s/%s/%s/hls.m3u8%s", addr, mediaInfo.getHttpSSlPort(), app, stream, callIdParam));
  118 + streamInfoResult.setWss_hls(String.format("wss://%s:%s/%s/%s/hls.m3u8%s", addr, mediaInfo.getHttpSSlPort(), app, stream, callIdParam));
  119 + streamInfoResult.setHttps_fmp4(String.format("https://%s:%s/%s/%s.live.mp4%s", addr, mediaInfo.getHttpSSlPort(), app, stream, callIdParam));
  120 + streamInfoResult.setWss_fmp4(String.format("wss://%s:%s/%s/%s.live.mp4%s", addr, mediaInfo.getHttpSSlPort(), app, stream, callIdParam));
  121 + streamInfoResult.setHttps_ts(String.format("https://%s:%s/%s/%s.live.ts%s", addr, mediaInfo.getHttpSSlPort(), app, stream, callIdParam));
  122 + streamInfoResult.setWss_ts(String.format("wss://%s:%s/%s/%s.live.ts%s", addr, mediaInfo.getHttpSSlPort(), app, stream, callIdParam));
  123 + streamInfoResult.setWss_ts(String.format("wss://%s:%s/%s/%s.live.ts%s", addr, mediaInfo.getHttpSSlPort(), app, stream, callIdParam));
  124 + streamInfoResult.setRtc(String.format("https://%s:%s/index/api/webrtc?app=%s&stream=%s&type=play%s", mediaInfo.getStreamIp(), mediaInfo.getHttpSSlPort(), app, stream, StringUtils.isEmpty(callId)?"":"&callId=" + callId));
111 125 }
112 126  
113 127 streamInfoResult.setTracks(tracks);
... ...
src/main/java/com/genersoft/iot/vmp/service/impl/PlatformChannelServiceImpl.java 0 → 100644
  1 +package com.genersoft.iot.vmp.service.impl;
  2 +
  3 +import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
  4 +import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
  5 +import com.genersoft.iot.vmp.gb28181.bean.PlatformCatalog;
  6 +import com.genersoft.iot.vmp.gb28181.bean.TreeType;
  7 +import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
  8 +import com.genersoft.iot.vmp.gb28181.event.subscribe.catalog.CatalogEvent;
  9 +import com.genersoft.iot.vmp.service.IPlatformChannelService;
  10 +import com.genersoft.iot.vmp.storager.dao.DeviceChannelMapper;
  11 +import com.genersoft.iot.vmp.storager.dao.ParentPlatformMapper;
  12 +import com.genersoft.iot.vmp.storager.dao.PlatformCatalogMapper;
  13 +import com.genersoft.iot.vmp.storager.dao.PlatformChannelMapper;
  14 +import com.genersoft.iot.vmp.vmanager.gb28181.platform.bean.ChannelReduce;
  15 +import org.slf4j.Logger;
  16 +import org.slf4j.LoggerFactory;
  17 +import org.springframework.beans.factory.annotation.Autowired;
  18 +import org.springframework.stereotype.Service;
  19 +
  20 +import java.util.ArrayList;
  21 +import java.util.HashMap;
  22 +import java.util.List;
  23 +import java.util.Map;
  24 +
  25 +/**
  26 + * @author lin
  27 + */
  28 +@Service
  29 +public class PlatformChannelServiceImpl implements IPlatformChannelService {
  30 +
  31 + private final static Logger logger = LoggerFactory.getLogger(PlatformChannelServiceImpl.class);
  32 +
  33 + @Autowired
  34 + private PlatformChannelMapper platformChannelMapper;
  35 +
  36 + @Autowired
  37 + private DeviceChannelMapper deviceChannelMapper;
  38 +
  39 + @Autowired
  40 + private PlatformCatalogMapper catalogManager;
  41 +
  42 + @Autowired
  43 + private ParentPlatformMapper platformMapper;
  44 +
  45 + @Autowired
  46 + EventPublisher eventPublisher;
  47 +
  48 + @Override
  49 + public int updateChannelForGB(String platformId, List<ChannelReduce> channelReduces, String catalogId) {
  50 + ParentPlatform platform = platformMapper.getParentPlatByServerGBId(platformId);
  51 + if (platform == null) {
  52 + logger.warn("更新级联通道信息时未找到平台{}的信息", platformId);
  53 + return 0;
  54 + }
  55 + Map<Integer, ChannelReduce> deviceAndChannels = new HashMap<>();
  56 + for (ChannelReduce channelReduce : channelReduces) {
  57 + channelReduce.setCatalogId(catalogId);
  58 + deviceAndChannels.put(channelReduce.getId(), channelReduce);
  59 + }
  60 + List<Integer> deviceAndChannelList = new ArrayList<>(deviceAndChannels.keySet());
  61 + // 查询当前已经存在的
  62 + List<Integer> channelIds = platformChannelMapper.findChannelRelatedPlatform(platformId, channelReduces);
  63 + if (deviceAndChannelList != null) {
  64 + deviceAndChannelList.removeAll(channelIds);
  65 + }
  66 + for (Integer channelId : channelIds) {
  67 + deviceAndChannels.remove(channelId);
  68 + }
  69 + List<ChannelReduce> channelReducesToAdd = new ArrayList<>(deviceAndChannels.values());
  70 + // 对剩下的数据进行存储
  71 + int result = 0;
  72 + if (channelReducesToAdd.size() > 0) {
  73 + result = platformChannelMapper.addChannels(platformId, channelReducesToAdd);
  74 + // TODO 后续给平台增加控制开关以控制是否响应目录订阅
  75 + List<DeviceChannel> deviceChannelList = getDeviceChannelListByChannelReduceList(channelReducesToAdd, catalogId, platform);
  76 + eventPublisher.catalogEventPublish(platformId, deviceChannelList, CatalogEvent.ADD);
  77 + }
  78 +
  79 + return result;
  80 + }
  81 +
  82 + private List<DeviceChannel> getDeviceChannelListByChannelReduceList(List<ChannelReduce> channelReduces, String catalogId, ParentPlatform platform) {
  83 + List<DeviceChannel> deviceChannelList = new ArrayList<>();
  84 + if (channelReduces.size() > 0){
  85 + PlatformCatalog catalog = catalogManager.select(catalogId);
  86 + if (catalog == null && !catalogId.equals(platform.getServerGBId())) {
  87 + logger.warn("未查询到目录{}的信息", catalogId);
  88 + return null;
  89 + }
  90 + for (ChannelReduce channelReduce : channelReduces) {
  91 + DeviceChannel deviceChannel = deviceChannelMapper.queryChannel(channelReduce.getDeviceId(), channelReduce.getChannelId());
  92 + deviceChannel.setParental(0);
  93 + deviceChannelList.add(deviceChannel);
  94 + if (platform.getTreeType().equals(TreeType.CIVIL_CODE)){
  95 + deviceChannel.setCivilCode(catalogId);
  96 + }else if (platform.getTreeType().equals(TreeType.BUSINESS_GROUP)){
  97 + deviceChannel.setParentId(catalogId);
  98 + if (catalog != null) {
  99 + deviceChannel.setBusinessGroupId(catalog.getBusinessGroupId());
  100 + }
  101 + }
  102 + }
  103 + }
  104 + return deviceChannelList;
  105 + }
  106 +}
... ...
src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java
... ... @@ -620,7 +620,7 @@ public class PlayServiceImpl implements IPlayService {
620 620 public StreamInfo onPublishHandler(MediaServerItem mediaServerItem, JSONObject resonse, String deviceId, String channelId) {
621 621 String streamId = resonse.getString("stream");
622 622 JSONArray tracks = resonse.getJSONArray("tracks");
623   - StreamInfo streamInfo = mediaService.getStreamInfoByAppAndStream(mediaServerItem,"rtp", streamId, tracks);
  623 + StreamInfo streamInfo = mediaService.getStreamInfoByAppAndStream(mediaServerItem,"rtp", streamId, tracks, null);
624 624 streamInfo.setDeviceID(deviceId);
625 625 streamInfo.setChannelId(channelId);
626 626 return streamInfo;
... ...
src/main/java/com/genersoft/iot/vmp/service/impl/RedisGpsMsgListener.java
... ... @@ -25,9 +25,7 @@ public class RedisGpsMsgListener implements MessageListener {
25 25  
26 26 @Override
27 27 public void onMessage(@NotNull Message message, byte[] bytes) {
28   - if (logger.isDebugEnabled()) {
29   - logger.debug("收到来自REDIS的GPS通知: {}", new String(message.getBody()));
30   - }
  28 + // TODO 加消息队列
31 29 GPSMsgInfo gpsMsgInfo = JSON.parseObject(message.getBody(), GPSMsgInfo.class);
32 30 redisCatchStorage.updateGpsMsgInfo(gpsMsgInfo);
33 31 }
... ...
src/main/java/com/genersoft/iot/vmp/service/impl/RedisPushStreamStatusMsgListener.java 0 → 100644
  1 +package com.genersoft.iot.vmp.service.impl;
  2 +
  3 +import com.alibaba.fastjson.JSON;
  4 +import com.alibaba.fastjson.JSONObject;
  5 +import com.genersoft.iot.vmp.common.VideoManagerConstants;
  6 +import com.genersoft.iot.vmp.conf.DynamicTask;
  7 +import com.genersoft.iot.vmp.conf.UserSetting;
  8 +import com.genersoft.iot.vmp.gb28181.bean.GbStream;
  9 +import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
  10 +import com.genersoft.iot.vmp.gb28181.event.subscribe.catalog.CatalogEvent;
  11 +import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander;
  12 +import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform;
  13 +import com.genersoft.iot.vmp.media.zlm.ZLMMediaListManager;
  14 +import com.genersoft.iot.vmp.media.zlm.dto.MediaItem;
  15 +import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem;
  16 +import com.genersoft.iot.vmp.service.IStreamPushService;
  17 +import com.genersoft.iot.vmp.service.bean.PushStreamStatusChangeFromRedisDto;
  18 +import com.genersoft.iot.vmp.service.bean.StreamPushItemFromRedis;
  19 +import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
  20 +import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
  21 +import org.slf4j.Logger;
  22 +import org.slf4j.LoggerFactory;
  23 +import org.springframework.beans.factory.annotation.Autowired;
  24 +import org.springframework.boot.ApplicationArguments;
  25 +import org.springframework.boot.ApplicationRunner;
  26 +import org.springframework.data.redis.connection.Message;
  27 +import org.springframework.data.redis.connection.MessageListener;
  28 +import org.springframework.stereotype.Component;
  29 +
  30 +import java.util.ArrayList;
  31 +import java.util.List;
  32 +
  33 +
  34 +/**
  35 + * 接收redis发送的推流设备上线下线通知
  36 + * @author lin
  37 + */
  38 +@Component
  39 +public class RedisPushStreamStatusMsgListener implements MessageListener, ApplicationRunner {
  40 +
  41 + private final static Logger logger = LoggerFactory.getLogger(RedisPushStreamStatusMsgListener.class);
  42 +
  43 + @Autowired
  44 + private IRedisCatchStorage redisCatchStorage;
  45 +
  46 + @Autowired
  47 + private IStreamPushService streamPushService;
  48 +
  49 + @Autowired
  50 + private EventPublisher eventPublisher;
  51 +
  52 + @Autowired
  53 + private UserSetting userSetting;
  54 +
  55 + @Autowired
  56 + private DynamicTask dynamicTask;
  57 +
  58 + @Override
  59 + public void onMessage(Message message, byte[] bytes) {
  60 + PushStreamStatusChangeFromRedisDto statusChangeFromPushStream = JSON.parseObject(message.getBody(), PushStreamStatusChangeFromRedisDto.class);
  61 + if (statusChangeFromPushStream == null) {
  62 + logger.warn("[REDIS 消息]推流设备状态变化消息解析失败");
  63 + return;
  64 + }
  65 + if (statusChangeFromPushStream.isSetAllOffline()) {
  66 + // 所有设备离线
  67 + streamPushService.allStreamOffline();
  68 + }
  69 + if (statusChangeFromPushStream.getOfflineStreams() != null
  70 + && statusChangeFromPushStream.getOfflineStreams().size() > 0) {
  71 + // 更新部分设备离线
  72 + streamPushService.offline(statusChangeFromPushStream.getOfflineStreams());
  73 + }
  74 + if (statusChangeFromPushStream.getOnlineStreams() != null &&
  75 + statusChangeFromPushStream.getOnlineStreams().size() > 0) {
  76 + // 更新部分设备上线
  77 + streamPushService.online(statusChangeFromPushStream.getOnlineStreams());
  78 + }
  79 + }
  80 +
  81 + @Override
  82 + public void run(ApplicationArguments args) throws Exception {
  83 + // 启动时设置所有推流通道离线,发起查询请求
  84 + redisCatchStorage.sendStreamPushRequestedMsgForStatus();
  85 + dynamicTask.startDelay(VideoManagerConstants.VM_MSG_GET_ALL_ONLINE_REQUESTED, ()->{
  86 + logger.info("[REDIS 消息]未收到redis回复推流设备状态,执行推流设备离线");
  87 + // 五秒收不到请求就设置通道离线,然后通知上级离线
  88 + streamPushService.allStreamOffline();
  89 + }, 5000);
  90 + }
  91 +
  92 +}
... ...
src/main/java/com/genersoft/iot/vmp/service/impl/RedisStreamMsgListener.java
... ... @@ -3,16 +3,12 @@ package com.genersoft.iot.vmp.service.impl;
3 3 import com.alibaba.fastjson.JSON;
4 4 import com.alibaba.fastjson.JSONObject;
5 5 import com.genersoft.iot.vmp.conf.UserSetting;
6   -import com.genersoft.iot.vmp.gb28181.bean.AlarmChannelMessage;
7   -import com.genersoft.iot.vmp.gb28181.bean.Device;
8   -import com.genersoft.iot.vmp.gb28181.bean.DeviceAlarm;
9   -import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
  6 +
10 7 import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander;
11 8 import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform;
12 9 import com.genersoft.iot.vmp.media.zlm.ZLMMediaListManager;
13 10 import com.genersoft.iot.vmp.media.zlm.dto.MediaItem;
14 11 import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
15   -import com.genersoft.iot.vmp.utils.DateUtil;
16 12 import org.slf4j.Logger;
17 13 import org.slf4j.LoggerFactory;
18 14 import org.springframework.beans.factory.annotation.Autowired;
... ... @@ -22,6 +18,7 @@ import org.springframework.stereotype.Component;
22 18  
23 19  
24 20 /**
  21 + * 接收其他wvp发送流变化通知
25 22 * @author lin
26 23 */
27 24 @Component
... ...
src/main/java/com/genersoft/iot/vmp/service/impl/StreamProxyServiceImpl.java
... ... @@ -3,10 +3,10 @@ package com.genersoft.iot.vmp.service.impl;
3 3 import com.alibaba.fastjson.JSONArray;
4 4 import com.alibaba.fastjson.JSONObject;
5 5 import com.genersoft.iot.vmp.common.StreamInfo;
6   -import com.genersoft.iot.vmp.conf.SipConfig;
7 6 import com.genersoft.iot.vmp.conf.UserSetting;
8 7 import com.genersoft.iot.vmp.gb28181.bean.GbStream;
9 8 import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
  9 +import com.genersoft.iot.vmp.gb28181.bean.TreeType;
10 10 import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
11 11 import com.genersoft.iot.vmp.gb28181.event.subscribe.catalog.CatalogEvent;
12 12 import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils;
... ... @@ -23,14 +23,19 @@ import com.genersoft.iot.vmp.storager.dao.ParentPlatformMapper;
23 23 import com.genersoft.iot.vmp.storager.dao.PlatformGbStreamMapper;
24 24 import com.genersoft.iot.vmp.storager.dao.StreamProxyMapper;
25 25 import com.genersoft.iot.vmp.service.IStreamProxyService;
  26 +import com.genersoft.iot.vmp.utils.DateUtil;
26 27 import com.genersoft.iot.vmp.vmanager.bean.WVPResult;
27 28 import com.github.pagehelper.PageInfo;
28 29 import org.slf4j.Logger;
29 30 import org.slf4j.LoggerFactory;
30 31 import org.springframework.beans.factory.annotation.Autowired;
  32 +import org.springframework.jdbc.datasource.DataSourceTransactionManager;
31 33 import org.springframework.stereotype.Service;
  34 +import org.springframework.transaction.TransactionDefinition;
  35 +import org.springframework.transaction.TransactionStatus;
32 36 import org.springframework.util.StringUtils;
33 37  
  38 +import java.net.InetAddress;
34 39 import java.util.*;
35 40  
36 41 /**
... ... @@ -48,7 +53,7 @@ public class StreamProxyServiceImpl implements IStreamProxyService {
48 53 private IMediaService mediaService;
49 54  
50 55 @Autowired
51   - private ZLMRESTfulUtils zlmresTfulUtils;;
  56 + private ZLMRESTfulUtils zlmresTfulUtils;
52 57  
53 58 @Autowired
54 59 private StreamProxyMapper streamProxyMapper;
... ... @@ -63,9 +68,6 @@ public class StreamProxyServiceImpl implements IStreamProxyService {
63 68 private UserSetting userSetting;
64 69  
65 70 @Autowired
66   - private SipConfig sipConfig;
67   -
68   - @Autowired
69 71 private GbStreamMapper gbStreamMapper;
70 72  
71 73 @Autowired
... ... @@ -83,6 +85,12 @@ public class StreamProxyServiceImpl implements IStreamProxyService {
83 85 @Autowired
84 86 private IMediaServerService mediaServerService;
85 87  
  88 + @Autowired
  89 + DataSourceTransactionManager dataSourceTransactionManager;
  90 +
  91 + @Autowired
  92 + TransactionDefinition transactionDefinition;
  93 +
86 94  
87 95 @Override
88 96 public WVPResult<StreamInfo> save(StreamProxyItem param) {
... ... @@ -99,6 +107,7 @@ public class StreamProxyServiceImpl implements IStreamProxyService {
99 107 wvpResult.setMsg("保存失败");
100 108 return wvpResult;
101 109 }
  110 +
102 111 String dstUrl = String.format("rtmp://%s:%s/%s/%s", "127.0.0.1", mediaInfo.getRtmpPort(), param.getApp(),
103 112 param.getStream() );
104 113 param.setDst_url(dstUrl);
... ... @@ -108,9 +117,9 @@ public class StreamProxyServiceImpl implements IStreamProxyService {
108 117 boolean saveResult;
109 118 // 更新
110 119 if (videoManagerStorager.queryStreamProxy(param.getApp(), param.getStream()) != null) {
111   - saveResult = videoManagerStorager.updateStreamProxy(param);
  120 + saveResult = updateStreamProxy(param);
112 121 }else { // 新增
113   - saveResult = videoManagerStorager.addStreamProxy(param);
  122 + saveResult = addStreamProxy(param);
114 123 }
115 124 if (saveResult) {
116 125 result.append("保存成功");
... ... @@ -124,7 +133,7 @@ public class StreamProxyServiceImpl implements IStreamProxyService {
124 133 if (param.isEnable_remove_none_reader()) {
125 134 del(param.getApp(), param.getStream());
126 135 }else {
127   - videoManagerStorager.updateStreamProxy(param);
  136 + updateStreamProxy(param);
128 137 }
129 138  
130 139 }else {
... ... @@ -147,25 +156,79 @@ public class StreamProxyServiceImpl implements IStreamProxyService {
147 156 result.append(", 关联国标平台[ " + param.getPlatformGbId() + " ]失败");
148 157 }
149 158 }
150   - if (!StringUtils.isEmpty(param.getGbId())) {
151   - // 查找开启了全部直播流共享的上级平台
152   - List<ParentPlatform> parentPlatforms = parentPlatformMapper.selectAllAhareAllLiveStream();
153   - if (parentPlatforms.size() > 0) {
154   - for (ParentPlatform parentPlatform : parentPlatforms) {
155   - param.setPlatformId(parentPlatform.getServerGBId());
156   - param.setCatalogId(parentPlatform.getCatalogId());
157   - String stream = param.getStream();
158   - StreamProxyItem streamProxyItems = platformGbStreamMapper.selectOne(param.getApp(), stream, parentPlatform.getServerGBId());
159   - if (streamProxyItems == null) {
160   - platformGbStreamMapper.add(param);
161   - eventPublisher.catalogEventPublishForStream(parentPlatform.getServerGBId(), param, CatalogEvent.ADD);
  159 + wvpResult.setMsg(result.toString());
  160 + return wvpResult;
  161 + }
  162 +
  163 + /**
  164 + * 新增代理流
  165 + * @param streamProxyItem
  166 + * @return
  167 + */
  168 + private boolean addStreamProxy(StreamProxyItem streamProxyItem) {
  169 + TransactionStatus transactionStatus = dataSourceTransactionManager.getTransaction(transactionDefinition);
  170 + boolean result = false;
  171 + streamProxyItem.setStreamType("proxy");
  172 + streamProxyItem.setStatus(true);
  173 + String now = DateUtil.getNow();
  174 + streamProxyItem.setCreateTime(now);
  175 + try {
  176 + if (streamProxyMapper.add(streamProxyItem) > 0) {
  177 + if (!StringUtils.isEmpty(streamProxyItem.getGbId())) {
  178 + if (gbStreamMapper.add(streamProxyItem) < 0) {
  179 + //事务回滚
  180 + dataSourceTransactionManager.rollback(transactionStatus);
  181 + return false;
162 182 }
163 183 }
  184 + }else {
  185 + //事务回滚
  186 + dataSourceTransactionManager.rollback(transactionStatus);
  187 + return false;
164 188 }
  189 + result = true;
  190 + dataSourceTransactionManager.commit(transactionStatus); //手动提交
  191 + }catch (Exception e) {
  192 + logger.error("向数据库添加流代理失败:", e);
  193 + dataSourceTransactionManager.rollback(transactionStatus);
165 194 }
166 195  
167   - wvpResult.setMsg(result.toString());
168   - return wvpResult;
  196 +
  197 + return result;
  198 + }
  199 +
  200 + /**
  201 + * 更新代理流
  202 + * @param streamProxyItem
  203 + * @return
  204 + */
  205 + @Override
  206 + public boolean updateStreamProxy(StreamProxyItem streamProxyItem) {
  207 + TransactionStatus transactionStatus = dataSourceTransactionManager.getTransaction(transactionDefinition);
  208 + boolean result = false;
  209 + streamProxyItem.setStreamType("proxy");
  210 + try {
  211 + if (streamProxyMapper.update(streamProxyItem) > 0) {
  212 + if (!StringUtils.isEmpty(streamProxyItem.getGbId())) {
  213 + if (gbStreamMapper.updateByAppAndStream(streamProxyItem) == 0) {
  214 + //事务回滚
  215 + dataSourceTransactionManager.rollback(transactionStatus);
  216 + return false;
  217 + }
  218 + }
  219 + } else {
  220 + //事务回滚
  221 + dataSourceTransactionManager.rollback(transactionStatus);
  222 + return false;
  223 + }
  224 +
  225 + dataSourceTransactionManager.commit(transactionStatus); //手动提交
  226 + result = true;
  227 + }catch (Exception e) {
  228 + e.printStackTrace();
  229 + dataSourceTransactionManager.rollback(transactionStatus);
  230 + }
  231 + return result;
169 232 }
170 233  
171 234 @Override
... ... @@ -239,7 +302,7 @@ public class StreamProxyServiceImpl implements IStreamProxyService {
239 302 if (jsonObject.getInteger("code") == 0) {
240 303 result = true;
241 304 streamProxy.setEnable(true);
242   - videoManagerStorager.updateStreamProxy(streamProxy);
  305 + updateStreamProxy(streamProxy);
243 306 }
244 307 }
245 308 return result;
... ... @@ -253,7 +316,7 @@ public class StreamProxyServiceImpl implements IStreamProxyService {
253 316 JSONObject jsonObject = removeStreamProxyFromZlm(streamProxyDto);
254 317 if (jsonObject != null && jsonObject.getInteger("code") == 0) {
255 318 streamProxyDto.setEnable(false);
256   - result = videoManagerStorager.updateStreamProxy(streamProxyDto);
  319 + result = updateStreamProxy(streamProxyDto);
257 320 }
258 321 }
259 322 return result;
... ... @@ -319,7 +382,7 @@ public class StreamProxyServiceImpl implements IStreamProxyService {
319 382 }
320 383 streamProxyMapper.deleteAutoRemoveItemByMediaServerId(mediaServerId);
321 384 // 其他的流设置离线
322   - streamProxyMapper.updateStatusByMediaServerId(false, mediaServerId);
  385 + streamProxyMapper.updateStatusByMediaServerId(mediaServerId, false);
323 386 String type = "PULL";
324 387  
325 388 // 发送redis消息
... ... @@ -346,7 +409,7 @@ public class StreamProxyServiceImpl implements IStreamProxyService {
346 409  
347 410 @Override
348 411 public int updateStatus(boolean status, String app, String stream) {
349   - return streamProxyMapper.updateStatus(status, app, stream);
  412 + return streamProxyMapper.updateStatus(app, stream, status);
350 413 }
351 414  
352 415 private void syncPullStream(String mediaServerId){
... ...
src/main/java/com/genersoft/iot/vmp/service/impl/StreamPushServiceImpl.java
... ... @@ -13,6 +13,7 @@ import com.genersoft.iot.vmp.media.zlm.dto.*;
13 13 import com.genersoft.iot.vmp.service.IGbStreamService;
14 14 import com.genersoft.iot.vmp.service.IMediaServerService;
15 15 import com.genersoft.iot.vmp.service.IStreamPushService;
  16 +import com.genersoft.iot.vmp.service.bean.StreamPushItemFromRedis;
16 17 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
17 18 import com.genersoft.iot.vmp.storager.dao.*;
18 19 import com.genersoft.iot.vmp.utils.DateUtil;
... ... @@ -39,6 +40,9 @@ public class StreamPushServiceImpl implements IStreamPushService {
39 40 private StreamPushMapper streamPushMapper;
40 41  
41 42 @Autowired
  43 + private StreamProxyMapper streamProxyMapper;
  44 +
  45 + @Autowired
42 46 private ParentPlatformMapper parentPlatformMapper;
43 47  
44 48 @Autowired
... ... @@ -130,29 +134,6 @@ public class StreamPushServiceImpl implements IStreamPushService {
130 134 stream.setStatus(true);
131 135 stream.setCreateTime(DateUtil.getNow());
132 136 int add = gbStreamMapper.add(stream);
133   -
134   - // 查找开启了全部直播流共享的上级平台
135   - List<ParentPlatform> parentPlatforms = parentPlatformMapper.selectAllAhareAllLiveStream();
136   - if (parentPlatforms.size() > 0) {
137   - for (ParentPlatform parentPlatform : parentPlatforms) {
138   - stream.setCatalogId(parentPlatform.getCatalogId());
139   - stream.setPlatformId(parentPlatform.getServerGBId());
140   - String streamId = stream.getStream();
141   - StreamProxyItem streamProxyItem = platformGbStreamMapper.selectOne(stream.getApp(), streamId, parentPlatform.getServerGBId());
142   - if (streamProxyItem == null) {
143   - platformGbStreamMapper.add(stream);
144   - eventPublisher.catalogEventPublishForStream(parentPlatform.getServerGBId(), stream, CatalogEvent.ADD);
145   - }else {
146   - if (!streamProxyItem.getGbId().equals(stream.getGbId())) {
147   - // 此流使用另一个国标Id已经与该平台关联,移除此记录
148   - platformGbStreamMapper.delByAppAndStreamAndPlatform(stream.getApp(), streamId, parentPlatform.getServerGBId());
149   - platformGbStreamMapper.add(stream);
150   - eventPublisher.catalogEventPublishForStream(parentPlatform.getServerGBId(), stream, CatalogEvent.ADD);
151   - }
152   - }
153   - }
154   - }
155   -
156 137 return add > 0;
157 138 }
158 139  
... ... @@ -178,7 +159,6 @@ public class StreamPushServiceImpl implements IStreamPushService {
178 159  
179 160 @Override
180 161 public StreamPushItem getPush(String app, String streamId) {
181   -
182 162 return streamPushMapper.selectOne(app, streamId);
183 163 }
184 164  
... ... @@ -285,7 +265,8 @@ public class StreamPushServiceImpl implements IStreamPushService {
285 265 streamPushMapper.deleteWithoutGBId(mediaServerId);
286 266 gbStreamMapper.deleteWithoutGBId("push", mediaServerId);
287 267 // 其他的流设置未启用
288   - gbStreamMapper.updateStatusByMediaServerId(mediaServerId, false);
  268 + streamPushMapper.updateStatusByMediaServerId(mediaServerId, false);
  269 + streamProxyMapper.updateStatusByMediaServerId(mediaServerId, false);
289 270 // 发送流停止消息
290 271 String type = "PUSH";
291 272 // 发送redis消息
... ... @@ -341,31 +322,6 @@ public class StreamPushServiceImpl implements IStreamPushService {
341 322 public void batchAdd(List<StreamPushItem> streamPushItems) {
342 323 streamPushMapper.addAll(streamPushItems);
343 324 gbStreamMapper.batchAdd(streamPushItems);
344   - // 查找开启了全部直播流共享的上级平台
345   - List<ParentPlatform> parentPlatforms = parentPlatformMapper.selectAllAhareAllLiveStream();
346   - if (parentPlatforms.size() > 0) {
347   - for (StreamPushItem stream : streamPushItems) {
348   - for (ParentPlatform parentPlatform : parentPlatforms) {
349   - stream.setCatalogId(parentPlatform.getCatalogId());
350   - stream.setPlatformId(parentPlatform.getServerGBId());
351   - String streamId = stream.getStream();
352   - StreamProxyItem streamProxyItem = platformGbStreamMapper.selectOne(stream.getApp(), streamId, parentPlatform.getServerGBId());
353   - if (streamProxyItem == null) {
354   - platformGbStreamMapper.add(stream);
355   - eventPublisher.catalogEventPublishForStream(parentPlatform.getServerGBId(), stream, CatalogEvent.ADD);
356   - }else {
357   - if (!streamProxyItem.getGbId().equals(stream.getGbId())) {
358   - // 此流使用另一个国标Id已经与该平台关联,移除此记录
359   - platformGbStreamMapper.delByAppAndStreamAndPlatform(stream.getApp(), streamId, parentPlatform.getServerGBId());
360   - platformGbStreamMapper.add(stream);
361   - eventPublisher.catalogEventPublishForStream(parentPlatform.getServerGBId(), stream, CatalogEvent.ADD);
362   - stream.setGbId(streamProxyItem.getGbId());
363   - eventPublisher.catalogEventPublishForStream(parentPlatform.getServerGBId(), stream, CatalogEvent.DEL);
364   - }
365   - }
366   - }
367   - }
368   - }
369 325 }
370 326  
371 327 @Override
... ... @@ -477,4 +433,34 @@ public class StreamPushServiceImpl implements IStreamPushService {
477 433 }
478 434 return true;
479 435 }
  436 +
  437 + @Override
  438 + public void allStreamOffline() {
  439 + List<GbStream> onlinePushers = streamPushMapper.getOnlinePusherForGb();
  440 + if (onlinePushers.size() == 0) {
  441 + return;
  442 + }
  443 + streamPushMapper.setAllStreamOffline();
  444 +
  445 + // 发送通知
  446 + eventPublisher.catalogEventPublishForStream(null, onlinePushers, CatalogEvent.OFF);
  447 + }
  448 +
  449 + @Override
  450 + public void offline(List<StreamPushItemFromRedis> offlineStreams) {
  451 + // 更新部分设备离线
  452 + List<GbStream> onlinePushers = streamPushMapper.getOnlinePusherForGbInList(offlineStreams);
  453 + streamPushMapper.offline(offlineStreams);
  454 + // 发送通知
  455 + eventPublisher.catalogEventPublishForStream(null, onlinePushers, CatalogEvent.OFF);
  456 + }
  457 +
  458 + @Override
  459 + public void online(List<StreamPushItemFromRedis> onlineStreams) {
  460 + // 更新部分设备上线streamPushService
  461 + List<GbStream> onlinePushers = streamPushMapper.getOfflinePusherForGbInList(onlineStreams);
  462 + streamPushMapper.online(onlineStreams);
  463 + // 发送通知
  464 + eventPublisher.catalogEventPublishForStream(null, onlinePushers, CatalogEvent.ON);
  465 + }
480 466 }
... ...
src/main/java/com/genersoft/iot/vmp/service/impl/StreamPushUploadFileHandler.java
... ... @@ -14,38 +14,60 @@ import java.util.*;
14 14  
15 15 public class StreamPushUploadFileHandler extends AnalysisEventListener<StreamPushExcelDto> {
16 16  
17   - // 错误数据的回调,用于将错误数据发送给页面
  17 + /**
  18 + * 错误数据的回调,用于将错误数据发送给页面
  19 + */
18 20 private ErrorDataHandler errorDataHandler;
19 21  
20   - // 推流的业务类用于存储数据
  22 + /**
  23 + * 推流的业务类用于存储数据
  24 + */
21 25 private IStreamPushService pushService;
22 26  
23   - // 默认流媒体节点ID
  27 + /**
  28 + * 默认流媒体节点ID
  29 + */
24 30 private String defaultMediaServerId;
25 31  
26   - // 用于存储不加过滤的所有数据
  32 + /**
  33 + * 用于存储不加过滤的所有数据
  34 + */
27 35 private List<StreamPushItem> streamPushItems = new ArrayList<>();
28 36  
29   - // 用于存储更具APP+Stream过滤后的数据,可以直接存入stream_push表与gb_stream表
  37 + /**
  38 + * 用于存储更具APP+Stream过滤后的数据,可以直接存入stream_push表与gb_stream表
  39 + */
30 40 private Map<String,StreamPushItem> streamPushItemForSave = new HashMap<>();
31 41  
32   - // 用于存储按照APP+Stream为KEY, 平台ID+目录Id 为value的数据,用于存储到gb_stream表后获取app+Stream对应的平台与目录信息,然后存入关联表
  42 + /**
  43 + * 用于存储按照APP+Stream为KEY, 平台ID+目录Id 为value的数据,用于存储到gb_stream表后获取app+Stream对应的平台与目录信息,然后存入关联表
  44 + */
33 45 private Map<String, List<String[]>> streamPushItemsForPlatform = new HashMap<>();
34 46  
35   - // 用于判断文件是否存在重复的app+Stream+平台ID
  47 + /**
  48 + * 用于判断文件是否存在重复的app+Stream+平台ID
  49 + */
36 50 private Set<String> streamPushStreamSet = new HashSet<>();
37 51  
38   - // 用于存储APP+Stream->国标ID 的数据结构, 数据一一对应,全局判断APP+Stream->国标ID是否存在不对应
  52 + /**
  53 + * 用于存储APP+Stream->国标ID 的数据结构, 数据一一对应,全局判断APP+Stream->国标ID是否存在不对应
  54 + */
39 55 private BiMap<String,String> gBMap = HashBiMap.create();
40 56  
41   - // 记录错误的APP+Stream
  57 + /**
  58 + * 记录错误的APP+Stream
  59 + */
42 60 private List<String> errorStreamList = new ArrayList<>();
43 61  
44 62  
45   - // 记录错误的国标ID
  63 + /**
  64 + * 记录错误的国标ID
  65 + */
46 66 private List<String> errorGBList = new ArrayList<>();
47 67  
48   - // 读取数量计数器
  68 + /**
  69 + * 读取数量计数器
  70 + */
49 71 private int loadedSize = 0;
50 72  
51 73 public StreamPushUploadFileHandler(IStreamPushService pushService, String defaultMediaServerId, ErrorDataHandler errorDataHandler) {
... ...
src/main/java/com/genersoft/iot/vmp/service/impl/UserServiceImpl.java
... ... @@ -3,14 +3,17 @@ package com.genersoft.iot.vmp.service.impl;
3 3 import com.genersoft.iot.vmp.service.IUserService;
4 4 import com.genersoft.iot.vmp.storager.dao.UserMapper;
5 5 import com.genersoft.iot.vmp.storager.dao.dto.User;
  6 +import com.github.pagehelper.PageHelper;
  7 +import com.github.pagehelper.PageInfo;
6 8 import org.springframework.beans.factory.annotation.Autowired;
7 9 import org.springframework.stereotype.Service;
  10 +import org.springframework.util.StringUtils;
8 11  
9 12 import java.util.List;
10 13  
11 14 @Service
12 15 public class UserServiceImpl implements IUserService {
13   -
  16 +
14 17 @Autowired
15 18 private UserMapper userMapper;
16 19  
... ... @@ -55,4 +58,24 @@ public class UserServiceImpl implements IUserService {
55 58 }
56 59  
57 60  
  61 + @Override
  62 + public boolean checkPushAuthority(String callId, String sign) {
  63 + if (StringUtils.isEmpty(callId)) {
  64 + return userMapper.checkPushAuthorityByCallId(sign).size() > 0;
  65 + }else {
  66 + return userMapper.checkPushAuthorityByCallIdAndSign(callId, sign).size() > 0;
  67 + }
  68 + }
  69 +
  70 + @Override
  71 + public PageInfo<User> getUsers(int page, int count) {
  72 + PageHelper.startPage(page, count);
  73 + List<User> users = userMapper.getUsers();
  74 + return new PageInfo<>(users);
  75 + }
  76 +
  77 + @Override
  78 + public int changePushKey(int id, String pushKey) {
  79 + return userMapper.changePushKey(id,pushKey);
  80 + }
58 81 }
... ...
src/main/java/com/genersoft/iot/vmp/storager/IRedisCatchStorage.java
... ... @@ -3,9 +3,7 @@ package com.genersoft.iot.vmp.storager;
3 3 import com.alibaba.fastjson.JSONObject;
4 4 import com.genersoft.iot.vmp.common.StreamInfo;
5 5 import com.genersoft.iot.vmp.gb28181.bean.*;
6   -import com.genersoft.iot.vmp.media.zlm.dto.MediaItem;
7   -import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
8   -import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem;
  6 +import com.genersoft.iot.vmp.media.zlm.dto.*;
9 7 import com.genersoft.iot.vmp.service.bean.GPSMsgInfo;
10 8 import com.genersoft.iot.vmp.service.bean.MessageForPushChannel;
11 9 import com.genersoft.iot.vmp.service.bean.SSRCInfo;
... ... @@ -213,4 +211,31 @@ public interface IRedisCatchStorage {
213 211 */
214 212 public boolean deviceIsOnline(String deviceId);
215 213  
  214 + /**
  215 + * 存储推流的鉴权信息
  216 + * @param app 应用名
  217 + * @param stream 流
  218 + * @param streamAuthorityInfo 鉴权信息
  219 + */
  220 + void updateStreamAuthorityInfo(String app, String stream, StreamAuthorityInfo streamAuthorityInfo);
  221 +
  222 + /**
  223 + * 移除推流的鉴权信息
  224 + * @param app 应用名
  225 + * @param streamId 流
  226 + */
  227 + void removeStreamAuthorityInfo(String app, String streamId);
  228 +
  229 + /**
  230 + * 获取推流的鉴权信息
  231 + * @param app 应用名
  232 + * @param stream 流
  233 + * @return
  234 + */
  235 + StreamAuthorityInfo getStreamAuthorityInfo(String app, String stream);
  236 +
  237 + /**
  238 + * 发送redis消息 查询所有推流设备的状态
  239 + */
  240 + void sendStreamPushRequestedMsgForStatus();
216 241 }
... ...
src/main/java/com/genersoft/iot/vmp/storager/IVideoManagerStorage.java
... ... @@ -27,22 +27,6 @@ public interface IVideoManagerStorage {
27 27 public boolean exists(String deviceId);
28 28  
29 29 /**
30   - * 添加设备通道
31   - *
32   - * @param deviceId 设备id
33   - * @param channel 通道
34   - */
35   - public void updateChannel(String deviceId, DeviceChannel channel);
36   -
37   - /**
38   - * 批量添加设备通道
39   - *
40   - * @param deviceId 设备id
41   - * @param channels 多个通道
42   - */
43   - public int updateChannels(String deviceId, List<DeviceChannel> channels);
44   -
45   - /**
46 30 * 开始播放
47 31 * @param deviceId 设备id
48 32 * @param channelId 通道ID
... ... @@ -224,13 +208,6 @@ public interface IVideoManagerStorage {
224 208 List<DeviceChannelInPlatform> queryChannelListInParentPlatform(String platformId);
225 209  
226 210  
227   - /**
228   - * 更新上级平台的通道信息
229   - * @param platformId
230   - * @param channelReduces
231   - * @return
232   - */
233   - int updateChannelForGB(String platformId, List<ChannelReduce> channelReduces, String catalogId);
234 211  
235 212 /**
236 213 * 移除上级平台的通道信息
... ... @@ -277,20 +254,6 @@ public interface IVideoManagerStorage {
277 254 public int clearMobilePositionsByDeviceId(String deviceId);
278 255  
279 256 /**
280   - * 新增代理流
281   - * @param streamProxyDto
282   - * @return
283   - */
284   - public boolean addStreamProxy(StreamProxyItem streamProxyDto);
285   -
286   - /**
287   - * 更新代理流
288   - * @param streamProxyDto
289   - * @return
290   - */
291   - public boolean updateStreamProxy(StreamProxyItem streamProxyDto);
292   -
293   - /**
294 257 * 移除代理流
295 258 * @param app
296 259 * @param stream
... ... @@ -334,7 +297,7 @@ public interface IVideoManagerStorage {
334 297 * @param platformId
335 298 * @return
336 299 */
337   - List<GbStream> queryGbStreamListInPlatform(String platformId);
  300 + List<DeviceChannel> queryGbStreamListInPlatform(String platformId);
338 301  
339 302 /**
340 303 * 批量更新推流列表
... ... @@ -372,14 +335,16 @@ public interface IVideoManagerStorage {
372 335  
373 336 /**
374 337 * 设置流离线
375   - * @param app
376   - * @param streamId
377 338 */
378   - int mediaOutline(String app, String streamId);
  339 + int mediaOffline(String app, String streamId);
  340 +
  341 + /**
  342 + * 设置流上线
  343 + */
  344 + int mediaOnline(String app, String streamId);
379 345  
380 346 /**
381 347 * 设置平台在线/离线
382   - * @param online
383 348 */
384 349 void updateParentPlatformStatus(String platformGbID, boolean online);
385 350  
... ... @@ -443,7 +408,7 @@ public interface IVideoManagerStorage {
443 408  
444 409 int setDefaultCatalog(String platformId, String catalogId);
445 410  
446   - List<PlatformCatalog> queryCatalogInPlatform(String serverGBId);
  411 + List<DeviceChannel> queryCatalogInPlatform(String serverGBId);
447 412  
448 413 int delRelation(PlatformCatalog platformCatalog);
449 414  
... ... @@ -464,4 +429,8 @@ public interface IVideoManagerStorage {
464 429 List<ChannelSourceInfo> getChannelSource(String platformId, String gbId);
465 430  
466 431 void updateChannelPosition(DeviceChannel deviceChannel);
  432 +
  433 + void cleanContentForPlatform(String serverGBId);
  434 +
  435 + List<DeviceChannel> queryChannelWithCatalog(String serverGBId);
467 436 }
... ...
src/main/java/com/genersoft/iot/vmp/storager/dao/DeviceChannelMapper.java
... ... @@ -329,5 +329,13 @@ public interface DeviceChannelMapper {
329 329 @Select("select * from device_channel where deviceId=#{deviceId} and SUBSTRING(channelId, 11, 3)=#{typeCode}")
330 330 List<DeviceChannel> getBusinessGroups(String deviceId, String typeCode);
331 331  
332   -
  332 + @Select("select dc.id, dc.channelId, dc.deviceId, dc.name, dc.manufacture,dc.model,dc.owner, pc.civilCode,dc.block, " +
  333 + " dc.address, '0' as parental,'0' as channelType, pc.id as parentId, dc.safetyWay, dc.registerWay,dc.certNum, dc.certifiable, " +
  334 + " dc.errCode,dc.endTime, dc.secrecy, dc.ipAddress, dc.port, dc.PTZType, dc.password, dc.status, " +
  335 + " dc.longitudeWgs84 as longitude, dc.latitudeWgs84 as latitude, pc.businessGroupId " +
  336 + " from device_channel dc" +
  337 + " left join platform_gb_channel pgc on dc.id = pgc.deviceChannelId" +
  338 + " left join platform_catalog pc on pgc.catalogId = pc.id and pgc.platformId = pc.platformId" +
  339 + " where pgc.platformId=#{serverGBId}")
  340 + List<DeviceChannel> queryChannelWithCatalog(String serverGBId);
333 341 }
... ...
src/main/java/com/genersoft/iot/vmp/storager/dao/GbStreamMapper.java
1 1 package com.genersoft.iot.vmp.storager.dao;
2 2  
  3 +import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
3 4 import com.genersoft.iot.vmp.gb28181.bean.GbStream;
4 5 import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem;
5 6 import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem;
... ... @@ -15,10 +16,10 @@ import java.util.List;
15 16 public interface GbStreamMapper {
16 17  
17 18 @Insert("REPLACE INTO gb_stream (app, stream, gbId, name, " +
18   - "longitude, latitude, streamType, mediaServerId, status, createTime) VALUES" +
  19 + "longitude, latitude, streamType, mediaServerId, createTime) VALUES" +
19 20 "('${app}', '${stream}', '${gbId}', '${name}', " +
20 21 "'${longitude}', '${latitude}', '${streamType}', " +
21   - "'${mediaServerId}', ${status}, '${createTime}')")
  22 + "'${mediaServerId}', '${createTime}')")
22 23 @Options(useGeneratedKeys = true, keyProperty = "gbStreamId", keyColumn = "gbStreamId")
23 24 int add(GbStream gbStream);
24 25  
... ... @@ -30,8 +31,7 @@ public interface GbStreamMapper {
30 31 "streamType=#{streamType}," +
31 32 "longitude=#{longitude}, " +
32 33 "latitude=#{latitude}," +
33   - "mediaServerId=#{mediaServerId}," +
34   - "status=${status} " +
  34 + "mediaServerId=#{mediaServerId}" +
35 35 "WHERE app=#{app} AND stream=#{stream}")
36 36 int updateByAppAndStream(GbStream gbStream);
37 37  
... ... @@ -43,8 +43,7 @@ public interface GbStreamMapper {
43 43 "streamType=#{streamType}," +
44 44 "longitude=#{longitude}, " +
45 45 "latitude=#{latitude}," +
46   - "mediaServerId=#{mediaServerId}," +
47   - "status=${status} " +
  46 + "mediaServerId=#{mediaServerId}" +
48 47 "WHERE gbStreamId=#{gbStreamId}")
49 48 int update(GbStream gbStream);
50 49  
... ... @@ -60,15 +59,13 @@ public interface GbStreamMapper {
60 59 " <if test='catalogId == null'> AND gs.gbStreamId not in" +
61 60 "(select pgs.gbStreamId from platform_gb_stream pgs where pgs.platformId = #{platformId}) </if> " +
62 61 " <if test='query != null'> AND (gs.app LIKE '%${query}%' OR gs.stream LIKE '%${query}%' OR gs.gbId LIKE '%${query}%' OR gs.name LIKE '%${query}%')</if> " +
63   - " <if test='pushing == true' > AND gs.status=1</if>" +
64   - " <if test='pushing == false' > AND gs.status=0</if>" +
65 62 " <if test='mediaServerId != null' > AND gs.mediaServerId=#{mediaServerId} </if>" +
66 63 " order by gs.gbStreamId asc " +
67 64 "</script>")
68   - List<GbStream> selectAll(String platformId, String catalogId, String query, Boolean pushing, String mediaServerId);
  65 + List<GbStream> selectAll(String platformId, String catalogId, String query, String mediaServerId);
69 66  
70 67 @Select("SELECT * FROM gb_stream WHERE app=#{app} AND stream=#{stream}")
71   - StreamProxyItem selectOne(String app, String stream);
  68 + GbStream selectOne(String app, String stream);
72 69  
73 70 @Select("SELECT * FROM gb_stream WHERE gbId=#{gbId}")
74 71 List<GbStream> selectByGBId(String gbId);
... ... @@ -78,26 +75,24 @@ public interface GbStreamMapper {
78 75 "WHERE gs.gbId = '${gbId}' AND pgs.platformId = '${platformId}'")
79 76 GbStream queryStreamInPlatform(String platformId, String gbId);
80 77  
81   - @Select("SELECT gs.*, pgs.platformId as platformId, pgs.catalogId as catalogId FROM gb_stream gs " +
82   - "LEFT JOIN platform_gb_stream pgs ON gs.gbStreamId = pgs.gbStreamId " +
83   - "WHERE pgs.platformId = #{platformId}")
84   - List<GbStream> queryGbStreamListInPlatform(String platformId);
  78 + @Select("select gt.gbId as channelId, gt.name, 'wvp-pro' as manufacture, st.status, gt.longitude, gt.latitude, pc.id as parentId," +
  79 + " '1' as registerWay, pc.civilCode, 'live' as model, 'wvp-pro' as owner, '0' as parental,'0' as secrecy" +
  80 + " from gb_stream gt " +
  81 + " left join (" +
  82 + " select sp.status, sp.app, sp.stream from stream_push sp" +
  83 + " union all" +
  84 + " select spxy.status, spxy.app, spxy.stream from stream_proxy spxy" +
  85 + " ) st on st.app = gt.app and st.stream = gt.stream" +
  86 + " left join platform_gb_stream pgs on gt.gbStreamId = pgs.gbStreamId" +
  87 + " left join platform_catalog pc on pgs.catalogId = pc.id and pgs.platformId = pc.platformId" +
  88 + " where pgs.platformId=#{platformId}")
  89 + List<DeviceChannel> queryGbStreamListInPlatform(String platformId);
85 90  
86 91  
87 92 @Select("SELECT gs.* FROM gb_stream gs LEFT JOIN platform_gb_stream pgs " +
88 93 "ON gs.gbStreamId = pgs.gbStreamId WHERE pgs.gbStreamId is NULL")
89 94 List<GbStream> queryStreamNotInPlatform();
90 95  
91   - @Update("UPDATE gb_stream " +
92   - "SET status=${status} " +
93   - "WHERE app=#{app} AND stream=#{stream}")
94   - int setStatus(String app, String stream, boolean status);
95   -
96   - @Update("UPDATE gb_stream " +
97   - "SET status=${status} " +
98   - "WHERE mediaServerId=#{mediaServerId} ")
99   - void updateStatusByMediaServerId(String mediaServerId, boolean status);
100   -
101 96 @Delete("DELETE FROM gb_stream WHERE streamType=#{type} AND gbId=NULL AND mediaServerId=#{mediaServerId}")
102 97 void deleteWithoutGBId(String type, String mediaServerId);
103 98  
... ... @@ -120,12 +115,12 @@ public interface GbStreamMapper {
120 115 @Insert("<script> " +
121 116 "INSERT IGNORE into gb_stream " +
122 117 "(app, stream, gbId, name, " +
123   - "longitude, latitude, streamType, mediaServerId, status, createTime)" +
  118 + "longitude, latitude, streamType, mediaServerId, createTime)" +
124 119 "values " +
125 120 "<foreach collection='subList' index='index' item='item' separator=','> " +
126 121 "('${item.app}', '${item.stream}', '${item.gbId}', '${item.name}', " +
127 122 "'${item.longitude}', '${item.latitude}', '${item.streamType}', " +
128   - "'${item.mediaServerId}', ${item.status}, '${item.createTime}') "+
  123 + "'${item.mediaServerId}', '${item.createTime}') "+
129 124 "</foreach> " +
130 125 "</script>")
131 126 @Options(useGeneratedKeys = true, keyProperty = "gbStreamId", keyColumn = "gbStreamId")
... ...
src/main/java/com/genersoft/iot/vmp/storager/dao/ParentPlatformMapper.java
... ... @@ -16,10 +16,10 @@ public interface ParentPlatformMapper {
16 16  
17 17 @Insert("INSERT INTO parent_platform (enable, name, serverGBId, serverGBDomain, serverIP, serverPort, deviceGBId, deviceIp, " +
18 18 " devicePort, username, password, expires, keepTimeout, transport, characterSet, ptz, rtcp, " +
19   - " status, shareAllLiveStream, startOfflinePush, catalogId, administrativeDivision, catalogGroup, createTime, updateTime) " +
  19 + " status, startOfflinePush, catalogId, administrativeDivision, catalogGroup, createTime, updateTime, treeType) " +
20 20 " VALUES (${enable}, '${name}', '${serverGBId}', '${serverGBDomain}', '${serverIP}', ${serverPort}, '${deviceGBId}', '${deviceIp}', " +
21 21 " '${devicePort}', '${username}', '${password}', '${expires}', '${keepTimeout}', '${transport}', '${characterSet}', ${ptz}, ${rtcp}, " +
22   - " ${status}, ${shareAllLiveStream}, ${startOfflinePush}, #{catalogId}, #{administrativeDivision}, #{catalogGroup}, #{createTime}, #{updateTime})")
  22 + " ${status}, ${startOfflinePush}, #{catalogId}, #{administrativeDivision}, #{catalogGroup}, #{createTime}, #{updateTime}, #{treeType})")
23 23 int addParentPlatform(ParentPlatform parentPlatform);
24 24  
25 25 @Update("UPDATE parent_platform " +
... ... @@ -41,12 +41,12 @@ public interface ParentPlatformMapper {
41 41 "ptz=#{ptz}, " +
42 42 "rtcp=#{rtcp}, " +
43 43 "status=#{status}, " +
44   - "shareAllLiveStream=#{shareAllLiveStream}, " +
45 44 "startOfflinePush=${startOfflinePush}, " +
46 45 "catalogGroup=#{catalogGroup}, " +
47 46 "administrativeDivision=#{administrativeDivision}, " +
48 47 "createTime=#{createTime}, " +
49 48 "updateTime=#{updateTime}, " +
  49 + "treeType=#{treeType}, " +
50 50 "catalogId=#{catalogId} " +
51 51 "WHERE id=#{id}")
52 52 int updateParentPlatform(ParentPlatform parentPlatform);
... ... @@ -83,9 +83,6 @@ public interface ParentPlatformMapper {
83 83 @Update("UPDATE parent_platform SET status=#{online} WHERE serverGBId=#{platformGbID}" )
84 84 int updateParentPlatformStatus(String platformGbID, boolean online);
85 85  
86   - @Select("SELECT * FROM parent_platform WHERE shareAllLiveStream=true")
87   - List<ParentPlatform> selectAllAhareAllLiveStream();
88   -
89 86 @Update(value = {" <script>" +
90 87 "UPDATE parent_platform " +
91 88 "SET catalogId=#{catalogId}, updateTime=#{updateTime}" +
... ...
src/main/java/com/genersoft/iot/vmp/storager/dao/PlatformCatalogMapper.java
1 1 package com.genersoft.iot.vmp.storager.dao;
2 2  
  3 +import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
3 4 import com.genersoft.iot.vmp.gb28181.bean.GbStream;
4 5 import com.genersoft.iot.vmp.gb28181.bean.PlatformCatalog;
5 6 import com.genersoft.iot.vmp.gb28181.bean.PlatformGbStream;
... ... @@ -14,8 +15,8 @@ import java.util.List;
14 15 @Repository
15 16 public interface PlatformCatalogMapper {
16 17  
17   - @Insert("INSERT INTO platform_catalog (id, name, platformId, parentId) VALUES" +
18   - "(#{id}, #{name}, #{platformId}, #{parentId})")
  18 + @Insert("INSERT INTO platform_catalog (id, name, platformId, parentId, civilCode, businessGroupId) VALUES" +
  19 + "(#{id}, #{name}, #{platformId}, #{parentId}, #{civilCode}, #{businessGroupId})")
19 20 int add(PlatformCatalog platformCatalog);
20 21  
21 22 @Delete("DELETE FROM platform_catalog WHERE id=#{id}")
... ... @@ -44,4 +45,12 @@ public interface PlatformCatalogMapper {
44 45  
45 46 @Select("SELECT pc.* FROM platform_catalog pc WHERE pc.id = (SELECT pp.catalogId from parent_platform pp WHERE pp.serverGBId=#{platformId})")
46 47 PlatformCatalog selectDefaultByPlatFormId(String platformId);
  48 +
  49 +
  50 + @Select("SELECT pc.* FROM platform_catalog pc WHERE pc.id = #{id}")
  51 + PlatformCatalog selectParentCatalog(String id);
  52 +
  53 + @Select("SELECT pc.id as channelId, pc.name, pc.civilCode, pc.businessGroupId,'0' as parental, pc.parentId " +
  54 + " FROM platform_catalog pc WHERE pc.platformId=#{platformId}")
  55 + List<DeviceChannel> queryCatalogInPlatform(String platformId);
47 56 }
... ...
src/main/java/com/genersoft/iot/vmp/storager/dao/StreamProxyMapper.java
... ... @@ -62,12 +62,12 @@ public interface StreamProxyMapper {
62 62 @Update("UPDATE stream_proxy " +
63 63 "SET status=#{status} " +
64 64 "WHERE mediaServerId=#{mediaServerId}")
65   - void updateStatusByMediaServerId(boolean status, String mediaServerId);
  65 + void updateStatusByMediaServerId(String mediaServerId, boolean status);
66 66  
67 67 @Update("UPDATE stream_proxy " +
68 68 "SET status=${status} " +
69 69 "WHERE app=#{app} AND stream=#{stream}")
70   - int updateStatus(boolean status, String app, String stream);
  70 + int updateStatus(String app, String stream, boolean status);
71 71  
72 72 @Delete("DELETE FROM stream_proxy WHERE enable_remove_none_reader=true AND mediaServerId=#{mediaServerId}")
73 73 void deleteAutoRemoveItemByMediaServerId(String mediaServerId);
... ...
src/main/java/com/genersoft/iot/vmp/storager/dao/StreamPushMapper.java
... ... @@ -2,6 +2,7 @@ package com.genersoft.iot.vmp.storager.dao;
2 2  
3 3 import com.genersoft.iot.vmp.gb28181.bean.GbStream;
4 4 import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem;
  5 +import com.genersoft.iot.vmp.service.bean.StreamPushItemFromRedis;
5 6 import org.apache.ibatis.annotations.*;
6 7 // import org.omg.PortableInterceptor.INACTIVE;
7 8 import org.springframework.stereotype.Repository;
... ... @@ -14,21 +15,24 @@ import java.util.List;
14 15 public interface StreamPushMapper {
15 16  
16 17 @Insert("INSERT INTO stream_push (app, stream, totalReaderCount, originType, originTypeStr, " +
17   - "createStamp, aliveSecond, mediaServerId, serverId) VALUES" +
  18 + "pushTime, aliveSecond, mediaServerId, serverId, updateTime, createTime, pushIng) VALUES" +
18 19 "('${app}', '${stream}', '${totalReaderCount}', '${originType}', '${originTypeStr}', " +
19   - "'${createStamp}', '${aliveSecond}', '${mediaServerId}' , '${serverId}' )")
  20 + "'${pushTime}', '${aliveSecond}', '${mediaServerId}' , '${serverId}' , '${updateTime}' , '${createTime}', ${pushIng} )")
20 21 int add(StreamPushItem streamPushItem);
21 22  
22   - @Update("UPDATE stream_push " +
23   - "SET app=#{app}," +
24   - "stream=#{stream}," +
25   - "mediaServerId=#{mediaServerId}," +
26   - "totalReaderCount=#{totalReaderCount}, " +
27   - "originType=#{originType}," +
28   - "originTypeStr=#{originTypeStr}, " +
29   - "createStamp=#{createStamp}, " +
30   - "aliveSecond=#{aliveSecond} " +
31   - "WHERE app=#{app} AND stream=#{stream}")
  23 +
  24 + @Update(value = {" <script>" +
  25 + "UPDATE stream_push " +
  26 + "SET updateTime='${updateTime}'" +
  27 + "<if test=\"mediaServerId != null\">, mediaServerId='${mediaServerId}'</if>" +
  28 + "<if test=\"totalReaderCount != null\">, totalReaderCount='${totalReaderCount}'</if>" +
  29 + "<if test=\"originType != null\">, originType=${originType}</if>" +
  30 + "<if test=\"originTypeStr != null\">, originTypeStr='${originTypeStr}'</if>" +
  31 + "<if test=\"pushTime != null\">, pushTime='${pushTime}'</if>" +
  32 + "<if test=\"aliveSecond != null\">, aliveSecond='${aliveSecond}'</if>" +
  33 + "<if test=\"pushIng != null\">, pushIng=${pushIng}</if>" +
  34 + "WHERE app=#{app} AND stream=#{stream}"+
  35 + " </script>"})
32 36 int update(StreamPushItem streamPushItem);
33 37  
34 38 @Delete("DELETE FROM stream_push WHERE app=#{app} AND stream=#{stream}")
... ... @@ -62,7 +66,7 @@ public interface StreamPushMapper {
62 66 @Select(value = {" <script>" +
63 67 "SELECT " +
64 68 "st.*, " +
65   - "gs.gbId, gs.status, gs.name, gs.longitude, gs.latitude, gs.gbStreamId " +
  69 + "gs.gbId, gs.name, gs.longitude, gs.latitude, gs.gbStreamId " +
66 70 "from " +
67 71 "stream_push st " +
68 72 "LEFT JOIN gb_stream gs " +
... ... @@ -70,25 +74,26 @@ public interface StreamPushMapper {
70 74 "WHERE " +
71 75 "1=1 " +
72 76 " <if test='query != null'> AND (st.app LIKE '%${query}%' OR st.stream LIKE '%${query}%' OR gs.gbId LIKE '%${query}%' OR gs.name LIKE '%${query}%')</if> " +
73   - " <if test='pushing == true' > AND (gs.gbId is null OR gs.status=1)</if>" +
74   - " <if test='pushing == false' > AND gs.status=0</if>" +
  77 + " <if test='pushing == true' > AND (gs.gbId is null OR st.status=1)</if>" +
  78 + " <if test='pushing == false' > AND st.status=0</if>" +
75 79 " <if test='mediaServerId != null' > AND st.mediaServerId=#{mediaServerId} </if>" +
76   - "order by st.createStamp desc" +
  80 + "order by st.createTime desc" +
77 81 " </script>"})
78 82 List<StreamPushItem> selectAllForList(String query, Boolean pushing, String mediaServerId);
79 83  
80   - @Select("SELECT st.*, gs.gbId, gs.status, gs.name, gs.longitude, gs.latitude FROM stream_push st LEFT JOIN gb_stream gs on st.app = gs.app AND st.stream = gs.stream order by st.createStamp desc")
  84 + @Select("SELECT st.*, gs.gbId, gs.name, gs.longitude, gs.latitude FROM stream_push st LEFT JOIN gb_stream gs on st.app = gs.app AND st.stream = gs.stream order by st.createTime desc")
81 85 List<StreamPushItem> selectAll();
82 86  
83   - @Select("SELECT st.*, gs.gbId, gs.status, gs.name, gs.longitude, gs.latitude FROM stream_push st LEFT JOIN gb_stream gs on st.app = gs.app AND st.stream = gs.stream WHERE st.app=#{app} AND st.stream=#{stream}")
  87 + @Select("SELECT st.*, gs.gbId, gs.name, gs.longitude, gs.latitude FROM stream_push st LEFT JOIN gb_stream gs on st.app = gs.app AND st.stream = gs.stream WHERE st.app=#{app} AND st.stream=#{stream}")
84 88 StreamPushItem selectOne(String app, String stream);
85 89  
86 90 @Insert("<script>" +
87 91 "Insert IGNORE INTO stream_push (app, stream, totalReaderCount, originType, originTypeStr, " +
88   - "createStamp, aliveSecond, mediaServerId) " +
  92 + "createTime, aliveSecond, mediaServerId, status, pushIng) " +
89 93 "VALUES <foreach collection='streamPushItems' item='item' index='index' separator=','>" +
90 94 "( '${item.app}', '${item.stream}', '${item.totalReaderCount}', #{item.originType}, " +
91   - "'${item.originTypeStr}',#{item.createStamp}, #{item.aliveSecond}, '${item.mediaServerId}' )" +
  95 + "'${item.originTypeStr}',#{item.createTime}, #{item.aliveSecond}, '${item.mediaServerId}', ${item.status} ," +
  96 + " ${item.pushIng} )" +
92 97 " </foreach>" +
93 98 "</script>")
94 99 @Options(useGeneratedKeys = true, keyProperty = "id", keyColumn = "id")
... ... @@ -106,4 +111,59 @@ public interface StreamPushMapper {
106 111 @Select("SELECT sp.* FROM stream_push sp left join gb_stream gs on gs.app = sp.app and gs.stream= sp.stream WHERE sp.mediaServerId=#{mediaServerId} and gs.gbId is null")
107 112 List<StreamPushItem> selectAllByMediaServerIdWithOutGbID(String mediaServerId);
108 113  
  114 + @Update("UPDATE stream_push " +
  115 + "SET status=${status} " +
  116 + "WHERE app=#{app} AND stream=#{stream}")
  117 + int updateStatus(String app, String stream, boolean status);
  118 +
  119 + @Update("UPDATE stream_push " +
  120 + "SET pushIng=${pushIng} " +
  121 + "WHERE app=#{app} AND stream=#{stream}")
  122 + int updatePushStatus(String app, String stream, boolean status);
  123 +
  124 + @Update("UPDATE stream_push " +
  125 + "SET status=#{status} " +
  126 + "WHERE mediaServerId=#{mediaServerId}")
  127 + void updateStatusByMediaServerId(String mediaServerId, boolean status);
  128 +
  129 +
  130 + @Select("<script> "+
  131 + "SELECT gs.* FROM stream_push sp left join gb_stream gs on sp.app = gs.app AND sp.stream = gs.stream " +
  132 + "where sp.status = 1 and (gs.app, gs.stream) in (" +
  133 + "<foreach collection='offlineStreams' item='item' separator=','>" +
  134 + "(#{item.app}, #{item.stream}) " +
  135 + "</foreach>" +
  136 + ")</script>")
  137 + List<GbStream> getOnlinePusherForGbInList(List<StreamPushItemFromRedis> offlineStreams);
  138 +
  139 + @Update("<script> "+
  140 + "UPDATE stream_push SET status=0 where (app, stream) in (" +
  141 + "<foreach collection='offlineStreams' item='item' separator=','>" +
  142 + "(#{item.app}, #{item.stream}) " +
  143 + "</foreach>" +
  144 + ")</script>")
  145 + void offline(List<StreamPushItemFromRedis> offlineStreams);
  146 +
  147 + @Select("<script> "+
  148 + "SELECT * FROM stream_push sp left join gb_stream gs on sp.app = gs.app AND sp.stream = gs.stream " +
  149 + "where sp.status = 0 and (gs.app, gs.stream) in (" +
  150 + "<foreach collection='onlineStreams' item='item' separator=','>" +
  151 + "(#{item.app}, #{item.stream}) " +
  152 + "</foreach>" +
  153 + ") </script>")
  154 + List<GbStream> getOfflinePusherForGbInList(List<StreamPushItemFromRedis> onlineStreams);
  155 +
  156 + @Update("<script> "+
  157 + "UPDATE stream_push SET status=1 where (app, stream) in (" +
  158 + "<foreach collection='onlineStreams' item='item' separator=','>" +
  159 + "(#{item.app}, #{item.stream}) " +
  160 + "</foreach>" +
  161 + ")</script>")
  162 + void online(List<StreamPushItemFromRedis> onlineStreams);
  163 +
  164 + @Select("SELECT gs.* FROM stream_push sp left join gb_stream gs on sp.app = gs.app AND sp.stream = gs.stream where sp.status = 1")
  165 + List<GbStream> getOnlinePusherForGb();
  166 +
  167 + @Update("UPDATE stream_push SET status=0")
  168 + void setAllStreamOffline();
109 169 }
... ...
src/main/java/com/genersoft/iot/vmp/storager/dao/UserMapper.java
... ... @@ -10,13 +10,14 @@ import java.util.List;
10 10 @Repository
11 11 public interface UserMapper {
12 12  
13   - @Insert("INSERT INTO user (username, password, roleId, createTime, updateTime) VALUES" +
14   - "('${username}', '${password}', '${role.id}', '${createTime}', '${updateTime}')")
  13 + @Insert("INSERT INTO user (username, password, roleId, pushKey, createTime, updateTime) VALUES" +
  14 + "('${username}', '${password}', '${role.id}', '${pushKey}', '${createTime}', '${updateTime}')")
15 15 int add(User user);
16 16  
17 17 @Update(value = {" <script>" +
18 18 "UPDATE user " +
19 19 "SET updateTime='${updateTime}' " +
  20 + "<if test=\"pushKey != null\">, pushKey='${pushKey}'</if>" +
20 21 "<if test=\"role != null\">, roleId='${role.id}'</if>" +
21 22 "<if test=\"password != null\">, password='${password}'</if>" +
22 23 "<if test=\"username != null\">, username='${username}'</if>" +
... ... @@ -48,4 +49,17 @@ public interface UserMapper {
48 49 @Select("select u.*, r.id as roleID, r.name as roleName, r.authority as roleAuthority , r.createTime as roleCreateTime , r.updateTime as roleUpdateTime FROM user u, user_role r WHERE u.roleId=r.id")
49 50 @ResultMap(value="roleMap")
50 51 List<User> selectAll();
  52 +
  53 + @Select("select * from (select user.*, concat('${callId}_', pushKey) as str1 from user) as u where md5(u.str1) = '${sign}'")
  54 + List<User> checkPushAuthorityByCallIdAndSign(String callId, String sign);
  55 +
  56 + @Select("select * from user where md5(pushKey) = '${sign}'")
  57 + List<User> checkPushAuthorityByCallId(String sign);
  58 +
  59 + @Select("select u.id, u.username,u.pushKey,u.roleId, r.id as roleID, r.name as roleName, r.authority as roleAuthority , r.createTime as roleCreateTime , r.updateTime as roleUpdateTime FROM user u join user_role r on u.roleId=r.id")
  60 + @ResultMap(value="roleMap")
  61 + List<User> getUsers();
  62 +
  63 + @Update("update user set pushKey=#{pushKey} where id=#{id}")
  64 + int changePushKey(int id, String pushKey);
51 65 }
... ...
src/main/java/com/genersoft/iot/vmp/storager/dao/dto/User.java
... ... @@ -7,6 +7,7 @@ public class User {
7 7 private String password;
8 8 private String createTime;
9 9 private String updateTime;
  10 + private String pushKey;
10 11 private Role role;
11 12  
12 13 public int getId() {
... ... @@ -56,4 +57,12 @@ public class User {
56 57 public void setRole(Role role) {
57 58 this.role = role;
58 59 }
  60 +
  61 + public String getPushKey() {
  62 + return pushKey;
  63 + }
  64 +
  65 + public void setPushKey(String pushKey) {
  66 + this.pushKey = pushKey;
  67 + }
59 68 }
... ...
src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java
... ... @@ -9,6 +9,8 @@ import com.genersoft.iot.vmp.conf.UserSetting;
9 9 import com.genersoft.iot.vmp.gb28181.bean.*;
10 10 import com.genersoft.iot.vmp.media.zlm.dto.MediaItem;
11 11 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
  12 +import com.genersoft.iot.vmp.media.zlm.dto.OnPublishHookParam;
  13 +import com.genersoft.iot.vmp.media.zlm.dto.StreamAuthorityInfo;
12 14 import com.genersoft.iot.vmp.service.bean.GPSMsgInfo;
13 15 import com.genersoft.iot.vmp.service.bean.MessageForPushChannel;
14 16 import com.genersoft.iot.vmp.service.bean.ThirdPartyGB;
... ... @@ -20,6 +22,7 @@ import org.slf4j.Logger;
20 22 import org.slf4j.LoggerFactory;
21 23 import org.springframework.beans.factory.annotation.Autowired;
22 24 import org.springframework.stereotype.Component;
  25 +import org.springframework.util.StringUtils;
23 26  
24 27 import java.util.*;
25 28  
... ... @@ -482,7 +485,12 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage {
482 485  
483 486 @Override
484 487 public void addStream(MediaServerItem mediaServerItem, String type, String app, String streamId, MediaItem mediaItem) {
  488 + // 查找是否使用了callID
  489 + StreamAuthorityInfo streamAuthorityInfo = getStreamAuthorityInfo(app, streamId);
485 490 String key = VideoManagerConstants.WVP_SERVER_STREAM_PREFIX + userSetting.getServerId() + "_" + type + "_" + app + "_" + streamId + "_" + mediaServerItem.getId();
  491 + if (streamAuthorityInfo != null) {
  492 + mediaItem.setCallId(streamAuthorityInfo.getCallId());
  493 + }
486 494 redis.set(key, mediaItem);
487 495 }
488 496  
... ... @@ -599,6 +607,26 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage {
599 607 }
600 608  
601 609 @Override
  610 + public void updateStreamAuthorityInfo(String app, String stream, StreamAuthorityInfo streamAuthorityInfo) {
  611 + String key = VideoManagerConstants.MEDIA_STREAM_AUTHORITY + userSetting.getServerId() + "_" + app+ "_" + stream;
  612 + redis.set(key, streamAuthorityInfo);
  613 + }
  614 +
  615 + @Override
  616 + public void removeStreamAuthorityInfo(String app, String stream) {
  617 + String key = VideoManagerConstants.MEDIA_STREAM_AUTHORITY + userSetting.getServerId() + "_" + app+ "_" + stream ;
  618 + redis.del(key);
  619 + }
  620 +
  621 + @Override
  622 + public StreamAuthorityInfo getStreamAuthorityInfo(String app, String stream) {
  623 + String key = VideoManagerConstants.MEDIA_STREAM_AUTHORITY + userSetting.getServerId() + "_" + app+ "_" + stream ;
  624 + return (StreamAuthorityInfo) redis.get(key);
  625 +
  626 + }
  627 +
  628 +
  629 + @Override
602 630 public MediaItem getStreamInfo(String app, String streamId, String mediaServerId) {
603 631 String scanKey = VideoManagerConstants.WVP_SERVER_STREAM_PREFIX + userSetting.getServerId() + "_*_" + app + "_" + streamId + "_" + mediaServerId;
604 632  
... ... @@ -682,4 +710,14 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage {
682 710 public boolean deviceIsOnline(String deviceId) {
683 711 return getDevice(deviceId).getOnline() == 1;
684 712 }
  713 +
  714 +
  715 + @Override
  716 + public void sendStreamPushRequestedMsgForStatus() {
  717 + String key = VideoManagerConstants.VM_MSG_GET_ALL_ONLINE_REQUESTED;
  718 + logger.info("[redis 通知]获取所有推流设备的状态");
  719 + JSONObject jsonObject = new JSONObject();
  720 + jsonObject.put(key, key);
  721 + redis.convertAndSend(key, jsonObject);
  722 + }
685 723 }
... ...
src/main/java/com/genersoft/iot/vmp/storager/impl/VideoManagerStorageImpl.java
... ... @@ -48,13 +48,14 @@ public class VideoManagerStorageImpl implements IVideoManagerStorage {
48 48 @Autowired
49 49 SipConfig sipConfig;
50 50  
51   - @Autowired
52   - DataSourceTransactionManager dataSourceTransactionManager;
53 51  
54 52 @Autowired
55 53 TransactionDefinition transactionDefinition;
56 54  
57 55 @Autowired
  56 + DataSourceTransactionManager dataSourceTransactionManager;
  57 +
  58 + @Autowired
58 59 private DeviceMapper deviceMapper;
59 60  
60 61 @Autowired
... ... @@ -105,96 +106,6 @@ public class VideoManagerStorageImpl implements IVideoManagerStorage {
105 106 }
106 107  
107 108 @Override
108   - public synchronized void updateChannel(String deviceId, DeviceChannel channel) {
109   - String channelId = channel.getChannelId();
110   - channel.setDeviceId(deviceId);
111   - StreamInfo streamInfo = redisCatchStorage.queryPlayByDevice(deviceId, channelId);
112   - if (streamInfo != null) {
113   - channel.setStreamId(streamInfo.getStream());
114   - }
115   - String now = DateUtil.getNow();
116   - channel.setUpdateTime(now);
117   - DeviceChannel deviceChannel = deviceChannelMapper.queryChannel(deviceId, channelId);
118   - if (deviceChannel == null) {
119   - channel.setCreateTime(now);
120   - deviceChannelMapper.add(channel);
121   - }else {
122   - deviceChannelMapper.update(channel);
123   - }
124   - deviceChannelMapper.updateChannelSubCount(deviceId,channel.getParentId());
125   - }
126   -
127   - @Override
128   - public int updateChannels(String deviceId, List<DeviceChannel> channels) {
129   - List<DeviceChannel> addChannels = new ArrayList<>();
130   - List<DeviceChannel> updateChannels = new ArrayList<>();
131   - HashMap<String, DeviceChannel> channelsInStore = new HashMap<>();
132   - if (channels != null && channels.size() > 0) {
133   - List<DeviceChannel> channelList = deviceChannelMapper.queryChannels(deviceId, null, null, null, null);
134   - if (channelList.size() == 0) {
135   - for (DeviceChannel channel : channels) {
136   - channel.setDeviceId(deviceId);
137   - StreamInfo streamInfo = redisCatchStorage.queryPlayByDevice(deviceId, channel.getChannelId());
138   - if (streamInfo != null) {
139   - channel.setStreamId(streamInfo.getStream());
140   - }
141   - String now = DateUtil.getNow();
142   - channel.setUpdateTime(now);
143   - channel.setCreateTime(now);
144   - addChannels.add(channel);
145   - }
146   - }else {
147   - for (DeviceChannel deviceChannel : channelList) {
148   - channelsInStore.put(deviceChannel.getChannelId(), deviceChannel);
149   - }
150   - for (DeviceChannel channel : channels) {
151   - channel.setDeviceId(deviceId);
152   - StreamInfo streamInfo = redisCatchStorage.queryPlayByDevice(deviceId, channel.getChannelId());
153   - if (streamInfo != null) {
154   - channel.setStreamId(streamInfo.getStream());
155   - }
156   - String now = DateUtil.getNow();
157   - channel.setUpdateTime(now);
158   - if (channelsInStore.get(channel.getChannelId()) != null) {
159   - updateChannels.add(channel);
160   - }else {
161   - addChannels.add(channel);
162   - channel.setCreateTime(now);
163   - }
164   - }
165   - }
166   - int limitCount = 300;
167   - if (addChannels.size() > 0) {
168   - if (addChannels.size() > limitCount) {
169   - for (int i = 0; i < addChannels.size(); i += limitCount) {
170   - int toIndex = i + limitCount;
171   - if (i + limitCount > addChannels.size()) {
172   - toIndex = addChannels.size();
173   - }
174   - deviceChannelMapper.batchAdd(addChannels.subList(i, toIndex));
175   - }
176   - }else {
177   - deviceChannelMapper.batchAdd(addChannels);
178   - }
179   - }
180   - if (updateChannels.size() > 0) {
181   - if (updateChannels.size() > limitCount) {
182   - for (int i = 0; i < updateChannels.size(); i += limitCount) {
183   - int toIndex = i + limitCount;
184   - if (i + limitCount > updateChannels.size()) {
185   - toIndex = updateChannels.size();
186   - }
187   - deviceChannelMapper.batchUpdate(updateChannels.subList(i, toIndex));
188   - }
189   - }else {
190   - deviceChannelMapper.batchUpdate(updateChannels);
191   - }
192   - }
193   - }
194   - return addChannels.size() + updateChannels.size();
195   - }
196   -
197   - @Override
198 109 public boolean resetChannels(String deviceId, List<DeviceChannel> deviceChannelList) {
199 110 if (CollectionUtils.isEmpty(deviceChannelList)) {
200 111 return false;
... ... @@ -532,20 +443,6 @@ public class VideoManagerStorageImpl implements IVideoManagerStorage {
532 443 // 更新缓存
533 444 parentPlatformCatch.setParentPlatform(parentPlatform);
534 445 redisCatchStorage.updatePlatformCatchInfo(parentPlatformCatch);
535   - if (parentPlatform.isEnable()) {
536   - // 共享所有视频流,需要将现有视频流添加到此平台
537   - List<GbStream> gbStreams = gbStreamMapper.queryStreamNotInPlatform();
538   - if (gbStreams.size() > 0) {
539   - for (GbStream gbStream : gbStreams) {
540   - gbStream.setCatalogId(parentPlatform.getCatalogId());
541   - }
542   - if (parentPlatform.isShareAllLiveStream()) {
543   - gbStreamService.addPlatformInfo(gbStreams, parentPlatform.getServerGBId(), parentPlatform.getCatalogId());
544   - }else {
545   - gbStreamService.delPlatformInfo(parentPlatform.getServerGBId(), gbStreams);
546   - }
547   - }
548   - }
549 446  
550 447 return result > 0;
551 448 }
... ... @@ -596,36 +493,6 @@ public class VideoManagerStorageImpl implements IVideoManagerStorage {
596 493 return deviceChannelMapper.queryChannelByPlatformId(platformId);
597 494 }
598 495  
599   - @Override
600   - public int updateChannelForGB(String platformId, List<ChannelReduce> channelReduces, String catalogId) {
601   -
602   - Map<Integer, ChannelReduce> deviceAndChannels = new HashMap<>();
603   - for (ChannelReduce channelReduce : channelReduces) {
604   - channelReduce.setCatalogId(catalogId);
605   - deviceAndChannels.put(channelReduce.getId(), channelReduce);
606   - }
607   - List<Integer> deviceAndChannelList = new ArrayList<>(deviceAndChannels.keySet());
608   - // 查询当前已经存在的
609   - List<Integer> channelIds = platformChannelMapper.findChannelRelatedPlatform(platformId, channelReduces);
610   - if (deviceAndChannelList != null) {
611   - deviceAndChannelList.removeAll(channelIds);
612   - }
613   - for (Integer channelId : channelIds) {
614   - deviceAndChannels.remove(channelId);
615   - }
616   - List<ChannelReduce> channelReducesToAdd = new ArrayList<>(deviceAndChannels.values());
617   - // 对剩下的数据进行存储
618   - int result = 0;
619   - if (channelReducesToAdd.size() > 0) {
620   - result = platformChannelMapper.addChannels(platformId, channelReducesToAdd);
621   - // TODO 后续给平台增加控制开关以控制是否响应目录订阅
622   - List<DeviceChannel> deviceChannelList = getDeviceChannelListByChannelReduceList(channelReducesToAdd, catalogId);
623   - eventPublisher.catalogEventPublish(platformId, deviceChannelList, CatalogEvent.ADD);
624   - }
625   -
626   - return result;
627   - }
628   -
629 496  
630 497 @Override
631 498 public int delChannelForGB(String platformId, List<ChannelReduce> channelReduces) {
... ... @@ -701,77 +568,6 @@ public class VideoManagerStorageImpl implements IVideoManagerStorage {
701 568 return deviceMobilePositionMapper.clearMobilePositionsByDeviceId(deviceId);
702 569 }
703 570  
704   - /**
705   - * 新增代理流
706   - * @param streamProxyItem
707   - * @return
708   - */
709   - @Override
710   - public boolean addStreamProxy(StreamProxyItem streamProxyItem) {
711   - TransactionStatus transactionStatus = dataSourceTransactionManager.getTransaction(transactionDefinition);
712   - boolean result = false;
713   - streamProxyItem.setStreamType("proxy");
714   - streamProxyItem.setStatus(true);
715   - String now = DateUtil.getNow();
716   - streamProxyItem.setCreateTime(now);
717   - try {
718   - if (streamProxyMapper.add(streamProxyItem) > 0) {
719   - if (!StringUtils.isEmpty(streamProxyItem.getGbId())) {
720   - if (gbStreamMapper.add(streamProxyItem) < 0) {
721   - //事务回滚
722   - dataSourceTransactionManager.rollback(transactionStatus);
723   - return false;
724   - }
725   - }
726   - }else {
727   - //事务回滚
728   - dataSourceTransactionManager.rollback(transactionStatus);
729   - return false;
730   - }
731   - result = true;
732   - dataSourceTransactionManager.commit(transactionStatus); //手动提交
733   - }catch (Exception e) {
734   - logger.error("向数据库添加流代理失败:", e);
735   - dataSourceTransactionManager.rollback(transactionStatus);
736   - }
737   -
738   -
739   - return result;
740   - }
741   -
742   - /**
743   - * 更新代理流
744   - * @param streamProxyItem
745   - * @return
746   - */
747   - @Override
748   - public boolean updateStreamProxy(StreamProxyItem streamProxyItem) {
749   - TransactionStatus transactionStatus = dataSourceTransactionManager.getTransaction(transactionDefinition);
750   - boolean result = false;
751   - streamProxyItem.setStreamType("proxy");
752   - try {
753   - if (streamProxyMapper.update(streamProxyItem) > 0) {
754   - if (!StringUtils.isEmpty(streamProxyItem.getGbId())) {
755   - if (gbStreamMapper.updateByAppAndStream(streamProxyItem) == 0) {
756   - //事务回滚
757   - dataSourceTransactionManager.rollback(transactionStatus);
758   - return false;
759   - }
760   - }
761   - } else {
762   - //事务回滚
763   - dataSourceTransactionManager.rollback(transactionStatus);
764   - return false;
765   - }
766   -
767   - dataSourceTransactionManager.commit(transactionStatus); //手动提交
768   - result = true;
769   - }catch (Exception e) {
770   - e.printStackTrace();
771   - dataSourceTransactionManager.rollback(transactionStatus);
772   - }
773   - return result;
774   - }
775 571  
776 572 /**
777 573 * 移除代理流
... ... @@ -824,7 +620,7 @@ public class VideoManagerStorageImpl implements IVideoManagerStorage {
824 620 * @return
825 621 */
826 622 @Override
827   - public List<GbStream> queryGbStreamListInPlatform(String platformId) {
  623 + public List<DeviceChannel> queryGbStreamListInPlatform(String platformId) {
828 624 return gbStreamMapper.queryGbStreamListInPlatform(platformId);
829 625 }
830 626  
... ... @@ -848,7 +644,7 @@ public class VideoManagerStorageImpl implements IVideoManagerStorage {
848 644 streamPushMapper.addAll(streamPushItems);
849 645 // TODO 待优化
850 646 for (int i = 0; i < streamPushItems.size(); i++) {
851   - int onlineResult = gbStreamMapper.setStatus(streamPushItems.get(i).getApp(), streamPushItems.get(i).getStream(), true);
  647 + int onlineResult = mediaOnline(streamPushItems.get(i).getApp(), streamPushItems.get(i).getStream());
852 648 if (onlineResult > 0) {
853 649 // 发送上线通知
854 650 eventPublisher.catalogEventPublishForStream(null, streamPushItems.get(i), CatalogEvent.ON);
... ... @@ -856,29 +652,13 @@ public class VideoManagerStorageImpl implements IVideoManagerStorage {
856 652 }
857 653 }
858 654  
  655 +
  656 +
859 657 @Override
860 658 public void updateMedia(StreamPushItem streamPushItem) {
861 659 streamPushMapper.del(streamPushItem.getApp(), streamPushItem.getStream());
862 660 streamPushMapper.add(streamPushItem);
863   - gbStreamMapper.setStatus(streamPushItem.getApp(), streamPushItem.getStream(), true);
864   -
865   - if(!StringUtils.isEmpty(streamPushItem.getGbId() )){
866   - // 查找开启了全部直播流共享的上级平台
867   - List<ParentPlatform> parentPlatforms = parentPlatformMapper.selectAllAhareAllLiveStream();
868   - if (parentPlatforms.size() > 0) {
869   - for (ParentPlatform parentPlatform : parentPlatforms) {
870   - StreamProxyItem streamProxyItem = platformGbStreamMapper.selectOne(streamPushItem.getApp(), streamPushItem.getStream(),
871   - parentPlatform.getServerGBId());
872   - if (streamProxyItem == null) {
873   - streamPushItem.setCatalogId(parentPlatform.getCatalogId());
874   - streamPushItem.setPlatformId(parentPlatform.getServerGBId());
875   - platformGbStreamMapper.add(streamPushItem);
876   - eventPublisher.catalogEventPublishForStream(parentPlatform.getServerGBId(), streamPushItem, CatalogEvent.ADD);
877   - }
878   - }
879   - }
880   - }
881   -
  661 + mediaOffline(streamPushItem.getApp(), streamPushItem.getStream());
882 662 }
883 663  
884 664 @Override
... ... @@ -897,8 +677,27 @@ public class VideoManagerStorageImpl implements IVideoManagerStorage {
897 677 }
898 678  
899 679 @Override
900   - public int mediaOutline(String app, String streamId) {
901   - return gbStreamMapper.setStatus(app, streamId, false);
  680 + public int mediaOffline(String app, String stream) {
  681 + GbStream gbStream = gbStreamMapper.selectOne(app, stream);
  682 + int result;
  683 + if ("proxy".equals(gbStream.getStreamType())) {
  684 + result = streamProxyMapper.updateStatus(app, stream, false);
  685 + }else {
  686 + result = streamPushMapper.updateStatus(app, stream, false);
  687 + }
  688 + return result;
  689 + }
  690 +
  691 + @Override
  692 + public int mediaOnline(String app, String stream) {
  693 + GbStream gbStream = gbStreamMapper.selectOne(app, stream);
  694 + int result;
  695 + if ("proxy".equals(gbStream.getStreamType())) {
  696 + result = streamProxyMapper.updateStatus(app, stream, true);
  697 + }else {
  698 + result = streamPushMapper.updateStatus(app, stream, true);
  699 + }
  700 + return result;
902 701 }
903 702  
904 703 @Override
... ... @@ -934,6 +733,24 @@ public class VideoManagerStorageImpl implements IVideoManagerStorage {
934 733  
935 734 @Override
936 735 public int addCatalog(PlatformCatalog platformCatalog) {
  736 + ParentPlatform platform = platformMapper.getParentPlatByServerGBId(platformCatalog.getPlatformId());
  737 + if (platform == null) {
  738 + return 0;
  739 + }
  740 + if (platform.getTreeType().equals(TreeType.BUSINESS_GROUP)) {
  741 + if (platformCatalog.getPlatformId().equals(platformCatalog.getParentId())) {
  742 + // 第一层节点
  743 + platformCatalog.setBusinessGroupId(platformCatalog.getId());
  744 + }else {
  745 + // 获取顶层的
  746 + PlatformCatalog topCatalog = getTopCatalog(platformCatalog.getParentId(), platformCatalog.getPlatformId());
  747 + platformCatalog.setBusinessGroupId(topCatalog.getId());
  748 + }
  749 + }
  750 + if (platform.getTreeType().equals(TreeType.CIVIL_CODE)) {
  751 + platformCatalog.setCivilCode(platformCatalog.getId());
  752 + }
  753 +
937 754 int result = catalogMapper.add(platformCatalog);
938 755 if (result > 0) {
939 756 DeviceChannel deviceChannel = getDeviceChannelByCatalog(platformCatalog);
... ... @@ -942,6 +759,15 @@ public class VideoManagerStorageImpl implements IVideoManagerStorage {
942 759 return result;
943 760 }
944 761  
  762 + private PlatformCatalog getTopCatalog(String id, String platformId) {
  763 + PlatformCatalog catalog = catalogMapper.selectParentCatalog(id);
  764 + if (catalog.getParentId().equals(platformId)) {
  765 + return catalog;
  766 + }else {
  767 + return getTopCatalog(catalog.getParentId(), platformId);
  768 + }
  769 + }
  770 +
945 771 @Override
946 772 public PlatformCatalog getCatalog(String id) {
947 773 return catalogMapper.select(id);
... ... @@ -1012,8 +838,8 @@ public class VideoManagerStorageImpl implements IVideoManagerStorage {
1012 838 }
1013 839  
1014 840 @Override
1015   - public List<PlatformCatalog> queryCatalogInPlatform(String platformId) {
1016   - return catalogMapper.selectByPlatForm(platformId);
  841 + public List<DeviceChannel> queryCatalogInPlatform(String platformId) {
  842 + return catalogMapper.queryCatalogInPlatform(platformId);
1017 843 }
1018 844  
1019 845 @Override
... ... @@ -1056,20 +882,24 @@ public class VideoManagerStorageImpl implements IVideoManagerStorage {
1056 882 }
1057 883  
1058 884 private DeviceChannel getDeviceChannelByCatalog(PlatformCatalog catalog) {
1059   - ParentPlatform parentPlatByServerGBId = platformMapper.getParentPlatByServerGBId(catalog.getPlatformId());
  885 + ParentPlatform platform = platformMapper.getParentPlatByServerGBId(catalog.getPlatformId());
1060 886 DeviceChannel deviceChannel = new DeviceChannel();
1061 887 deviceChannel.setChannelId(catalog.getId());
1062 888 deviceChannel.setName(catalog.getName());
1063 889 deviceChannel.setLongitude(0.0);
1064 890 deviceChannel.setLatitude(0.0);
1065   - deviceChannel.setDeviceId(parentPlatByServerGBId.getDeviceGBId());
  891 + deviceChannel.setDeviceId(platform.getDeviceGBId());
1066 892 deviceChannel.setManufacture("wvp-pro");
1067 893 deviceChannel.setStatus(1);
1068 894 deviceChannel.setParental(1);
1069   - deviceChannel.setParentId(catalog.getParentId());
  895 +
1070 896 deviceChannel.setRegisterWay(1);
1071 897 // 行政区划应该是Domain的前八位
1072   - deviceChannel.setCivilCode(parentPlatByServerGBId.getAdministrativeDivision());
  898 + if (platform.getTreeType().equals(TreeType.BUSINESS_GROUP)) {
  899 + deviceChannel.setParentId(catalog.getParentId());
  900 + deviceChannel.setBusinessGroupId(catalog.getBusinessGroupId());
  901 + }
  902 +
1073 903 deviceChannel.setModel("live");
1074 904 deviceChannel.setOwner("wvp-pro");
1075 905 deviceChannel.setSecrecy("0");
... ... @@ -1131,4 +961,27 @@ public class VideoManagerStorageImpl implements IVideoManagerStorage {
1131 961  
1132 962 deviceChannelMapper.updatePosition(deviceChannel);
1133 963 }
  964 +
  965 + @Override
  966 + public void cleanContentForPlatform(String serverGBId) {
  967 +// List<PlatformCatalog> catalogList = catalogMapper.selectByPlatForm(serverGBId);
  968 +// if (catalogList.size() > 0) {
  969 +// int result = catalogMapper.delByPlatformId(serverGBId);
  970 +// if (result > 0) {
  971 +// List<DeviceChannel> deviceChannels = new ArrayList<>();
  972 +// for (PlatformCatalog catalog : catalogList) {
  973 +// deviceChannels.add(getDeviceChannelByCatalog(catalog));
  974 +// }
  975 +// eventPublisher.catalogEventPublish(serverGBId, deviceChannels, CatalogEvent.DEL);
  976 +// }
  977 +// }
  978 + catalogMapper.delByPlatformId(serverGBId);
  979 + platformChannelMapper.delByPlatformId(serverGBId);
  980 + platformGbStreamMapper.delByPlatformId(serverGBId);
  981 + }
  982 +
  983 + @Override
  984 + public List<DeviceChannel> queryChannelWithCatalog(String serverGBId) {
  985 + return deviceChannelMapper.queryChannelWithCatalog(serverGBId);
  986 + }
1134 987 }
... ...
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/device/DeviceQuery.java
... ... @@ -12,6 +12,7 @@ import com.genersoft.iot.vmp.gb28181.task.impl.MobilePositionSubscribeTask;
12 12 import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder;
13 13 import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage;
14 14 import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
  15 +import com.genersoft.iot.vmp.service.IDeviceChannelService;
15 16 import com.genersoft.iot.vmp.service.IDeviceService;
16 17 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
17 18 import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
... ... @@ -53,6 +54,9 @@ public class DeviceQuery {
53 54 private IVideoManagerStorage storager;
54 55  
55 56 @Autowired
  57 + private IDeviceChannelService deviceChannelService;
  58 +
  59 + @Autowired
56 60 private IRedisCatchStorage redisCatchStorage;
57 61  
58 62 @Autowired
... ... @@ -280,7 +284,7 @@ public class DeviceQuery {
280 284 })
281 285 @PostMapping("/channel/update/{deviceId}")
282 286 public ResponseEntity<PageInfo> updateChannel(@PathVariable String deviceId,DeviceChannel channel){
283   - storager.updateChannel(deviceId, channel);
  287 + deviceChannelService.updateChannel(deviceId, channel);
284 288 return new ResponseEntity<>(null,HttpStatus.OK);
285 289 }
286 290  
... ...
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/gbStream/GbStreamController.java
... ... @@ -44,7 +44,6 @@ public class GbStreamController {
44 44 @ApiImplicitParam(name = "platformId", value = "平台ID", required = true , dataTypeClass = String.class),
45 45 @ApiImplicitParam(name = "catalogId", value = "目录ID", required = false , dataTypeClass = String.class),
46 46 @ApiImplicitParam(name="query", value = "查询内容", required = false , dataTypeClass = String.class),
47   - @ApiImplicitParam(name="pushing", value = "是否正在推流", required = false , dataTypeClass = Boolean.class),
48 47 @ApiImplicitParam(name="mediaServerId", value = "流媒体ID", required = false , dataTypeClass = String.class),
49 48  
50 49 })
... ... @@ -55,7 +54,6 @@ public class GbStreamController {
55 54 @RequestParam(required = true)String platformId,
56 55 @RequestParam(required = false)String catalogId,
57 56 @RequestParam(required = false)String query,
58   - @RequestParam(required = false)Boolean pushing,
59 57 @RequestParam(required = false)String mediaServerId){
60 58 if (StringUtils.isEmpty(catalogId)) {
61 59 catalogId = null;
... ... @@ -69,7 +67,7 @@ public class GbStreamController {
69 67  
70 68 // catalogId 为null 查询未在平台下分配的数据
71 69 // catalogId 不为null 查询平台下这个,目录下的通道
72   - return gbStreamService.getAll(page, count, platformId, catalogId, query, pushing, mediaServerId);
  70 + return gbStreamService.getAll(page, count, platformId, catalogId, query, mediaServerId);
73 71 }
74 72  
75 73  
... ...
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/media/MediaController.java
1 1 package com.genersoft.iot.vmp.vmanager.gb28181.media;
2 2  
3 3 import com.genersoft.iot.vmp.common.StreamInfo;
  4 +import com.genersoft.iot.vmp.conf.security.SecurityUtils;
  5 +import com.genersoft.iot.vmp.conf.security.dto.LoginUser;
  6 +import com.genersoft.iot.vmp.media.zlm.dto.OnPublishHookParam;
  7 +import com.genersoft.iot.vmp.media.zlm.dto.StreamAuthorityInfo;
4 8 import com.genersoft.iot.vmp.service.IMediaServerService;
5 9 import com.genersoft.iot.vmp.service.IStreamPushService;
6 10 import com.genersoft.iot.vmp.service.IMediaService;
  11 +import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
7 12 import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
8 13 import com.genersoft.iot.vmp.vmanager.bean.WVPResult;
9 14 import io.swagger.annotations.Api;
... ... @@ -16,6 +21,8 @@ import org.springframework.beans.factory.annotation.Autowired;
16 21 import org.springframework.stereotype.Controller;
17 22 import org.springframework.web.bind.annotation.*;
18 23  
  24 +import javax.servlet.http.HttpServletRequest;
  25 +
19 26  
20 27 @Api(tags = "媒体流相关")
21 28 @Controller
... ... @@ -26,17 +33,11 @@ public class MediaController {
26 33 private final static Logger logger = LoggerFactory.getLogger(MediaController.class);
27 34  
28 35 @Autowired
29   - private IVideoManagerStorage storager;
30   -
31   - @Autowired
32   - private IStreamPushService streamPushService;
  36 + private IRedisCatchStorage redisCatchStorage;
33 37  
34 38 @Autowired
35 39 private IMediaService mediaService;
36 40  
37   - @Autowired
38   - private IMediaServerService mediaServerService;
39   -
40 41  
41 42 /**
42 43 * 根据应用名和流id获取播放地址
... ... @@ -52,13 +53,47 @@ public class MediaController {
52 53 })
53 54 @GetMapping(value = "/stream_info_by_app_and_stream")
54 55 @ResponseBody
55   - public WVPResult<StreamInfo> getStreamInfoByAppAndStream(@RequestParam String app, @RequestParam String stream, @RequestParam(required = false) String mediaServerId){
56   - StreamInfo streamInfoByAppAndStreamWithCheck = mediaService.getStreamInfoByAppAndStreamWithCheck(app, stream, mediaServerId);
  56 + public WVPResult<StreamInfo> getStreamInfoByAppAndStream(HttpServletRequest request, @RequestParam String app,
  57 + @RequestParam String stream,
  58 + @RequestParam(required = false) String mediaServerId,
  59 + @RequestParam(required = false) String callId,
  60 + @RequestParam(required = false) Boolean useSourceIpAsStreamIp){
  61 + boolean authority = false;
  62 + if (callId != null) {
  63 + // 权限校验
  64 + StreamAuthorityInfo streamAuthorityInfo = redisCatchStorage.getStreamAuthorityInfo(app, stream);
  65 + if (streamAuthorityInfo.getCallId().equals(callId)) {
  66 + authority = true;
  67 + }else {
  68 + WVPResult<StreamInfo> result = new WVPResult<>();
  69 + result.setCode(401);
  70 + result.setMsg("fail");
  71 + return result;
  72 + }
  73 + }else {
  74 + // 是否登陆用户, 登陆用户返回完整信息
  75 + LoginUser userInfo = SecurityUtils.getUserInfo();
  76 + if (userInfo!= null) {
  77 + authority = true;
  78 + }
  79 + }
  80 +
  81 + StreamInfo streamInfo;
  82 +
  83 + if (useSourceIpAsStreamIp != null && useSourceIpAsStreamIp) {
  84 + String host = request.getHeader("Host");
  85 + String localAddr = host.split(":")[0];
  86 + logger.info("使用{}作为返回流的ip", localAddr);
  87 + streamInfo = mediaService.getStreamInfoByAppAndStreamWithCheck(app, stream, mediaServerId, localAddr, authority);
  88 + }else {
  89 + streamInfo = mediaService.getStreamInfoByAppAndStreamWithCheck(app, stream, mediaServerId, authority);
  90 + }
  91 +
57 92 WVPResult<StreamInfo> result = new WVPResult<>();
58   - if (streamInfoByAppAndStreamWithCheck != null){
  93 + if (streamInfo != null){
59 94 result.setCode(0);
60 95 result.setMsg("scccess");
61   - result.setData(streamInfoByAppAndStreamWithCheck);
  96 + result.setData(streamInfo);
62 97 }else {
63 98 result.setCode(-1);
64 99 result.setMsg("fail");
... ...
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/platform/PlatformController.java
... ... @@ -9,6 +9,7 @@ import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
9 9 import com.genersoft.iot.vmp.gb28181.bean.PlatformCatalog;
10 10 import com.genersoft.iot.vmp.gb28181.bean.SubscribeHolder;
11 11 import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform;
  12 +import com.genersoft.iot.vmp.service.IPlatformChannelService;
12 13 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
13 14 import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
14 15 import com.genersoft.iot.vmp.utils.DateUtil;
... ... @@ -49,6 +50,9 @@ public class PlatformController {
49 50 private IVideoManagerStorage storager;
50 51  
51 52 @Autowired
  53 + private IPlatformChannelService platformChannelService;
  54 +
  55 + @Autowired
52 56 private IRedisCatchStorage redisCatchStorage;
53 57  
54 58 @Autowired
... ... @@ -236,6 +240,12 @@ public class PlatformController {
236 240 parentPlatform.setCharacterSet(parentPlatform.getCharacterSet().toUpperCase());
237 241 ParentPlatform parentPlatformOld = storager.queryParentPlatByServerGBId(parentPlatform.getServerGBId());
238 242 parentPlatform.setUpdateTime(DateUtil.getNow());
  243 + if (!parentPlatformOld.getTreeType().equals(parentPlatform.getTreeType())) {
  244 + // 目录结构发生变化,清空之前的关联关系
  245 + logger.info("保存平台{}时发现目录结构变化,清空关联关系", parentPlatform.getDeviceGBId());
  246 + storager.cleanContentForPlatform(parentPlatform.getServerGBId());
  247 +
  248 + }
239 249 boolean updateResult = storager.updateParentPlatform(parentPlatform);
240 250  
241 251 if (updateResult) {
... ... @@ -256,6 +266,8 @@ public class PlatformController {
256 266 }
257 267 } else if (parentPlatformOld != null && parentPlatformOld.isEnable() && !parentPlatform.isEnable()) { // 关闭启用时注销
258 268 commanderForPlatform.unregister(parentPlatformOld, null, null);
  269 + // 停止订阅相关的定时任务
  270 + subscribeHolder.removeAllSubscribe(parentPlatform.getServerGBId());
259 271 }
260 272 wvpResult.setCode(0);
261 273 wvpResult.setMsg("success");
... ... @@ -405,7 +417,7 @@ public class PlatformController {
405 417 if (logger.isDebugEnabled()) {
406 418 logger.debug("给上级平台添加国标通道API调用");
407 419 }
408   - int result = storager.updateChannelForGB(param.getPlatformId(), param.getChannelReduces(), param.getCatalogId());
  420 + int result = platformChannelService.updateChannelForGB(param.getPlatformId(), param.getChannelReduces(), param.getCatalogId());
409 421  
410 422 return new ResponseEntity<>(String.valueOf(result > 0), HttpStatus.OK);
411 423 }
... ... @@ -485,7 +497,6 @@ public class PlatformController {
485 497 PlatformCatalog platformCatalogInStore = storager.getCatalog(platformCatalog.getId());
486 498 WVPResult<List<PlatformCatalog>> result = new WVPResult<>();
487 499  
488   -
489 500 if (platformCatalogInStore != null) {
490 501 result.setCode(-1);
491 502 result.setMsg(platformCatalog.getId() + " already exists");
... ...
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/play/PlayController.java
... ... @@ -193,7 +193,7 @@ public class PlayController {
193 193 JSONObject data = jsonObject.getJSONObject("data");
194 194 if (data != null) {
195 195 result.put("key", data.getString("key"));
196   - StreamInfo streamInfoResult = mediaService.getStreamInfoByAppAndStreamWithCheck("convert", streamId, mediaInfo.getId());
  196 + StreamInfo streamInfoResult = mediaService.getStreamInfoByAppAndStreamWithCheck("convert", streamId, mediaInfo.getId(), false);
197 197 result.put("data", streamInfoResult);
198 198 }
199 199 }else {
... ...
src/main/java/com/genersoft/iot/vmp/vmanager/streamPush/StreamPushController.java
... ... @@ -3,11 +3,16 @@ package com.genersoft.iot.vmp.vmanager.streamPush;
3 3 import com.alibaba.excel.EasyExcel;
4 4 import com.alibaba.excel.ExcelReader;
5 5 import com.alibaba.excel.read.metadata.ReadSheet;
  6 +import com.genersoft.iot.vmp.common.StreamInfo;
  7 +import com.genersoft.iot.vmp.conf.security.SecurityUtils;
  8 +import com.genersoft.iot.vmp.conf.security.dto.LoginUser;
6 9 import com.genersoft.iot.vmp.gb28181.bean.GbStream;
7 10 import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder;
8 11 import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage;
  12 +import com.genersoft.iot.vmp.media.zlm.dto.StreamAuthorityInfo;
9 13 import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem;
10 14 import com.genersoft.iot.vmp.service.IMediaServerService;
  15 +import com.genersoft.iot.vmp.service.IMediaService;
11 16 import com.genersoft.iot.vmp.service.IStreamPushService;
12 17 import com.genersoft.iot.vmp.service.impl.StreamPushUploadFileHandler;
13 18 import com.genersoft.iot.vmp.vmanager.bean.BatchGBStreamParam;
... ... @@ -30,6 +35,7 @@ import org.springframework.web.bind.annotation.*;
30 35 import org.springframework.web.context.request.async.DeferredResult;
31 36 import org.springframework.web.multipart.MultipartFile;
32 37  
  38 +import javax.servlet.http.HttpServletRequest;
33 39 import java.io.IOException;
34 40 import java.io.InputStream;
35 41 import java.util.HashMap;
... ... @@ -54,6 +60,9 @@ public class StreamPushController {
54 60 @Autowired
55 61 private DeferredResultHolder resultHolder;
56 62  
  63 + @Autowired
  64 + private IMediaService mediaService;
  65 +
57 66 @ApiOperation("推流列表查询")
58 67 @ApiImplicitParams({
59 68 @ApiImplicitParam(name="page", value = "当前页", required = true, dataTypeClass = Integer.class),
... ... @@ -237,5 +246,43 @@ public class StreamPushController {
237 246 return result;
238 247 }
239 248  
  249 + /**
  250 + * 获取推流播放地址
  251 + * @param app 应用名
  252 + * @param stream 流id
  253 + * @return
  254 + */
  255 + @ApiOperation("获取推流播放地址")
  256 + @ApiImplicitParams({
  257 + @ApiImplicitParam(name = "app", value = "应用名", dataTypeClass = String.class),
  258 + @ApiImplicitParam(name = "stream", value = "流id", dataTypeClass = String.class),
  259 + @ApiImplicitParam(name = "mediaServerId", value = "媒体服务器id", dataTypeClass = String.class, required = false),
  260 + })
  261 + @GetMapping(value = "/getPlayUrl")
  262 + @ResponseBody
  263 + public WVPResult<StreamInfo> getPlayUrl(HttpServletRequest request, @RequestParam String app,
  264 + @RequestParam String stream,
  265 + @RequestParam(required = false) String mediaServerId){
  266 + boolean authority = false;
  267 + // 是否登陆用户, 登陆用户返回完整信息
  268 + LoginUser userInfo = SecurityUtils.getUserInfo();
  269 + if (userInfo!= null) {
  270 + authority = true;
  271 + }
  272 +
  273 + StreamInfo streamInfo = mediaService.getStreamInfoByAppAndStreamWithCheck(app, stream, mediaServerId, authority);
  274 +
  275 + WVPResult<StreamInfo> result = new WVPResult<>();
  276 + if (streamInfo != null){
  277 + result.setCode(0);
  278 + result.setMsg("scccess");
  279 + result.setData(streamInfo);
  280 + }else {
  281 + result.setCode(-1);
  282 + result.setMsg("fail");
  283 + }
  284 + return result;
  285 + }
  286 +
240 287  
241 288 }
... ...
src/main/java/com/genersoft/iot/vmp/vmanager/user/UserController.java
... ... @@ -8,6 +8,7 @@ import com.genersoft.iot.vmp.storager.dao.dto.Role;
8 8 import com.genersoft.iot.vmp.storager.dao.dto.User;
9 9 import com.genersoft.iot.vmp.utils.DateUtil;
10 10 import com.genersoft.iot.vmp.vmanager.bean.WVPResult;
  11 +import com.github.pagehelper.PageInfo;
11 12 import io.swagger.annotations.Api;
12 13 import io.swagger.annotations.ApiImplicitParam;
13 14 import io.swagger.annotations.ApiImplicitParams;
... ... @@ -123,7 +124,8 @@ public class UserController {
123 124 User user = new User();
124 125 user.setUsername(username);
125 126 user.setPassword(DigestUtils.md5DigestAsHex(password.getBytes()));
126   -
  127 + //新增用户的pushKey的生成规则为md5(时间戳+用户名)
  128 + user.setPushKey(DigestUtils.md5DigestAsHex((System.currentTimeMillis()+password).getBytes()));
127 129 Role role = roleService.getRoleById(roleId);
128 130  
129 131 if (role == null) {
... ... @@ -137,6 +139,7 @@ public class UserController {
137 139 user.setUpdateTime(DateUtil.getNow());
138 140 int addResult = userService.addUser(user);
139 141  
  142 +
140 143 result.setCode(addResult > 0 ? 0 : -1);
141 144 result.setMsg(addResult > 0 ? "success" : "fail");
142 145 result.setData(addResult);
... ... @@ -177,4 +180,68 @@ public class UserController {
177 180 result.setData(allUsers);
178 181 return new ResponseEntity<>(result, HttpStatus.OK);
179 182 }
  183 +
  184 + /**
  185 + * 分页查询用户
  186 + *
  187 + * @param page 当前页
  188 + * @param count 每页查询数量
  189 + * @return 分页用户列表
  190 + */
  191 + @ApiOperation("分页查询用户")
  192 + @ApiImplicitParams({
  193 + @ApiImplicitParam(name = "page", value = "当前页", required = true, dataTypeClass = Integer.class),
  194 + @ApiImplicitParam(name = "count", value = "每页查询数量", required = true, dataTypeClass = Integer.class),
  195 + })
  196 + @GetMapping("/users")
  197 + public PageInfo<User> users(int page, int count) {
  198 + return userService.getUsers(page, count);
  199 + }
  200 +
  201 + @ApiOperation("修改pushkey")
  202 + @ApiImplicitParams({
  203 + @ApiImplicitParam(name = "userId", required = true, value = "用户Id", dataTypeClass = Integer.class),
  204 + @ApiImplicitParam(name = "pushKey", required = true, value = "新的pushKey", dataTypeClass = String.class),
  205 + })
  206 + @RequestMapping("/changePushKey")
  207 + public ResponseEntity<WVPResult<String>> changePushKey(@RequestParam Integer userId,@RequestParam String pushKey) {
  208 + // 获取当前登录用户id
  209 + int currenRoleId = SecurityUtils.getUserInfo().getRole().getId();
  210 + WVPResult<String> result = new WVPResult<>();
  211 + if (currenRoleId != 1) {
  212 + // 只用角色id为0才可以删除和添加用户
  213 + result.setCode(-1);
  214 + result.setMsg("用户无权限");
  215 + return new ResponseEntity<>(result, HttpStatus.FORBIDDEN);
  216 + }
  217 + int resetPushKeyResult = userService.changePushKey(userId,pushKey);
  218 +
  219 + result.setCode(resetPushKeyResult > 0 ? 0 : -1);
  220 + result.setMsg(resetPushKeyResult > 0 ? "success" : "fail");
  221 + return new ResponseEntity<>(result, HttpStatus.OK);
  222 + }
  223 +
  224 + @ApiOperation("管理员修改普通用户密码")
  225 + @ApiImplicitParams({
  226 + @ApiImplicitParam(name = "adminId", required = true, value = "管理员id", dataTypeClass = String.class),
  227 + @ApiImplicitParam(name = "userId", required = true, value = "用户id", dataTypeClass = String.class),
  228 + @ApiImplicitParam(name = "password", required = true, value = "新密码(未md5加密的密码)", dataTypeClass = String.class),
  229 + })
  230 + @PostMapping("/changePasswordForAdmin")
  231 + public String changePasswordForAdmin(@RequestParam int userId, @RequestParam String password) {
  232 + // 获取当前登录用户id
  233 + LoginUser userInfo = SecurityUtils.getUserInfo();
  234 + if (userInfo == null) {
  235 + return "fail";
  236 + }
  237 + Role role = userInfo.getRole();
  238 + if (role != null && role.getId() == 1) {
  239 + boolean result = userService.changePassword(userId, DigestUtils.md5DigestAsHex(password.getBytes()));
  240 + if (result) {
  241 + return "success";
  242 + }
  243 + }
  244 +
  245 + return "fail";
  246 + }
180 247 }
... ...
src/main/resources/8042900_www.wvp-pro.cn.jks 0 → 100644
No preview for this file type
src/main/resources/all-application.yml
... ... @@ -185,8 +185,6 @@ user-settings:
185 185 record-sip: true
186 186 # 是否将日志存储进数据库
187 187 logInDatebase: true
188   - # 第三方匹配,用于从stream钟获取有效信息
189   - thirdPartyGBIdReg: "[\\s\\S]*"
190 188  
191 189 # 在线文档: swagger-ui(生产环境建议关闭)
192 190 swagger-ui:
... ...
web_src/src/components/Login.vue
... ... @@ -86,7 +86,7 @@ export default {
86 86 }).then(function (res) {
87 87 console.log(JSON.stringify(res));
88 88 if (res.data.code == 0 && res.data.msg == "success") {
89   - that.$cookies.set("session", {"username": that.username}) ;
  89 + that.$cookies.set("session", {"username": that.username,"roleId":res.data.data.role.id}) ;
90 90 //登录成功后
91 91 that.cancelEnterkeyDefaultAction();
92 92 that.$router.push('/');
... ...
web_src/src/components/ParentPlatformList.vue
... ... @@ -143,7 +143,7 @@ export default {
143 143 });
144 144 },
145 145 chooseChannel: function(platform) {
146   - this.$refs.chooseChannelDialog.openDialog(platform.serverGBId, platform.name, platform.catalogId, this.initData)
  146 + this.$refs.chooseChannelDialog.openDialog(platform.serverGBId, platform.name, platform.catalogId, platform.treeType, this.initData)
147 147 },
148 148 initData: function() {
149 149 this.getPlatformList();
... ...
web_src/src/components/PushVideoList.vue
... ... @@ -56,13 +56,18 @@
56 56 <el-table-column label="开始时间" min-width="200">
57 57 <template slot-scope="scope">
58 58 <el-button-group>
59   - {{ dateFormat(parseInt(scope.row.createStamp)) }}
  59 + {{ scope.row.pushTime == null? "-":scope.row.pushTime }}
60 60 </el-button-group>
61 61 </template>
62 62 </el-table-column>
63 63 <el-table-column label="正在推流" min-width="100">
64 64 <template slot-scope="scope">
65   - {{ (scope.row.status == false && scope.row.gbId == null) || scope.row.status ? '是' : '否' }}
  65 + {{scope.row.pushIng ? '是' : '否' }}
  66 + </template>
  67 + </el-table-column>
  68 + <el-table-column label="本平台推流" min-width="100">
  69 + <template slot-scope="scope">
  70 + {{scope.row.pushIng && !!!scope.row.serverId ? '是' : '否' }}
66 71 </template>
67 72 </el-table-column>
68 73  
... ... @@ -187,7 +192,7 @@ export default {
187 192 this.getListLoading = true;
188 193 this.$axios({
189 194 method: 'get',
190   - url: '/api/media/stream_info_by_app_and_stream',
  195 + url: '/api/push/getPlayUrl',
191 196 params: {
192 197 app: row.app,
193 198 stream: row.stream,
... ... @@ -242,19 +247,6 @@ export default {
242 247 console.error(error);
243 248 });
244 249 },
245   - dateFormat: function (/** timestamp=0 **/) {
246   - let ts = arguments[0] || 0;
247   - let t, y, m, d, h, i, s;
248   - t = ts ? new Date(ts) : new Date();
249   - y = t.getFullYear();
250   - m = t.getMonth() + 1;
251   - d = t.getDate();
252   - h = t.getHours();
253   - i = t.getMinutes();
254   - s = t.getSeconds();
255   - // 可根据需要在这里定义时间格式
256   - return y + '-' + (m < 10 ? '0' + m : m) + '-' + (d < 10 ? '0' + d : d) + ' ' + (h < 10 ? '0' + h : h) + ':' + (i < 10 ? '0' + i : i) + ':' + (s < 10 ? '0' + s : s);
257   - },
258 250 importChannel: function () {
259 251 this.$refs.importChannel.openDialog(() => {
260 252  
... ...
web_src/src/components/UserManager.vue 0 → 100644
  1 +<template>
  2 +
  3 + <div id="app" style="width: 100%">
  4 + <div class="page-header">
  5 +
  6 + <div class="page-title">用户列表</div>
  7 + <div class="page-header-btn">
  8 + <el-button icon="el-icon-plus" size="mini" style="margin-right: 1rem;" type="primary" @click="addUser">
  9 + 添加用户
  10 + </el-button>
  11 +
  12 + </div>
  13 + </div>
  14 + <!--用户列表-->
  15 + <el-table :data="userList" style="width: 100%;font-size: 12px;" :height="winHeight"
  16 + header-row-class-name="table-header">
  17 + <el-table-column prop="username" label="用户名" min-width="160"/>
  18 + <el-table-column prop="pushKey" label="pushkey" min-width="160"/>
  19 + <el-table-column prop="role.name" label="类型" min-width="160"/>
  20 + <el-table-column label="操作" min-width="450" fixed="right">
  21 + <template slot-scope="scope">
  22 + <el-button size="medium" icon="el-icon-edit" type="text" @click="edit(scope.row)">修改密码</el-button>
  23 + <el-divider direction="vertical"></el-divider>
  24 + <el-button size="medium" icon="el-icon-edit" type="text" @click="changePushKey(scope.row)">修改pushkey</el-button>
  25 + <el-divider direction="vertical"></el-divider>
  26 + <el-button size="medium" icon="el-icon-delete" type="text" @click="deleteUser(scope.row)"
  27 + style="color: #f56c6c">删除
  28 + </el-button>
  29 + </template>
  30 + </el-table-column>
  31 + </el-table>
  32 + <changePasswordForAdmin ref="changePasswordForAdmin"></changePasswordForAdmin>
  33 + <changePushKey ref="changePushKey"></changePushKey>
  34 + <addUser ref="addUser"></addUser>
  35 + <el-pagination
  36 + style="float: right"
  37 + @size-change="handleSizeChange"
  38 + @current-change="currentChange"
  39 + :current-page="currentPage"
  40 + :page-size="count"
  41 + :page-sizes="[15, 25, 35, 50]"
  42 + layout="total, sizes, prev, pager, next"
  43 + :total="total">
  44 + </el-pagination>
  45 + </div>
  46 +</template>
  47 +
  48 +<script>
  49 +import uiHeader from '../layout/UiHeader.vue'
  50 +import changePasswordForAdmin from './dialog/changePasswordForAdmin.vue'
  51 +import changePushKey from './dialog/changePushKey.vue'
  52 +import addUser from '../components/dialog/addUser.vue'
  53 +
  54 +export default {
  55 + name: 'userManager',
  56 + components: {
  57 + uiHeader,
  58 + changePasswordForAdmin,
  59 + changePushKey,
  60 + addUser
  61 + },
  62 + data() {
  63 + return {
  64 + userList: [], //设备列表
  65 + currentUser: {}, //当前操作设备对象
  66 +
  67 + videoComponentList: [],
  68 + updateLooper: 0, //数据刷新轮训标志
  69 + currentUserLenth: 0,
  70 + winHeight: window.innerHeight - 200,
  71 + currentPage: 1,
  72 + count: 15,
  73 + total: 0,
  74 + getUserListLoading: false
  75 + };
  76 + },
  77 + mounted() {
  78 + this.initData();
  79 + this.updateLooper = setInterval(this.initData, 10000);
  80 + },
  81 + destroyed() {
  82 + this.$destroy('videojs');
  83 + clearTimeout(this.updateLooper);
  84 + },
  85 + methods: {
  86 + initData: function () {
  87 + this.getUserList();
  88 + },
  89 + currentChange: function (val) {
  90 + this.currentPage = val;
  91 + this.getUserList();
  92 + },
  93 + handleSizeChange: function (val) {
  94 + this.count = val;
  95 + this.getUserList();
  96 + },
  97 + getUserList: function () {
  98 + let that = this;
  99 + this.getUserListLoading = true;
  100 + this.$axios({
  101 + method: 'get',
  102 + url: `/api/user/users`,
  103 + params: {
  104 + page: that.currentPage,
  105 + count: that.count
  106 + }
  107 + }).then(function (res) {
  108 + that.total = res.data.total;
  109 + that.userList = res.data.list;
  110 + that.getUserListLoading = false;
  111 + }).catch(function (error) {
  112 + that.getUserListLoading = false;
  113 + });
  114 +
  115 + },
  116 + edit: function (row) {
  117 + this.$refs.changePasswordForAdmin.openDialog(row, () => {
  118 + this.$refs.changePasswordForAdmin.close();
  119 + this.$message({
  120 + showClose: true,
  121 + message: "密码修改成功",
  122 + type: "success",
  123 + });
  124 + setTimeout(this.getUserList, 200)
  125 +
  126 + })
  127 + },
  128 + deleteUser: function (row) {
  129 + let msg = "确定删除此用户?"
  130 + if (row.online !== 0) {
  131 + msg = "<strong>确定删除此用户?</strong>"
  132 + }
  133 + this.$confirm(msg, '提示', {
  134 + dangerouslyUseHTMLString: true,
  135 + confirmButtonText: '确定',
  136 + cancelButtonText: '取消',
  137 + center: true,
  138 + type: 'warning'
  139 + }).then(() => {
  140 + this.$axios({
  141 + method: 'delete',
  142 + url: `/api/user/delete?id=${row.id}`
  143 + }).then((res) => {
  144 + this.getUserList();
  145 + }).catch((error) => {
  146 + console.error(error);
  147 + });
  148 + }).catch(() => {
  149 +
  150 + });
  151 +
  152 +
  153 + },
  154 +
  155 + changePushKey: function (row) {
  156 + this.$refs.changePushKey.openDialog(row, () => {
  157 + this.$refs.changePushKey.close();
  158 + this.$message({
  159 + showClose: true,
  160 + message: "pushKey修改成功",
  161 + type: "success",
  162 + });
  163 + setTimeout(this.getUserList, 200)
  164 +
  165 + })
  166 + },
  167 + addUser: function () {
  168 + // this.$refs.addUser.openDialog()
  169 + this.$refs.addUser.openDialog( () => {
  170 + this.$refs.addUser.close();
  171 + this.$message({
  172 + showClose: true,
  173 + message: "用户添加成功",
  174 + type: "success",
  175 + });
  176 + setTimeout(this.getUserList, 200)
  177 +
  178 + })
  179 + }
  180 + }
  181 +}
  182 +</script>
  183 +<style>
  184 +.videoList {
  185 + display: flex;
  186 + flex-wrap: wrap;
  187 + align-content: flex-start;
  188 +}
  189 +
  190 +.video-item {
  191 + position: relative;
  192 + width: 15rem;
  193 + height: 10rem;
  194 + margin-right: 1rem;
  195 + background-color: #000000;
  196 +}
  197 +
  198 +.video-item-img {
  199 + position: absolute;
  200 + top: 0;
  201 + bottom: 0;
  202 + left: 0;
  203 + right: 0;
  204 + margin: auto;
  205 + width: 100%;
  206 + height: 100%;
  207 +}
  208 +
  209 +.video-item-img:after {
  210 + content: "";
  211 + display: inline-block;
  212 + position: absolute;
  213 + z-index: 2;
  214 + top: 0;
  215 + bottom: 0;
  216 + left: 0;
  217 + right: 0;
  218 + margin: auto;
  219 + width: 3rem;
  220 + height: 3rem;
  221 + background-image: url("../assets/loading.png");
  222 + background-size: cover;
  223 + background-color: #000000;
  224 +}
  225 +
  226 +.video-item-title {
  227 + position: absolute;
  228 + bottom: 0;
  229 + color: #000000;
  230 + background-color: #ffffff;
  231 + line-height: 1.5rem;
  232 + padding: 0.3rem;
  233 + width: 14.4rem;
  234 +}
  235 +
  236 +</style>
... ...
web_src/src/components/dialog/addUser.vue 0 → 100644
  1 +<template>
  2 + <div id="addUser" v-loading="isLoging">
  3 + <el-dialog
  4 + title="添加用户"
  5 + width="40%"
  6 + top="2rem"
  7 + :close-on-click-modal="false"
  8 + :visible.sync="showDialog"
  9 + :destroy-on-close="true"
  10 + @close="close()"
  11 + >
  12 + <div id="shared" style="margin-right: 20px;">
  13 + <el-form ref="passwordForm" :rules="rules" status-icon label-width="80px">
  14 + <el-form-item label="用户名" prop="username">
  15 + <el-input v-model="username" autocomplete="off"></el-input>
  16 + </el-form-item>
  17 + <el-form-item label="用户类型" prop="roleId">
  18 + <el-select v-model="roleId" placeholder="请选择">
  19 + <el-option
  20 + v-for="item in options"
  21 + :key="item.id"
  22 + :label="item.name"
  23 + :value="item.id">
  24 + </el-option>
  25 + </el-select>
  26 + </el-form-item>
  27 + <el-form-item label="密码" prop="password">
  28 + <el-input v-model="password" autocomplete="off"></el-input>
  29 + </el-form-item>
  30 + <el-form-item label="确认密码" prop="confirmPassword">
  31 + <el-input v-model="confirmPassword" autocomplete="off"></el-input>
  32 + </el-form-item>
  33 +
  34 + <el-form-item>
  35 + <div style="float: right;">
  36 + <el-button type="primary" @click="onSubmit">保存</el-button>
  37 + <el-button @click="close">取消</el-button>
  38 + </div>
  39 + </el-form-item>
  40 + </el-form>
  41 + </div>
  42 + </el-dialog>
  43 + </div>
  44 +</template>
  45 +
  46 +<script>
  47 +
  48 +export default {
  49 + name: "addUser",
  50 + props: {},
  51 + computed: {},
  52 + created() {
  53 + this.getAllRole();
  54 + },
  55 + data() {
  56 + let validatePass1 = (rule, value, callback) => {
  57 + if (value === '') {
  58 + callback(new Error('请输入新密码'));
  59 + } else {
  60 + if (this.confirmPassword !== '') {
  61 + this.$refs.passwordForm.validateField('confirmPassword');
  62 + }
  63 + callback();
  64 + }
  65 + };
  66 + let validatePass2 = (rule, value, callback) => {
  67 + if (this.confirmPassword === '') {
  68 + callback(new Error('请再次输入密码'));
  69 + } else if (this.confirmPassword !== this.password) {
  70 + callback(new Error('两次输入密码不一致!'));
  71 + } else {
  72 + callback();
  73 + }
  74 + };
  75 + return {
  76 + value:"",
  77 + options: [],
  78 + loading: false,
  79 + username: null,
  80 + password: null,
  81 + roleId: null,
  82 + confirmPassword: null,
  83 + listChangeCallback: null,
  84 + showDialog: false,
  85 + isLoging: false,
  86 + rules: {
  87 + newPassword: [{required: true, validator: validatePass1, trigger: "blur"}, {
  88 + pattern: /^(?=.*[a-zA-Z])(?=.*\d)(?=.*[~!@#$%^&*()_+`\-={}:";'<>?,.\/]).{8,20}$/,
  89 + message: "密码长度在8-20位之间,由字母+数字+特殊字符组成",
  90 + },],
  91 + confirmPassword: [{required: true, validator: validatePass2, trigger: "blur"}],
  92 + },
  93 + };
  94 + },
  95 + methods: {
  96 + openDialog: function (callback) {
  97 + this.listChangeCallback = callback;
  98 + this.showDialog = true;
  99 + },
  100 + onSubmit: function () {
  101 + this.$axios({
  102 + method: 'post',
  103 + url: "/api/user/add",
  104 + params: {
  105 + username: this.username,
  106 + password: this.password,
  107 + roleId: this.roleId
  108 + }
  109 + }).then((res) => {
  110 + if (res.data.code === 0) {
  111 + this.$message({
  112 + showClose: true,
  113 + message: '添加成功',
  114 + type: 'success',
  115 +
  116 + });
  117 + this.showDialog = false;
  118 + this.listChangeCallback()
  119 +
  120 + } else {
  121 + this.$message({
  122 + showClose: true,
  123 + message: res.data.msg,
  124 + type: 'error'
  125 + });
  126 + }
  127 + }).catch((error) => {
  128 + console.error(error)
  129 + });
  130 + },
  131 + close: function () {
  132 + this.showDialog = false;
  133 + this.password = null;
  134 + this.confirmPassword = null;
  135 + this.username = null;
  136 + this.roleId = null;
  137 + },
  138 + getAllRole:function () {
  139 +
  140 + this.$axios({
  141 + method: 'get',
  142 + url: "/api/role/all"
  143 + }).then((res) => {
  144 + this.loading = true;
  145 + console.info(res)
  146 + res.data
  147 + console.info(res.data.code)
  148 + if (res.data.code === 0) {
  149 + console.info(res.data.data)
  150 + this.options=res.data.data
  151 +
  152 + }
  153 + }).catch((error) => {
  154 + console.error(error)
  155 + });
  156 + }
  157 + },
  158 +};
  159 +</script>
... ...
web_src/src/components/dialog/catalogEdit.vue
... ... @@ -49,11 +49,43 @@ export default {
49 49 props: ['platformId'],
50 50 created() {},
51 51 data() {
  52 + let checkId = (rule, value, callback) => {
  53 + console.log("checkId")
  54 + console.log(this.treeType)
  55 + console.log(rule)
  56 + console.log(value)
  57 + console.log(value.length)
  58 + console.log(this.level)
  59 + if (!value) {
  60 + return callback(new Error('编号不能为空'));
  61 + }
  62 + if (this.treeType === "BusinessGroup" && value.length !== 20) {
  63 + return callback(new Error('编号必须由20位数字组成'));
  64 + }
  65 + if (this.treeType === "CivilCode" && value.length <= 8 && value.length%2 !== 0) {
  66 + return callback(new Error('行政区划必须是八位以下的偶数个数字组成'));
  67 + }
  68 + if (this.treeType === "BusinessGroup") {
  69 + let catalogType = value.substring(10, 13);
  70 + console.log(catalogType)
  71 + // 216 为虚拟组织 215 为业务分组;目录第一级必须为业务分组, 业务分组下为虚拟组织,虚拟组织下可以有其他虚拟组织
  72 + if (this.level === 1 && catalogType !== "215") {
  73 + return callback(new Error('业务分组模式下第一层目录的编号10到13位必须为215'));
  74 + }
  75 + if (this.level > 1 && catalogType !== "216") {
  76 + return callback(new Error('业务分组模式下第一层以下目录的编号10到13位必须为216'));
  77 + }
  78 +
  79 + }
  80 + callback();
  81 + }
52 82 return {
53 83 submitCallback: null,
54 84 showDialog: false,
55 85 isLoging: false,
56 86 isEdit: false,
  87 + treeType: null,
  88 + level: 0,
57 89 form: {
58 90 id: null,
59 91 name: null,
... ... @@ -62,12 +94,12 @@ export default {
62 94 },
63 95 rules: {
64 96 name: [{ required: true, message: "请输入名称", trigger: "blur" }],
65   - id: [{ required: true, message: "请输入ID", trigger: "blur" }]
  97 + id: [{ trigger: "blur",validator: checkId }]
66 98 },
67 99 };
68 100 },
69 101 methods: {
70   - openDialog: function (isEdit, id, name, parentId, callback) {
  102 + openDialog: function (isEdit, id, name, parentId, treeType, level, callback) {
71 103 console.log("parentId: " + parentId)
72 104 console.log(this.form)
73 105 this.isEdit = isEdit;
... ... @@ -77,6 +109,8 @@ export default {
77 109 this.form.parentId = parentId;
78 110 this.showDialog = true;
79 111 this.submitCallback = callback;
  112 + this.treeType = treeType;
  113 + this.level = level;
80 114 },
81 115 onSubmit: function () {
82 116 console.log("onSubmit");
... ...
web_src/src/components/dialog/changePasswordForAdmin.vue 0 → 100644
  1 +<template>
  2 + <div id="changePassword" v-loading="isLoging">
  3 + <el-dialog
  4 + title="修改密码"
  5 + width="40%"
  6 + top="2rem"
  7 + :close-on-click-modal="false"
  8 + :visible.sync="showDialog"
  9 + :destroy-on-close="true"
  10 + @close="close()"
  11 + >
  12 + <div id="shared" style="margin-right: 20px;">
  13 + <el-form ref="passwordForm" :rules="rules" status-icon label-width="80px">
  14 + <el-form-item label="新密码" prop="newPassword" >
  15 + <el-input v-model="newPassword" autocomplete="off"></el-input>
  16 + </el-form-item>
  17 + <el-form-item label="确认密码" prop="confirmPassword">
  18 + <el-input v-model="confirmPassword" autocomplete="off"></el-input>
  19 + </el-form-item>
  20 +
  21 + <el-form-item>
  22 + <div style="float: right;">
  23 + <el-button type="primary" @click="onSubmit">保存</el-button>
  24 + <el-button @click="close">取消</el-button>
  25 + </div>
  26 + </el-form-item>
  27 + </el-form>
  28 + </div>
  29 + </el-dialog>
  30 + </div>
  31 +</template>
  32 +
  33 +<script>
  34 +export default {
  35 + name: "changePasswordForAdmin",
  36 + props: {},
  37 + computed: {},
  38 + created() {},
  39 + data() {
  40 + let validatePass1 = (rule, value, callback) => {
  41 + if (value === '') {
  42 + callback(new Error('请输入新密码'));
  43 + } else {
  44 + if (this.confirmPassword !== '') {
  45 + this.$refs.passwordForm.validateField('confirmPassword');
  46 + }
  47 + callback();
  48 + }
  49 + };
  50 + let validatePass2 = (rule, value, callback) => {
  51 + if (this.confirmPassword === '') {
  52 + callback(new Error('请再次输入密码'));
  53 + } else if (this.confirmPassword !== this.newPassword) {
  54 + callback(new Error('两次输入密码不一致!'));
  55 + } else {
  56 + callback();
  57 + }
  58 + };
  59 + return {
  60 + newPassword: null,
  61 + confirmPassword: null,
  62 + userId: null,
  63 + showDialog: false,
  64 + isLoging: false,
  65 + listChangeCallback: null,
  66 + form: {},
  67 + rules: {
  68 + newPassword: [{ required: true, validator: validatePass1, trigger: "blur" }, {
  69 + pattern: /^(?=.*[a-zA-Z])(?=.*\d)(?=.*[~!@#$%^&*()_+`\-={}:";'<>?,.\/]).{8,20}$/,
  70 + message: "密码长度在8-20位之间,由字母+数字+特殊字符组成",
  71 + },],
  72 + confirmPassword: [{ required: true, validator: validatePass2, trigger: "blur" }],
  73 + },
  74 + };
  75 + },
  76 + methods: {
  77 + openDialog: function (row, callback) {
  78 + console.log(row)
  79 + this.showDialog = true;
  80 + this.listChangeCallback = callback;
  81 + if (row != null) {
  82 + this.form = row;
  83 + }
  84 + },
  85 + onSubmit: function () {
  86 + this.$axios({
  87 + method: 'post',
  88 + url:"/api/user/changePasswordForAdmin",
  89 + params: {
  90 + password: this.newPassword,
  91 + userId: this.form.id,
  92 + }
  93 + }).then((res)=> {
  94 + if (res.data === "success"){
  95 + this.$message({
  96 + showClose: true,
  97 + message: '修改成功',
  98 + type: 'success'
  99 + });
  100 + this.showDialog = false;
  101 + }else {
  102 + this.$message({
  103 + showClose: true,
  104 + message: '修改密码失败,是否已登录(接口鉴权关闭无法修改密码)',
  105 + type: 'error'
  106 + });
  107 + }
  108 + }).catch((error)=> {
  109 + console.error(error)
  110 + });
  111 + },
  112 + close: function () {
  113 + this.showDialog = false;
  114 + this.newPassword = null;
  115 + this.confirmPassword = null;
  116 + this.userId=null;
  117 + this.adminId=null;
  118 + },
  119 + },
  120 +};
  121 +</script>
... ...
web_src/src/components/dialog/changePushKey.vue 0 → 100644
  1 +<template>
  2 + <div id="changepushKey" v-loading="isLoging">
  3 + <el-dialog
  4 + title="修改密码"
  5 + width="42%"
  6 + top="2rem"
  7 + :close-on-click-modal="false"
  8 + :visible.sync="showDialog"
  9 + :destroy-on-close="true"
  10 + @close="close()"
  11 + >
  12 + <div id="shared" style="margin-right: 18px;">
  13 + <el-form ref="pushKeyForm" :rules="rules" status-icon label-width="86px">
  14 + <el-form-item label="新pushKey" prop="newPushKey" >
  15 + <el-input v-model="newPushKey" autocomplete="off"></el-input>
  16 + </el-form-item>
  17 + <el-form-item>
  18 + <div style="float: right;">
  19 + <el-button type="primary" @click="onSubmit">保存</el-button>
  20 + <el-button @click="close">取消</el-button>
  21 + </div>
  22 + </el-form-item>
  23 + </el-form>
  24 + </div>
  25 + </el-dialog>
  26 + </div>
  27 +</template>
  28 +
  29 +<script>
  30 +export default {
  31 + name: "changePushKey",
  32 + props: {},
  33 + computed: {},
  34 + created() {},
  35 + data() {
  36 + let validatePass1 = (rule, value, callback) => {
  37 + if (value === '') {
  38 + callback(new Error('请输入新pushKey'));
  39 + } else {
  40 + callback();
  41 + }
  42 + };
  43 + return {
  44 + newPushKey: null,
  45 + confirmpushKey: null,
  46 + userId: null,
  47 + showDialog: false,
  48 + isLoging: false,
  49 + listChangeCallback: null,
  50 + form: {},
  51 + rules: {
  52 + newpushKey: [{ required: true, validator: validatePass1, trigger: "blur" }],
  53 + },
  54 + };
  55 + },
  56 + methods: {
  57 + openDialog: function (row, callback) {
  58 + console.log(row)
  59 + this.showDialog = true;
  60 + this.listChangeCallback = callback;
  61 + if (row != null) {
  62 + this.form = row;
  63 + }
  64 + },
  65 + onSubmit: function () {
  66 + this.$axios({
  67 + method: 'post',
  68 + url:"/api/user/changePushKey",
  69 + params: {
  70 + pushKey: this.newPushKey,
  71 + userId: this.form.id,
  72 + }
  73 + }).then((res)=> {
  74 + console.log(res.data)
  75 + if (res.data.msg === "success"){
  76 + this.$message({
  77 + showClose: true,
  78 + message: '修改成功',
  79 + type: 'success'
  80 + });
  81 + this.showDialog = false;
  82 + this.listChangeCallback();
  83 + }else {
  84 + this.$message({
  85 + showClose: true,
  86 + message: '修改密码失败,是否已登录(接口鉴权关闭无法修改密码)',
  87 + type: 'error'
  88 + });
  89 + }
  90 + }).catch((error)=> {
  91 + console.error(error)
  92 + });
  93 + },
  94 + close: function () {
  95 + this.showDialog = false;
  96 + this.newpushKey = null;
  97 + this.userId=null;
  98 + this.adminId=null;
  99 + },
  100 + },
  101 +};
  102 +</script>
... ...
web_src/src/components/dialog/chooseChannel.vue
... ... @@ -8,7 +8,7 @@
8 8 <el-tab-pane label="目录结构" name="catalog">
9 9 <el-container>
10 10 <el-main v-bind:style="{backgroundColor: '#FFF', maxHeight: winHeight + 'px'}">
11   - <chooseChannelForCatalog ref="chooseChannelForCatalog" :platformId=platformId :platformName=platformName :defaultCatalogId=defaultCatalogId :catalogIdChange="catalogIdChange" ></chooseChannelForCatalog>
  11 + <chooseChannelForCatalog ref="chooseChannelForCatalog" :platformId=platformId :platformName=platformName :defaultCatalogId=defaultCatalogId :catalogIdChange="catalogIdChange" :treeType=treeType ></chooseChannelForCatalog>
12 12 </el-main>
13 13 </el-container>
14 14 </el-tab-pane>
... ... @@ -66,18 +66,20 @@ export default {
66 66 platformName: "",
67 67 defaultCatalogId: "",
68 68 showDialog: false,
  69 + treeType: null,
69 70 chooseData: {},
70 71 winHeight: window.innerHeight - 250,
71 72  
72 73 };
73 74 },
74 75 methods: {
75   - openDialog(platformId, platformName, defaultCatalogId, closeCallback) {
  76 + openDialog(platformId, platformName, defaultCatalogId, treeType, closeCallback) {
76 77 this.platformId = platformId
77 78 this.platformName = platformName
78 79 this.defaultCatalogId = defaultCatalogId
79 80 this.showDialog = true
80 81 this.closeCallback = closeCallback
  82 + this.treeType = treeType
81 83 },
82 84 tabClick (tab, event){
83 85  
... ...
web_src/src/components/dialog/chooseChannelForCatalog.vue
... ... @@ -38,7 +38,7 @@
38 38 import catalogEdit from './catalogEdit.vue'
39 39 export default {
40 40 name: 'chooseChannelForCatalog',
41   - props: ['platformId', 'platformName', 'defaultCatalogId', 'catalogIdChange'],
  41 + props: ['platformId', 'platformName', 'defaultCatalogId', 'catalogIdChange', 'treeType'],
42 42 created() {
43 43 this.chooseId = this.defaultCatalogId;
44 44 this.defaultCatalogIdSign = this.defaultCatalogId;
... ... @@ -102,8 +102,9 @@ export default {
102 102 },
103 103 addCatalog: function (parentId, node){
104 104 let that = this;
  105 + console.log(this.treeType)
105 106 // 打开添加弹窗
106   - that.$refs.catalogEdit.openDialog(false, null, null, parentId, ()=>{
  107 + that.$refs.catalogEdit.openDialog(false, null, null, parentId, this.treeType, node.level, ()=>{
107 108 node.loaded = false
108 109 node.expand();
109 110 });
... ...
web_src/src/components/dialog/chooseChannelForStream.vue
... ... @@ -174,7 +174,6 @@ export default {
174 174 page: that.currentPage,
175 175 count: that.count,
176 176 query: that.searchSrt,
177   - pushing: that.pushing,
178 177 platformId: that.platformId,
179 178 catalogId: that.catalogId,
180 179 mediaServerId: that.mediaServerId
... ...
web_src/src/components/dialog/platformEdit.vue
... ... @@ -78,6 +78,12 @@
78 78 <el-option label="8" value="8"></el-option>
79 79 </el-select>
80 80 </el-form-item>
  81 + <el-form-item label="目录结构" prop="treeType" >
  82 + <el-select v-model="platform.treeType" style="width: 100%" >
  83 + <el-option key="WGS84" label="行政区划" value="CivilCode"></el-option>
  84 + <el-option key="GCJ02" label="业务分组" value="BusinessGroup"></el-option>
  85 + </el-select>
  86 + </el-form-item>
81 87 <el-form-item label="字符集" prop="characterSet">
82 88 <el-select
83 89 v-model="platform.characterSet"
... ... @@ -91,7 +97,6 @@
91 97 <el-form-item label="其他选项">
92 98 <el-checkbox label="启用" v-model="platform.enable" @change="checkExpires"></el-checkbox>
93 99 <el-checkbox label="云台控制" v-model="platform.ptz"></el-checkbox>
94   - <el-checkbox label="共享所有直播流" v-model="platform.shareAllLiveStream"></el-checkbox>
95 100 <el-checkbox label="拉起离线推流" v-model="platform.startOfflinePush"></el-checkbox>
96 101 </el-form-item>
97 102 <el-form-item>
... ... @@ -153,10 +158,10 @@ export default {
153 158 keepTimeout: 60,
154 159 transport: "UDP",
155 160 characterSet: "GB2312",
156   - shareAllLiveStream: false,
157 161 startOfflinePush: false,
158 162 catalogGroup: 1,
159 163 administrativeDivision: null,
  164 + treeType: "BusinessGroup",
160 165 },
161 166 rules: {
162 167 name: [{ required: true, message: "请输入平台名称", trigger: "blur" }],
... ... @@ -194,6 +199,7 @@ export default {
194 199 that.platform.devicePort = res.data.devicePort;
195 200 that.platform.username = res.data.username;
196 201 that.platform.password = res.data.password;
  202 + that.platform.treeType = "BusinessGroup";
197 203 that.platform.administrativeDivision = res.data.username.substr(0, 6);
198 204 }).catch(function (error) {
199 205 console.log(error);
... ... @@ -217,11 +223,11 @@ export default {
217 223 this.platform.keepTimeout = platform.keepTimeout;
218 224 this.platform.transport = platform.transport;
219 225 this.platform.characterSet = platform.characterSet;
220   - this.platform.shareAllLiveStream = platform.shareAllLiveStream;
221 226 this.platform.catalogId = platform.catalogId;
222 227 this.platform.startOfflinePush = platform.startOfflinePush;
223 228 this.platform.catalogGroup = platform.catalogGroup;
224 229 this.platform.administrativeDivision = platform.administrativeDivision;
  230 + this.platform.treeType = platform.treeType;
225 231 this.onSubmit_text = "保存";
226 232 this.saveUrl = "/api/platform/save";
227 233 }
... ... @@ -242,32 +248,49 @@ export default {
242 248  
243 249 },
244 250 onSubmit: function () {
  251 + if (this.onSubmit_text === "保存") {
  252 + this.$confirm("修改目录结构会导致关联目录与通道数据被清空", '提示', {
  253 + dangerouslyUseHTMLString: true,
  254 + confirmButtonText: '确定',
  255 + cancelButtonText: '取消',
  256 + center: true,
  257 + type: 'warning'
  258 + }).then(() => {
  259 + this.saveForm()
  260 + }).catch(() => {
  261 +
  262 + });
  263 + }else {
  264 + this.saveForm()
  265 + }
  266 + },
  267 + saveForm: function (){
245 268 var that = this;
246 269 that.$axios({
247 270 method: 'post',
248 271 url: this.saveUrl,
249 272 data: that.platform
250 273 }).then(function (res) {
251   - if (res.data.code === 0) {
252   - that.$message({
253   - showClose: true,
254   - message: "保存成功",
255   - type: "success",
256   - });
257   - that.showDialog = false;
258   - if (that.listChangeCallback != null) {
259   - that.listChangeCallback();
260   - }
261   - }else {
262   - that.$message({
263   - showClose: true,
264   - message: res.data.msg,
265   - type: "error",
266   - });
  274 + if (res.data.code === 0) {
  275 + that.$message({
  276 + showClose: true,
  277 + message: "保存成功",
  278 + type: "success",
  279 + });
  280 + that.showDialog = false;
  281 + if (that.listChangeCallback != null) {
  282 + that.listChangeCallback();
267 283 }
268   - }).catch(function (error) {
269   - console.log(error);
270   - });
  284 + }else {
  285 + that.$message({
  286 + showClose: true,
  287 + message: res.data.msg,
  288 + type: "error",
  289 + });
  290 + }
  291 + }).catch(function (error) {
  292 + console.log(error);
  293 + });
271 294 },
272 295 close: function () {
273 296 this.showDialog = false;
... ... @@ -293,7 +316,7 @@ export default {
293 316 keepTimeout: 60,
294 317 transport: "UDP",
295 318 characterSet: "GB2312",
296   - shareAllLiveStream: false,
  319 + treeType: "BusinessGroup",
297 320 startOfflinePush: false,
298 321 catalogGroup: 1,
299 322 }
... ...
web_src/src/layout/UiHeader.vue
... ... @@ -13,6 +13,7 @@
13 13 <el-menu-item index="/cloudRecord">云端录像</el-menu-item>
14 14 <el-menu-item index="/mediaServerManger">节点管理</el-menu-item>
15 15 <el-menu-item index="/parentPlatformList/15/1">国标级联</el-menu-item>
  16 + <el-menu-item v-if="editUser" index="/userManager">用户管理</el-menu-item>
16 17  
17 18 <!-- <el-submenu index="/setting">-->
18 19 <!-- <template slot="title">系统设置</template>-->
... ... @@ -23,12 +24,12 @@
23 24 <!-- <el-menu-item style="float: right;" @click="loginout">退出</el-menu-item>-->
24 25 <el-submenu index="" style="float: right;">
25 26 <template slot="title">欢迎,{{ this.$cookies.get("session").username }}</template>
26   - <el-menu-item @click="changePassword">修改密码</el-menu-item>
27   - <el-menu-item @click="loginout">注销</el-menu-item>
28 27 <el-menu-item @click="openDoc">在线文档</el-menu-item>
29 28 <el-menu-item >
30 29 <el-switch v-model="alarmNotify" inactive-text="报警信息推送" @change="alarmNotifyChannge"></el-switch>
31 30 </el-menu-item>
  31 + <el-menu-item @click="changePassword">修改密码</el-menu-item>
  32 + <el-menu-item @click="loginout">注销</el-menu-item>
32 33 </el-submenu>
33 34 </el-menu>
34 35 <changePasswordDialog ref="changePasswordDialog"></changePasswordDialog>
... ... @@ -47,9 +48,11 @@ export default {
47 48 alarmNotify: false,
48 49 sseSource: null,
49 50 activeIndex: this.$route.path,
  51 + editUser: this.$cookies.get("session").roleId==1
50 52 };
51 53 },
52 54 created() {
  55 + console.log(this.$cookies.get("session"))
53 56 if (this.$route.path.startsWith("/channelList")) {
54 57 this.activeIndex = "/deviceList"
55 58 }
... ...
web_src/src/router/index.js
... ... @@ -17,6 +17,7 @@ import sip from &#39;../components/setting/Sip.vue&#39;
17 17 import media from '../components/setting/Media.vue'
18 18 import live from '../components/live.vue'
19 19 import deviceTree from '../components/common/DeviceTree.vue'
  20 +import userManager from '../components/UserManager.vue'
20 21  
21 22 import wasmPlayer from '../components/common/jessibuca.vue'
22 23 import rtcPlayer from '../components/dialog/rtcPlayer.vue'
... ... @@ -103,6 +104,11 @@ export default new VueRouter({
103 104 name: 'map',
104 105 component: map,
105 106 },
  107 + {
  108 + path: '/userManager',
  109 + name: 'userManager',
  110 + component: userManager,
  111 + }
106 112 ]
107 113 },
108 114 {
... ...
web_src/static/file/推流通道导入.zip
No preview for this file type