Browse Source

为级联平台增加虚拟目录功能

pull/311/head
648540858 3 years ago
parent
commit
6e0f7fae6e
  1. 4
      README.md
  2. 539
      sql/dump-wvp-202201051515.sql
  3. 12
      sql/mysql.sql
  4. 21
      src/main/java/com/genersoft/iot/vmp/gb28181/bean/DeviceNotFoundEvent.java
  5. 13
      src/main/java/com/genersoft/iot/vmp/gb28181/bean/ParentPlatform.java
  6. 71
      src/main/java/com/genersoft/iot/vmp/gb28181/bean/PlatformCatalog.java
  7. 8
      src/main/java/com/genersoft/iot/vmp/gb28181/bean/PlatformGbStream.java
  8. 8
      src/main/java/com/genersoft/iot/vmp/gb28181/event/SipSubscribe.java
  9. 3
      src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorObserver.java
  10. 6
      src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java
  11. 14
      src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/MessageRequestProcessor.java
  12. 43
      src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/CatalogNotifyMessageHandler.java
  13. 41
      src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/query/cmd/CatalogQueryMessageHandler.java
  14. 7
      src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java
  15. 2
      src/main/java/com/genersoft/iot/vmp/service/IGbStreamService.java
  16. 4
      src/main/java/com/genersoft/iot/vmp/service/impl/GbStreamServiceImpl.java
  17. 3
      src/main/java/com/genersoft/iot/vmp/service/impl/StreamProxyServiceImpl.java
  18. 1
      src/main/java/com/genersoft/iot/vmp/service/impl/StreamPushServiceImpl.java
  19. 2
      src/main/java/com/genersoft/iot/vmp/storager/IRedisCatchStorage.java
  20. 27
      src/main/java/com/genersoft/iot/vmp/storager/IVideoManagerStorager.java
  21. 3
      src/main/java/com/genersoft/iot/vmp/storager/dao/DeviceChannelMapper.java
  22. 12
      src/main/java/com/genersoft/iot/vmp/storager/dao/GbStreamMapper.java
  23. 14
      src/main/java/com/genersoft/iot/vmp/storager/dao/ParentPlatformMapper.java
  24. 42
      src/main/java/com/genersoft/iot/vmp/storager/dao/PlatformCatalogMapper.java
  25. 21
      src/main/java/com/genersoft/iot/vmp/storager/dao/PlatformChannelMapper.java
  26. 24
      src/main/java/com/genersoft/iot/vmp/storager/dao/PlatformGbStreamMapper.java
  27. 6
      src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java
  28. 95
      src/main/java/com/genersoft/iot/vmp/storager/impl/VideoManagerStoragerImpl.java
  29. 15
      src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/device/DeviceQuery.java
  30. 2
      src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/gbStream/GbStreamController.java
  31. 10
      src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/gbStream/bean/GbStreamParam.java
  32. 201
      src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/platform/PlatformController.java
  33. 13
      src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/platform/bean/ChannelReduce.java
  34. 9
      src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/platform/bean/UpdateChannelParam.java
  35. 2
      src/main/resources/all-application.yml
  36. 2
      src/main/resources/application-dev.yml
  37. 2
      src/main/resources/application-docker.yml
  38. BIN
      src/main/resources/wvp.sqlite
  39. 11
      web_src/package-lock.json
  40. 1
      web_src/package.json
  41. 2
      web_src/src/components/ParentPlatformList.vue
  42. 101
      web_src/src/components/dialog/catalogEdit.vue
  43. 83
      web_src/src/components/dialog/chooseChannel.vue
  44. 311
      web_src/src/components/dialog/chooseChannelForCatalog.vue
  45. 55
      web_src/src/components/dialog/chooseChannelForGb.vue
  46. 11
      web_src/src/components/dialog/chooseChannelForStream.vue
  47. 1
      web_src/src/components/dialog/platformEdit.vue
  48. 2
      web_src/src/main.js
  49. 26
      web_src/static/css/iconfont.css
  50. BIN
      web_src/static/css/iconfont.woff2

4
README.md

@ -95,15 +95,13 @@ https://gitee.com/pan648540858/wvp-GB28181-pro.git
- [X] 平台状态查询 - [X] 平台状态查询
- [X] 平台信息查询 - [X] 平台信息查询
- [X] 平台远程启动 - [X] 平台远程启动
- [X] 每个级联平台可自定义的虚拟目录
- [X] 添加RTSP视频 - [X] 添加RTSP视频
- [X] 添加接口鉴权 - [X] 添加接口鉴权
- [ ] 添加ONVIF探测局域网内的设备
- [X] 添加RTMP视频 - [X] 添加RTMP视频
- [X] 云端录像(需要部署单独服务配合使用) - [X] 云端录像(需要部署单独服务配合使用)
- [X] 多流媒体节点,自动选择负载最低的节点使用。 - [X] 多流媒体节点,自动选择负载最低的节点使用。
- [X] 支持使用mysql作为数据库,默认sqlite3,开箱即用。 - [X] 支持使用mysql作为数据库,默认sqlite3,开箱即用。
- [ ] 添加系统配置
- [ ] 添加用户管理
- [X] WEB端支持播放H264与H265,音频支持G.711A/G.711U/AAC,覆盖国标常用编码格式。 - [X] WEB端支持播放H264与H265,音频支持G.711A/G.711U/AAC,覆盖国标常用编码格式。
# docker快速体验 # docker快速体验

539
sql/dump-wvp-202201051515.sql

@ -0,0 +1,539 @@
-- MySQL dump 10.13 Distrib 8.0.27, for Linux (x86_64)
--
-- Host: localhost Database: wvp
-- ------------------------------------------------------
-- Server version 8.0.27-0ubuntu0.20.04.1
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!50503 SET NAMES utf8mb4 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
--
-- Table structure for table `device`
--
DROP TABLE IF EXISTS `device`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `device` (
`deviceId` varchar(50) NOT NULL,
`name` varchar(255) DEFAULT NULL,
`manufacturer` varchar(255) DEFAULT NULL,
`model` varchar(255) DEFAULT NULL,
`firmware` varchar(255) DEFAULT NULL,
`transport` varchar(50) DEFAULT NULL,
`streamMode` varchar(50) DEFAULT NULL,
`online` varchar(50) DEFAULT NULL,
`registerTime` varchar(50) DEFAULT NULL,
`keepaliveTime` varchar(50) DEFAULT NULL,
`ip` varchar(50) NOT NULL,
`createTime` varchar(50) NOT NULL,
`updateTime` varchar(50) NOT NULL,
`port` int NOT NULL,
`expires` int NOT NULL,
`subscribeCycleForCatalog` int NOT NULL,
`hostAddress` varchar(50) NOT NULL,
`charset` varchar(50) NOT NULL,
PRIMARY KEY (`deviceId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `device`
--
LOCK TABLES `device` WRITE;
/*!40000 ALTER TABLE `device` DISABLE KEYS */;
INSERT INTO `device` VALUES ('34020000001320000005','IPC-HFW4433M-I2','Dahua','IPC-HFW4433M-I2','2.622.0000000.31.R,2017-12-14','UDP','UDP','1','2022-01-05 15:08:26','2022-01-05 15:15:26','192.168.1.100','2022-01-05 15:08:26','2022-01-05 15:15:26',5060,3600,0,'192.168.1.100:5060','gb2312'),('34020000002000000005','DH-NVR5864-I','Dahua','DH-NVR5864-I','4.001.0000000.3,2020-10-22','UDP','UDP','1','2022-01-05 14:07:36','2022-01-05 15:15:25','192.168.1.19','2022-01-05 15:08:25','2022-01-05 15:15:25',5060,3600,0,'192.168.1.19:5060','gb2312'),('44010000001110008008',NULL,'Mercury','MIPC368(P)W-4','1.0.1 Build 210304 Rel.60784n','UDP','UDP','1','2022-01-05 15:08:35','2022-01-05 15:14:35','192.168.1.17','2022-01-05 15:08:35','2022-01-05 15:14:35',5060,36000,0,'192.168.1.17:5060','gb2312');
/*!40000 ALTER TABLE `device` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `device_alarm`
--
DROP TABLE IF EXISTS `device_alarm`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `device_alarm` (
`id` int NOT NULL AUTO_INCREMENT,
`deviceId` varchar(50) NOT NULL,
`channelId` varchar(50) NOT NULL,
`alarmPriority` varchar(50) NOT NULL,
`alarmMethod` varchar(50) DEFAULT NULL,
`alarmTime` varchar(50) NOT NULL,
`alarmDescription` varchar(255) DEFAULT NULL,
`longitude` double DEFAULT NULL,
`latitude` double DEFAULT NULL,
`alarmType` varchar(50) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `device_alarm`
--
LOCK TABLES `device_alarm` WRITE;
/*!40000 ALTER TABLE `device_alarm` DISABLE KEYS */;
/*!40000 ALTER TABLE `device_alarm` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `device_channel`
--
DROP TABLE IF EXISTS `device_channel`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `device_channel` (
`channelId` varchar(50) NOT NULL,
`name` varchar(255) DEFAULT NULL,
`manufacture` varchar(50) DEFAULT NULL,
`model` varchar(50) DEFAULT NULL,
`owner` varchar(50) DEFAULT NULL,
`civilCode` varchar(50) DEFAULT NULL,
`block` varchar(50) DEFAULT NULL,
`address` varchar(50) DEFAULT NULL,
`parentId` varchar(50) DEFAULT NULL,
`safetyWay` int DEFAULT NULL,
`registerWay` int DEFAULT NULL,
`certNum` varchar(50) DEFAULT NULL,
`certifiable` int DEFAULT NULL,
`errCode` int DEFAULT NULL,
`endTime` varchar(50) DEFAULT NULL,
`secrecy` varchar(50) DEFAULT NULL,
`ipAddress` varchar(50) DEFAULT NULL,
`port` int DEFAULT NULL,
`password` varchar(255) DEFAULT NULL,
`PTZType` int DEFAULT NULL,
`status` int DEFAULT NULL,
`longitude` double DEFAULT NULL,
`latitude` double DEFAULT NULL,
`streamId` varchar(50) DEFAULT NULL,
`deviceId` varchar(50) NOT NULL,
`parental` varchar(50) DEFAULT NULL,
`hasAudio` bit(1) DEFAULT NULL,
`createTime` varchar(50) NOT NULL,
`updateTime` varchar(50) NOT NULL,
PRIMARY KEY (`channelId`,`deviceId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `device_channel`
--
LOCK TABLES `device_channel` WRITE;
/*!40000 ALTER TABLE `device_channel` DISABLE KEYS */;
INSERT INTO `device_channel` VALUES ('34020000001310000001','IPC','Dahua','IPC-HFW4433M-I2','0','340200','','axy','34020000001320000005',0,1,'',0,0,NULL,'0','',0,'',0,1,0,0,'','34020000001320000005','0',NULL,'2022-01-05 15:11:21','2022-01-05 15:11:21'),('34020000001310000001','通道1','Dahua','DH-NVR5864-I','0','340200','','axy','34020000002000000005',0,1,'',0,0,NULL,'0','192.168.1.17',37777,'',0,1,0,0,'','34020000002000000005','0',NULL,'2022-01-05 15:11:25','2022-01-05 15:11:25'),('34020000001310000065','GB_Chn_065','Dahua','DH-NVR5864-I','0','340200','','axy','34020000002000000005',0,1,'',0,0,NULL,'0','',0,'',0,1,0,0,'','34020000002000000005','0',NULL,'2022-01-05 15:11:25','2022-01-05 15:11:25'),('34020000001320000001','IPCamera 01','Mercury','MIPC368(P)W-4','Owner','CivilCode','','Address','',0,1,'',0,0,NULL,'0','',0,'',0,1,0,0,'','44010000001110008008','0',NULL,'2022-01-05 15:11:26','2022-01-05 15:11:26');
/*!40000 ALTER TABLE `device_channel` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `device_mobile_position`
--
DROP TABLE IF EXISTS `device_mobile_position`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `device_mobile_position` (
`deviceId` varchar(50) NOT NULL,
`channelId` varchar(50) NOT NULL,
`deviceName` varchar(255) DEFAULT NULL,
`time` varchar(50) NOT NULL,
`longitude` double NOT NULL,
`latitude` double NOT NULL,
`altitude` double DEFAULT NULL,
`speed` double DEFAULT NULL,
`direction` double DEFAULT NULL,
`reportSource` varchar(50) DEFAULT NULL,
`geodeticSystem` varchar(50) DEFAULT NULL,
`cnLng` varchar(50) DEFAULT NULL,
`cnLat` varchar(50) DEFAULT NULL,
PRIMARY KEY (`deviceId`,`time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `device_mobile_position`
--
LOCK TABLES `device_mobile_position` WRITE;
/*!40000 ALTER TABLE `device_mobile_position` DISABLE KEYS */;
/*!40000 ALTER TABLE `device_mobile_position` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `gb_stream`
--
DROP TABLE IF EXISTS `gb_stream`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `gb_stream` (
`app` varchar(255) NOT NULL,
`stream` varchar(255) NOT NULL,
`gbId` varchar(50) NOT NULL,
`name` varchar(255) DEFAULT NULL,
`longitude` double DEFAULT NULL,
`latitude` double DEFAULT NULL,
`streamType` varchar(50) DEFAULT NULL,
`mediaServerId` varchar(50) DEFAULT NULL,
`status` int DEFAULT NULL,
PRIMARY KEY (`app`,`stream`,`gbId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `gb_stream`
--
LOCK TABLES `gb_stream` WRITE;
/*!40000 ALTER TABLE `gb_stream` DISABLE KEYS */;
INSERT INTO `gb_stream` VALUES ('1000','10000001_52869999','77777777777777777777','shoulei1111',0,0,'push','XR1LEpKlfQtSg9Z1',1);
/*!40000 ALTER TABLE `gb_stream` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `log`
--
DROP TABLE IF EXISTS `log`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `log` (
`id` int NOT NULL AUTO_INCREMENT,
`name` varchar(50) NOT NULL,
`type` varchar(50) NOT NULL,
`uri` varchar(200) NOT NULL,
`address` varchar(50) NOT NULL,
`result` varchar(50) NOT NULL,
`timing` bigint NOT NULL,
`username` varchar(50) NOT NULL,
`createTime` varchar(50) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=21 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `log`
--
LOCK TABLES `log` WRITE;
/*!40000 ALTER TABLE `log` DISABLE KEYS */;
INSERT INTO `log` VALUES (1,'登录','GET','/api/user/login','127.0.0.1','200 OK',245,'admin','2022-01-05 15:09:06'),(2,'添加上级平台','POST','/api/platform/save','127.0.0.1','200 OK',88,'admin','2022-01-05 15:09:24'),(3,'[设备查询] 同步设备通道','POST','/api/device/query/devices/34020000001320000005/sync','127.0.0.1','200 OK',17,'admin','2022-01-05 15:11:21'),(4,'[设备查询] 同步设备通道','POST','/api/device/query/devices/34020000002000000005/sync','127.0.0.1','200 OK',4,'admin','2022-01-05 15:11:25'),(5,'[设备查询] 同步设备通道','POST','/api/device/query/devices/44010000001110008008/sync','127.0.0.1','200 OK',4,'admin','2022-01-05 15:11:26'),(6,'向上级平台添加国标通道','POST','/api/platform/update_channel_for_gb','127.0.0.1','200 OK',52,'admin','2022-01-05 15:11:32'),(7,'从上级平台移除国标通道','DELETE','/api/platform/del_channel_for_gb','127.0.0.1','200 OK',35,'admin','2022-01-05 15:11:34'),(8,'向上级平台添加国标通道','POST','/api/platform/update_channel_for_gb','127.0.0.1','200 OK',39,'admin','2022-01-05 15:11:35'),(9,'从上级平台移除国标通道','DELETE','/api/platform/del_channel_for_gb','127.0.0.1','200 OK',46,'admin','2022-01-05 15:14:00'),(10,'向上级平台添加国标通道','POST','/api/platform/update_channel_for_gb','127.0.0.1','200 OK',59,'admin','2022-01-05 15:14:01'),(11,'添加通道与国标的关联','POST','/api/gbStream/add','127.0.0.1','200 OK',12,'admin','2022-01-05 15:14:16'),(12,'添加通道与国标的关联','POST','/api/gbStream/add','127.0.0.1','200 OK',8,'admin','2022-01-05 15:14:17'),(13,'添加通道与国标的关联','POST','/api/gbStream/add','127.0.0.1','200 OK',6,'admin','2022-01-05 15:14:19'),(14,'添加通道与国标的关联','POST','/api/gbStream/add','127.0.0.1','200 OK',8,'admin','2022-01-05 15:14:19'),(15,'移除通道与国标的关联','DELETE','/api/gbStream/del','127.0.0.1','200 OK',11,'admin','2022-01-05 15:14:21'),(16,'添加通道与国标的关联','POST','/api/gbStream/add','127.0.0.1','200 OK',42,'admin','2022-01-05 15:14:24'),(17,'移除通道与国标的关联','DELETE','/api/gbStream/del','127.0.0.1','200 OK',43,'admin','2022-01-05 15:14:25'),(18,'添加通道与国标的关联','POST','/api/gbStream/add','127.0.0.1','200 OK',9,'admin','2022-01-05 15:14:27'),(19,'添加通道与国标的关联','POST','/api/gbStream/add','127.0.0.1','200 OK',9,'admin','2022-01-05 15:14:37'),(20,'添加通道与国标的关联','POST','/api/gbStream/add','127.0.0.1','200 OK',10,'admin','2022-01-05 15:14:38');
/*!40000 ALTER TABLE `log` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `media_server`
--
DROP TABLE IF EXISTS `media_server`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `media_server` (
`id` varchar(255) NOT NULL,
`ip` varchar(50) NOT NULL,
`hookIp` varchar(50) NOT NULL,
`sdpIp` varchar(50) NOT NULL,
`streamIp` varchar(50) NOT NULL,
`httpPort` int NOT NULL,
`httpSSlPort` int NOT NULL,
`rtmpPort` int NOT NULL,
`rtmpSSlPort` int NOT NULL,
`rtpProxyPort` int NOT NULL,
`rtspPort` int NOT NULL,
`rtspSSLPort` int NOT NULL,
`autoConfig` int NOT NULL,
`secret` varchar(50) NOT NULL,
`streamNoneReaderDelayMS` int NOT NULL,
`rtpEnable` int NOT NULL,
`rtpPortRange` varchar(50) NOT NULL,
`sendRtpPortRange` varchar(50) NOT NULL,
`recordAssistPort` int NOT NULL,
`defaultServer` int NOT NULL,
`createTime` varchar(50) NOT NULL,
`updateTime` varchar(50) NOT NULL,
`hookAliveInterval` int NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `media_server_i` (`ip`,`httpPort`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `media_server`
--
LOCK TABLES `media_server` WRITE;
/*!40000 ALTER TABLE `media_server` DISABLE KEYS */;
INSERT INTO `media_server` VALUES ('XR1LEpKlfQtSg9Z1','192.168.1.3','127.0.0.1','192.168.1.3','192.168.1.3',6080,0,10935,0,10000,10554,0,1,'035c73f7-bb6b-4889-a715-d9eb2d1925cc',100000,1,'30000,30500','30000,30500',18081,1,'2022-01-05 15:08:27','2022-01-05 15:08:27',10);
/*!40000 ALTER TABLE `media_server` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `parent_platform`
--
DROP TABLE IF EXISTS `parent_platform`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `parent_platform` (
`id` int NOT NULL AUTO_INCREMENT,
`enable` int DEFAULT NULL,
`name` varchar(255) DEFAULT NULL,
`serverGBId` varchar(50) NOT NULL,
`serverGBDomain` varchar(50) DEFAULT NULL,
`serverIP` varchar(50) DEFAULT NULL,
`serverPort` int DEFAULT NULL,
`deviceGBId` varchar(50) NOT NULL,
`deviceIp` varchar(50) DEFAULT NULL,
`devicePort` varchar(50) DEFAULT NULL,
`username` varchar(255) DEFAULT NULL,
`password` varchar(50) DEFAULT NULL,
`expires` varchar(50) DEFAULT NULL,
`keepTimeout` varchar(50) DEFAULT NULL,
`transport` varchar(50) DEFAULT NULL,
`characterSet` varchar(50) DEFAULT NULL,
`catalogId` varchar(50) NOT NULL,
`ptz` int DEFAULT NULL,
`rtcp` int DEFAULT NULL,
`status` bit(1) DEFAULT NULL,
`shareAllLiveStream` int DEFAULT NULL,
PRIMARY KEY (`id`,`serverGBId`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `parent_platform`
--
LOCK TABLES `parent_platform` WRITE;
/*!40000 ALTER TABLE `parent_platform` DISABLE KEYS */;
INSERT INTO `parent_platform` VALUES (1,1,'1112','1111111111111','1111111111','11.11.11.11',111111,'34020000002110000015','192.168.1.3','5060','34020000002110000015','12345678','300','60','UDP','GB2312','1111111111111',1,0,_binary '\0',1);
/*!40000 ALTER TABLE `parent_platform` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `platform_catalog`
--
DROP TABLE IF EXISTS `platform_catalog`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `platform_catalog` (
`id` varchar(50) NOT NULL,
`platformId` varchar(50) NOT NULL,
`name` varchar(255) NOT NULL,
`parentId` varchar(50) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `platform_catalog`
--
LOCK TABLES `platform_catalog` WRITE;
/*!40000 ALTER TABLE `platform_catalog` DISABLE KEYS */;
INSERT INTO `platform_catalog` VALUES ('1111111111','1111111111111','11122','1111111111111');
/*!40000 ALTER TABLE `platform_catalog` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `platform_gb_channel`
--
DROP TABLE IF EXISTS `platform_gb_channel`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `platform_gb_channel` (
`channelId` varchar(50) NOT NULL,
`deviceId` varchar(50) NOT NULL,
`platformId` varchar(50) NOT NULL,
`deviceAndChannelId` varchar(50) NOT NULL,
`catalogId` varchar(50) NOT NULL,
PRIMARY KEY (`deviceAndChannelId`,`platformId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `platform_gb_channel`
--
LOCK TABLES `platform_gb_channel` WRITE;
/*!40000 ALTER TABLE `platform_gb_channel` DISABLE KEYS */;
INSERT INTO `platform_gb_channel` VALUES ('34020000001310000001','34020000001320000005','1111111111111','34020000001320000005_34020000001310000001','1111111111'),('34020000001310000001','34020000002000000005','1111111111111','34020000002000000005_34020000001310000001','1111111111'),('34020000001310000065','34020000002000000005','1111111111111','34020000002000000005_34020000001310000065','1111111111'),('34020000001320000001','44010000001110008008','1111111111111','44010000001110008008_34020000001320000001','1111111111');
/*!40000 ALTER TABLE `platform_gb_channel` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `platform_gb_stream`
--
DROP TABLE IF EXISTS `platform_gb_stream`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `platform_gb_stream` (
`platformId` varchar(50) NOT NULL,
`app` varchar(255) NOT NULL,
`stream` varchar(255) NOT NULL,
`catalogId` varchar(50) NOT NULL,
PRIMARY KEY (`platformId`,`app`,`stream`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `platform_gb_stream`
--
LOCK TABLES `platform_gb_stream` WRITE;
/*!40000 ALTER TABLE `platform_gb_stream` DISABLE KEYS */;
INSERT INTO `platform_gb_stream` VALUES ('1111111111111','1000','10000001_52869999','1111111111');
/*!40000 ALTER TABLE `platform_gb_stream` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `role`
--
DROP TABLE IF EXISTS `role`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `role` (
`id` int NOT NULL AUTO_INCREMENT,
`name` text NOT NULL,
`authority` text NOT NULL,
`createTime` varchar(50) NOT NULL,
`updateTime` varchar(50) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `role`
--
LOCK TABLES `role` WRITE;
/*!40000 ALTER TABLE `role` DISABLE KEYS */;
INSERT INTO `role` VALUES (1,'admin','0','2021-04-13 14:14:57','2021-04-13 14:14:57');
/*!40000 ALTER TABLE `role` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `stream_proxy`
--
DROP TABLE IF EXISTS `stream_proxy`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `stream_proxy` (
`type` varchar(50) NOT NULL,
`app` varchar(255) NOT NULL,
`stream` varchar(255) NOT NULL,
`url` varchar(255) DEFAULT NULL,
`src_url` varchar(255) DEFAULT NULL,
`dst_url` varchar(255) DEFAULT NULL,
`timeout_ms` int DEFAULT NULL,
`ffmpeg_cmd_key` varchar(255) DEFAULT NULL,
`rtp_type` varchar(50) DEFAULT NULL,
`mediaServerId` varchar(50) DEFAULT NULL,
`enable_hls` bit(1) DEFAULT NULL,
`enable_mp4` bit(1) DEFAULT NULL,
`enable` bit(1) NOT NULL,
`enable_remove_none_reader` bit(1) NOT NULL,
`createTime` varchar(50) NOT NULL,
PRIMARY KEY (`app`,`stream`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `stream_proxy`
--
LOCK TABLES `stream_proxy` WRITE;
/*!40000 ALTER TABLE `stream_proxy` DISABLE KEYS */;
/*!40000 ALTER TABLE `stream_proxy` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `stream_push`
--
DROP TABLE IF EXISTS `stream_push`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `stream_push` (
`app` varchar(255) NOT NULL,
`stream` varchar(255) NOT NULL,
`totalReaderCount` varchar(50) DEFAULT NULL,
`originType` int DEFAULT NULL,
`originTypeStr` varchar(50) DEFAULT NULL,
`createStamp` int DEFAULT NULL,
`aliveSecond` int DEFAULT NULL,
`mediaServerId` varchar(50) DEFAULT NULL,
PRIMARY KEY (`app`,`stream`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `stream_push`
--
LOCK TABLES `stream_push` WRITE;
/*!40000 ALTER TABLE `stream_push` DISABLE KEYS */;
INSERT INTO `stream_push` VALUES ('1000','10000001_52869999','0',2,'rtsp_push',1641366850,0,'XR1LEpKlfQtSg9Z1');
/*!40000 ALTER TABLE `stream_push` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `user`
--
DROP TABLE IF EXISTS `user`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `user` (
`id` int NOT NULL AUTO_INCREMENT,
`username` varchar(255) NOT NULL,
`password` varchar(255) NOT NULL,
`roleId` int NOT NULL,
`createTime` varchar(50) NOT NULL,
`updateTime` varchar(50) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `user_username_uindex` (`username`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `user`
--
LOCK TABLES `user` WRITE;
/*!40000 ALTER TABLE `user` DISABLE KEYS */;
INSERT INTO `user` VALUES (1,'admin','21232f297a57a5a743894a0e4a801fc3',1,'2021-04-13 14:14:57','2021-04-13 14:14:57');
/*!40000 ALTER TABLE `user` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Dumping routines for database 'wvp'
--
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-- Dump completed on 2022-01-05 15:15:35

12
sql/mysql.sql

@ -171,6 +171,7 @@ create table parent_platform
keepTimeout varchar(50) null, keepTimeout varchar(50) null,
transport varchar(50) null, transport varchar(50) null,
characterSet varchar(50) null, characterSet varchar(50) null,
catalogId varchar(50) not null,
ptz int null, ptz int null,
rtcp int null, rtcp int null,
status bit null, status bit null,
@ -178,12 +179,22 @@ create table parent_platform
primary key (id, serverGBId) primary key (id, serverGBId)
); );
create table platform_catalog
(
id varchar(50) primary key,
platformId varchar(50) not null,
name varchar(255) not null,
parentId varchar(50)
);
create table platform_gb_channel create table platform_gb_channel
( (
channelId varchar(50) not null, channelId varchar(50) not null,
deviceId varchar(50) not null, deviceId varchar(50) not null,
platformId varchar(50) not null, platformId varchar(50) not null,
deviceAndChannelId varchar(50) not null, deviceAndChannelId varchar(50) not null,
catalogId varchar(50) not null,
primary key (deviceAndChannelId, platformId) primary key (deviceAndChannelId, platformId)
); );
@ -192,6 +203,7 @@ create table platform_gb_stream
platformId varchar(50) not null, platformId varchar(50) not null,
app varchar(255) not null, app varchar(255) not null,
stream varchar(255) not null, stream varchar(255) not null,
catalogId varchar(50) not null,
primary key (platformId, app, stream) primary key (platformId, app, stream)
); );

21
src/main/java/com/genersoft/iot/vmp/gb28181/bean/DeviceNotFoundEvent.java

@ -0,0 +1,21 @@
package com.genersoft.iot.vmp.gb28181.bean;
import javax.sip.Dialog;
import java.util.EventObject;
public class DeviceNotFoundEvent extends EventObject {
/**
* Constructs a prototypical Event.
*
* @param dialog
* @throws IllegalArgumentException if source is null.
*/
public DeviceNotFoundEvent(Dialog dialog) {
super(dialog);
}
public Dialog getDialog() {
return (Dialog)super.getSource();
}
}

13
src/main/java/com/genersoft/iot/vmp/gb28181/bean/ParentPlatform.java

@ -109,6 +109,11 @@ public class ParentPlatform {
*/ */
private boolean shareAllLiveStream; private boolean shareAllLiveStream;
/**
* 默认目录Id,自动添加的通道多放在这个目录下
*/
private String catalogId;
public Integer getId() { public Integer getId() {
return id; return id;
} }
@ -277,4 +282,12 @@ public class ParentPlatform {
public void setShareAllLiveStream(boolean shareAllLiveStream) { public void setShareAllLiveStream(boolean shareAllLiveStream) {
this.shareAllLiveStream = shareAllLiveStream; this.shareAllLiveStream = shareAllLiveStream;
} }
public String getCatalogId() {
return catalogId;
}
public void setCatalogId(String catalogId) {
this.catalogId = catalogId;
}
} }

71
src/main/java/com/genersoft/iot/vmp/gb28181/bean/PlatformCatalog.java

@ -0,0 +1,71 @@
package com.genersoft.iot.vmp.gb28181.bean;
public class PlatformCatalog {
private String id;
private String name;
private String platformId;
private String parentId;
private int childrenCount; // 子节点数
private int type; // 0 目录, 1 国标通道, 2 直播流
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPlatformId() {
return platformId;
}
public void setPlatformId(String platformId) {
this.platformId = platformId;
}
public String getParentId() {
return parentId;
}
public void setParentId(String parentId) {
this.parentId = parentId;
}
public int getChildrenCount() {
return childrenCount;
}
public void setChildrenCount(int childrenCount) {
this.childrenCount = childrenCount;
}
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
public void setTypeForCatalog() {
this.type = 0;
}
public void setTypeForGb() {
this.type = 1;
}
public void setTypeForStream() {
this.type = 2;
}
}

8
src/main/java/com/genersoft/iot/vmp/gb28181/bean/PlatformGbStream.java

@ -4,6 +4,7 @@ public class PlatformGbStream {
private String app; private String app;
private String stream; private String stream;
private String platformId; private String platformId;
private String catalogId;
public String getApp() { public String getApp() {
return app; return app;
@ -29,4 +30,11 @@ public class PlatformGbStream {
this.platformId = platformId; this.platformId = platformId;
} }
public String getCatalogId() {
return catalogId;
}
public void setCatalogId(String catalogId) {
this.catalogId = catalogId;
}
} }

8
src/main/java/com/genersoft/iot/vmp/gb28181/event/SipSubscribe.java

@ -1,5 +1,6 @@
package com.genersoft.iot.vmp.gb28181.event; package com.genersoft.iot.vmp.gb28181.event;
import com.genersoft.iot.vmp.gb28181.bean.DeviceNotFoundEvent;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Scheduled; import org.springframework.scheduling.annotation.Scheduled;
@ -91,6 +92,13 @@ public class SipSubscribe {
this.statusCode = -1024; this.statusCode = -1024;
this.callId = dialogTerminatedEvent.getDialog().getCallId().getCallId(); this.callId = dialogTerminatedEvent.getDialog().getCallId().getCallId();
this.dialog = dialogTerminatedEvent.getDialog(); this.dialog = dialogTerminatedEvent.getDialog();
}else if (event instanceof DeviceNotFoundEvent) {
DeviceNotFoundEvent deviceNotFoundEvent = (DeviceNotFoundEvent)event;
this.type = "deviceNotFoundEvent";
this.msg = "设备未找到";
this.statusCode = -1024;
this.callId = deviceNotFoundEvent.getDialog().getCallId().getCallId();
this.dialog = deviceNotFoundEvent.getDialog();
} }
} }
} }

3
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorObserver.java

@ -94,7 +94,6 @@ public class SIPProcessorObserver implements ISIPProcessorObserver {
logger.debug(responseEvent.getResponse().toString()); logger.debug(responseEvent.getResponse().toString());
int status = response.getStatusCode(); int status = response.getStatusCode();
if (((status >= 200) && (status < 300)) || status == 401) { // Success! if (((status >= 200) && (status < 300)) || status == 401) { // Success!
// ISIPResponseProcessor processor = processorFactory.createResponseProcessor(evt);
CSeqHeader cseqHeader = (CSeqHeader) responseEvent.getResponse().getHeader(CSeqHeader.NAME); CSeqHeader cseqHeader = (CSeqHeader) responseEvent.getResponse().getHeader(CSeqHeader.NAME);
String method = cseqHeader.getMethod(); String method = cseqHeader.getMethod();
ISIPResponseProcessor sipRequestProcessor = responseProcessorMap.get(method); ISIPResponseProcessor sipRequestProcessor = responseProcessorMap.get(method);
@ -108,6 +107,7 @@ public class SIPProcessorObserver implements ISIPProcessorObserver {
if (subscribe != null) { if (subscribe != null) {
SipSubscribe.EventResult eventResult = new SipSubscribe.EventResult(responseEvent); SipSubscribe.EventResult eventResult = new SipSubscribe.EventResult(responseEvent);
subscribe.response(eventResult); subscribe.response(eventResult);
sipSubscribe.removeOkSubscribe(callIdHeader.getCallId());
} }
} }
} }
@ -122,6 +122,7 @@ public class SIPProcessorObserver implements ISIPProcessorObserver {
if (subscribe != null) { if (subscribe != null) {
SipSubscribe.EventResult eventResult = new SipSubscribe.EventResult(responseEvent); SipSubscribe.EventResult eventResult = new SipSubscribe.EventResult(responseEvent);
subscribe.response(eventResult); subscribe.response(eventResult);
sipSubscribe.removeErrorSubscribe(callIdHeader.getCallId());
} }
} }
} }

6
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java

@ -107,6 +107,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
// 查询平台下是否有该通道 // 查询平台下是否有该通道
DeviceChannel channel = storager.queryChannelInParentPlatform(requesterId, channelId); DeviceChannel channel = storager.queryChannelInParentPlatform(requesterId, channelId);
List<GbStream> gbStreams = storager.queryStreamInParentPlatform(requesterId, channelId); List<GbStream> gbStreams = storager.queryStreamInParentPlatform(requesterId, channelId);
PlatformCatalog catalog = storager.getCatalog(channelId);
GbStream gbStream = gbStreams.size() > 0? gbStreams.get(0):null; GbStream gbStream = gbStreams.size() > 0? gbStreams.get(0):null;
MediaServerItem mediaServerItem = null; MediaServerItem mediaServerItem = null;
// 不是通道可能是直播流 // 不是通道可能是直播流
@ -132,7 +133,10 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
return; return;
} }
responseAck(evt, Response.CALL_IS_BEING_FORWARDED); // 通道存在,发181,呼叫转接中 responseAck(evt, Response.CALL_IS_BEING_FORWARDED); // 通道存在,发181,呼叫转接中
}else { }else if (catalog != null) {
responseAck(evt, Response.BAD_REQUEST, "catalog channel can not play"); // 目录不支持点播
return;
} else {
logger.info("通道不存在,返回404"); logger.info("通道不存在,返回404");
responseAck(evt, Response.NOT_FOUND); // 通道不存在,发404,资源不存在 responseAck(evt, Response.NOT_FOUND); // 通道不存在,发404,资源不存在
return; return;

14
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/MessageRequestProcessor.java

@ -1,7 +1,9 @@
package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message; package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message;
import com.genersoft.iot.vmp.gb28181.bean.Device; import com.genersoft.iot.vmp.gb28181.bean.Device;
import com.genersoft.iot.vmp.gb28181.bean.DeviceNotFoundEvent;
import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
import com.genersoft.iot.vmp.gb28181.event.SipSubscribe;
import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver; import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver;
import com.genersoft.iot.vmp.gb28181.transmit.event.request.ISIPRequestProcessor; import com.genersoft.iot.vmp.gb28181.transmit.event.request.ISIPRequestProcessor;
import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent; import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent;
@ -19,6 +21,7 @@ import org.springframework.stereotype.Component;
import javax.sip.InvalidArgumentException; import javax.sip.InvalidArgumentException;
import javax.sip.RequestEvent; import javax.sip.RequestEvent;
import javax.sip.SipException; import javax.sip.SipException;
import javax.sip.header.CallIdHeader;
import javax.sip.message.Response; import javax.sip.message.Response;
import java.text.ParseException; import java.text.ParseException;
import java.util.Map; import java.util.Map;
@ -39,6 +42,9 @@ public class MessageRequestProcessor extends SIPRequestProcessorParent implement
@Autowired @Autowired
private IVideoManagerStorager storage; private IVideoManagerStorager storage;
@Autowired
private SipSubscribe sipSubscribe;
@Autowired @Autowired
private IRedisCatchStorage redisCatchStorage; private IRedisCatchStorage redisCatchStorage;
@ -56,6 +62,7 @@ public class MessageRequestProcessor extends SIPRequestProcessorParent implement
public void process(RequestEvent evt) { public void process(RequestEvent evt) {
logger.debug("接收到消息:" + evt.getRequest()); logger.debug("接收到消息:" + evt.getRequest());
String deviceId = SipUtils.getUserIdFromFromHeader(evt.getRequest()); String deviceId = SipUtils.getUserIdFromFromHeader(evt.getRequest());
CallIdHeader callIdHeader = (CallIdHeader)evt.getRequest().getHeader(CallIdHeader.NAME);
// 查询设备是否存在 // 查询设备是否存在
Device device = redisCatchStorage.getDevice(deviceId); Device device = redisCatchStorage.getDevice(deviceId);
// 查询上级平台是否存在 // 查询上级平台是否存在
@ -63,7 +70,12 @@ public class MessageRequestProcessor extends SIPRequestProcessorParent implement
try { try {
if (device == null && parentPlatform == null) { if (device == null && parentPlatform == null) {
// 不存在则回复404 // 不存在则回复404
responseAck(evt, Response.NOT_FOUND, "device id not found"); responseAck(evt, Response.NOT_FOUND, "device "+ deviceId +" not found");
logger.warn("[设备未找到 ]: {}", deviceId);
if (sipSubscribe.getErrorSubscribe(callIdHeader.getCallId()) != null){
SipSubscribe.EventResult eventResult = new SipSubscribe.EventResult(new DeviceNotFoundEvent(evt.getDialog()));
sipSubscribe.getErrorSubscribe(callIdHeader.getCallId()).response(eventResult);
};
}else { }else {
Element rootElement = getRootElement(evt); Element rootElement = getRootElement(evt);
String name = rootElement.getName(); String name = rootElement.getName();

43
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/CatalogNotifyMessageHandler.java

@ -1,10 +1,7 @@
package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.notify.cmd; package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.notify.cmd;
import com.genersoft.iot.vmp.conf.SipConfig; import com.genersoft.iot.vmp.conf.SipConfig;
import com.genersoft.iot.vmp.gb28181.bean.Device; import com.genersoft.iot.vmp.gb28181.bean.*;
import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
import com.genersoft.iot.vmp.gb28181.bean.GbStream;
import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
import com.genersoft.iot.vmp.gb28181.event.EventPublisher; import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder; import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder;
import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform; import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform;
@ -71,11 +68,41 @@ public class CatalogNotifyMessageHandler extends SIPRequestProcessorParent imple
// 查询关联的直播通道 // 查询关联的直播通道
List<GbStream> gbStreams = storager.queryGbStreamListInPlatform(parentPlatform.getServerGBId()); List<GbStream> gbStreams = storager.queryGbStreamListInPlatform(parentPlatform.getServerGBId());
int size = channelReduces.size() + gbStreams.size(); int size = channelReduces.size() + gbStreams.size();
// 回复目录信息
List<PlatformCatalog> catalogs = storager.queryCatalogInPlatform(parentPlatform.getServerGBId());
if (catalogs.size() > 0) {
for (PlatformCatalog catalog : catalogs) {
DeviceChannel deviceChannel = new DeviceChannel();
deviceChannel.setChannelId(catalog.getId());
deviceChannel.setName(catalog.getName());
deviceChannel.setLongitude(0.0);
deviceChannel.setLatitude(0.0);
deviceChannel.setDeviceId(parentPlatform.getDeviceGBId());
deviceChannel.setManufacture("wvp-pro");
deviceChannel.setStatus(1);
deviceChannel.setParental(1);
deviceChannel.setParentId(catalog.getParentId());
deviceChannel.setRegisterWay(1);
deviceChannel.setCivilCode(config.getDomain());
deviceChannel.setModel("live");
deviceChannel.setOwner("wvp-pro");
deviceChannel.setSecrecy("0");
cmderFroPlatform.catalogQuery(deviceChannel, parentPlatform, sn, fromHeader.getTag(), size);
// 防止发送过快
Thread.sleep(10);
}
}
// 回复级联的通道 // 回复级联的通道
if (channelReduces.size() > 0) { if (channelReduces.size() > 0) {
for (ChannelReduce channelReduce : channelReduces) { for (ChannelReduce channelReduce : channelReduces) {
DeviceChannel deviceChannel = storager.queryChannel(channelReduce.getDeviceId(), channelReduce.getChannelId()); DeviceChannel deviceChannel = storager.queryChannel(channelReduce.getDeviceId(), channelReduce.getChannelId());
// TODO 目前暂时认为这里只用通道没有目录
deviceChannel.setParental(0);
deviceChannel.setParentId(channelReduce.getCatalogId());
cmderFroPlatform.catalogQuery(deviceChannel, parentPlatform, sn, fromHeader.getTag(), size); cmderFroPlatform.catalogQuery(deviceChannel, parentPlatform, sn, fromHeader.getTag(), size);
// 防止发送过快
Thread.sleep(10);
} }
} }
// 回复直播的通道 // 回复直播的通道
@ -89,16 +116,16 @@ public class CatalogNotifyMessageHandler extends SIPRequestProcessorParent imple
deviceChannel.setDeviceId(parentPlatform.getDeviceGBId()); deviceChannel.setDeviceId(parentPlatform.getDeviceGBId());
deviceChannel.setManufacture("wvp-pro"); deviceChannel.setManufacture("wvp-pro");
deviceChannel.setStatus(gbStream.isStatus()?1:0); deviceChannel.setStatus(gbStream.isStatus()?1:0);
// deviceChannel.setParentId(parentPlatform.getDeviceGBId()); deviceChannel.setParentId(gbStream.getCatalogId());
deviceChannel.setRegisterWay(1); deviceChannel.setRegisterWay(1);
deviceChannel.setCivilCode(config.getDomain()); deviceChannel.setCivilCode(config.getDomain());
deviceChannel.setModel("live"); deviceChannel.setModel("live");
deviceChannel.setOwner("wvp-pro"); deviceChannel.setOwner("wvp-pro");
deviceChannel.setParental(0); deviceChannel.setParental(0);
deviceChannel.setSecrecy("0"); deviceChannel.setSecrecy("0");
deviceChannel.setSecrecy("0");
cmderFroPlatform.catalogQuery(deviceChannel, parentPlatform, sn, fromHeader.getTag(), size); cmderFroPlatform.catalogQuery(deviceChannel, parentPlatform, sn, fromHeader.getTag(), size);
// 防止发送过快
Thread.sleep(10);
} }
} }
if (size == 0) { if (size == 0) {
@ -111,6 +138,8 @@ public class CatalogNotifyMessageHandler extends SIPRequestProcessorParent imple
e.printStackTrace(); e.printStackTrace();
} catch (ParseException e) { } catch (ParseException e) {
e.printStackTrace(); e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
} }
} }

41
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/query/cmd/CatalogQueryMessageHandler.java

@ -1,10 +1,7 @@
package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.query.cmd; package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.query.cmd;
import com.genersoft.iot.vmp.conf.SipConfig; import com.genersoft.iot.vmp.conf.SipConfig;
import com.genersoft.iot.vmp.gb28181.bean.Device; import com.genersoft.iot.vmp.gb28181.bean.*;
import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
import com.genersoft.iot.vmp.gb28181.bean.GbStream;
import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
import com.genersoft.iot.vmp.gb28181.event.EventPublisher; import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder; import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder;
import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform; import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform;
@ -73,12 +70,41 @@ public class CatalogQueryMessageHandler extends SIPRequestProcessorParent implem
List<ChannelReduce> channelReduces = storager.queryChannelListInParentPlatform(parentPlatform.getServerGBId()); List<ChannelReduce> channelReduces = storager.queryChannelListInParentPlatform(parentPlatform.getServerGBId());
// 查询关联的直播通道 // 查询关联的直播通道
List<GbStream> gbStreams = storager.queryGbStreamListInPlatform(parentPlatform.getServerGBId()); List<GbStream> gbStreams = storager.queryGbStreamListInPlatform(parentPlatform.getServerGBId());
int size = channelReduces.size() + gbStreams.size(); // 回复目录信息
List<PlatformCatalog> catalogs = storager.queryCatalogInPlatform(parentPlatform.getServerGBId());
int size = catalogs.size() + channelReduces.size() + gbStreams.size();
if (catalogs.size() > 0) {
for (PlatformCatalog catalog : catalogs) {
DeviceChannel deviceChannel = new DeviceChannel();
deviceChannel.setChannelId(catalog.getId());
deviceChannel.setName(catalog.getName());
deviceChannel.setLongitude(0.0);
deviceChannel.setLatitude(0.0);
deviceChannel.setDeviceId(parentPlatform.getDeviceGBId());
deviceChannel.setManufacture("wvp-pro");
deviceChannel.setStatus(1);
deviceChannel.setParental(1);
deviceChannel.setParentId(catalog.getParentId());
deviceChannel.setRegisterWay(1);
deviceChannel.setCivilCode(config.getDomain());
deviceChannel.setModel("live");
deviceChannel.setOwner("wvp-pro");
deviceChannel.setSecrecy("0");
cmderFroPlatform.catalogQuery(deviceChannel, parentPlatform, sn, fromHeader.getTag(), size);
// 防止发送过快
Thread.sleep(10);
}
}
// 回复级联的通道 // 回复级联的通道
if (channelReduces.size() > 0) { if (channelReduces.size() > 0) {
for (ChannelReduce channelReduce : channelReduces) { for (ChannelReduce channelReduce : channelReduces) {
DeviceChannel deviceChannel = storager.queryChannel(channelReduce.getDeviceId(), channelReduce.getChannelId()); DeviceChannel deviceChannel = storager.queryChannel(channelReduce.getDeviceId(), channelReduce.getChannelId());
// TODO 目前暂时认为这里只用通道没有目录
deviceChannel.setParental(0);
deviceChannel.setParentId(channelReduce.getCatalogId());
cmderFroPlatform.catalogQuery(deviceChannel, parentPlatform, sn, fromHeader.getTag(), size); cmderFroPlatform.catalogQuery(deviceChannel, parentPlatform, sn, fromHeader.getTag(), size);
// 防止发送过快
Thread.sleep(10);
} }
} }
// 回复直播的通道 // 回复直播的通道
@ -92,14 +118,13 @@ public class CatalogQueryMessageHandler extends SIPRequestProcessorParent implem
deviceChannel.setDeviceId(parentPlatform.getDeviceGBId()); deviceChannel.setDeviceId(parentPlatform.getDeviceGBId());
deviceChannel.setManufacture("wvp-pro"); deviceChannel.setManufacture("wvp-pro");
deviceChannel.setStatus(gbStream.isStatus()?1:0); deviceChannel.setStatus(gbStream.isStatus()?1:0);
// deviceChannel.setParentId(parentPlatform.getDeviceGBId()); deviceChannel.setParentId(gbStream.getCatalogId());
deviceChannel.setRegisterWay(1); deviceChannel.setRegisterWay(1);
deviceChannel.setCivilCode(config.getDomain()); deviceChannel.setCivilCode(config.getDomain());
deviceChannel.setModel("live"); deviceChannel.setModel("live");
deviceChannel.setOwner("wvp-pro"); deviceChannel.setOwner("wvp-pro");
deviceChannel.setParental(0); deviceChannel.setParental(0);
deviceChannel.setSecrecy("0"); deviceChannel.setSecrecy("0");
deviceChannel.setSecrecy("0");
cmderFroPlatform.catalogQuery(deviceChannel, parentPlatform, sn, fromHeader.getTag(), size); cmderFroPlatform.catalogQuery(deviceChannel, parentPlatform, sn, fromHeader.getTag(), size);
} }
@ -114,6 +139,8 @@ public class CatalogQueryMessageHandler extends SIPRequestProcessorParent implem
e.printStackTrace(); e.printStackTrace();
} catch (ParseException e) { } catch (ParseException e) {
e.printStackTrace(); e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
} }
} }

7
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java

@ -4,7 +4,6 @@ import java.util.List;
import java.util.UUID; import java.util.UUID;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.genersoft.iot.vmp.common.StreamInfo; import com.genersoft.iot.vmp.common.StreamInfo;
import com.genersoft.iot.vmp.conf.MediaConfig; import com.genersoft.iot.vmp.conf.MediaConfig;
import com.genersoft.iot.vmp.conf.UserSetup; import com.genersoft.iot.vmp.conf.UserSetup;
@ -302,7 +301,7 @@ public class ZLMHttpHookListener {
@ResponseBody @ResponseBody
@PostMapping(value = "/on_stream_changed", produces = "application/json;charset=UTF-8") @PostMapping(value = "/on_stream_changed", produces = "application/json;charset=UTF-8")
public ResponseEntity<String> onStreamChanged(@RequestBody MediaItem item){ public ResponseEntity<String> onStreamChanged(@RequestBody MediaItem item){
if (logger.isDebugEnabled()) { if (logger.isDebugEnabled()) {
logger.debug("[ ZLM HOOK ]on_stream_changed API调用,参数:" + JSONObject.toJSONString(item)); logger.debug("[ ZLM HOOK ]on_stream_changed API调用,参数:" + JSONObject.toJSONString(item));
} }
@ -322,10 +321,8 @@ public class ZLMHttpHookListener {
String schema = item.getSchema(); String schema = item.getSchema();
List<MediaItem.MediaTrack> tracks = item.getTracks(); List<MediaItem.MediaTrack> tracks = item.getTracks();
boolean regist = item.isRegist(); boolean regist = item.isRegist();
if (tracks != null) {
logger.info("[stream: " + streamId + "] on_stream_changed->>" + schema);
}
if ("rtmp".equals(schema)){ if ("rtmp".equals(schema)){
logger.info("on_stream_changed:注册->{}, app->{}, stream->{}", regist, app, streamId);
if (regist) { if (regist) {
mediaServerService.addCount(mediaServerId); mediaServerService.addCount(mediaServerId);
}else { }else {

2
src/main/java/com/genersoft/iot/vmp/service/IGbStreamService.java

@ -30,7 +30,7 @@ public interface IGbStreamService {
* 保存国标关联 * 保存国标关联
* @param gbStreams * @param gbStreams
*/ */
boolean addPlatformInfo(List<GbStream> gbStreams, String platformId); boolean addPlatformInfo(List<GbStream> gbStreams, String platformId, String catalogId);
/** /**
* 移除国标关联 * 移除国标关联

4
src/main/java/com/genersoft/iot/vmp/service/impl/GbStreamServiceImpl.java

@ -47,13 +47,15 @@ public class GbStreamServiceImpl implements IGbStreamService {
@Override @Override
public boolean addPlatformInfo(List<GbStream> gbStreams, String platformId) { public boolean addPlatformInfo(List<GbStream> gbStreams, String platformId, String catalogId) {
// 放在事务内执行 // 放在事务内执行
boolean result = false; boolean result = false;
TransactionStatus transactionStatus = dataSourceTransactionManager.getTransaction(transactionDefinition); TransactionStatus transactionStatus = dataSourceTransactionManager.getTransaction(transactionDefinition);
try { try {
for (GbStream gbStream : gbStreams) { for (GbStream gbStream : gbStreams) {
gbStream.setCatalogId(catalogId);
gbStream.setPlatformId(platformId); gbStream.setPlatformId(platformId);
// TODO 修改为批量提交
platformGbStreamMapper.add(gbStream); platformGbStreamMapper.add(gbStream);
} }
dataSourceTransactionManager.commit(transactionStatus); //手动提交 dataSourceTransactionManager.commit(transactionStatus); //手动提交

3
src/main/java/com/genersoft/iot/vmp/service/impl/StreamProxyServiceImpl.java

@ -130,7 +130,7 @@ public class StreamProxyServiceImpl implements IStreamProxyService {
if ( !StringUtils.isEmpty(param.getPlatformGbId()) && streamLive) { if ( !StringUtils.isEmpty(param.getPlatformGbId()) && streamLive) {
List<GbStream> gbStreams = new ArrayList<>(); List<GbStream> gbStreams = new ArrayList<>();
gbStreams.add(param); gbStreams.add(param);
if (gbStreamService.addPlatformInfo(gbStreams, param.getPlatformGbId())){ if (gbStreamService.addPlatformInfo(gbStreams, param.getPlatformGbId(), param.getCatalogId())){
result.append(", 关联国标平台[ " + param.getPlatformGbId() + " ]成功"); result.append(", 关联国标平台[ " + param.getPlatformGbId() + " ]成功");
}else { }else {
result.append(", 关联国标平台[ " + param.getPlatformGbId() + " ]失败"); result.append(", 关联国标平台[ " + param.getPlatformGbId() + " ]失败");
@ -141,6 +141,7 @@ public class StreamProxyServiceImpl implements IStreamProxyService {
if (parentPlatforms.size() > 0) { if (parentPlatforms.size() > 0) {
for (ParentPlatform parentPlatform : parentPlatforms) { for (ParentPlatform parentPlatform : parentPlatforms) {
param.setPlatformId(parentPlatform.getServerGBId()); param.setPlatformId(parentPlatform.getServerGBId());
param.setCatalogId(parentPlatform.getCatalogId());
String stream = param.getStream(); String stream = param.getStream();
StreamProxyItem streamProxyItems = platformGbStreamMapper.selectOne(param.getApp(), stream, parentPlatform.getServerGBId()); StreamProxyItem streamProxyItems = platformGbStreamMapper.selectOne(param.getApp(), stream, parentPlatform.getServerGBId());
if (streamProxyItems == null) { if (streamProxyItems == null) {

1
src/main/java/com/genersoft/iot/vmp/service/impl/StreamPushServiceImpl.java

@ -119,6 +119,7 @@ public class StreamPushServiceImpl implements IStreamPushService {
List<ParentPlatform> parentPlatforms = parentPlatformMapper.selectAllAhareAllLiveStream(); List<ParentPlatform> parentPlatforms = parentPlatformMapper.selectAllAhareAllLiveStream();
if (parentPlatforms.size() > 0) { if (parentPlatforms.size() > 0) {
for (ParentPlatform parentPlatform : parentPlatforms) { for (ParentPlatform parentPlatform : parentPlatforms) {
stream.setCatalogId(parentPlatform.getCatalogId());
stream.setPlatformId(parentPlatform.getServerGBId()); stream.setPlatformId(parentPlatform.getServerGBId());
String streamId = stream.getStream(); String streamId = stream.getStream();
StreamProxyItem streamProxyItems = platformGbStreamMapper.selectOne(stream.getApp(), streamId, parentPlatform.getServerGBId()); StreamProxyItem streamProxyItems = platformGbStreamMapper.selectOne(stream.getApp(), streamId, parentPlatform.getServerGBId());

2
src/main/java/com/genersoft/iot/vmp/storager/IRedisCatchStorage.java

@ -185,6 +185,8 @@ public interface IRedisCatchStorage {
*/ */
void updateDevice(Device device); void updateDevice(Device device);
void removeDevice(String deviceId);
/** /**
* 获取Device * 获取Device
*/ */

27
src/main/java/com/genersoft/iot/vmp/storager/IVideoManagerStorager.java

@ -243,7 +243,7 @@ public interface IVideoManagerStorager {
* @param channelReduces * @param channelReduces
* @return * @return
*/ */
int updateChannelForGB(String platformId, List<ChannelReduce> channelReduces); int updateChannelForGB(String platformId, List<ChannelReduce> channelReduces, String catalogId);
/** /**
* 移除上级平台的通道信息 * 移除上级平台的通道信息
@ -256,6 +256,9 @@ public interface IVideoManagerStorager {
DeviceChannel queryChannelInParentPlatform(String platformId, String channelId); DeviceChannel queryChannelInParentPlatform(String platformId, String channelId);
List<PlatformCatalog> queryChannelInParentPlatformAndCatalog(String platformId, String catalogId);
List<PlatformCatalog> queryStreamInParentPlatformAndCatalog(String platformId, String catalogId);
Device queryVideoDeviceByPlatformIdAndChannelId(String platformId, String channelId); Device queryVideoDeviceByPlatformIdAndChannelId(String platformId, String channelId);
@ -431,4 +434,26 @@ public interface IVideoManagerStorager {
* @param deviceChannelList * @param deviceChannelList
*/ */
boolean resetChannels(String deviceId, List<DeviceChannel> deviceChannelList); boolean resetChannels(String deviceId, List<DeviceChannel> deviceChannelList);
/**
* 获取目录信息
* @param platformId
* @param parentId
* @return
*/
List<PlatformCatalog> getChildrenCatalogByPlatform(String platformId, String parentId);
int addCatalog(PlatformCatalog platformCatalog);
PlatformCatalog getCatalog(String id);
int delCatalog(String id);
int updateCatalog(PlatformCatalog platformCatalog);
int setDefaultCatalog(String platformId, String catalogId);
List<PlatformCatalog> queryCatalogInPlatform(String serverGBId);
int delRelation(PlatformCatalog platformCatalog);
} }

3
src/main/java/com/genersoft/iot/vmp/storager/dao/DeviceChannelMapper.java

@ -91,7 +91,8 @@ public interface DeviceChannelMapper {
"SELECT * FROM ( "+ "SELECT * FROM ( "+
" SELECT dc.channelId, dc.deviceId, dc.name, de.manufacturer, de.hostAddress, " + " SELECT dc.channelId, dc.deviceId, dc.name, de.manufacturer, de.hostAddress, " +
"(SELECT count(0) FROM device_channel WHERE parentId=dc.channelId) as subCount, " + "(SELECT count(0) FROM device_channel WHERE parentId=dc.channelId) as subCount, " +
"(SELECT pc.platformId FROM platform_gb_channel pc WHERE pc.deviceId=dc.deviceId AND pc.channelId = dc.channelId ) as platformId " + "(SELECT pc.platformId FROM platform_gb_channel pc WHERE pc.deviceId=dc.deviceId AND pc.channelId = dc.channelId ) as platformId, " +
"(SELECT pc.catalogId FROM platform_gb_channel pc WHERE pc.deviceId=dc.deviceId AND pc.channelId = dc.channelId ) as catalogId " +
"FROM device_channel dc " + "FROM device_channel dc " +
"LEFT JOIN device de ON dc.deviceId = de.deviceId " + "LEFT JOIN device de ON dc.deviceId = de.deviceId " +
" WHERE 1=1 " + " WHERE 1=1 " +

12
src/main/java/com/genersoft/iot/vmp/storager/dao/GbStreamMapper.java

@ -35,7 +35,7 @@ public interface GbStreamMapper {
@Delete("DELETE FROM gb_stream WHERE app=#{app} AND stream=#{stream}") @Delete("DELETE FROM gb_stream WHERE app=#{app} AND stream=#{stream}")
int del(String app, String stream); int del(String app, String stream);
@Select("SELECT gs.*, pgs.platformId FROM gb_stream gs LEFT JOIN platform_gb_stream pgs ON gs.app = pgs.app AND gs.stream = pgs.stream") @Select("SELECT gs.*, pgs.platformId AS platformId, pgs.catalogId AS catalogId FROM gb_stream gs LEFT JOIN platform_gb_stream pgs ON gs.app = pgs.app AND gs.stream = pgs.stream")
List<GbStream> selectAll(); List<GbStream> selectAll();
@Select("SELECT * FROM gb_stream WHERE app=#{app} AND stream=#{stream}") @Select("SELECT * FROM gb_stream WHERE app=#{app} AND stream=#{stream}")
@ -44,12 +44,12 @@ public interface GbStreamMapper {
@Select("SELECT * FROM gb_stream WHERE gbId=#{gbId}") @Select("SELECT * FROM gb_stream WHERE gbId=#{gbId}")
List<GbStream> selectByGBId(String gbId); List<GbStream> selectByGBId(String gbId);
@Select("SELECT gs.*, pgs.platformId FROM gb_stream gs " + @Select("SELECT gs.*, pgs.platformId as platformId, pgs.catalogId as catalogId FROM gb_stream gs " +
"LEFT JOIN platform_gb_stream pgs ON gs.app = pgs.app AND gs.stream = pgs.stream " + "LEFT JOIN platform_gb_stream pgs ON gs.app = pgs.app AND gs.stream = pgs.stream " +
"WHERE gs.gbId = '${gbId}' AND pgs.platformId = '${platformId}'") "WHERE gs.gbId = '${gbId}' AND pgs.platformId = '${platformId}'")
List<GbStream> queryStreamInPlatform(String platformId, String gbId); List<GbStream> queryStreamInPlatform(String platformId, String gbId);
@Select("SELECT gs.*, pgs.platformId FROM gb_stream gs " + @Select("SELECT gs.*, pgs.platformId as platformId, pgs.catalogId as catalogId FROM gb_stream gs " +
"LEFT JOIN platform_gb_stream pgs ON gs.app = pgs.app AND gs.stream = pgs.stream " + "LEFT JOIN platform_gb_stream pgs ON gs.app = pgs.app AND gs.stream = pgs.stream " +
"WHERE pgs.platformId = '${platformId}'") "WHERE pgs.platformId = '${platformId}'")
List<GbStream> queryGbStreamListInPlatform(String platformId); List<GbStream> queryGbStreamListInPlatform(String platformId);
@ -59,17 +59,11 @@ public interface GbStreamMapper {
"WHERE app=#{app} AND stream=#{stream}") "WHERE app=#{app} AND stream=#{stream}")
int setStatus(String app, String stream, boolean status); int setStatus(String app, String stream, boolean status);
@Select("SELECT gs.*, pgs.platformId FROM gb_stream gs LEFT JOIN platform_gb_stream pgs ON gs.app = pgs.app AND gs.stream = pgs.stream WHERE mediaServerId=#{mediaServerId} ")
List<GbStream> selectAllByMediaServerId(String mediaServerId);
@Update("UPDATE gb_stream " + @Update("UPDATE gb_stream " +
"SET status=${status} " + "SET status=${status} " +
"WHERE mediaServerId=#{mediaServerId} ") "WHERE mediaServerId=#{mediaServerId} ")
void updateStatusByMediaServerId(String mediaServerId, boolean status); void updateStatusByMediaServerId(String mediaServerId, boolean status);
@Select("SELECT * FROM gb_stream WHERE mediaServerId=#{mediaServerId}")
void delByMediaServerId(String mediaServerId);
@Delete("DELETE FROM gb_stream WHERE streamType=#{type} AND gbId=NULL AND mediaServerId=#{mediaServerId}") @Delete("DELETE FROM gb_stream WHERE streamType=#{type} AND gbId=NULL AND mediaServerId=#{mediaServerId}")
void deleteWithoutGBId(String type, String mediaServerId); void deleteWithoutGBId(String type, String mediaServerId);

14
src/main/java/com/genersoft/iot/vmp/storager/dao/ParentPlatformMapper.java

@ -15,10 +15,10 @@ public interface ParentPlatformMapper {
@Insert("INSERT INTO parent_platform (enable, name, serverGBId, serverGBDomain, serverIP, serverPort, deviceGBId, deviceIp, " + @Insert("INSERT INTO parent_platform (enable, name, serverGBId, serverGBDomain, serverIP, serverPort, deviceGBId, deviceIp, " +
" devicePort, username, password, expires, keepTimeout, transport, characterSet, ptz, rtcp, " + " devicePort, username, password, expires, keepTimeout, transport, characterSet, ptz, rtcp, " +
" status, shareAllLiveStream) " + " status, shareAllLiveStream, catalogId) " +
" VALUES (${enable}, '${name}', '${serverGBId}', '${serverGBDomain}', '${serverIP}', ${serverPort}, '${deviceGBId}', '${deviceIp}', " + " VALUES (${enable}, '${name}', '${serverGBId}', '${serverGBDomain}', '${serverIP}', ${serverPort}, '${deviceGBId}', '${deviceIp}', " +
" '${devicePort}', '${username}', '${password}', '${expires}', '${keepTimeout}', '${transport}', '${characterSet}', ${ptz}, ${rtcp}, " + " '${devicePort}', '${username}', '${password}', '${expires}', '${keepTimeout}', '${transport}', '${characterSet}', ${ptz}, ${rtcp}, " +
" ${status}, ${shareAllLiveStream})") " ${status}, ${shareAllLiveStream}, #{catalogId})")
int addParentPlatform(ParentPlatform parentPlatform); int addParentPlatform(ParentPlatform parentPlatform);
@Update("UPDATE parent_platform " + @Update("UPDATE parent_platform " +
@ -40,7 +40,8 @@ public interface ParentPlatformMapper {
"ptz=#{ptz}, " + "ptz=#{ptz}, " +
"rtcp=#{rtcp}, " + "rtcp=#{rtcp}, " +
"status=#{status}, " + "status=#{status}, " +
"shareAllLiveStream=#{shareAllLiveStream} " + "shareAllLiveStream=#{shareAllLiveStream}, " +
"catalogId=#{catalogId} " +
"WHERE id=#{id}") "WHERE id=#{id}")
int updateParentPlatform(ParentPlatform parentPlatform); int updateParentPlatform(ParentPlatform parentPlatform);
@ -74,4 +75,11 @@ public interface ParentPlatformMapper {
@Select("SELECT * FROM parent_platform WHERE shareAllLiveStream=true") @Select("SELECT * FROM parent_platform WHERE shareAllLiveStream=true")
List<ParentPlatform> selectAllAhareAllLiveStream(); List<ParentPlatform> selectAllAhareAllLiveStream();
@Update(value = {" <script>" +
"UPDATE parent_platform " +
"SET catalogId=#{catalogId}" +
"WHERE serverGBId=#{platformId}"+
"</script>"})
int setDefaultCatalog(String platformId, String catalogId);
} }

42
src/main/java/com/genersoft/iot/vmp/storager/dao/PlatformCatalogMapper.java

@ -0,0 +1,42 @@
package com.genersoft.iot.vmp.storager.dao;
import com.genersoft.iot.vmp.gb28181.bean.GbStream;
import com.genersoft.iot.vmp.gb28181.bean.PlatformCatalog;
import com.genersoft.iot.vmp.gb28181.bean.PlatformGbStream;
import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem;
import org.apache.ibatis.annotations.*;
import org.springframework.stereotype.Repository;
import java.util.List;
@Mapper
@Repository
public interface PlatformCatalogMapper {
@Insert("INSERT INTO platform_catalog (id, name, platformId, parentId) VALUES" +
"(#{id}, #{name}, #{platformId}, #{parentId})")
int add(PlatformCatalog platformCatalog);
@Delete("DELETE FROM platform_catalog WHERE id=#{id}")
int del(String id);
@Delete("DELETE FROM platform_catalog WHERE platformId=#{platformId}")
int delByPlatformId(String platformId);
@Select("SELECT *, (SELECT COUNT(1) from platform_catalog where parentId = pc.id AND platformId=#{platformId}) as childrenCount FROM platform_catalog pc WHERE parentId=#{parentId} AND platformId=#{platformId}")
List<PlatformCatalog> selectByParentId(String platformId, String parentId);
@Select("SELECT *, (SELECT COUNT(1) from platform_catalog where parentId = pc.id) as childrenCount FROM platform_catalog pc WHERE pc.id=#{id}")
PlatformCatalog select(String id);
@Update(value = {" <script>" +
"UPDATE platform_catalog " +
"SET name=#{name}" +
"WHERE id=#{id}"+
"</script>"})
int update(PlatformCatalog platformCatalog);
@Select("SELECT *, (SELECT COUNT(1) from platform_catalog where parentId = pc.id) as childrenCount FROM platform_catalog pc WHERE pc.platformId=#{platformId}")
List<PlatformCatalog> selectByPlatForm(String platformId);
}

21
src/main/java/com/genersoft/iot/vmp/storager/dao/PlatformChannelMapper.java

@ -2,6 +2,7 @@ package com.genersoft.iot.vmp.storager.dao;
import com.genersoft.iot.vmp.gb28181.bean.Device; import com.genersoft.iot.vmp.gb28181.bean.Device;
import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
import com.genersoft.iot.vmp.gb28181.bean.PlatformCatalog;
import com.genersoft.iot.vmp.vmanager.gb28181.platform.bean.ChannelReduce; import com.genersoft.iot.vmp.vmanager.gb28181.platform.bean.ChannelReduce;
import org.apache.ibatis.annotations.Delete; import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert; import org.apache.ibatis.annotations.Insert;
@ -25,9 +26,9 @@ public interface PlatformChannelMapper {
List<String> findChannelRelatedPlatform(String platformId, List<String> deviceAndChannelIds); List<String> findChannelRelatedPlatform(String platformId, List<String> deviceAndChannelIds);
@Insert("<script> "+ @Insert("<script> "+
"INSERT INTO platform_gb_channel (channelId, deviceId, platformId, deviceAndChannelId) VALUES" + "INSERT INTO platform_gb_channel (channelId, deviceId, platformId, deviceAndChannelId, catalogId) VALUES" +
"<foreach collection='channelReducesToAdd' item='item' separator=','>" + "<foreach collection='channelReducesToAdd' item='item' separator=','>" +
" ('${item.channelId}','${item.deviceId}', '${platformId}', '${item.deviceId}_${item.channelId}' )" + " ('${item.channelId}','${item.deviceId}', '${platformId}', '${item.deviceId}_${item.channelId}' , '${item.catalogId}' )" +
"</foreach>" + "</foreach>" +
"</script>") "</script>")
int addChannels(String platformId, List<ChannelReduce> channelReducesToAdd); int addChannels(String platformId, List<ChannelReduce> channelReducesToAdd);
@ -54,6 +55,22 @@ public interface PlatformChannelMapper {
"platformId='${platformId}' AND channelId='${channelId}' ) AND channelId='${channelId}'") "platformId='${platformId}' AND channelId='${channelId}' ) AND channelId='${channelId}'")
DeviceChannel queryChannelInParentPlatform(String platformId, String channelId); DeviceChannel queryChannelInParentPlatform(String platformId, String channelId);
@Select("select dc.channelId as id, dc.name as name, pgc.platformId as platformId, pgc.catalogId as parentId, 0 as childrenCount, 1 as type " +
"from device_channel dc left join platform_gb_channel pgc on dc.deviceId = pgc.deviceId and dc.channelId = pgc.channelId " +
"where pgc.platformId=#{platformId} and pgc.catalogId=#{catalogId}")
List<PlatformCatalog> queryChannelInParentPlatformAndCatalog(String platformId, String catalogId);
@Select("SELECT * FROM device WHERE deviceId = (SELECT deviceId FROM platform_gb_channel WHERE platformId='${platformId}' AND channelId='${channelId}')") @Select("SELECT * FROM device WHERE deviceId = (SELECT deviceId FROM platform_gb_channel WHERE platformId='${platformId}' AND channelId='${channelId}')")
Device queryVideoDeviceByPlatformIdAndChannelId(String platformId, String channelId); Device queryVideoDeviceByPlatformIdAndChannelId(String platformId, String channelId);
@Delete("<script> "+
"DELETE FROM platform_gb_channel WHERE catalogId=#{id}" +
"</script>")
int delByCatalogId(String id);
@Delete("<script> "+
"DELETE FROM platform_gb_channel WHERE catalogId=#{parentId} AND platformId=#{platformId} AND channelId=#{id}" +
"</script>")
int delByCatalogIdAndChannelIdAndPlatformId(PlatformCatalog platformCatalog);
} }

24
src/main/java/com/genersoft/iot/vmp/storager/dao/PlatformGbStreamMapper.java

@ -1,5 +1,7 @@
package com.genersoft.iot.vmp.storager.dao; package com.genersoft.iot.vmp.storager.dao;
import com.genersoft.iot.vmp.gb28181.bean.GbStream;
import com.genersoft.iot.vmp.gb28181.bean.PlatformCatalog;
import com.genersoft.iot.vmp.gb28181.bean.PlatformGbStream; import com.genersoft.iot.vmp.gb28181.bean.PlatformGbStream;
import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem; import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem;
import org.apache.ibatis.annotations.*; import org.apache.ibatis.annotations.*;
@ -12,8 +14,8 @@ import java.util.List;
@Repository @Repository
public interface PlatformGbStreamMapper { public interface PlatformGbStreamMapper {
@Insert("INSERT INTO platform_gb_stream (app, stream, platformId) VALUES" + @Insert("INSERT INTO platform_gb_stream (app, stream, platformId, catalogId) VALUES" +
"('${app}', '${stream}', '${platformId}')") "('${app}', '${stream}', '${platformId}', '${catalogId}')")
int add(PlatformGbStream platformGbStream); int add(PlatformGbStream platformGbStream);
@Delete("DELETE FROM platform_gb_stream WHERE app=#{app} AND stream=#{stream}") @Delete("DELETE FROM platform_gb_stream WHERE app=#{app} AND stream=#{stream}")
@ -27,4 +29,22 @@ public interface PlatformGbStreamMapper {
@Select("SELECT * FROM platform_gb_stream WHERE app=#{app} AND stream=#{stream} AND platformId=#{serverGBId}") @Select("SELECT * FROM platform_gb_stream WHERE app=#{app} AND stream=#{stream} AND platformId=#{serverGBId}")
StreamProxyItem selectOne(String app, String stream, String serverGBId); StreamProxyItem selectOne(String app, String stream, String serverGBId);
@Select("select gs.* \n" +
"from gb_stream gs\n" +
" left join platform_gb_stream pgs\n" +
" on gs.app = pgs.app and gs.stream = pgs.stream\n" +
"where pgs.platformId=#{platformId} and pgs.catalogId=#{catalogId}")
List<GbStream> queryChannelInParentPlatformAndCatalog(String platformId, String catalogId);
@Select("select gs.gbId as id, gs.name as name, pgs.platformId as platformId, pgs.catalogId as catalogId , 0 as childrenCount, 2 as type\n" +
"from gb_stream gs\n" +
" left join platform_gb_stream pgs\n" +
" on gs.app = pgs.app and gs.stream = pgs.stream\n" +
"where pgs.platformId=#{platformId} and pgs.catalogId=#{catalogId}")
List<PlatformCatalog> queryChannelInParentPlatformAndCatalogForCatlog(String platformId, String catalogId);
@Delete("DELETE FROM platform_gb_stream WHERE catalogId=#{id}")
int delByCatalogId(String id);
} }

6
src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java

@ -406,6 +406,12 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage {
redis.set(key, device); redis.set(key, device);
} }
@Override
public void removeDevice(String deviceId) {
String key = VideoManagerConstants.DEVICE_PREFIX + userSetup.getServerId() + "_" + deviceId;
redis.del(key);
}
@Override @Override
public Device getDevice(String deviceId) { public Device getDevice(String deviceId) {
String key = VideoManagerConstants.DEVICE_PREFIX + userSetup.getServerId() + "_" + deviceId; String key = VideoManagerConstants.DEVICE_PREFIX + userSetup.getServerId() + "_" + deviceId;

95
src/main/java/com/genersoft/iot/vmp/storager/impl/VideoManagerStoragerImpl.java

@ -71,6 +71,9 @@ public class VideoManagerStoragerImpl implements IVideoManagerStorager {
@Autowired @Autowired
private GbStreamMapper gbStreamMapper; private GbStreamMapper gbStreamMapper;
@Autowired
private PlatformCatalogMapper catalogMapper;
; ;
@Autowired @Autowired
@ -449,6 +452,9 @@ public class VideoManagerStoragerImpl implements IVideoManagerStorager {
@Override @Override
public boolean addParentPlatform(ParentPlatform parentPlatform) { public boolean addParentPlatform(ParentPlatform parentPlatform) {
if (parentPlatform.getCatalogId() == null) {
parentPlatform.setCatalogId(parentPlatform.getServerGBId());
}
int result = platformMapper.addParentPlatform(parentPlatform); int result = platformMapper.addParentPlatform(parentPlatform);
return result > 0; return result > 0;
} }
@ -458,6 +464,9 @@ public class VideoManagerStoragerImpl implements IVideoManagerStorager {
int result = 0; int result = 0;
ParentPlatformCatch parentPlatformCatch = redisCatchStorage.queryPlatformCatchInfo(parentPlatform.getServerGBId()); // .getDeviceGBId()); ParentPlatformCatch parentPlatformCatch = redisCatchStorage.queryPlatformCatchInfo(parentPlatform.getServerGBId()); // .getDeviceGBId());
if (parentPlatform.getId() == null ) { if (parentPlatform.getId() == null ) {
if (parentPlatform.getCatalogId() == null) {
parentPlatform.setCatalogId(parentPlatform.getServerGBId());
}
result = platformMapper.addParentPlatform(parentPlatform); result = platformMapper.addParentPlatform(parentPlatform);
if (parentPlatformCatch == null) { if (parentPlatformCatch == null) {
parentPlatformCatch = new ParentPlatformCatch(); parentPlatformCatch = new ParentPlatformCatch();
@ -480,8 +489,11 @@ public class VideoManagerStoragerImpl implements IVideoManagerStorager {
// 共享所有视频流,需要将现有视频流添加到此平台 // 共享所有视频流,需要将现有视频流添加到此平台
List<GbStream> gbStreams = gbStreamMapper.selectAll(); List<GbStream> gbStreams = gbStreamMapper.selectAll();
if (gbStreams.size() > 0) { if (gbStreams.size() > 0) {
for (GbStream gbStream : gbStreams) {
gbStream.setCatalogId(parentPlatform.getCatalogId());
}
if (parentPlatform.isShareAllLiveStream()) { if (parentPlatform.isShareAllLiveStream()) {
gbStreamService.addPlatformInfo(gbStreams, parentPlatform.getServerGBId()); gbStreamService.addPlatformInfo(gbStreams, parentPlatform.getServerGBId(), parentPlatform.getCatalogId());
}else { }else {
gbStreamService.delPlatformInfo(gbStreams); gbStreamService.delPlatformInfo(gbStreams);
} }
@ -536,10 +548,11 @@ public class VideoManagerStoragerImpl implements IVideoManagerStorager {
} }
@Override @Override
public int updateChannelForGB(String platformId, List<ChannelReduce> channelReduces) { public int updateChannelForGB(String platformId, List<ChannelReduce> channelReduces, String catalogId) {
Map<String, ChannelReduce> deviceAndChannels = new HashMap<>(); Map<String, ChannelReduce> deviceAndChannels = new HashMap<>();
for (ChannelReduce channelReduce : channelReduces) { for (ChannelReduce channelReduce : channelReduces) {
channelReduce.setCatalogId(catalogId);
deviceAndChannels.put(channelReduce.getDeviceId() + "_" + channelReduce.getChannelId(), channelReduce); deviceAndChannels.put(channelReduce.getDeviceId() + "_" + channelReduce.getChannelId(), channelReduce);
} }
List<String> deviceAndChannelList = new ArrayList<>(deviceAndChannels.keySet()); List<String> deviceAndChannelList = new ArrayList<>(deviceAndChannels.keySet());
@ -576,6 +589,18 @@ public class VideoManagerStoragerImpl implements IVideoManagerStorager {
return channel; return channel;
} }
@Override
public List<PlatformCatalog> queryChannelInParentPlatformAndCatalog(String platformId, String catalogId) {
List<PlatformCatalog> catalogs = platformChannelMapper.queryChannelInParentPlatformAndCatalog(platformId, catalogId);
return catalogs;
}
@Override
public List<PlatformCatalog> queryStreamInParentPlatformAndCatalog(String platformId, String catalogId) {
List<PlatformCatalog> catalogs = platformGbStreamMapper.queryChannelInParentPlatformAndCatalogForCatlog(platformId, catalogId);
return catalogs;
}
@Override @Override
public Device queryVideoDeviceByPlatformIdAndChannelId(String platformId, String channelId) { public Device queryVideoDeviceByPlatformIdAndChannelId(String platformId, String channelId) {
Device device = platformChannelMapper.queryVideoDeviceByPlatformIdAndChannelId(platformId, channelId); Device device = platformChannelMapper.queryVideoDeviceByPlatformIdAndChannelId(platformId, channelId);
@ -739,6 +764,7 @@ public class VideoManagerStoragerImpl implements IVideoManagerStorager {
List<ParentPlatform> parentPlatforms = parentPlatformMapper.selectAllAhareAllLiveStream(); List<ParentPlatform> parentPlatforms = parentPlatformMapper.selectAllAhareAllLiveStream();
if (parentPlatforms.size() > 0) { if (parentPlatforms.size() > 0) {
for (ParentPlatform parentPlatform : parentPlatforms) { for (ParentPlatform parentPlatform : parentPlatforms) {
streamPushItem.setCatalogId(parentPlatform.getCatalogId());
streamPushItem.setPlatformId(parentPlatform.getServerGBId()); streamPushItem.setPlatformId(parentPlatform.getServerGBId());
String stream = streamPushItem.getStream(); String stream = streamPushItem.getStream();
StreamProxyItem streamProxyItems = platformGbStreamMapper.selectOne(streamPushItem.getApp(), stream, parentPlatform.getServerGBId()); StreamProxyItem streamProxyItems = platformGbStreamMapper.selectOne(streamPushItem.getApp(), stream, parentPlatform.getServerGBId());
@ -804,4 +830,69 @@ public class VideoManagerStoragerImpl implements IVideoManagerStorager {
return streamProxyMapper.selectOne(app, streamId); return streamProxyMapper.selectOne(app, streamId);
} }
@Override
public List<PlatformCatalog> getChildrenCatalogByPlatform(String platformId, String parentId) {
return catalogMapper.selectByParentId(platformId, parentId);
}
@Override
public int addCatalog(PlatformCatalog platformCatalog) {
return catalogMapper.add(platformCatalog);
}
@Override
public PlatformCatalog getCatalog(String id) {
return catalogMapper.select(id);
}
@Override
public int delCatalog(String id) {
PlatformCatalog platformCatalog = catalogMapper.select(id);
if (platformCatalog.getChildrenCount() > 0) {
List<PlatformCatalog> platformCatalogList = catalogMapper.selectByParentId(platformCatalog.getPlatformId(), platformCatalog.getId());
for (PlatformCatalog catalog : platformCatalogList) {
if (catalog.getChildrenCount() == 0) {
catalogMapper.del(catalog.getId());
platformGbStreamMapper.delByCatalogId(catalog.getId());
platformChannelMapper.delByCatalogId(catalog.getId());
}else {
delCatalog(catalog.getId());
}
}
}
int delresult = catalogMapper.del(id);
int delStreamresult = platformGbStreamMapper.delByCatalogId(id);
int delChanneresult = platformChannelMapper.delByCatalogId(id);
return delresult + delChanneresult + delStreamresult;
}
@Override
public int updateCatalog(PlatformCatalog platformCatalog) {
return catalogMapper.update(platformCatalog);
}
@Override
public int setDefaultCatalog(String platformId, String catalogId) {
return platformMapper.setDefaultCatalog(platformId, catalogId);
}
@Override
public List<PlatformCatalog> queryCatalogInPlatform(String platformId) {
return catalogMapper.selectByPlatForm(platformId);
}
@Override
public int delRelation(PlatformCatalog platformCatalog) {
if (platformCatalog.getType() == 1) {
return platformChannelMapper.delByCatalogIdAndChannelIdAndPlatformId(platformCatalog);
}else if (platformCatalog.getType() == 2) {
List<GbStream> gbStreams = platformGbStreamMapper.queryChannelInParentPlatformAndCatalog(platformCatalog.getPlatformId(), platformCatalog.getParentId());
for (GbStream gbStream : gbStreams) {
if (gbStream.getGbId().equals(platformCatalog.getId())) {
return platformGbStreamMapper.delByAppAndStream(gbStream.getApp(), gbStream.getStream());
}
}
}
return 0;
}
} }

15
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/device/DeviceQuery.java

@ -152,12 +152,16 @@ public class DeviceQuery {
String uuid = UUID.randomUUID().toString(); String uuid = UUID.randomUUID().toString();
DeferredResult<ResponseEntity<Device>> result = new DeferredResult<ResponseEntity<Device>>(15*1000L); DeferredResult<ResponseEntity<Device>> result = new DeferredResult<ResponseEntity<Device>>(15*1000L);
result.onTimeout(()->{ result.onTimeout(()->{
logger.warn(String.format("设备通道信息同步超时")); logger.warn("设备[{}]通道信息同步超时", deviceId);
// 释放rtpserver // 释放rtpserver
RequestMessage msg = new RequestMessage(); RequestMessage msg = new RequestMessage();
msg.setKey(key); msg.setKey(key);
msg.setId(uuid); msg.setId(uuid);
msg.setData("Timeout"); WVPResult<Object> wvpResult = new WVPResult<>();
wvpResult.setCode(-1);
wvpResult.setData(device);
wvpResult.setMsg("更新超时");
msg.setData(wvpResult);
resultHolder.invokeAllResult(msg); resultHolder.invokeAllResult(msg);
}); });
// 等待其他相同请求返回时一起返回 // 等待其他相同请求返回时一起返回
@ -168,7 +172,11 @@ public class DeviceQuery {
RequestMessage msg = new RequestMessage(); RequestMessage msg = new RequestMessage();
msg.setKey(key); msg.setKey(key);
msg.setId(uuid); msg.setId(uuid);
msg.setData(String.format("同步通道失败,错误码: %s, %s", event.statusCode, event.msg)); WVPResult<Object> wvpResult = new WVPResult<>();
wvpResult.setCode(-1);
wvpResult.setData(device);
wvpResult.setMsg(String.format("同步通道失败,错误码: %s, %s", event.statusCode, event.msg));
msg.setData(wvpResult);
resultHolder.invokeAllResult(msg); resultHolder.invokeAllResult(msg);
}); });
@ -199,6 +207,7 @@ public class DeviceQuery {
boolean isSuccess = storager.delete(deviceId); boolean isSuccess = storager.delete(deviceId);
if (isSuccess) { if (isSuccess) {
redisCatchStorage.clearCatchByDeviceId(deviceId); redisCatchStorage.clearCatchByDeviceId(deviceId);
redisCatchStorage.removeDevice(deviceId);
JSONObject json = new JSONObject(); JSONObject json = new JSONObject();
json.put("deviceId", deviceId); json.put("deviceId", deviceId);
return new ResponseEntity<>(json.toString(),HttpStatus.OK); return new ResponseEntity<>(json.toString(),HttpStatus.OK);

2
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/gbStream/GbStreamController.java

@ -82,7 +82,7 @@ public class GbStreamController {
@PostMapping(value = "/add") @PostMapping(value = "/add")
@ResponseBody @ResponseBody
public Object add(@RequestBody GbStreamParam gbStreamParam){ public Object add(@RequestBody GbStreamParam gbStreamParam){
if (gbStreamService.addPlatformInfo(gbStreamParam.getGbStreams(), gbStreamParam.getPlatformId())) { if (gbStreamService.addPlatformInfo(gbStreamParam.getGbStreams(), gbStreamParam.getPlatformId(), gbStreamParam.getCatalogId())) {
return "success"; return "success";
}else { }else {
return "fail"; return "fail";

10
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/gbStream/bean/GbStreamParam.java

@ -8,12 +8,22 @@ public class GbStreamParam {
private String platformId; private String platformId;
private String catalogId;
private List<GbStream> gbStreams; private List<GbStream> gbStreams;
public String getPlatformId() { public String getPlatformId() {
return platformId; return platformId;
} }
public String getCatalogId() {
return catalogId;
}
public void setCatalogId(String catalogId) {
this.catalogId = catalogId;
}
public void setPlatformId(String platformId) { public void setPlatformId(String platformId) {
this.platformId = platformId; this.platformId = platformId;
} }

201
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/platform/PlatformController.java

@ -1,10 +1,15 @@
package com.genersoft.iot.vmp.vmanager.gb28181.platform; package com.genersoft.iot.vmp.vmanager.gb28181.platform;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.genersoft.iot.vmp.gb28181.bean.CatalogData;
import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
import com.genersoft.iot.vmp.gb28181.bean.PlatformCatalog;
import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform;
import com.genersoft.iot.vmp.storager.IRedisCatchStorage; import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
import com.genersoft.iot.vmp.storager.IVideoManagerStorager; import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
import com.genersoft.iot.vmp.vmanager.bean.WVPResult;
import com.genersoft.iot.vmp.vmanager.gb28181.platform.bean.ChannelReduce; import com.genersoft.iot.vmp.vmanager.gb28181.platform.bean.ChannelReduce;
import com.genersoft.iot.vmp.vmanager.gb28181.platform.bean.UpdateChannelParam; import com.genersoft.iot.vmp.vmanager.gb28181.platform.bean.UpdateChannelParam;
import com.github.pagehelper.PageInfo; import com.github.pagehelper.PageInfo;
@ -21,6 +26,8 @@ import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import com.genersoft.iot.vmp.conf.SipConfig; import com.genersoft.iot.vmp.conf.SipConfig;
import java.util.List;
/** /**
* 级联平台管理 * 级联平台管理
*/ */
@ -253,7 +260,7 @@ public class PlatformController {
if (logger.isDebugEnabled()) { if (logger.isDebugEnabled()) {
logger.debug("给上级平台添加国标通道API调用"); logger.debug("给上级平台添加国标通道API调用");
} }
int result = storager.updateChannelForGB(param.getPlatformId(), param.getChannelReduces()); int result = storager.updateChannelForGB(param.getPlatformId(), param.getChannelReduces(), param.getCatalogId());
return new ResponseEntity<>(String.valueOf(result > 0), HttpStatus.OK); return new ResponseEntity<>(String.valueOf(result > 0), HttpStatus.OK);
} }
@ -279,5 +286,197 @@ public class PlatformController {
return new ResponseEntity<>(String.valueOf(result > 0), HttpStatus.OK); return new ResponseEntity<>(String.valueOf(result > 0), HttpStatus.OK);
} }
/**
* 获取目录
* @param platformId 平台ID
* @param parentId 目录父ID
* @return
*/
@ApiOperation("获取目录")
@ApiImplicitParams({
@ApiImplicitParam(name = "platformId", value = "平台ID", dataTypeClass = String.class, required = true),
@ApiImplicitParam(name = "parentId", value = "目录父ID", dataTypeClass = String.class, required = true),
})
@GetMapping("/catalog")
@ResponseBody
public ResponseEntity<WVPResult<List<PlatformCatalog>>> getCatalogByPlatform(String platformId, String parentId){
if (logger.isDebugEnabled()) {
logger.debug("查询目录,platformId: {}, parentId: {}", platformId, parentId);
}
List<PlatformCatalog> platformCatalogList = storager.getChildrenCatalogByPlatform(platformId, parentId);
// 查询下属的国标通道
List<PlatformCatalog> catalogsForChannel = storager.queryChannelInParentPlatformAndCatalog(platformId, parentId);
List<PlatformCatalog> catalogsForStream = storager.queryStreamInParentPlatformAndCatalog(platformId, parentId);
platformCatalogList.addAll(catalogsForChannel);
platformCatalogList.addAll(catalogsForStream);
WVPResult<List<PlatformCatalog>> result = new WVPResult<>();
result.setCode(0);
result.setMsg("success");
result.setData(platformCatalogList);
return new ResponseEntity<>(result, HttpStatus.OK);
}
/**
* 添加目录
* @param platformCatalog 目录
* @return
*/
@ApiOperation("添加目录")
@ApiImplicitParams({
@ApiImplicitParam(name = "platformCatalog", value = "目录信息", dataTypeClass = PlatformCatalog.class, required = true),
})
@PostMapping("/catalog/add")
@ResponseBody
public ResponseEntity<WVPResult<List<PlatformCatalog>>> addCatalog(@RequestBody PlatformCatalog platformCatalog){
if (logger.isDebugEnabled()) {
logger.debug("添加目录,{}", JSON.toJSONString(platformCatalog));
}
PlatformCatalog platformCatalogInStore = storager.getCatalog(platformCatalog.getId());
WVPResult<List<PlatformCatalog>> result = new WVPResult<>();
if (platformCatalogInStore != null) {
result.setCode(-1);
result.setMsg( platformCatalog.getId() + " already exists");
return new ResponseEntity<>(result, HttpStatus.OK);
}
int addResult = storager.addCatalog(platformCatalog);
if (addResult > 0) {
result.setCode(0);
result.setMsg("success");
return new ResponseEntity<>(result, HttpStatus.OK);
}else {
result.setCode(-500);
result.setMsg("save error");
return new ResponseEntity<>(result, HttpStatus.OK);
}
}
/**
* 编辑目录
* @param platformCatalog 目录
* @return
*/
@ApiOperation("编辑目录")
@ApiImplicitParams({
@ApiImplicitParam(name = "platformCatalog", value = "目录信息", dataTypeClass = PlatformCatalog.class, required = true),
})
@PostMapping("/catalog/edit")
@ResponseBody
public ResponseEntity<WVPResult<List<PlatformCatalog>>> editCatalog(@RequestBody PlatformCatalog platformCatalog){
if (logger.isDebugEnabled()) {
logger.debug("编辑目录,{}", JSON.toJSONString(platformCatalog));
}
PlatformCatalog platformCatalogInStore = storager.getCatalog(platformCatalog.getId());
WVPResult<List<PlatformCatalog>> result = new WVPResult<>();
result.setCode(0);
if (platformCatalogInStore == null) {
result.setMsg( platformCatalog.getId() + " not exists");
return new ResponseEntity<>(result, HttpStatus.OK);
}
int addResult = storager.updateCatalog(platformCatalog);
if (addResult > 0) {
result.setMsg("success");
return new ResponseEntity<>(result, HttpStatus.OK);
}else {
result.setMsg("save error");
return new ResponseEntity<>(result, HttpStatus.OK);
}
}
/**
* 删除目录
* @param id 目录Id
* @return
*/
@ApiOperation("删除目录")
@ApiImplicitParams({
@ApiImplicitParam(name = "id", value = "目录Id", dataTypeClass = String.class, required = true),
})
@DeleteMapping("/catalog/del")
@ResponseBody
public ResponseEntity<WVPResult<List<PlatformCatalog>>> delCatalog(String id){
if (logger.isDebugEnabled()) {
logger.debug("删除目录,{}", id);
}
int delResult = storager.delCatalog(id);
WVPResult<List<PlatformCatalog>> result = new WVPResult<>();
result.setCode(0);
if (delResult > 0) {
result.setMsg("success");
return new ResponseEntity<>(result, HttpStatus.OK);
}else {
result.setMsg("save error");
return new ResponseEntity<>(result, HttpStatus.OK);
}
}
/**
* 删除关联
* @param platformCatalog 关联的信息
* @return
*/
@ApiOperation("删除关联")
@ApiImplicitParams({
@ApiImplicitParam(name = "platformCatalog", value = "关联的信息", dataTypeClass = PlatformCatalog.class, required = true),
})
@DeleteMapping("/catalog/relation/del")
@ResponseBody
public ResponseEntity<WVPResult<List<PlatformCatalog>>> delRelation(@RequestBody PlatformCatalog platformCatalog){
if (logger.isDebugEnabled()) {
logger.debug("删除关联,{}", JSON.toJSONString(platformCatalog));
}
int delResult = storager.delRelation(platformCatalog);
WVPResult<List<PlatformCatalog>> result = new WVPResult<>();
result.setCode(0);
if (delResult > 0) {
result.setMsg("success");
return new ResponseEntity<>(result, HttpStatus.OK);
}else {
result.setMsg("save error");
return new ResponseEntity<>(result, HttpStatus.OK);
}
}
/**
* 修改默认目录
* @param platformId 平台Id
* @param catalogId 目录Id
* @return
*/
@ApiOperation("修改默认目录")
@ApiImplicitParams({
@ApiImplicitParam(name = "platformId", value = "平台Id", dataTypeClass = String.class, required = true),
@ApiImplicitParam(name = "catalogId", value = "目录Id", dataTypeClass = String.class, required = true),
})
@PostMapping("/catalog/default/update")
@ResponseBody
public ResponseEntity<WVPResult<String>> setDefaultCatalog(String platformId, String catalogId){
if (logger.isDebugEnabled()) {
logger.debug("修改默认目录,{},{}", platformId, catalogId);
}
int updateResult = storager.setDefaultCatalog(platformId, catalogId);
WVPResult<String> result = new WVPResult<>();
result.setCode(0);
if (updateResult > 0) {
result.setMsg("success");
return new ResponseEntity<>(result, HttpStatus.OK);
}else {
result.setMsg("save error");
return new ResponseEntity<>(result, HttpStatus.OK);
}
}
} }

13
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/platform/bean/ChannelReduce.java

@ -40,6 +40,11 @@ public class ChannelReduce {
*/ */
private String platformId; private String platformId;
/**
* 目录Id
*/
private String catalogId;
public String getChannelId() { public String getChannelId() {
return channelId; return channelId;
@ -96,4 +101,12 @@ public class ChannelReduce {
public void setPlatformId(String platformId) { public void setPlatformId(String platformId) {
this.platformId = platformId; this.platformId = platformId;
} }
public String getCatalogId() {
return catalogId;
}
public void setCatalogId(String catalogId) {
this.catalogId = catalogId;
}
} }

9
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/platform/bean/UpdateChannelParam.java

@ -4,6 +4,7 @@ import java.util.List;
public class UpdateChannelParam { public class UpdateChannelParam {
private String platformId; private String platformId;
private String catalogId;
private List<ChannelReduce> channelReduces; private List<ChannelReduce> channelReduces;
public String getPlatformId() { public String getPlatformId() {
@ -21,4 +22,12 @@ public class UpdateChannelParam {
public void setChannelReduces(List<ChannelReduce> channelReduces) { public void setChannelReduces(List<ChannelReduce> channelReduces) {
this.channelReduces = channelReduces; this.channelReduces = channelReduces;
} }
public String getCatalogId() {
return catalogId;
}
public void setCatalogId(String catalogId) {
this.catalogId = catalogId;
}
} }

2
src/main/resources/all-application.yml

@ -27,7 +27,7 @@ spring:
datasource: datasource:
# 使用mysql 打开23-28行注释, 删除29-36行 # 使用mysql 打开23-28行注释, 删除29-36行
# name: wvp # name: wvp
# url: jdbc:mysql://127.0.0.1:3306/wvp?useUnicode=true&characterEncoding=UTF8&rewriteBatchedStatements=true # url: jdbc:mysql://127.0.0.1:3306/wvp?useUnicode=true&characterEncoding=UTF8&rewriteBatchedStatements=true&allowMultiQueries=true
# username: # username:
# password: # password:
# type: com.alibaba.druid.pool.DruidDataSource # type: com.alibaba.druid.pool.DruidDataSource

2
src/main/resources/application-dev.yml

@ -15,7 +15,7 @@ spring:
datasource: datasource:
# 使用mysql 打开23-28行注释, 删除29-36行 # 使用mysql 打开23-28行注释, 删除29-36行
# name: wvp # name: wvp
# url: jdbc:mysql://127.0.0.1:3306/wvp?useUnicode=true&characterEncoding=UTF8&rewriteBatchedStatements=true # url: jdbc:mysql://127.0.0.1:3306/wvp?useUnicode=true&characterEncoding=UTF8&rewriteBatchedStatements=true&allowMultiQueries=true
# username: # username:
# password: # password:
# type: com.alibaba.druid.pool.DruidDataSource # type: com.alibaba.druid.pool.DruidDataSource

2
src/main/resources/application-docker.yml

@ -15,7 +15,7 @@ spring:
datasource: datasource:
# 使用mysql 打开23-28行注释, 删除29-36行 # 使用mysql 打开23-28行注释, 删除29-36行
# name: wvp # name: wvp
# url: jdbc:mysql://127.0.0.1:3306/wvp?useUnicode=true&characterEncoding=UTF8&rewriteBatchedStatements=true # url: jdbc:mysql://127.0.0.1:3306/wvp?useUnicode=true&characterEncoding=UTF8&rewriteBatchedStatements=true&allowMultiQueries=true
# username: # username:
# password: # password:
# type: com.alibaba.druid.pool.DruidDataSource # type: com.alibaba.druid.pool.DruidDataSource

BIN
src/main/resources/wvp.sqlite

Binary file not shown.

11
web_src/package-lock.json

@ -19,6 +19,7 @@
"vue-baidu-map": "^0.21.22", "vue-baidu-map": "^0.21.22",
"vue-clipboard2": "^0.3.1", "vue-clipboard2": "^0.3.1",
"vue-clipboards": "^1.3.0", "vue-clipboards": "^1.3.0",
"vue-contextmenujs": "^1.3.13",
"vue-cookies": "^1.7.4", "vue-cookies": "^1.7.4",
"vue-router": "^3.1.6" "vue-router": "^3.1.6"
}, },
@ -12920,6 +12921,11 @@
"tiny-emitter": "^2.0.0" "tiny-emitter": "^2.0.0"
} }
}, },
"node_modules/vue-contextmenujs": {
"version": "1.3.13",
"resolved": "https://registry.npmmirror.com/vue-contextmenujs/download/vue-contextmenujs-1.3.13.tgz",
"integrity": "sha1-O9rgI8e9QgleeNpCWAACUNUKuO8="
},
"node_modules/vue-cookies": { "node_modules/vue-cookies": {
"version": "1.7.4", "version": "1.7.4",
"resolved": "https://registry.npm.taobao.org/vue-cookies/download/vue-cookies-1.7.4.tgz?cache=0&sync_timestamp=1598941352058&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fvue-cookies%2Fdownload%2Fvue-cookies-1.7.4.tgz", "resolved": "https://registry.npm.taobao.org/vue-cookies/download/vue-cookies-1.7.4.tgz?cache=0&sync_timestamp=1598941352058&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fvue-cookies%2Fdownload%2Fvue-cookies-1.7.4.tgz",
@ -25077,6 +25083,11 @@
} }
} }
}, },
"vue-contextmenujs": {
"version": "1.3.13",
"resolved": "https://registry.npmmirror.com/vue-contextmenujs/download/vue-contextmenujs-1.3.13.tgz",
"integrity": "sha1-O9rgI8e9QgleeNpCWAACUNUKuO8="
},
"vue-cookies": { "vue-cookies": {
"version": "1.7.4", "version": "1.7.4",
"resolved": "https://registry.npm.taobao.org/vue-cookies/download/vue-cookies-1.7.4.tgz?cache=0&sync_timestamp=1598941352058&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fvue-cookies%2Fdownload%2Fvue-cookies-1.7.4.tgz", "resolved": "https://registry.npm.taobao.org/vue-cookies/download/vue-cookies-1.7.4.tgz?cache=0&sync_timestamp=1598941352058&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fvue-cookies%2Fdownload%2Fvue-cookies-1.7.4.tgz",

1
web_src/package.json

@ -21,6 +21,7 @@
"vue-baidu-map": "^0.21.22", "vue-baidu-map": "^0.21.22",
"vue-clipboard2": "^0.3.1", "vue-clipboard2": "^0.3.1",
"vue-clipboards": "^1.3.0", "vue-clipboards": "^1.3.0",
"vue-contextmenujs": "^1.3.13",
"vue-cookies": "^1.7.4", "vue-cookies": "^1.7.4",
"vue-router": "^3.1.6" "vue-router": "^3.1.6"
}, },

2
web_src/src/components/ParentPlatformList.vue

@ -138,7 +138,7 @@ export default {
}); });
}, },
chooseChannel: function(platform) { chooseChannel: function(platform) {
this.$refs.chooseChannelDialog.openDialog(platform.serverGBId, this.initData) this.$refs.chooseChannelDialog.openDialog(platform.serverGBId, platform.name, platform.catalogId, this.initData)
}, },
initData: function() { initData: function() {
this.getPlatformList(); this.getPlatformList();

101
web_src/src/components/dialog/catalogEdit.vue

@ -0,0 +1,101 @@
<template>
<div id="catalogEdit" v-loading="isLoging">
<el-dialog
title="节点编辑"
width="40%"
top="2rem"
:append-to-body="true"
:close-on-click-modal="false"
:visible.sync="showDialog"
:destroy-on-close="true"
@close="close()"
>
<div id="shared" style="margin-top: 1rem;margin-right: 100px;">
<el-form ref="form" :rules="rules" :model="form" label-width="140px" >
<el-form-item label="节点编号" prop="id" >
<el-input v-model="form.id" :disabled="isEdit"></el-input>
</el-form-item>
<el-form-item label="节点名称" prop="name">
<el-input v-model="form.name" clearable></el-input>
</el-form-item>
<el-form-item>
<div style="float: right;">
<el-button type="primary" @click="onSubmit" >确认</el-button>
<el-button @click="close">取消</el-button>
</div>
</el-form-item>
</el-form>
</div>
</el-dialog>
</div>
</template>
<script>
export default {
name: "catalogEdit",
computed: {},
props: ['platformId'],
created() {},
data() {
return {
submitCallback: null,
showDialog: false,
isLoging: false,
isEdit: false,
form: {
id: null,
name: null,
platformId: null,
parentId: null,
},
rules: {
name: [{ required: true, message: "请输入名称", trigger: "blur" }],
id: [{ required: true, message: "请输入id", trigger: "blur" }]
},
};
},
methods: {
openDialog: function (isEdit, id, name, parentId, callback) {
console.log("parentId: " + parentId)
this.isEdit = isEdit;
this.form.id = id;
this.form.name = name;
this.form.platformId = this.platformId;
this.form.parentId = parentId;
this.showDialog = true;
this.submitCallback = callback;
},
onSubmit: function () {
console.log("onSubmit");
console.log(this.form);
this.$axios({
method:"post",
url:`/api/platform/catalog/${!this.isEdit? "add":"edit"}`,
data: this.form
})
.then((res)=> {
if (res.data.code === 0) {
console.log("添加/修改成功")
if (this.submitCallback)this.submitCallback()
}else {
this.$message({
showClose: true,
message: res.data.msg,
type: "error",
});
}
this.close();
})
.catch((error)=> {
console.log(error);
});
},
close: function () {
this.showDialog = false;
this.$refs.form.resetFields();
},
},
};
</script>

83
web_src/src/components/dialog/chooseChannel.vue

@ -1,25 +1,40 @@
<template> <template>
<div id="chooseChannel" v-loading="isLoging"> <div id="chooseChannel" v-loading="isLoging">
<el-dialog title="选择通道" v-if="showDialog" top="2rem" width="70%" :close-on-click-modal="false" :visible.sync="showDialog" :destroy-on-close="true" @close="close()"> <el-dialog title="选择通道" v-if="showDialog" top="2rem" width="90%" :close-on-click-modal="false" :visible.sync="showDialog" :destroy-on-close="true" @close="close()">
<el-tabs v-model="tabActiveName" > <el-row>
<el-tab-pane label="国标通道" name="gbChannel"> <el-col :span="10">
<el-container> <el-tabs v-model="catalogTabActiveName" >
<el-main style="background-color: #FFF;"> <el-tab-pane label="目录结构" name="catalog">
<chooseChannelForGb :platformId=platformId ></chooseChannelForGb> <el-container>
</el-main> <el-main style="background-color: #FFF;">
</el-container> <chooseChannelForCatalog ref="chooseChannelForCatalog" :platformId=platformId :platformName=platformName :defaultCatalogId=defaultCatalogId :catalogIdChange="catalogIdChange"></chooseChannelForCatalog>
</el-main>
</el-container>
</el-tab-pane>
</el-tabs>
</el-col>
<el-col :span="14">
<el-tabs v-model="tabActiveName" @tab-click="tabClick">
<el-tab-pane label="国标通道" name="gbChannel">
<el-container>
<el-main style="background-color: #FFF;">
<chooseChannelForGb ref="chooseChannelForGb" :platformId=platformId :updateChoosedCallback="updateChooseChannelCallback"></chooseChannelForGb>
</el-main>
</el-container>
</el-tab-pane> </el-tab-pane>
<el-tab-pane label="直播流通道" name="streamchannel"> <el-tab-pane label="直播流通道" name="streamchannel">
<el-container> <el-container>
<el-main style="background-color: #FFF;"> <el-main style="background-color: #FFF;">
<chooseChannelFoStream :platformId=platformId ></chooseChannelFoStream> <chooseChannelFoStream ref="chooseChannelFoStream" :platformId=platformId :updateChoosedCallback="updateChooseChannelCallback"></chooseChannelFoStream>
</el-main> </el-main>
</el-container> </el-container>
</el-tab-pane> </el-tab-pane>
</el-tabs> </el-tabs>
</el-col>
</el-row>
</el-dialog> </el-dialog>
</div> </div>
</template> </template>
@ -27,12 +42,14 @@
<script> <script>
import chooseChannelForGb from '../dialog/chooseChannelForGb.vue' import chooseChannelForGb from '../dialog/chooseChannelForGb.vue'
import chooseChannelFoStream from '../dialog/chooseChannelForStream.vue' import chooseChannelFoStream from '../dialog/chooseChannelForStream.vue'
import chooseChannelForCatalog from '../dialog/chooseChannelForCatalog.vue'
export default { export default {
name: 'chooseChannel', name: 'chooseChannel',
props: {}, props: {},
components: { components: {
chooseChannelForGb, chooseChannelForGb,
chooseChannelFoStream, chooseChannelFoStream,
chooseChannelForCatalog,
}, },
computed: { computed: {
// getPlayerShared: function () { // getPlayerShared: function () {
@ -47,20 +64,35 @@ export default {
return { return {
isLoging: false, isLoging: false,
tabActiveName: "gbChannel", tabActiveName: "gbChannel",
catalogTabActiveName: "catalog",
platformId: "", platformId: "",
isLoging: false, catalogId: "",
platformName: "",
defaultCatalogId: "",
showDialog: false, showDialog: false,
chooseData: {} chooseData: {}
}; };
}, },
methods: { methods: {
openDialog: function (platformId, closeCallback) { openDialog(platformId, platformName, defaultCatalogId, closeCallback) {
console.log(platformId)
this.platformId = platformId this.platformId = platformId
this.platformName = platformName
this.defaultCatalogId = defaultCatalogId
this.showDialog = true this.showDialog = true
this.closeCallback = closeCallback this.closeCallback = closeCallback
}, },
tabClick (tab, event){
console.log(tab.label)
if (tab.label === "gbChannel") {
this.$refs.chooseChannelForGb.catalogIdChange(this.catalogId);
this.$refs.chooseChannelForGb.initData();
}else {
this.$refs.chooseChannelFoStream.catalogIdChange(this.catalogId);
this.$refs.chooseChannelFoStream.initData();
}
},
close: function() { close: function() {
this.closeCallback() this.closeCallback()
}, },
@ -88,6 +120,21 @@ export default {
}).catch(function (error) { }).catch(function (error) {
console.log(error); console.log(error);
}); });
},
catalogIdChange: function (id) {
console.log("中间模块收到: " + id)
this.catalogId = id;
if (this.tabActiveName === "gbChannel") {
this.$refs.chooseChannelForGb.catalogIdChange(id);
}else {
this.$refs.chooseChannelFoStream.catalogIdChange(id);
}
},
updateChooseChannelCallback (id, nodeIds){
console.log("中间模块收到选择通道变化: " + id)
console.log("中间模块收到选择通道变化: " + nodeIds)
console.log("中间模块收到选择通道变化: " + typeof (nodeIds))
this.$refs.chooseChannelForCatalog.refreshCatalogById(id, nodeIds)
} }
} }
}; };

311
web_src/src/components/dialog/chooseChannelForCatalog.vue

@ -0,0 +1,311 @@
<template>
<div id="chooseChannelForCatalog" >
<div style="background-color: #FFFFFF; margin-bottom: 1rem; position: relative; padding: 0.5rem; text-align: left;font-size: 14px;">
<el-tree class="el-scrollbar"
ref="tree"
id="catalogTree"
empty-text="未知节点"
node-key="id"
default-expand-all
:highlight-current="true"
:expand-on-click-node="false"
:props="props"
:load="loadNode"
@node-contextmenu="contextmenuEventHandler"
lazy>
<span class="custom-tree-node" slot-scope="{ node, data }" style="width: 100%">
<el-radio v-if="node.data.type === 0" style="margin-right: 0" v-model="chooseId" :label="node.data.id">{{''}}</el-radio>
<span v-if="node.data.type === 0 && node.level === 1" class="el-icon-s-home"></span>
<span v-if="node.data.type === 0 && node.level > 1" class="el-icon-folder-opened"></span>
<span v-if="node.data.type === 1" class="iconfont icon-shexiangtou"></span>
<span v-if="node.data.type === 2" class="iconfont icon-zhibo"></span>
<span style="padding-left: 1px">{{ node.label }}</span>
<span>
<i style="margin-left: 5rem; color: #9d9d9d; padding-right: 20px" v-if="node.data.id === defaultCatalogId">默认</i>
</span>
</span>
</el-tree>
</div>
<catalogEdit ref="catalogEdit" :platformId="platformId"></catalogEdit>
</div>
</template>
<script>
import catalogEdit from './catalogEdit.vue'
export default {
name: 'chooseChannelForCatalog',
props: ['platformId', 'platformName', 'defaultCatalogId', 'catalogIdChange'],
created() {
this.initData();
setTimeout(()=>{
if (this.catalogIdChange)this.catalogIdChange(this.defaultCatalogId);
}, 100)
},
components: {
catalogEdit,
},
data() {
return {
props: {
label: 'name',
children: 'children',
isLeaf: 'leaf'
},
chooseNode: null,
chooseId: this.defaultCatalogId,
catalogTree: null,
contextmenuShow: false
};
},
watch:{
platformId(newData, oldData){
console.log(newData)
this.initData()
},
chooseId(newData, oldData){
console.log("发送: " + newData)
if (this.catalogIdChange)this.catalogIdChange(newData);
},
},
methods: {
initData: function () {
this.getCatalog();
},
getCatalog: function(parentId, callback) {
let that = this;
this.$axios({
method:"get",
url:`/api/platform/catalog`,
params: {
platformId: that.platformId,
parentId: parentId
}
})
.then((res)=> {
if (res.data.code === 0) {
if (typeof(callback) === 'function') {
callback(res.data.data)
}
//
// if (typeof (this.$refs.tree.setCurrentKey) == "undefined") {
// this.$refs.tree.setCurrentKey(this.defaultCatalogId)
// let data = this.$refs.tree.getCurrentNode()
// if (data != null && data.id === this.defaultCatalogId) {
// this.currentCatalogChange(data, this.$refs.tree.getNode(data.id))
// }
// }
}
})
.catch(function (error) {
console.log(error);
});
},
addCatalog: function (parentId, node){
let that = this;
//
that.$refs.catalogEdit.openDialog(false, null, null, parentId, ()=>{
node.loaded = false
node.expand();
});
},
refreshCatalog: function (node){
node.loaded = false
node.expand();
},
refreshCatalogById: function (id, nodeIds) {
if (id) {
console.log("refreshCatalogById: " + id)
let node = this.$refs.tree.getNode(id);
console.log(node)
this.refreshCatalog(node);
}
if (nodeIds !== null) {
let refreshNode = {}
for (let i = 0; i < nodeIds.length; i++) {
let node = this.$refs.tree.getNode(nodeIds[i]);
refreshNode[node.parent.data.id] = node.parent
}
if (Object.values(refreshNode).length > 0) {
for (let j = 0; j < Object.values(refreshNode).length; j++) {
this.refreshCatalog(Object.values(refreshNode)[j]);
}
}
}
},
editCatalog: function (data, node){
let that = this;
//
that.$refs.catalogEdit.openDialog(true, data.id, data.name, data.parentId, (data)=>{
node.parent.loaded = false
node.parent.expand();
});
},
removeCatalog: function (id, node){
this.$axios({
method:"delete",
url:`/api/platform/catalog/del`,
params: {
id: id,
}
})
.then((res) => {
if (res.data.code === 0) {
console.log("移除成功")
node.parent.loaded = false
node.parent.expand();
}
})
.catch(function (error) {
console.log(error);
});
},
setDefaultCatalog: function (id){
this.$axios({
method:"post",
url:`/api/platform/catalog/default/update`,
params: {
platformId: this.platformId,
catalogId: id,
}
})
.then((res)=> {
if (res.data.code === 0) {
this.defaultCatalogId = id;
}
})
.catch(function (error) {
console.log(error);
});
},
loadNode: function(node, resolve){
if (node.level === 0) {
resolve([{
name: this.platformName,
id: this.platformId,
type: 0
}]);
}
if (node.level >= 1){
this.getCatalog(node.data.id, resolve)
}
},
contextmenuEventHandler: function (event,data,node,element){
if (node.data.type !== 0) {
data.parentId = node.parent.data.id;
this.$contextmenu({
items: [
{
label: "移除通道",
icon: "el-icon-delete",
disabled: false,
onClick: () => {
this.$axios({
method:"delete",
url:"/api/platform/catalog/relation/del",
data: data
}).then((res)=>{
console.log("移除成功")
node.parent.loaded = false
node.parent.expand();
}).catch(function (error) {
console.log(error);
});
}
}
],
event, //
customClass: "custom-class", // class
zIndex: 3000, // z-index
});
}else {
this.$contextmenu({
items: [
{
label: "刷新节点",
icon: "el-icon-refresh",
disabled: false,
onClick: () => {
this.refreshCatalog(node);
}
},
{
label: "新建节点",
icon: "el-icon-plus",
disabled: false,
onClick: () => {
this.addCatalog(data.id, node);
}
},
{
label: "修改节点",
icon: "el-icon-edit",
disabled: node.level === 1,
onClick: () => {
this.editCatalog(data, node);
}
},
{
label: "删除节点",
icon: "el-icon-delete",
disabled: node.level === 1,
divided: true,
onClick: () => {
this.removeCatalog(data.id, node)
}
},
{
label: "设为默认",
icon: "el-icon-folder-checked",
disabled: node.data.id === this.defaultCatalogId,
onClick: () => {
this.setDefaultCatalog(data.id)
},
},
// {
// label: "",
// icon: "el-icon-download",
// disabled: false,
// children: [
// {
// label: "",
// onClick: () => {
//
// },
// },
// {
// label: "",
// onClick: () => {
//
// },
// }
// ]
// },
],
event, //
customClass: "custom-class", // class
zIndex: 3000, // z-index
});
}
return false;
},
}
};
</script>
<style>
#catalogTree{
display: inline-block;
}
</style>

55
web_src/src/components/dialog/chooseChannelForGb.vue

@ -21,9 +21,9 @@
<el-option label="离线" value="false"></el-option> <el-option label="离线" value="false"></el-option>
</el-select> </el-select>
<el-checkbox @change="shareAllCheckedChanage">全部共享</el-checkbox> <el-checkbox @change="shareAllCheckedChange">全部共享</el-checkbox>
</div> </div>
<el-table ref="gbChannelsTable" :data="gbChannels" border style="width: 100%" @selection-change="checkedChanage" > <el-table ref="gbChannelsTable" :data="gbChannels" border style="width: 100%" @selection-change="checkedChange" >
<el-table-column type="selection" width="55" align="center" fixed > </el-table-column> <el-table-column type="selection" width="55" align="center" fixed > </el-table-column>
<el-table-column prop="channelId" label="通道编号" width="210"> <el-table-column prop="channelId" label="通道编号" width="210">
</el-table-column> </el-table-column>
@ -49,7 +49,6 @@
<script> <script>
export default { export default {
name: 'chooseChannelForGb', name: 'chooseChannelForGb',
props: {},
computed: { computed: {
// getPlayerShared: function () { // getPlayerShared: function () {
// return { // return {
@ -59,7 +58,7 @@ export default {
// }; // };
// } // }
}, },
props: ['platformId'], props: ['platformId', 'updateChoosedCallback'],
created() { created() {
this.initData(); this.initData();
}, },
@ -71,6 +70,7 @@ export default {
channelType: "", channelType: "",
online: "", online: "",
choosed: "", choosed: "",
catalogId: null,
currentPage: 1, currentPage: 1,
count: 10, count: 10,
total: 0, total: 0,
@ -97,28 +97,28 @@ export default {
this.count = val; this.count = val;
console.log(val) console.log(val)
this.initData(); this.initData();
}, },
rowcheckedChanage: function (val, row) { rowcheckedChange: function (val, row) {
console.log(val) console.log(val)
console.log(row) console.log(row)
}, },
checkedChanage: function (val) { // selectDisable: function (){
var that = this; // if (this.catalogId == null) {
// return false;
// }
// },
checkedChange: function (val) {
let that = this;
if (!that.eventEnanle) { if (!that.eventEnanle) {
return; return;
} }
var tabelData = JSON.parse(JSON.stringify(this.$refs.gbChannelsTable.data)); let newData = {};
console.log("checkedChanage") let addData = [];
console.log(val) let delData = [];
var newData = {};
var addData = [];
var delData = [];
if (val.length > 0) { if (val.length > 0) {
for (let i = 0; i < val.length; i++) { for (let i = 0; i < val.length; i++) {
const element = val[i]; const element = val[i];
var key = element.deviceId + "_" + element.channelId; let key = element.deviceId + "_" + element.channelId;
newData[key] = element; newData[key] = element;
if (!!!that.gbChoosechannel[key]){ if (!!!that.gbChoosechannel[key]){
addData.push(element) addData.push(element)
@ -127,7 +127,7 @@ export default {
} }
} }
var oldKeys = Object.keys(that.gbChoosechannel); let oldKeys = Object.keys(that.gbChoosechannel);
if (oldKeys.length > 0) { if (oldKeys.length > 0) {
for (let i = 0; i < oldKeys.length; i++) { for (let i = 0; i < oldKeys.length; i++) {
const key = oldKeys[i]; const key = oldKeys[i];
@ -136,7 +136,7 @@ export default {
} }
}else{ }else{
var oldKeys = Object.keys(that.gbChoosechannel); let oldKeys = Object.keys(that.gbChoosechannel);
if (oldKeys.length > 0) { if (oldKeys.length > 0) {
for (let i = 0; i < oldKeys.length; i++) { for (let i = 0; i < oldKeys.length; i++) {
const key = oldKeys[i]; const key = oldKeys[i];
@ -152,15 +152,17 @@ export default {
url:"/api/platform/update_channel_for_gb", url:"/api/platform/update_channel_for_gb",
data:{ data:{
platformId: that.platformId, platformId: that.platformId,
channelReduces: addData channelReduces: addData,
catalogId: that.catalogId
} }
}).then((res)=>{ }).then((res)=>{
console.log("保存成功") console.log("保存成功")
if(that.updateChoosedCallback)that.updateChoosedCallback(that.catalogId)
}).catch(function (error) { }).catch(function (error) {
console.log(error); console.log(error);
}); });
} }
if (Object.keys(delData).length >0) { if (delData.length >0) {
that.$axios({ that.$axios({
method:"delete", method:"delete",
url:"/api/platform/del_channel_for_gb", url:"/api/platform/del_channel_for_gb",
@ -170,13 +172,18 @@ export default {
} }
}).then((res)=>{ }).then((res)=>{
console.log("移除成功") console.log("移除成功")
let nodeIds = new Array();
for (let i = 0; i < delData.length; i++) {
nodeIds.push(delData[i].channelId)
}
if(that.updateChoosedCallback)that.updateChoosedCallback(null, nodeIds)
}).catch(function (error) { }).catch(function (error) {
console.log(error); console.log(error);
}); });
} }
}, },
shareAllCheckedChanage: function (val) { shareAllCheckedChange: function (val) {
this.chooseChanage(null, val) this.chooseChanage(null, val)
}, },
getChannelList: function () { getChannelList: function () {
@ -215,7 +222,7 @@ export default {
} }
} }
that.eventEnanle = true; that.eventEnanle = true;
// that.checkedChanage(chooseGBS) // that.checkedChange(chooseGBS)
}) })
console.log(that.gbChoosechannel) console.log(that.gbChoosechannel)
}) })
@ -230,6 +237,10 @@ export default {
handleGBSelectionChange: function() { handleGBSelectionChange: function() {
this.initData(); this.initData();
}, },
catalogIdChange: function(id) {
this.catalogId = id;
console.log("通道选择模块收到: " + id)
},
} }
}; };
</script> </script>

11
web_src/src/components/dialog/chooseChannelForStream.vue

@ -27,7 +27,6 @@
<script> <script>
export default { export default {
name: 'chooseChannelFoStream', name: 'chooseChannelFoStream',
props: {},
computed: { computed: {
// getPlayerShared: function () { // getPlayerShared: function () {
// return { // return {
@ -37,7 +36,7 @@ export default {
// }; // };
// } // }
}, },
props: ['platformId'], props: ['platformId', 'updateChoosedCallback'],
created() { created() {
this.initData(); this.initData();
}, },
@ -49,6 +48,7 @@ export default {
channelType: "", channelType: "",
online: "", online: "",
choosed: "", choosed: "",
catalogId: null,
currentPage: 1, currentPage: 1,
count: 10, count: 10,
total: 0, total: 0,
@ -131,10 +131,12 @@ export default {
url:"/api/gbStream/add", url:"/api/gbStream/add",
data:{ data:{
platformId: that.platformId, platformId: that.platformId,
catalogId: that.catalogId,
gbStreams: addData, gbStreams: addData,
} }
}).then((res)=>{ }).then((res)=>{
console.log("保存成功") console.log("保存成功")
if(this.updateChoosedCallback)this.updateChoosedCallback(this.catalogId)
}).catch(function (error) { }).catch(function (error) {
console.log(error); console.log(error);
}); });
@ -149,6 +151,7 @@ export default {
} }
}).then((res)=>{ }).then((res)=>{
console.log("移除成功") console.log("移除成功")
if(this.updateChoosedCallback)this.updateChoosedCallback(this.catalogId)
}).catch(function (error) { }).catch(function (error) {
console.log(error); console.log(error);
}); });
@ -207,6 +210,10 @@ export default {
handleGBSelectionChange: function() { handleGBSelectionChange: function() {
this.initData(); this.initData();
}, },
catalogIdChange: function(id) {
this.catalogId = id;
console.log("直播通道选择模块收到: " + id)
},
} }
}; };
</script> </script>

1
web_src/src/components/dialog/platformEdit.vue

@ -196,6 +196,7 @@ export default {
this.platform.transport = platform.transport; this.platform.transport = platform.transport;
this.platform.characterSet = platform.characterSet; this.platform.characterSet = platform.characterSet;
this.platform.shareAllLiveStream = platform.shareAllLiveStream; this.platform.shareAllLiveStream = platform.shareAllLiveStream;
this.platform.catalogId = platform.catalogId;
this.onSubmit_text = "保存"; this.onSubmit_text = "保存";
} }
this.showDialog = true; this.showDialog = true;

2
web_src/src/main.js

@ -12,6 +12,7 @@ import VueClipboard from 'vue-clipboard2';
import { Notification } from 'element-ui'; import { Notification } from 'element-ui';
import Fingerprint2 from 'fingerprintjs2'; import Fingerprint2 from 'fingerprintjs2';
import VueClipboards from 'vue-clipboards'; import VueClipboards from 'vue-clipboards';
import Contextmenu from "vue-contextmenujs"
// 生成唯一ID // 生成唯一ID
@ -37,6 +38,7 @@ Vue.use(VueCookies);
Vue.use(VueClipboards); Vue.use(VueClipboards);
Vue.prototype.$axios = axios; Vue.prototype.$axios = axios;
Vue.prototype.$notify = Notification; Vue.prototype.$notify = Notification;
Vue.use(Contextmenu);
axios.defaults.baseURL = (process.env.NODE_ENV === 'development') ? process.env.BASE_API : ""; axios.defaults.baseURL = (process.env.NODE_ENV === 'development') ? process.env.BASE_API : "";

26
web_src/static/css/iconfont.css

@ -1,8 +1,8 @@
@font-face { @font-face {
font-family: "iconfont"; /* Project id 1291092 */ font-family: "iconfont"; /* Project id 1291092 */
src: url('iconfont.woff2?t=1637741914969') format('woff2'), src: url('iconfont.woff2?t=1640922722742') format('woff2'),
url('iconfont.woff?t=1637741914969') format('woff'), url('iconfont.woff?t=1640922722742') format('woff'),
url('iconfont.ttf?t=1637741914969') format('truetype'); url('iconfont.ttf?t=1640922722742') format('truetype');
} }
.iconfont { .iconfont {
@ -13,6 +13,22 @@
-moz-osx-font-smoothing: grayscale; -moz-osx-font-smoothing: grayscale;
} }
.icon-wxbzhuye:before {
content: "\e7d1";
}
.icon-mulu:before {
content: "\e7d2";
}
.icon-zhibo:before {
content: "\e8c1";
}
.icon-shexiangtou:before {
content: "\e7d3";
}
.icon-suoxiao:before { .icon-suoxiao:before {
content: "\e79a"; content: "\e79a";
} }
@ -49,7 +65,7 @@
content: "\e7a2"; content: "\e7a2";
} }
.icon-kuaijin:before { .icon-houtui:before {
content: "\e7a3"; content: "\e7a3";
} }
@ -57,7 +73,7 @@
content: "\e7a4"; content: "\e7a4";
} }
.icon-kuaitui:before { .icon-kuaijin:before {
content: "\e7a5"; content: "\e7a5";
} }

BIN
web_src/static/css/iconfont.woff2

Binary file not shown.
Loading…
Cancel
Save