From f5fcc79a2c7e6379a73b14ba4e366ad1654e9475 Mon Sep 17 00:00:00 2001 From: 648540858 <648540858@qq.com> Date: Sun, 3 Jul 2022 07:40:54 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=9B=BD=E6=A0=87=E6=A0=91?= =?UTF-8?q?=E5=9E=8B=E5=B1=95=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sql/mysql.sql | 527 +++++++++--------- sql/update.sql | 5 + .../iot/vmp/gb28181/bean/ChannelIdType.java | 23 + .../iot/vmp/gb28181/bean/Device.java | 13 + .../iot/vmp/gb28181/bean/DeviceChannel.java | 13 + .../cmd/impl/SIPCommanderFroPlatform.java | 5 +- .../impl/RegisterRequestProcessor.java | 1 + .../iot/vmp/gb28181/utils/XmlUtil.java | 35 +- .../iot/vmp/service/IDeviceService.java | 19 + .../vmp/service/impl/DeviceServiceImpl.java | 185 +++++- .../iot/vmp/service/impl/PlayServiceImpl.java | 3 +- .../vmp/storager/dao/DeviceChannelMapper.java | 45 +- .../iot/vmp/storager/dao/DeviceMapper.java | 3 + .../iot/vmp/vmanager/bean/BaseTree.java | 87 +++ .../vmanager/gb28181/device/DeviceQuery.java | 96 ++++ src/main/resources/logback-spring-local.xml | 5 + web_src/package-lock.json | 78 ++- web_src/package.json | 4 +- web_src/src/components/DeviceList.vue | 6 +- web_src/src/components/channelList.vue | 301 ++++++---- web_src/src/components/common/DeviceTree.vue | 141 ++--- .../components/common/DeviceTreeForZtree.vue | 112 ++++ web_src/src/components/dialog/deviceEdit.vue | 6 + web_src/src/components/live.vue | 20 +- web_src/src/components/map.vue | 72 ++- .../src/components/service/DeviceService.js | 43 ++ web_src/src/router/index.js | 2 +- web_src/static/css/iconfont.css | 28 +- web_src/static/css/iconfont.woff2 | Bin 54140 -> 54780 bytes 29 files changed, 1341 insertions(+), 537 deletions(-) create mode 100644 src/main/java/com/genersoft/iot/vmp/gb28181/bean/ChannelIdType.java create mode 100644 src/main/java/com/genersoft/iot/vmp/vmanager/bean/BaseTree.java create mode 100644 web_src/src/components/common/DeviceTreeForZtree.vue diff --git a/sql/mysql.sql b/sql/mysql.sql index e23f0550..f28e3982 100644 --- a/sql/mysql.sql +++ b/sql/mysql.sql @@ -1,13 +1,13 @@ --- MariaDB dump 10.19 Distrib 10.7.3-MariaDB, for Linux (x86_64) +-- MySQL dump 10.13 Distrib 8.0.29, for Linux (x86_64) -- -- Host: 127.0.0.1 Database: wvp3 -- ------------------------------------------------------ --- Server version 8.0.0-dmr +-- Server version 8.0.29-0ubuntu0.22.04.2 /*!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 */; -/*!40101 SET NAMES utf8mb4 */; +/*!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 */; @@ -21,34 +21,36 @@ DROP TABLE IF EXISTS `device`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `device` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `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(11) NOT NULL, - `expires` int(11) NOT NULL, - `subscribeCycleForCatalog` int(11) NOT NULL, - `subscribeCycleForMobilePosition` int(11) NOT NULL, - `mobilePositionSubmissionInterval` int(11) NOT NULL DEFAULT '5', - `subscribeCycleForAlarm` int(11) NOT NULL, - `hostAddress` varchar(50) NOT NULL, - `charset` varchar(50) NOT NULL, - `ssrcCheck` int(11) DEFAULT '0', - PRIMARY KEY (`id`), - UNIQUE KEY `device_deviceId_uindex` (`deviceId`) -) ENGINE=InnoDB AUTO_INCREMENT=47 DEFAULT CHARSET=utf8mb4; + `id` int NOT NULL AUTO_INCREMENT, + `deviceId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, + `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, + `manufacturer` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, + `model` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, + `firmware` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, + `transport` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, + `streamMode` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, + `online` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, + `registerTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, + `keepaliveTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, + `ip` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, + `createTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, + `updateTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, + `port` int NOT NULL, + `expires` int NOT NULL, + `subscribeCycleForCatalog` int NOT NULL, + `hostAddress` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, + `charset` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, + `subscribeCycleForMobilePosition` int DEFAULT NULL, + `mobilePositionSubmissionInterval` int DEFAULT '5', + `subscribeCycleForAlarm` int DEFAULT NULL, + `ssrcCheck` int DEFAULT '0', + `geoCoordSys` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, + `treeType` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, + PRIMARY KEY (`id`) USING BTREE, + UNIQUE KEY `device_deviceId_uindex` (`deviceId`) USING BTREE +) ENGINE=InnoDB AUTO_INCREMENT=32 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -66,20 +68,20 @@ UNLOCK TABLES; DROP TABLE IF EXISTS `device_alarm`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `device_alarm` ( - `id` int(11) 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`) USING BTREE -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC; + `id` int NOT NULL AUTO_INCREMENT, + `deviceId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, + `channelId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, + `alarmPriority` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, + `alarmMethod` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, + `alarmTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, + `alarmDescription` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, + `longitude` double DEFAULT NULL, + `latitude` double DEFAULT NULL, + `alarmType` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, + PRIMARY KEY (`id`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -97,43 +99,48 @@ UNLOCK TABLES; DROP TABLE IF EXISTS `device_channel`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `device_channel` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `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(11) DEFAULT NULL, - `registerWay` int(11) DEFAULT NULL, - `certNum` varchar(50) DEFAULT NULL, - `certifiable` int(11) DEFAULT NULL, - `errCode` int(11) DEFAULT NULL, - `endTime` varchar(50) DEFAULT NULL, - `secrecy` varchar(50) DEFAULT NULL, - `ipAddress` varchar(50) DEFAULT NULL, - `port` int(11) DEFAULT NULL, - `password` varchar(255) DEFAULT NULL, - `PTZType` int(11) DEFAULT NULL, - `status` int(11) 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, - `subCount` int(11) DEFAULT '0', - PRIMARY KEY (`id`), - UNIQUE KEY `device_channel_id_uindex` (`id`), - UNIQUE KEY `device_channel_pk` (`channelId`,`deviceId`) -) ENGINE=InnoDB AUTO_INCREMENT=81657 DEFAULT CHARSET=utf8mb4; + `id` int NOT NULL AUTO_INCREMENT, + `channelId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, + `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, + `manufacture` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, + `model` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, + `owner` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, + `civilCode` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, + `block` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, + `address` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, + `parentId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, + `safetyWay` int DEFAULT NULL, + `registerWay` int DEFAULT NULL, + `certNum` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, + `certifiable` int DEFAULT NULL, + `errCode` int DEFAULT NULL, + `endTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, + `secrecy` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, + `ipAddress` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, + `port` int DEFAULT NULL, + `password` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, + `PTZType` int DEFAULT NULL, + `status` int DEFAULT NULL, + `longitude` double DEFAULT NULL, + `latitude` double DEFAULT NULL, + `streamId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, + `deviceId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, + `parental` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, + `hasAudio` bit(1) DEFAULT NULL, + `createTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, + `updateTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, + `subCount` int DEFAULT '0', + `longitudeGcj02` double DEFAULT NULL, + `latitudeGcj02` double DEFAULT NULL, + `longitudeWgs84` double DEFAULT NULL, + `latitudeWgs84` double DEFAULT NULL, + `businessGroupId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, + PRIMARY KEY (`id`) USING BTREE, + UNIQUE KEY `device_channel_id_uindex` (`id`) USING BTREE, + UNIQUE KEY `device_channel_pk` (`channelId`,`deviceId`) USING BTREE +) ENGINE=InnoDB AUTO_INCREMENT=19314 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -151,24 +158,24 @@ UNLOCK TABLES; DROP TABLE IF EXISTS `device_mobile_position`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `device_mobile_position` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `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 (`id`) -) ENGINE=InnoDB AUTO_INCREMENT=6108 DEFAULT CHARSET=utf8mb4; + `id` int NOT NULL AUTO_INCREMENT, + `deviceId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, + `channelId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, + `deviceName` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, + `time` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci 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) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, + `geodeticSystem` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, + `cnLng` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, + `cnLat` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, + PRIMARY KEY (`id`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -186,23 +193,23 @@ UNLOCK TABLES; DROP TABLE IF EXISTS `gb_stream`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `gb_stream` ( - `gbStreamId` int(11) NOT NULL AUTO_INCREMENT, - `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(11) DEFAULT NULL, - `createStamp` bigint(20) DEFAULT NULL, - PRIMARY KEY (`gbStreamId`) USING BTREE, - UNIQUE KEY `app` (`app`,`stream`) USING BTREE, - UNIQUE KEY `gbId` (`gbId`) USING BTREE -) ENGINE=InnoDB AUTO_INCREMENT=300769 DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC; + `gbStreamId` int NOT NULL AUTO_INCREMENT, + `app` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, + `stream` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, + `gbId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, + `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, + `longitude` double DEFAULT NULL, + `latitude` double DEFAULT NULL, + `streamType` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, + `mediaServerId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, + `status` int DEFAULT NULL, + `createStamp` bigint DEFAULT NULL, + PRIMARY KEY (`gbStreamId`) USING BTREE, + UNIQUE KEY `app` (`app`,`stream`) USING BTREE, + UNIQUE KEY `gbId` (`gbId`) USING BTREE +) ENGINE=InnoDB AUTO_INCREMENT=301679 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -220,19 +227,19 @@ UNLOCK TABLES; DROP TABLE IF EXISTS `log`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `log` ( - `id` int(11) 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(20) NOT NULL, - `username` varchar(50) NOT NULL, - `createTime` varchar(50) NOT NULL, - PRIMARY KEY (`id`) USING BTREE -) ENGINE=InnoDB AUTO_INCREMENT=1552 DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC; + `id` int NOT NULL AUTO_INCREMENT, + `name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, + `type` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, + `uri` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, + `address` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, + `result` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, + `timing` bigint NOT NULL, + `username` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, + `createTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, + PRIMARY KEY (`id`) USING BTREE +) ENGINE=InnoDB AUTO_INCREMENT=21611 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -250,34 +257,34 @@ UNLOCK TABLES; DROP TABLE IF EXISTS `media_server`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!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(11) NOT NULL, - `httpSSlPort` int(11) NOT NULL, - `rtmpPort` int(11) NOT NULL, - `rtmpSSlPort` int(11) NOT NULL, - `rtpProxyPort` int(11) NOT NULL, - `rtspPort` int(11) NOT NULL, - `rtspSSLPort` int(11) NOT NULL, - `autoConfig` int(11) NOT NULL, - `secret` varchar(50) NOT NULL, - `streamNoneReaderDelayMS` int(11) NOT NULL, - `rtpEnable` int(11) NOT NULL, - `rtpPortRange` varchar(50) NOT NULL, - `sendRtpPortRange` varchar(50) NOT NULL, - `recordAssistPort` int(11) NOT NULL, - `defaultServer` int(11) NOT NULL, - `createTime` varchar(50) NOT NULL, - `updateTime` varchar(50) NOT NULL, - `hookAliveInterval` int(11) NOT NULL, - PRIMARY KEY (`id`) USING BTREE, - UNIQUE KEY `media_server_i` (`ip`,`httpPort`) USING BTREE -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC; + `id` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, + `ip` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, + `hookIp` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, + `sdpIp` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, + `streamIp` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci 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) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, + `streamNoneReaderDelayMS` int NOT NULL, + `rtpEnable` int NOT NULL, + `rtpPortRange` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, + `sendRtpPortRange` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, + `recordAssistPort` int NOT NULL, + `defaultServer` int NOT NULL, + `createTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, + `updateTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, + `hookAliveInterval` int NOT NULL, + PRIMARY KEY (`id`) USING BTREE, + UNIQUE KEY `media_server_i` (`ip`,`httpPort`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -295,36 +302,36 @@ UNLOCK TABLES; DROP TABLE IF EXISTS `parent_platform`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `parent_platform` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `enable` int(11) DEFAULT NULL, - `name` varchar(255) DEFAULT NULL, - `serverGBId` varchar(50) NOT NULL, - `serverGBDomain` varchar(50) DEFAULT NULL, - `serverIP` varchar(50) DEFAULT NULL, - `serverPort` int(11) 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(11) DEFAULT NULL, - `rtcp` int(11) DEFAULT NULL, - `status` bit(1) DEFAULT NULL, - `shareAllLiveStream` int(11) DEFAULT NULL, - `startOfflinePush` int(11) DEFAULT '0', - `administrativeDivision` varchar(50) NOT NULL, - `catalogGroup` int(11) DEFAULT '1', - PRIMARY KEY (`id`), - UNIQUE KEY `parent_platform_id_uindex` (`id`), - UNIQUE KEY `parent_platform_pk` (`serverGBId`) -) ENGINE=InnoDB AUTO_INCREMENT=25 DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC; + `id` int NOT NULL AUTO_INCREMENT, + `enable` int DEFAULT NULL, + `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, + `serverGBId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, + `serverGBDomain` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, + `serverIP` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, + `serverPort` int DEFAULT NULL, + `deviceGBId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, + `deviceIp` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, + `devicePort` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, + `username` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, + `password` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, + `expires` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, + `keepTimeout` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, + `transport` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, + `characterSet` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, + `catalogId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, + `ptz` int DEFAULT NULL, + `rtcp` int DEFAULT NULL, + `status` bit(1) DEFAULT NULL, + `shareAllLiveStream` int DEFAULT NULL, + `startOfflinePush` int DEFAULT '0', + `administrativeDivision` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, + `catalogGroup` int DEFAULT '1', + PRIMARY KEY (`id`) USING BTREE, + UNIQUE KEY `parent_platform_id_uindex` (`id`) USING BTREE, + UNIQUE KEY `parent_platform_pk` (`serverGBId`) USING BTREE +) ENGINE=InnoDB AUTO_INCREMENT=31 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -342,14 +349,14 @@ UNLOCK TABLES; DROP TABLE IF EXISTS `platform_catalog`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!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`) USING BTREE -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC; + `id` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, + `platformId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, + `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, + `parentId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, + PRIMARY KEY (`id`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -367,14 +374,14 @@ UNLOCK TABLES; DROP TABLE IF EXISTS `platform_gb_channel`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `platform_gb_channel` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `platformId` varchar(50) NOT NULL, - `catalogId` varchar(50) NOT NULL, - `deviceChannelId` int(11) NOT NULL, - PRIMARY KEY (`id`) -) ENGINE=InnoDB AUTO_INCREMENT=250 DEFAULT CHARSET=utf8mb4; + `id` int NOT NULL AUTO_INCREMENT, + `platformId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, + `catalogId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, + `deviceChannelId` int NOT NULL, + PRIMARY KEY (`id`) USING BTREE +) ENGINE=InnoDB AUTO_INCREMENT=4889 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -392,15 +399,15 @@ UNLOCK TABLES; DROP TABLE IF EXISTS `platform_gb_stream`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `platform_gb_stream` ( - `platformId` varchar(50) NOT NULL, - `catalogId` varchar(50) NOT NULL, - `gbStreamId` int(11) NOT NULL, - `id` int(11) NOT NULL AUTO_INCREMENT, - PRIMARY KEY (`id`), - UNIQUE KEY `platform_gb_stream_pk` (`platformId`,`catalogId`,`gbStreamId`) -) ENGINE=InnoDB AUTO_INCREMENT=301210 DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC; + `platformId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, + `catalogId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, + `gbStreamId` int NOT NULL, + `id` int NOT NULL AUTO_INCREMENT, + PRIMARY KEY (`id`) USING BTREE, + UNIQUE KEY `platform_gb_stream_pk` (`platformId`,`catalogId`,`gbStreamId`) USING BTREE +) ENGINE=InnoDB AUTO_INCREMENT=302077 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -418,29 +425,29 @@ UNLOCK TABLES; DROP TABLE IF EXISTS `stream_proxy`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `stream_proxy` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `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(11) 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, - `status` bit(1) NOT NULL, - `enable_remove_none_reader` bit(1) NOT NULL, - `createTime` varchar(50) NOT NULL, - `name` varchar(255) DEFAULT NULL, - PRIMARY KEY (`id`), - UNIQUE KEY `stream_proxy_pk` (`app`,`stream`) -) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8mb4; + `id` int NOT NULL AUTO_INCREMENT, + `type` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, + `app` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, + `stream` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, + `url` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, + `src_url` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, + `dst_url` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, + `timeout_ms` int DEFAULT NULL, + `ffmpeg_cmd_key` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, + `rtp_type` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, + `mediaServerId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, + `enable_hls` bit(1) DEFAULT NULL, + `enable_mp4` bit(1) DEFAULT NULL, + `enable` bit(1) NOT NULL, + `status` bit(1) NOT NULL, + `enable_remove_none_reader` bit(1) NOT NULL, + `createTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, + `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, + PRIMARY KEY (`id`) USING BTREE, + UNIQUE KEY `stream_proxy_pk` (`app`,`stream`) USING BTREE +) ENGINE=InnoDB AUTO_INCREMENT=61 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -458,21 +465,21 @@ UNLOCK TABLES; DROP TABLE IF EXISTS `stream_push`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `stream_push` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `app` varchar(255) NOT NULL, - `stream` varchar(255) NOT NULL, - `totalReaderCount` varchar(50) DEFAULT NULL, - `originType` int(11) DEFAULT NULL, - `originTypeStr` varchar(50) DEFAULT NULL, - `createStamp` bigint(20) DEFAULT NULL, - `aliveSecond` int(11) DEFAULT NULL, - `mediaServerId` varchar(50) DEFAULT NULL, - `serverId` varchar(50) not NULL, - PRIMARY KEY (`id`), - UNIQUE KEY `stream_push_pk` (`app`,`stream`) -) ENGINE=InnoDB AUTO_INCREMENT=300838 DEFAULT CHARSET=utf8mb4; + `id` int NOT NULL AUTO_INCREMENT, + `app` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, + `stream` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, + `totalReaderCount` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, + `originType` int DEFAULT NULL, + `originTypeStr` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, + `createStamp` bigint DEFAULT NULL, + `aliveSecond` int DEFAULT NULL, + `mediaServerId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, + `serverId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, + PRIMARY KEY (`id`) USING BTREE, + UNIQUE KEY `stream_push_pk` (`app`,`stream`) USING BTREE +) ENGINE=InnoDB AUTO_INCREMENT=305291 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -490,17 +497,17 @@ UNLOCK TABLES; DROP TABLE IF EXISTS `user`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `user` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `username` varchar(255) NOT NULL, - `password` varchar(255) NOT NULL, - `roleId` int(11) NOT NULL, - `createTime` varchar(50) NOT NULL, - `updateTime` varchar(50) NOT NULL, - PRIMARY KEY (`id`) USING BTREE, - UNIQUE KEY `user_username_uindex` (`username`) USING BTREE -) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC; + `id` int NOT NULL AUTO_INCREMENT, + `username` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, + `password` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, + `roleId` int NOT NULL, + `createTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, + `updateTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, + PRIMARY KEY (`id`) USING BTREE, + UNIQUE KEY `user_username_uindex` (`username`) USING BTREE +) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -509,8 +516,7 @@ CREATE 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'); +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; @@ -520,15 +526,15 @@ UNLOCK TABLES; DROP TABLE IF EXISTS `user_role`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `user_role` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `name` varchar(50) NOT NULL, - `authority` varchar(50) NOT NULL, - `createTime` varchar(50) NOT NULL, - `updateTime` varchar(50) NOT NULL, - PRIMARY KEY (`id`) USING BTREE -) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC; + `id` int NOT NULL AUTO_INCREMENT, + `name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, + `authority` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, + `createTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, + `updateTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, + PRIMARY KEY (`id`) USING BTREE +) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -537,8 +543,7 @@ CREATE TABLE `user_role` ( LOCK TABLES `user_role` WRITE; /*!40000 ALTER TABLE `user_role` DISABLE KEYS */; -INSERT INTO `user_role` VALUES - (1,'admin','0','2021-04-13 14:14:57','2021-04-13 14:14:57'); +INSERT INTO `user_role` VALUES (1,'admin','0','2021-04-13 14:14:57','2021-04-13 14:14:57'); /*!40000 ALTER TABLE `user_role` ENABLE KEYS */; UNLOCK TABLES; /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; @@ -551,4 +556,4 @@ UNLOCK TABLES; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; --- Dump completed on 2022-04-18 10:50:27 +-- Dump completed on 2022-06-26 17:33:30 diff --git a/sql/update.sql b/sql/update.sql index f78744d7..0ab8d296 100644 --- a/sql/update.sql +++ b/sql/update.sql @@ -2,7 +2,10 @@ alter table stream_push add serverId varchar(50) not null; alter table device add geoCoordSys varchar(50) not null; +alter table device + add treeType varchar(50) not null; update device set device.geoCoordSys='WGS84'; +update device set device.treeType='CivilCode'; alter table device_channel add longitudeGcj02 double default null; alter table device_channel @@ -11,6 +14,8 @@ alter table device_channel add longitudeWgs84 double default null; alter table device_channel add latitudeWgs84 double default null; +alter table device_channel + add businessGroupId varchar(50) default null; diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/ChannelIdType.java b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/ChannelIdType.java new file mode 100644 index 00000000..320bbdd0 --- /dev/null +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/ChannelIdType.java @@ -0,0 +1,23 @@ +package com.genersoft.iot.vmp.gb28181.bean; + +/** + * 国标类型编码,国标编码中11-13位为类型编码 + * 详见 附 录 D 编码规则 A + * @author lin + */ +public class ChannelIdType { + /** + * 中心信令控制服务器编码 + */ + public final static String CENTRAL_SIGNALING_CONTROL_SERVER = "200"; + + /** + * 业务分组编码 + */ + public final static String BUSINESS_GROUP = "215"; + + /** + * 虚拟组织编码 + */ + public final static String VIRTUAL_ORGANIZATION = "216"; +} diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/Device.java b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/Device.java index 253520bc..880117ff 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/Device.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/Device.java @@ -138,6 +138,11 @@ public class Device { */ private String geoCoordSys; + /** + * 树类型 国标规定了两种树的展现方式 行政区划:CivilCode 和业务分组:BusinessGroup + */ + private String treeType; + public String getDeviceId() { return deviceId; @@ -338,4 +343,12 @@ public class Device { public void setGeoCoordSys(String geoCoordSys) { this.geoCoordSys = geoCoordSys; } + + public String getTreeType() { + return treeType; + } + + public void setTreeType(String treeType) { + this.treeType = treeType; + } } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/DeviceChannel.java b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/DeviceChannel.java index 63452775..16ead73d 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/DeviceChannel.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/DeviceChannel.java @@ -194,6 +194,11 @@ public class DeviceChannel { */ private int channelType; + /** + * 业务分组 + */ + private String businessGroupId; + public int getId() { return id; } @@ -506,4 +511,12 @@ public class DeviceChannel { public void setChannelType(int channelType) { this.channelType = channelType; } + + public String getBusinessGroupId() { + return businessGroupId; + } + + public void setBusinessGroupId(String businessGroupId) { + this.businessGroupId = businessGroupId; + } } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java index 2e70ea75..73f9c4f7 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java @@ -406,7 +406,10 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { if (parentPlatform == null) { return false; } - logger.info("[发送 移动位置订阅] {}/{}->{},{}", parentPlatform.getServerGBId(), gpsMsgInfo.getId(), gpsMsgInfo.getLng(), gpsMsgInfo.getLat()); + if (logger.isDebugEnabled()) { + logger.debug("[发送 移动位置订阅] {}/{}->{},{}", parentPlatform.getServerGBId(), gpsMsgInfo.getId(), gpsMsgInfo.getLng(), gpsMsgInfo.getLat()); + } + try { String characterSet = parentPlatform.getCharacterSet(); StringBuffer deviceStatusXml = new StringBuffer(600); diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/RegisterRequestProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/RegisterRequestProcessor.java index c2226a18..622cf073 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/RegisterRequestProcessor.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/RegisterRequestProcessor.java @@ -141,6 +141,7 @@ public class RegisterRequestProcessor extends SIPRequestProcessorParent implemen device.setStreamMode("UDP"); device.setCharset("GB2312"); device.setGeoCoordSys("WGS84"); + device.setTreeType("CivilCode"); device.setDeviceId(deviceId); } device.setIp(received); diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/utils/XmlUtil.java b/src/main/java/com/genersoft/iot/vmp/gb28181/utils/XmlUtil.java index 5ada1e4d..0d34c00a 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/utils/XmlUtil.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/utils/XmlUtil.java @@ -249,23 +249,26 @@ public class XmlUtil { }else { deviceChannel.setParentId(parentId); } - }else { - if (deviceChannel.getChannelId().length() <= 10) { // 此时为行政区划, 上下级行政区划使用DeviceId关联 - deviceChannel.setParentId(deviceChannel.getChannelId().substring(0, deviceChannel.getChannelId().length() - 2)); - }else if (deviceChannel.getChannelId().length() == 20) { - if (Integer.parseInt(deviceChannel.getChannelId().substring(10, 13)) == 216) { // 虚拟组织 - deviceChannel.setParentId(businessGroupID); - }else if (Integer.parseInt(device.getDeviceId().substring(10, 13) )== 118) {//NVR 如果上级设备编号是NVR则直接将NVR的编号设置给通道的上级编号 - deviceChannel.setParentId(device.getDeviceId()); - }else if (deviceChannel.getCivilCode() != null) { - // 设备, 无parentId的20位是使用CivilCode表示上级的设备, - // 注:215 业务分组是需要有parentId的 - deviceChannel.setParentId(deviceChannel.getCivilCode()); - } - }else { - deviceChannel.setParentId(deviceChannel.getDeviceId()); - } } + deviceChannel.setBusinessGroupId(businessGroupID); + +// else { +// if (deviceChannel.getChannelId().length() <= 10) { // 此时为行政区划, 上下级行政区划使用DeviceId关联 +// deviceChannel.setParentId(deviceChannel.getChannelId().substring(0, deviceChannel.getChannelId().length() - 2)); +// }else if (deviceChannel.getChannelId().length() == 20) { +// if (Integer.parseInt(deviceChannel.getChannelId().substring(10, 13)) == 216) { // 虚拟组织 +// deviceChannel.setBusinessGroupId(businessGroupID); +// }else if (Integer.parseInt(device.getDeviceId().substring(10, 13) )== 118) {//NVR 如果上级设备编号是NVR则直接将NVR的编号设置给通道的上级编号 +// deviceChannel.setParentId(device.getDeviceId()); +// }else if (deviceChannel.getCivilCode() != null) { +// // 设备, 无parentId的20位是使用CivilCode表示上级的设备, +// // 注:215 业务分组是需要有parentId的 +// deviceChannel.setParentId(deviceChannel.getCivilCode()); +// } +// }else { +// deviceChannel.setParentId(deviceChannel.getDeviceId()); +// } +// } if (XmlUtil.getText(itemDevice, "SafetyWay") == null || XmlUtil.getText(itemDevice, "SafetyWay") == "") { diff --git a/src/main/java/com/genersoft/iot/vmp/service/IDeviceService.java b/src/main/java/com/genersoft/iot/vmp/service/IDeviceService.java index 72af803d..5b43496b 100644 --- a/src/main/java/com/genersoft/iot/vmp/service/IDeviceService.java +++ b/src/main/java/com/genersoft/iot/vmp/service/IDeviceService.java @@ -1,7 +1,9 @@ package com.genersoft.iot.vmp.service; import com.genersoft.iot.vmp.gb28181.bean.Device; +import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; import com.genersoft.iot.vmp.gb28181.bean.SyncStatus; +import com.genersoft.iot.vmp.vmanager.bean.BaseTree; import java.util.List; @@ -110,4 +112,21 @@ public interface IDeviceService { * @param device 设备信息 */ void updateDevice(Device device); + + /** + * 树形查询接口 + * @param deviceId 设备ID + * @param parentId 父ID + * @param onlyCatalog 只获取目录 + * @return + */ + List> queryVideoDeviceTree(String deviceId, String parentId, boolean onlyCatalog); + + /** + * 查询树节点下的通道 + * @param deviceId 设备ID + * @param parentId 父ID + * @return + */ + List queryVideoDeviceInTreeNode(String deviceId, String parentId); } diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/DeviceServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/DeviceServiceImpl.java index ec30cd48..9d376fb0 100644 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/DeviceServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/DeviceServiceImpl.java @@ -1,9 +1,7 @@ package com.genersoft.iot.vmp.service.impl; import com.genersoft.iot.vmp.conf.DynamicTask; -import com.genersoft.iot.vmp.gb28181.bean.Device; -import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; -import com.genersoft.iot.vmp.gb28181.bean.SsrcTransaction; +import com.genersoft.iot.vmp.gb28181.bean.*; import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager; import com.genersoft.iot.vmp.gb28181.task.ISubscribeTask; import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander; @@ -12,20 +10,23 @@ import com.genersoft.iot.vmp.gb28181.utils.Coordtransform; import com.genersoft.iot.vmp.service.IDeviceService; import com.genersoft.iot.vmp.gb28181.task.impl.CatalogSubscribeTask; import com.genersoft.iot.vmp.gb28181.task.impl.MobilePositionSubscribeTask; -import com.genersoft.iot.vmp.gb28181.bean.SyncStatus; import com.genersoft.iot.vmp.service.IMediaServerService; import com.genersoft.iot.vmp.storager.IRedisCatchStorage; import com.genersoft.iot.vmp.storager.IVideoManagerStorage; import com.genersoft.iot.vmp.storager.dao.DeviceChannelMapper; import com.genersoft.iot.vmp.storager.dao.DeviceMapper; import com.genersoft.iot.vmp.utils.DateUtil; +import com.genersoft.iot.vmp.vmanager.bean.BaseTree; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.jdbc.support.incrementer.AbstractIdentityColumnMaxValueIncrementer; import org.springframework.stereotype.Service; import org.springframework.util.StringUtils; import java.time.Instant; +import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.concurrent.TimeUnit; @@ -341,4 +342,180 @@ public class DeviceServiceImpl implements IDeviceService { } storage.updateChannels(device.getDeviceId(), deviceChannels); } + + + @Override + public List> queryVideoDeviceTree(String deviceId, String parentId, boolean onlyCatalog) { + Device device = deviceMapper.getDeviceByDeviceId(deviceId); + if (device == null) { + return null; + } + if (parentId == null || parentId.equals(deviceId)) { + // 字根节点开始查询 + List rootNodes = getRootNodes(deviceId, "CivilCode".equals(device.getTreeType()), true, !onlyCatalog); + return transportChannelsToTree(rootNodes, ""); + } + + if ("CivilCode".equals(device.getTreeType())) { + if (parentId.length()%2 != 0) { + return null; + } + // 使用行政区划展示树 + if (parentId.length() > 10) { + // TODO 可能是行政区划与业务分组混杂的情形 + return null; + } + + if (parentId.length() == 10 ) { + if (onlyCatalog) { + return null; + } + // parentId为行业编码, 其下不会再有行政区划 + List channels = deviceChannelMapper.getChannelsByCivilCode(deviceId, parentId); + List> trees = transportChannelsToTree(channels, parentId); + return trees; + } + // 查询其下的行政区划和摄像机 + List channelsForCivilCode = deviceChannelMapper.getChannelsWithCivilCodeAndLength(deviceId, parentId, parentId.length() + 2); + if (!onlyCatalog) { + List channels = deviceChannelMapper.getChannelsByCivilCode(deviceId, parentId); + channelsForCivilCode.addAll(channels); + } + List> trees = transportChannelsToTree(channelsForCivilCode, parentId); + return trees; + + } + // 使用业务分组展示树 + if ("BusinessGroup".equals(device.getTreeType())) { + if (parentId.length() < 14 ) { + return null; + } + List deviceChannels = deviceChannelMapper.queryChannels(deviceId, parentId, null, null, null); + List> trees = transportChannelsToTree(deviceChannels, parentId); + return trees; + } + + return null; + } + + @Override + public List queryVideoDeviceInTreeNode(String deviceId, String parentId) { + Device device = deviceMapper.getDeviceByDeviceId(deviceId); + if (device == null) { + return null; + } + if (parentId == null || parentId.equals(deviceId)) { + // 字根节点开始查询 + List rootNodes = getRootNodes(deviceId, "CivilCode".equals(device.getTreeType()), false, true); + return rootNodes; + } + + if ("CivilCode".equals(device.getTreeType())) { + if (parentId.length()%2 != 0) { + return null; + } + // 使用行政区划展示树 + if (parentId.length() > 10) { + // TODO 可能是行政区划与业务分组混杂的情形 + return null; + } + + if (parentId.length() == 10 ) { + // parentId为行业编码, 其下不会再有行政区划 + List channels = deviceChannelMapper.getChannelsByCivilCode(deviceId, parentId); + return channels; + } + // 查询其下的行政区划和摄像机 + List channels = deviceChannelMapper.getChannelsByCivilCode(deviceId, parentId); + return channels; + + } + // 使用业务分组展示树 + if ("BusinessGroup".equals(device.getTreeType())) { + if (parentId.length() < 14 ) { + return null; + } + List deviceChannels = deviceChannelMapper.queryChannels(deviceId, parentId, null, null, null); + return deviceChannels; + } + + return null; + } + + private List> transportChannelsToTree(List channels, String parentId) { + if (channels == null) { + return null; + } + List> treeNotes = new ArrayList<>(); + if (channels.size() == 0) { + return treeNotes; + } + for (DeviceChannel channel : channels) { + + BaseTree node = new BaseTree<>(); + node.setId(channel.getChannelId()); + node.setDeviceId(channel.getDeviceId()); + node.setName(channel.getName()); + node.setPid(parentId); + node.setBasicData(channel); + node.setParent(false); + if (channel.getChannelId().length() > 8) { + String gbCodeType = channel.getChannelId().substring(10, 13); + node.setParent(gbCodeType.equals(ChannelIdType.BUSINESS_GROUP) || gbCodeType.equals(ChannelIdType.VIRTUAL_ORGANIZATION) ); + }else { + node.setParent(true); + } + treeNotes.add(node); + } + Collections.sort(treeNotes); + return treeNotes; + } + + private List getRootNodes(String deviceId, boolean isCivilCode, boolean haveCatalog, boolean haveChannel) { + if (!haveCatalog && !haveChannel) { + return null; + } + List result = new ArrayList<>(); + if (isCivilCode) { + // 使用行政区划 + Integer length= deviceChannelMapper.getChannelMinLength(deviceId); + if (length == null) { + return null; + } + if (length <= 10) { + if (haveCatalog) { + List provinceNode = deviceChannelMapper.getChannelsWithCivilCodeAndLength(deviceId, null, length); + if (provinceNode != null && provinceNode.size() > 0) { + result.addAll(provinceNode); + } + } + + if (haveChannel) { + // 查询那些civilCode不在通道中的不规范通道,放置在根目录 + List nonstandardNode = deviceChannelMapper.getChannelWithoutCiviCode(deviceId); + if (nonstandardNode != null && nonstandardNode.size() > 0) { + result.addAll(nonstandardNode); + } + } + }else { + if (haveChannel) { + List deviceChannels = deviceChannelMapper.queryChannels(deviceId, null, null, null, null); + if (deviceChannels != null && deviceChannels.size() > 0) { + result.addAll(deviceChannels); + } + } + } + + }else { + // 使用业务分组+虚拟组织 + + // 只获取业务分组 + List deviceChannels = deviceChannelMapper.getBusinessGroups(deviceId, ChannelIdType.BUSINESS_GROUP); + if (deviceChannels != null && deviceChannels.size() > 0) { + result.addAll(deviceChannels); + } + } + return result; + } + } diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java index 41eca5da..041fdf00 100644 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java @@ -123,7 +123,7 @@ public class PlayServiceImpl implements IPlayService { result.onCompletion(()->{ // 点播结束时调用截图接口 // TODO 应该在上流时调用更好,结束也可能是错误结束 - String path = "static/static/snap/"; + String path = "snap"; String fileName = deviceId + "_" + channelId + ".jpg"; ResponseEntity responseEntity = (ResponseEntity)result.getResult(); if (responseEntity != null && responseEntity.getStatusCode() == HttpStatus.OK) { @@ -178,7 +178,6 @@ public class PlayServiceImpl implements IPlayService { } - } if (streamInfo == null) { String streamId = null; diff --git a/src/main/java/com/genersoft/iot/vmp/storager/dao/DeviceChannelMapper.java b/src/main/java/com/genersoft/iot/vmp/storager/dao/DeviceChannelMapper.java index 5c46fb92..69ce4a7d 100644 --- a/src/main/java/com/genersoft/iot/vmp/storager/dao/DeviceChannelMapper.java +++ b/src/main/java/com/genersoft/iot/vmp/storager/dao/DeviceChannelMapper.java @@ -1,5 +1,6 @@ package com.genersoft.iot.vmp.storager.dao; +import com.genersoft.iot.vmp.gb28181.bean.Device; import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; import com.genersoft.iot.vmp.gb28181.bean.DeviceChannelInPlatform; import com.genersoft.iot.vmp.vmanager.gb28181.platform.bean.ChannelReduce; @@ -17,10 +18,12 @@ public interface DeviceChannelMapper { @Insert("INSERT INTO device_channel (channelId, deviceId, name, manufacture, model, owner, civilCode, block, " + "address, parental, parentId, safetyWay, registerWay, certNum, certifiable, errCode, secrecy, " + - "ipAddress, port, password, PTZType, status, streamId, longitude, latitude, longitudeGcj02, latitudeGcj02, longitudeWgs84, latitudeWgs84, createTime, updateTime) " + + "ipAddress, port, password, PTZType, status, streamId, longitude, latitude, longitudeGcj02, latitudeGcj02, " + + "longitudeWgs84, latitudeWgs84, createTime, updateTime, businessGroupId) " + "VALUES ('${channelId}', '${deviceId}', '${name}', '${manufacture}', '${model}', '${owner}', '${civilCode}', '${block}'," + "'${address}', ${parental}, '${parentId}', ${safetyWay}, ${registerWay}, '${certNum}', ${certifiable}, ${errCode}, '${secrecy}', " + - "'${ipAddress}', ${port}, '${password}', ${PTZType}, ${status}, '${streamId}', ${longitude}, ${latitude}, ${longitudeGcj02}, ${latitudeGcj02}, ${longitudeWgs84}, ${latitudeWgs84},'${createTime}', '${updateTime}')") + "'${ipAddress}', ${port}, '${password}', ${PTZType}, ${status}, '${streamId}', ${longitude}, ${latitude}, ${longitudeGcj02}, " + + "${latitudeGcj02}, ${longitudeWgs84}, ${latitudeWgs84},'${createTime}', '${updateTime}', '${businessGroupId}')") int add(DeviceChannel channel); @Update(value = {" "}) int update(DeviceChannel channel); @@ -143,7 +147,7 @@ public interface DeviceChannelMapper { "(channelId, deviceId, name, manufacture, model, owner, civilCode, block, subCount, " + " address, parental, parentId, safetyWay, registerWay, certNum, certifiable, errCode, secrecy, " + " ipAddress, port, password, PTZType, status, streamId, longitude, latitude, longitudeGcj02, latitudeGcj02, " + - " longitudeWgs84, latitudeWgs84, createTime, updateTime) " + + " longitudeWgs84, latitudeWgs84, createTime, updateTime, businessGroupId) " + "values " + " " + "('${item.channelId}', '${item.deviceId}', '${item.name}', '${item.manufacture}', '${item.model}', " + @@ -152,7 +156,7 @@ public interface DeviceChannelMapper { "'${item.certNum}', ${item.certifiable}, ${item.errCode}, '${item.secrecy}', " + "'${item.ipAddress}', ${item.port}, '${item.password}', ${item.PTZType}, ${item.status}, " + "'${item.streamId}', ${item.longitude}, ${item.latitude},${item.longitudeGcj02}, " + - "${item.latitudeGcj02},${item.longitudeWgs84}, ${item.latitudeWgs84},'${item.createTime}', '${item.updateTime}')" + + "${item.latitudeGcj02},${item.longitudeWgs84}, ${item.latitudeWgs84},'${item.createTime}', '${item.updateTime}, '${item.businessGroupId}')" + " " + "ON DUPLICATE KEY UPDATE " + "updateTime=VALUES(updateTime), " + @@ -183,7 +187,8 @@ public interface DeviceChannelMapper { "longitudeGcj02=VALUES(longitudeGcj02), " + "latitudeGcj02=VALUES(latitudeGcj02), " + "longitudeWgs84=VALUES(longitudeWgs84), " + - "latitudeWgs84=VALUES(latitudeWgs84) " + + "latitudeWgs84=VALUES(latitudeWgs84), " + + "businessGroupId=VALUES(businessGroupId) " + "") int batchAdd(List addChannels); @@ -221,6 +226,7 @@ public interface DeviceChannelMapper { ", latitudeGcj02=${item.latitudeGcj02}" + ", longitudeWgs84=${item.longitudeWgs84}" + ", latitudeWgs84=${item.latitudeWgs84}" + + ", businessGroupId=${item.businessGroupId}" + "WHERE deviceId='${item.deviceId}' AND channelId='${item.channelId}'"+ "" + ""}) @@ -277,4 +283,33 @@ public interface DeviceChannelMapper { @Select("select * from device_channel where longitude*latitude > 0 and deviceId = #{deviceId}") List getAllChannelWithCoordinate(String deviceId); + + + @Select(value = {" "}) + List getChannelsWithCivilCodeAndLength(String deviceId, String parentId, Integer length); + + @Select(value = {" "}) + List getChannelsByCivilCode(String deviceId, String parentId); + + @Select("select min(length(channelId)) as minLength " + + "from device_channel " + + "where deviceId=#{deviceId}") + Integer getChannelMinLength(String deviceId); + + @Select("select * from device_channel where deviceId=#{deviceId} and civilCode not in " + + "(select civilCode from device_channel where deviceId=#{deviceId} group by civilCode)") + List getChannelWithoutCiviCode(String deviceId); + + @Select("select * from device_channel where deviceId=#{deviceId} and SUBSTRING(channelId, 11, 3)=#{typeCode}") + List getBusinessGroups(String deviceId, String typeCode); } diff --git a/src/main/java/com/genersoft/iot/vmp/storager/dao/DeviceMapper.java b/src/main/java/com/genersoft/iot/vmp/storager/dao/DeviceMapper.java index 3e15b739..7e8dd3c6 100644 --- a/src/main/java/com/genersoft/iot/vmp/storager/dao/DeviceMapper.java +++ b/src/main/java/com/genersoft/iot/vmp/storager/dao/DeviceMapper.java @@ -39,6 +39,7 @@ public interface DeviceMapper { "subscribeCycleForAlarm," + "ssrcCheck," + "geoCoordSys," + + "treeType," + "online" + ") VALUES (" + "#{deviceId}," + @@ -63,6 +64,7 @@ public interface DeviceMapper { "#{subscribeCycleForAlarm}," + "#{ssrcCheck}," + "#{geoCoordSys}," + + "#{treeType}," + "#{online}" + ")") int add(Device device); @@ -90,6 +92,7 @@ public interface DeviceMapper { ", subscribeCycleForAlarm=${subscribeCycleForAlarm}" + ", ssrcCheck=${ssrcCheck}" + ", geoCoordSys=#{geoCoordSys}" + + ", treeType=#{treeType}" + "WHERE deviceId='${deviceId}'"+ " "}) int update(Device device); diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/bean/BaseTree.java b/src/main/java/com/genersoft/iot/vmp/vmanager/bean/BaseTree.java new file mode 100644 index 00000000..23690e54 --- /dev/null +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/bean/BaseTree.java @@ -0,0 +1,87 @@ +package com.genersoft.iot.vmp.vmanager.bean; + +import org.jetbrains.annotations.NotNull; + +import java.text.Collator; +import java.util.Comparator; + +/** + * @author lin + */ +public class BaseTree implements Comparable{ + private String id; + + private String deviceId; + private String pid; + private String name; + private boolean parent; + + private T basicData; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getPid() { + return pid; + } + + public void setPid(String pid) { + this.pid = pid; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public T getBasicData() { + return basicData; + } + + public void setBasicData(T basicData) { + this.basicData = basicData; + } + + public boolean isParent() { + return parent; + } + + public void setParent(boolean parent) { + this.parent = parent; + } + + @Override + public int compareTo(@NotNull BaseTree treeNode) { + if (this.parent || treeNode.isParent()) { + if (!this.parent && !treeNode.isParent()) { + Comparator cmp = Collator.getInstance(java.util.Locale.CHINA); + return cmp.compare(treeNode.getName(), this.getName()); + }else { + if (this.isParent()) { + return 1; + }else { + return -1; + } + } + }else{ + Comparator cmp = Collator.getInstance(java.util.Locale.CHINA); + return cmp.compare(treeNode.getName(), this.getName()); + } + } +} diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/device/DeviceQuery.java b/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/device/DeviceQuery.java index 5e1e40be..767e9c40 100644 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/device/DeviceQuery.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/device/DeviceQuery.java @@ -15,6 +15,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander; import com.genersoft.iot.vmp.service.IDeviceService; import com.genersoft.iot.vmp.storager.IRedisCatchStorage; import com.genersoft.iot.vmp.storager.IVideoManagerStorage; +import com.genersoft.iot.vmp.vmanager.bean.BaseTree; import com.genersoft.iot.vmp.vmanager.bean.WVPResult; import com.github.pagehelper.PageInfo; import io.swagger.annotations.Api; @@ -479,4 +480,99 @@ public class DeviceQuery { resp.setStatus(HttpServletResponse.SC_NOT_FOUND); } } + + /** + * 查询国标树 + * @param deviceId 设备ID + * @param parentId 父ID + * @param page 当前页 + * @param count 每页条数 + * @return 国标设备 + */ + @ApiOperation("查询国标树") + @ApiImplicitParams({ + @ApiImplicitParam(name = "deviceId", value = "设备ID", required = true, dataTypeClass = String.class), + @ApiImplicitParam(name = "parentId", value = "父ID", required = false, dataTypeClass = String.class), + @ApiImplicitParam(name = "onlyCatalog", value = "只获取目录", required = false, dataTypeClass = Boolean.class), + @ApiImplicitParam(name="page", value = "当前页", required = true, dataTypeClass = Integer.class), + @ApiImplicitParam(name="count", value = "每页条数", required = true, dataTypeClass = Integer.class), + }) + @GetMapping("/tree/{deviceId}") + public ResponseEntity getTree(@PathVariable String deviceId, @RequestParam(required = false) String parentId, @RequestParam(required = false) Boolean onlyCatalog, int page, int count){ + + + if (page <= 0) { + page = 1; + } + if (onlyCatalog == null) { + onlyCatalog = false; + } + + List> treeData = deviceService.queryVideoDeviceTree(deviceId, parentId, onlyCatalog); + if (treeData == null || (page - 1) * count > treeData.size()) { + PageInfo> pageInfo = new PageInfo<>(); + pageInfo.setPageNum(page); + pageInfo.setTotal(treeData == null? 0 : treeData.size()); + pageInfo.setSize(0); + pageInfo.setList(new ArrayList<>()); + return new ResponseEntity<>(pageInfo,HttpStatus.OK); + } + + int toIndex = Math.min(page * count, treeData.size()); + // 处理分页 + List> trees = treeData.subList((page - 1) * count, toIndex); + PageInfo> pageInfo = new PageInfo<>(); + pageInfo.setPageNum(page); + pageInfo.setTotal(treeData.size()); + pageInfo.setSize(trees.size()); + pageInfo.setList(trees); + + return new ResponseEntity<>(pageInfo,HttpStatus.OK); + } + + + /** + * 查询国标树下的通道 + * @param deviceId 设备ID + * @param parentId 父ID + * @param page 当前页 + * @param count 每页条数 + * @return 国标设备 + */ + @ApiOperation("查询国标树下的通道") + @ApiImplicitParams({ + @ApiImplicitParam(name = "deviceId", value = "设备ID", required = true, dataTypeClass = String.class), + @ApiImplicitParam(name = "parentId", value = "父ID", required = false, dataTypeClass = String.class), + @ApiImplicitParam(name="page", value = "当前页", required = true, dataTypeClass = Integer.class), + @ApiImplicitParam(name="count", value = "每页条数", required = true, dataTypeClass = Integer.class), + }) + @GetMapping("/tree/channel/{deviceId}") + public ResponseEntity getChannelInTreeNode(@PathVariable String deviceId, @RequestParam(required = false) String parentId, int page, int count){ + + + if (page <= 0) { + page = 1; + } + + List treeData = deviceService.queryVideoDeviceInTreeNode(deviceId, parentId); + if (treeData == null || (page - 1) * count > treeData.size()) { + PageInfo> pageInfo = new PageInfo<>(); + pageInfo.setPageNum(page); + pageInfo.setTotal(treeData == null? 0 : treeData.size()); + pageInfo.setSize(0); + pageInfo.setList(new ArrayList<>()); + return new ResponseEntity<>(pageInfo,HttpStatus.OK); + } + + int toIndex = Math.min(page * count, treeData.size()); + // 处理分页 + List trees = treeData.subList((page - 1) * count, toIndex); + PageInfo pageInfo = new PageInfo<>(); + pageInfo.setPageNum(page); + pageInfo.setTotal(treeData.size()); + pageInfo.setSize(trees.size()); + pageInfo.setList(trees); + + return new ResponseEntity<>(pageInfo,HttpStatus.OK); + } } diff --git a/src/main/resources/logback-spring-local.xml b/src/main/resources/logback-spring-local.xml index ec80d2dd..9e583553 100644 --- a/src/main/resources/logback-spring-local.xml +++ b/src/main/resources/logback-spring-local.xml @@ -11,6 +11,11 @@ %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50}:%L - %msg%n + + + + DEBUG + diff --git a/web_src/package-lock.json b/web_src/package-lock.json index 0d4c886c..8e0a324c 100644 --- a/web_src/package-lock.json +++ b/web_src/package-lock.json @@ -22,7 +22,9 @@ "vue-clipboards": "^1.3.0", "vue-contextmenujs": "^1.3.13", "vue-cookies": "^1.7.4", - "vue-router": "^3.1.6" + "vue-giant-tree": "^0.1.5", + "vue-router": "^3.1.6", + "vue-ztree-2.0": "^1.0.4" }, "devDependencies": { "autoprefixer": "^7.1.2", @@ -50,7 +52,7 @@ "postcss-url": "^7.2.1", "rimraf": "^2.6.0", "semver": "^5.3.0", - "shelljs": "^0.7.6", + "shelljs": "^0.8.5", "uglifyjs-webpack-plugin": "^1.1.1", "url-loader": "^0.5.8", "vue-loader": "^13.3.0", @@ -116,6 +118,17 @@ "integrity": "sha512-1HcDas8SEj4z1Wc696tH56G8OlRaH/sqZOynNNB+HF0WOeXPaxTtbYzJY2oEfiUxjSKjhCKr+MvR7dCHcEelug==", "dev": true }, + "node_modules/@ztree/ztree_v3": { + "version": "3.5.48", + "resolved": "https://registry.npmmirror.com/@ztree/ztree_v3/-/ztree_v3-3.5.48.tgz", + "integrity": "sha512-4dSA1g26T3j/O3I89+r/Palg+a+xwMGRS1etZoggnCGBPoOrwW8VGA3zitJCK/Yd7eEMX+LfKTRJjEGiWpoN3w==", + "dependencies": { + "jquery": ">=1.4.4" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/accepts": { "version": "1.3.7", "resolved": "https://registry.npm.taobao.org/accepts/download/accepts-1.3.7.tgz", @@ -6034,6 +6047,11 @@ "node": ">=0.10.0" } }, + "node_modules/jquery": { + "version": "3.6.0", + "resolved": "https://registry.npmmirror.com/jquery/-/jquery-3.6.0.tgz", + "integrity": "sha512-JVzAR/AjBvVt2BmYhxRCSYysDsPcssdmTFnzyLEts9qNwmjmu4JTAMYubEfwVOSwpQ1I1sKKFcxhZCI2buerfw==" + }, "node_modules/js-base64": { "version": "2.6.4", "resolved": "https://registry.npm.taobao.org/js-base64/download/js-base64-2.6.4.tgz?cache=0&sync_timestamp=1599897619557&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fjs-base64%2Fdownload%2Fjs-base64-2.6.4.tgz", @@ -11655,9 +11673,9 @@ } }, "node_modules/shelljs": { - "version": "0.7.8", - "resolved": "https://registry.npm.taobao.org/shelljs/download/shelljs-0.7.8.tgz", - "integrity": "sha1-3svPh0sNHl+3LhSxZKloMEjprLM=", + "version": "0.8.5", + "resolved": "https://registry.npmmirror.com/shelljs/-/shelljs-0.8.5.tgz", + "integrity": "sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==", "dev": true, "dependencies": { "glob": "^7.0.0", @@ -11668,8 +11686,7 @@ "shjs": "bin/shjs" }, "engines": { - "iojs": "*", - "node": ">=0.11.0" + "node": ">=4" } }, "node_modules/shellwords": { @@ -13068,6 +13085,15 @@ "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", "integrity": "sha1-0kHQoEMdoHlYN2UdELTXPnyNPo0=" }, + "node_modules/vue-giant-tree": { + "version": "0.1.5", + "resolved": "https://registry.npmmirror.com/vue-giant-tree/-/vue-giant-tree-0.1.5.tgz", + "integrity": "sha512-P3KEHSZU2NkpWl6frss+sJLO0DLrtarMNLeTV/IGU2/w50rgrlKbKNr/ckK6BBVdWXAJYlYf6HUTNkKvGq5hlg==", + "dependencies": { + "@ztree/ztree_v3": "^3.5.44", + "jquery": "^3.5.1" + } + }, "node_modules/vue-hot-reload-api": { "version": "2.3.4", "resolved": "https://registry.npm.taobao.org/vue-hot-reload-api/download/vue-hot-reload-api-2.3.4.tgz", @@ -13175,6 +13201,11 @@ "integrity": "sha1-HuO8mhbsv1EYvjNLsV+cRvgvWCU=", "dev": true }, + "node_modules/vue-ztree-2.0": { + "version": "1.0.4", + "resolved": "https://registry.npmmirror.com/vue-ztree-2.0/-/vue-ztree-2.0-1.0.4.tgz", + "integrity": "sha512-d7KZsquEYpM0jD/k1uwOMFCd08L6++7zwRESaL2sF43OtRFCump8BxcLpjusBIHpFadPvOSMMnK5P41y+ZiTlA==" + }, "node_modules/watchpack": { "version": "1.7.4", "resolved": "https://registry.npm.taobao.org/watchpack/download/watchpack-1.7.4.tgz?cache=0&sync_timestamp=1600385388649&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fwatchpack%2Fdownload%2Fwatchpack-1.7.4.tgz", @@ -14419,6 +14450,14 @@ "integrity": "sha512-1HcDas8SEj4z1Wc696tH56G8OlRaH/sqZOynNNB+HF0WOeXPaxTtbYzJY2oEfiUxjSKjhCKr+MvR7dCHcEelug==", "dev": true }, + "@ztree/ztree_v3": { + "version": "3.5.48", + "resolved": "https://registry.npmmirror.com/@ztree/ztree_v3/-/ztree_v3-3.5.48.tgz", + "integrity": "sha512-4dSA1g26T3j/O3I89+r/Palg+a+xwMGRS1etZoggnCGBPoOrwW8VGA3zitJCK/Yd7eEMX+LfKTRJjEGiWpoN3w==", + "requires": { + "jquery": ">=1.4.4" + } + }, "accepts": { "version": "1.3.7", "resolved": "https://registry.npm.taobao.org/accepts/download/accepts-1.3.7.tgz", @@ -19488,6 +19527,11 @@ "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", "dev": true }, + "jquery": { + "version": "3.6.0", + "resolved": "https://registry.npmmirror.com/jquery/-/jquery-3.6.0.tgz", + "integrity": "sha512-JVzAR/AjBvVt2BmYhxRCSYysDsPcssdmTFnzyLEts9qNwmjmu4JTAMYubEfwVOSwpQ1I1sKKFcxhZCI2buerfw==" + }, "js-base64": { "version": "2.6.4", "resolved": "https://registry.npm.taobao.org/js-base64/download/js-base64-2.6.4.tgz?cache=0&sync_timestamp=1599897619557&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fjs-base64%2Fdownload%2Fjs-base64-2.6.4.tgz", @@ -24156,9 +24200,9 @@ "dev": true }, "shelljs": { - "version": "0.7.8", - "resolved": "https://registry.npm.taobao.org/shelljs/download/shelljs-0.7.8.tgz", - "integrity": "sha1-3svPh0sNHl+3LhSxZKloMEjprLM=", + "version": "0.8.5", + "resolved": "https://registry.npmmirror.com/shelljs/-/shelljs-0.8.5.tgz", + "integrity": "sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==", "dev": true, "requires": { "glob": "^7.0.0", @@ -25352,6 +25396,15 @@ "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", "integrity": "sha1-0kHQoEMdoHlYN2UdELTXPnyNPo0=" }, + "vue-giant-tree": { + "version": "0.1.5", + "resolved": "https://registry.npmmirror.com/vue-giant-tree/-/vue-giant-tree-0.1.5.tgz", + "integrity": "sha512-P3KEHSZU2NkpWl6frss+sJLO0DLrtarMNLeTV/IGU2/w50rgrlKbKNr/ckK6BBVdWXAJYlYf6HUTNkKvGq5hlg==", + "requires": { + "@ztree/ztree_v3": "^3.5.44", + "jquery": "^3.5.1" + } + }, "vue-hot-reload-api": { "version": "2.3.4", "resolved": "https://registry.npm.taobao.org/vue-hot-reload-api/download/vue-hot-reload-api-2.3.4.tgz", @@ -25448,6 +25501,11 @@ "integrity": "sha1-HuO8mhbsv1EYvjNLsV+cRvgvWCU=", "dev": true }, + "vue-ztree-2.0": { + "version": "1.0.4", + "resolved": "https://registry.npmmirror.com/vue-ztree-2.0/-/vue-ztree-2.0-1.0.4.tgz", + "integrity": "sha512-d7KZsquEYpM0jD/k1uwOMFCd08L6++7zwRESaL2sF43OtRFCump8BxcLpjusBIHpFadPvOSMMnK5P41y+ZiTlA==" + }, "watchpack": { "version": "1.7.4", "resolved": "https://registry.npm.taobao.org/watchpack/download/watchpack-1.7.4.tgz?cache=0&sync_timestamp=1600385388649&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fwatchpack%2Fdownload%2Fwatchpack-1.7.4.tgz", diff --git a/web_src/package.json b/web_src/package.json index b825f840..d19a58d2 100644 --- a/web_src/package.json +++ b/web_src/package.json @@ -24,7 +24,9 @@ "vue-clipboards": "^1.3.0", "vue-contextmenujs": "^1.3.13", "vue-cookies": "^1.7.4", - "vue-router": "^3.1.6" + "vue-giant-tree": "^0.1.5", + "vue-router": "^3.1.6", + "vue-ztree-2.0": "^1.0.4" }, "devDependencies": { "autoprefixer": "^7.1.2", diff --git a/web_src/src/components/DeviceList.vue b/web_src/src/components/DeviceList.vue index 1911d1db..97fa4f22 100644 --- a/web_src/src/components/DeviceList.vue +++ b/web_src/src/components/DeviceList.vue @@ -56,11 +56,11 @@ @mouseover="getTooltipContent(scope.row.deviceId)">刷新 - 通道 - 定位 @@ -192,7 +192,7 @@ export default { }, showChannelList: function (row) { - this.$router.push(`/channelList/${row.deviceId}/0/15/1`); + this.$router.push(`/channelList/${row.deviceId}/0`); }, showDevicePosition: function (row) { this.$router.push(`/map?deviceId=${row.deviceId}`); diff --git a/web_src/src/components/channelList.vue b/web_src/src/components/channelList.vue index d27e62bd..2a09c5ce 100644 --- a/web_src/src/components/channelList.vue +++ b/web_src/src/components/channelList.vue @@ -7,104 +7,116 @@ 通道列表
- 搜索: - +
+ 搜索: + - 通道类型: - - - - - - 在线状态: - - - - - + 通道类型: + + + + + + 在线状态: + + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -114,12 +126,14 @@ import uiHeader from '../layout/UiHeader.vue' import moment from "moment"; import DviceService from "./service/DeviceService"; import DeviceService from "./service/DeviceService"; +import DeviceTree from "./common/DeviceTree"; export default { name: 'channelList', components: { devicePlayer, - uiHeader + uiHeader, + DeviceTree }, data() { return { @@ -134,12 +148,13 @@ export default { searchSrt: "", channelType: "", online: "", - winHeight: window.innerHeight - 250, - currentPage: parseInt(this.$route.params.page), - count: parseInt(this.$route.params.count), + winHeight: window.innerHeight - 200, + currentPage: 1, + count: 15, total: 0, beforeUrl: "/deviceList", isLoging: false, + showTree: false, loadSnap: {} }; }, @@ -172,19 +187,16 @@ export default { initParam: function () { this.deviceId = this.$route.params.deviceId; this.parentChannelId = this.$route.params.parentChannelId; - this.currentPage = parseInt(this.$route.params.page); - this.count = parseInt(this.$route.params.count); + this.currentPage = 1; + this.count = 15; if (this.parentChannelId == "" || this.parentChannelId == 0) { this.beforeUrl = "/deviceList" } }, currentChange: function (val) { - var url = `/${this.$router.currentRoute.name}/${this.deviceId}/${this.parentChannelId}/${this.count}/${val}` - this.$router.push(url).then(() => { - this.initParam(); - this.initData(); - }) + this.currentPage = val; + this.initData(); }, handleSizeChange: function (val) { this.count = val; @@ -316,28 +328,48 @@ export default { }) }, showSubchannels: function (channelId) { - let that = this; + if (!this.showTree) { + this.$axios({ + method: 'get', + url: `/api/device/query/sub_channels/${this.deviceId}/${this.parentChannelId}/channels`, + params: { + page: this.currentPage, + count: this.count, + query: this.searchSrt, + online: this.online, + channelType: this.channelType + } + }).then( (res) =>{ + this.total = res.data.total; + this.deviceChannelList = res.data.list; + // 防止出现表格错位 + this.$nextTick(() => { + this.$refs.channelListTable.doLayout(); + }) + }).catch(function (error) { + console.log(error); + }); + }else { + this.$axios({ + method: 'get', + url: `/api/device/query/tree/channel/${this.deviceId}`, + params: { + parentId: this.parentChannelId, + page: this.currentPage, + count: this.count, + } + }).then((res)=> { + this.total = res.data.total; + this.deviceChannelList = res.data.list; + // 防止出现表格错位 + this.$nextTick(() => { + this.$refs.channelListTable.doLayout(); + }) + }).catch(function (error) { + console.log(error); + }); + } - this.$axios({ - method: 'get', - url: `/api/device/query/sub_channels/${this.deviceId}/${this.parentChannelId}/channels`, - params: { - page: that.currentPage, - count: that.count, - query: that.searchSrt, - online: that.online, - channelType: that.channelType - } - }).then(function (res) { - that.total = res.data.total; - that.deviceChannelList = res.data.list; - // 防止出现表格错位 - that.$nextTick(() => { - that.$refs.channelListTable.doLayout(); - }) - }).catch(function (error) { - console.log(error); - }); }, search: function () { this.currentPage = 1; @@ -355,6 +387,29 @@ export default { }, refresh: function () { this.initData(); + }, + switchTree: function (){ + this.showTree = true; + this.deviceChannelList = []; + this.parentChannelId = 0; + this.currentPage = 1; + + }, + switchList: function (){ + this.showTree = false; + this.deviceChannelList = []; + this.parentChannelId = 0; + this.currentPage = 1; + this.initData(); + }, + treeNodeClickEvent: function (device, data, isCatalog) { + console.log(device) + if (!!!data.channelId) { + this.parentChannelId = device.deviceId; + }else { + this.parentChannelId = data.channelId; + } + this.initData(); } } diff --git a/web_src/src/components/common/DeviceTree.vue b/web_src/src/components/common/DeviceTree.vue index 73618cc3..c701bf0f 100644 --- a/web_src/src/components/common/DeviceTree.vue +++ b/web_src/src/components/common/DeviceTree.vue @@ -4,7 +4,7 @@ 设备列表
- + @@ -47,98 +47,112 @@ export default { } }; }, - props: ['clickEvent', 'contextMenuEvent'], + props: ['device', 'onlyCatalog', 'clickEvent', 'contextMenuEvent'], methods: { handleNodeClick(data,node,element) { - console.log("点击事件") - console.log(data) + let deviceNode = this.$refs.gdTree.getNode(data.userData.deviceId) if(typeof (this.clickEvent) == "function") { - this.clickEvent(data.userData) + this.clickEvent(deviceNode.data.userData, data.userData, data.type === 2) } }, handleContextMenu(event,data,node,element) { console.log("右键点击事件") + let deviceNode = this.$refs.gdTree.getNode(data.userData.deviceId) if(typeof (this.contextMenuEvent) == "function") { - this.contextMenuEvent(event, data.userData) + this.contextMenuEvent(deviceNode.data.userData, event, data.userData, data.type === 2) } }, loadNode: function(node, resolve){ + console.log(this.device) if (node.level === 0) { - this.deviceService.getAllDeviceList((data)=>{ - console.log(data) - if (data.length > 0) { - let nodeList = [] - for (let i = 0; i < data.length; i++) { - console.log(data[i].name) - let node = { - name: data[i].name || data[i].deviceId, - isLeaf: false, - id: data[i].deviceId, - type: data[i].online, - online: data[i].online === 1, - userData: data[i] - } - nodeList.push(node); - } - resolve(nodeList) - }else { - resolve([]) + if (this.device) { + let node = { + name: this.device.name || this.device.deviceId, + isLeaf: false, + id: this.device.deviceId, + type: this.device.online, + online: this.device.online === 1, + userData: this.device } - }, (list)=>{ + resolve([node]) + }else { + this.deviceService.getAllDeviceList((data)=>{ + console.log(data) + if (data.length > 0) { + let nodeList = [] + for (let i = 0; i < data.length; i++) { + console.log(data[i].name) + let node = { + name: data[i].name || data[i].deviceId, + isLeaf: false, + id: data[i].deviceId, + type: data[i].online, + online: data[i].online === 1, + userData: data[i] + } + nodeList.push(node); + } + resolve(nodeList) + }else { + resolve([]) + } + }, (list)=>{ console.log("设备加载完成") - }, (error)=>{ + }, (error)=>{ - }) - } - if (node.level === 1) { + }) + } + }else { let channelArray = [] - this.deviceService.getAllChannel(true, true, node.data.id, catalogData =>{ + + this.deviceService.getTree(node.data.userData.deviceId, node.data.id, this.onlyCatalog, catalogData =>{ + console.log(catalogData) channelArray = channelArray.concat(catalogData) this.channelDataHandler(channelArray, resolve) },(endCatalogData) => { - this.deviceService.getAllChannel(false, true, node.data.id, channelData => { - channelArray = channelArray.concat(channelData) - this.channelDataHandler(channelArray, resolve) - }, endChannelList => { - }) - }) - }else if (node.level > 1){ - let channelArray = [] - this.deviceService.getAllSubChannel(true, node.data.deviceId, node.data.id, (catalogData)=>{ - channelArray = channelArray.concat(catalogData) - this.channelDataHandler(channelArray, resolve) - }, (endCatalogData)=>{ - this.deviceService.getAllSubChannel(false, node.data.deviceId, node.data.id, (channelData)=>{ - channelArray = channelArray.concat(channelData) - this.channelDataHandler(channelArray, resolve) - }) }) } + }, channelDataHandler: function (data, resolve) { if (data.length > 0) { let nodeList = [] - for (let i = 0; i < data.length; i++) { + for (let i = 0; i 0 || data[i].parental === 1) { + if (item.id.length <= 10) { type = 2; - }else if (data[i].ptztype === 1 ) { // 1-球机;2-半球;3-固定枪机;4-遥控枪机 - type = 4; - }else if (data[i].ptztype === 2) { - type = 5; - }else if (data[i].ptztype === 3 || data[i].ptztype === 4) { - type = 6; + }else { + if (item.id.length > 14) { + let channelType = item.id.substring(10, 13) + console.log("channelType: " + channelType) + if (channelType === '215' || channelType === '216') { + type = 2; + } + console.log(type) + if (item.basicData.ptztype === 1 ) { // 1-球机;2-半球;3-固定枪机;4-遥控枪机 + type = 4; + }else if (item.basicData.ptztype === 2) { + type = 5; + }else if (item.basicData.ptztype === 3 || item.basicData.ptztype === 4) { + type = 6; + } + }else { + if (item.basicData.subCount > 0 || item.basicData.parental === 1) { + type = 2; + } + } } let node = { - name: data[i].name || data[i].channelId, - isLeaf: data[i].subCount === 0, - id: data[i].channelId, - deviceId: data[i].deviceId, + name: item.name || item.basicData.channelId, + isLeaf: type !== 2, + id: item.id, + deviceId: item.deviceId, type: type, - online: data[i].status === 1, - hasGPS: data[i].longitude*data[i].latitude !== 0, - userData: data[i] + online: item.basicData.status === 1, + hasGPS: item.basicData.longitude*item.basicData.latitude !== 0, + userData: item.basicData } nodeList.push(node); } @@ -146,6 +160,9 @@ export default { }else { resolve([]) } + }, + reset: function (){ + this.$forceUpdate(); } }, destroyed() { diff --git a/web_src/src/components/common/DeviceTreeForZtree.vue b/web_src/src/components/common/DeviceTreeForZtree.vue new file mode 100644 index 00000000..6c02bcca --- /dev/null +++ b/web_src/src/components/common/DeviceTreeForZtree.vue @@ -0,0 +1,112 @@ + + + + + diff --git a/web_src/src/components/dialog/deviceEdit.vue b/web_src/src/components/dialog/deviceEdit.vue index ed17d171..773e7c9e 100644 --- a/web_src/src/components/dialog/deviceEdit.vue +++ b/web_src/src/components/dialog/deviceEdit.vue @@ -42,6 +42,12 @@ + + + + + + diff --git a/web_src/src/components/live.vue b/web_src/src/components/live.vue index 797be84a..1f2d6caa 100644 --- a/web_src/src/components/live.vue +++ b/web_src/src/components/live.vue @@ -107,20 +107,24 @@ export default { console.log(idx); this.clear(idx.substring(idx.length - 1)) }, - clickEvent: function (data) { - if (data.channelId && data.subCount == 0) { - this.sendDevicePush(data) + clickEvent: function (device, data, isCatalog) { + if (data.channelId && !isCatalog) { + if (device.online === 0) { + this.$message.error('设备离线!不允许点播'); + }else { + this.sendDevicePush(data) + } } }, - contextMenuEvent: function (data) { + contextMenuEvent: function (device, event, data, isCatalog) { }, //通知设备上传媒体流 sendDevicePush: function (itemData) { - if (itemData.status === 0) { - this.$message.error('设备离线!'); - return - } + // if (itemData.status === 0) { + // this.$message.error('设备离线!'); + // return + // } this.save(itemData) let deviceId = itemData.deviceId; // this.isLoging = true; diff --git a/web_src/src/components/map.vue b/web_src/src/components/map.vue index e9e86287..d4a36cf0 100644 --- a/web_src/src/components/map.vue +++ b/web_src/src/components/map.vue @@ -16,7 +16,8 @@ {{channel.channelId}} {{channel.model}} - {{channel.longitude}},{{channel.latitude}} + {{channel[longitudeStr]}} + {{channel[latitudeStr]}} {{channel.manufacture}} {{channel.civilCode}} {{channel.owner}} @@ -28,7 +29,7 @@
- +
@@ -64,11 +65,14 @@ export default { layer: null, lineLayer: null, channel: null, + device: null, infoBoxId: null, labelStyle: { width: "56px" }, isLoging: false, + longitudeStr: "longitude", + latitudeStr: "latitude", }; }, created() { @@ -78,17 +82,27 @@ export default { setTimeout(()=>{ // 延迟以等待地图加载完成 TODO 后续修改为通过是实际这;状态加回调完成 this.deviceService.getAllChannel(false, false, this.$route.query.deviceId, this.channelsHandler) }, 1000) - + } + if (window.mapParam.coordinateSystem == "GCJ-02") { + this.longitudeStr = "longitudeGcj02"; + this.latitudeStr = "latitudeGcj02"; + }else if (window.mapParam.coordinateSystem == "WGS84") { + this.longitudeStr = "longitudeWgs84"; + this.latitudeStr = "latitudeWgs84"; + }else { + this.longitudeStr = "longitude"; + this.latitudeStr = "latitude"; } }, destroyed() { }, methods: { - clickEvent: function (data) { - if (data.channelId && data.subCount == 0) { + clickEvent: function (device, data, isCatalog) { + this.device = device; + if (data.channelId && !isCatalog) { // 点击通道 - if (data.longitude * data.latitude === 0) { + if (data[this.longitudeStr] * data[this.latitudeStr] === 0) { this.$message.error('未获取到位置信息'); } else { if (this.layer != null) { @@ -96,26 +110,29 @@ export default { } this.closeInfoBox() this.layer = this.$refs.map.addLayer([{ - position: [data.longitude, data.latitude], + position: [data[this.longitudeStr], data[this.latitudeStr]], image: { src: this.getImageByChannel(data), anchor: [0.5, 1] }, data: data }], this.featureClickEvent) - this.$refs.map.panTo([data.longitude, data.latitude], mapParam.maxZoom) + this.$refs.map.panTo([data[this.longitudeStr], data[this.latitudeStr]], mapParam.maxZoom) } } }, - contextmenuEventHandler: function (event, data) { - if (data.channelId && data.subCount == 0) { + contextmenuEventHandler: function (device, event, data, isCatalog) { + console.log(device) + console.log(device.online) + this.device = device; + if (data.channelId && !isCatalog) { // 点击通道 this.$contextmenu({ items: [ { label: "播放", icon: "el-icon-video-play", - disabled: false, + disabled: device.online === 0, onClick: () => { this.play(data); } @@ -183,22 +200,11 @@ export default { this.clean() this.closeInfoBox() let params = []; - let longitudeStr; - let latitudeStr; - if (window.mapParam.coordinateSystem == "GCJ-02") { - longitudeStr = "longitudeGcj02"; - latitudeStr = "latitudeGcj02"; - }else if (window.mapParam.coordinateSystem == "WGS84") { - longitudeStr = "longitudeWgs84"; - latitudeStr = "latitudeWgs84"; - }else { - longitudeStr = "longitude"; - latitudeStr = "latitude"; - } + for (let i = 0; i < channels.length; i++) { - let longitude = channels[i][longitudeStr]; - let latitude = channels[i][latitudeStr]; + let longitude = channels[i][this.longitudeStr]; + let latitude = channels[i][this.latitudeStr]; if (longitude * latitude === 0) { continue; } @@ -217,7 +223,7 @@ export default { this.layer = this.$refs.map.addLayer(params, this.featureClickEvent) console.log(4) if (params.length === 1) { - this.$refs.map.panTo([channels[0][longitudeStr], channels[0][latitudeStr]], mapParam.maxZoom) + this.$refs.map.panTo([channels[0][this.longitudeStr], channels[0][this.latitudeStr]], mapParam.maxZoom) } else if (params.length > 1) { this.$refs.map.fit(this.layer) } else { @@ -266,19 +272,7 @@ export default { this.channel = channels[0] } this.$nextTick(() => { - let longitudeStr; - let latitudeStr; - if (window.mapParam.coordinateSystem == "GCJ-02") { - longitudeStr = "longitudeGcj02"; - latitudeStr = "latitudeGcj02"; - }else if (window.mapParam.coordinateSystem == "WGS84") { - longitudeStr = "longitudeWgs84"; - latitudeStr = "latitudeWgs84"; - }else { - longitudeStr = "longitude"; - latitudeStr = "latitude"; - } - let position = [this.channel[longitudeStr], this.channel[latitudeStr]]; + let position = [this.channel[this.longitudeStr], this.channel[this.latitudeStr]]; this.infoBoxId = this.$refs.map.openInfoBox(position, this.$refs.infobox, [0, -50]) }) }, diff --git a/web_src/src/components/service/DeviceService.js b/web_src/src/components/service/DeviceService.js index fb663744..45d4ac23 100644 --- a/web_src/src/components/service/DeviceService.js +++ b/web_src/src/components/service/DeviceService.js @@ -133,6 +133,49 @@ class DeviceService{ if (typeof (callback) == "function") callback(res.data) }).catch(errorCallback); } + + getTree(deviceId, id, param3, param4) { + + } + + getTree(deviceId, parentId, onlyCatalog, callback, endCallback, errorCallback) { + let currentPage = 1; + let count = 100; + let catalogList = [] + this.getTreeIteration(deviceId, parentId, onlyCatalog, catalogList, currentPage, count, callback, endCallback, errorCallback) + } + + getTreeIteration(deviceId, parentId, onlyCatalog, catalogList, currentPage, count, callback, endCallback, errorCallback) { + this.getTreeInfo(deviceId, parentId, onlyCatalog, currentPage, count, (data) => { + if (data.list) { + if (typeof (callback) == "function") callback(data.list) + catalogList = catalogList.concat(data.list); + if (catalogList.length < data.total) { + currentPage ++ + this.getTreeIteration(deviceId, parentId, onlyCatalog, catalogList, currentPage, count, callback, endCallback, errorCallback) + }else { + if (typeof (endCallback) == "function") endCallback(catalogList) + } + } + }, errorCallback) + } + getTreeInfo(deviceId, parentId, onlyCatalog, currentPage, count, callback, errorCallback) { + if (onlyCatalog == null || typeof onlyCatalog === "undefined") { + onlyCatalog = false; + } + this.$axios({ + method: 'get', + url: `/api/device/query/tree/${deviceId}`, + params:{ + page: currentPage, + count: count, + parentId: parentId, + onlyCatalog: onlyCatalog + } + }).then((res) =>{ + if (typeof (callback) == "function") callback(res.data) + }).catch(errorCallback); + } } export default DeviceService; diff --git a/web_src/src/router/index.js b/web_src/src/router/index.js index 2f44fd85..2c9c6f37 100644 --- a/web_src/src/router/index.js +++ b/web_src/src/router/index.js @@ -59,7 +59,7 @@ export default new VueRouter({ component: streamProxyList, }, { - path: '/channelList/:deviceId/:parentChannelId/:count/:page', + path: '/channelList/:deviceId/:parentChannelId/', name: 'channelList', component: channelList, }, diff --git a/web_src/static/css/iconfont.css b/web_src/static/css/iconfont.css index 2a08b07f..a09b98e9 100644 --- a/web_src/static/css/iconfont.css +++ b/web_src/static/css/iconfont.css @@ -1,6 +1,8 @@ @font-face { font-family: "iconfont"; /* Project id 1291092 */ - src: url('iconfont.woff2?t=1650436696596') format('woff2'); + src: url('iconfont.woff2?t=1655453611360') format('woff2'), + url('iconfont.woff?t=1655453611360') format('woff'), + url('iconfont.ttf?t=1655453611360') format('truetype'); } .iconfont { @@ -11,6 +13,30 @@ -moz-osx-font-smoothing: grayscale; } +.icon-list:before { + content: "\e7de"; +} + +.icon-tree:before { + content: "\e7df"; +} + +.icon-shipin:before { + content: "\e7db"; +} + +.icon-shipin1:before { + content: "\e7dc"; +} + +.icon-shipin2:before { + content: "\e7dd"; +} + +.icon-LC_icon_gps_fill:before { + content: "\e7da"; +} + .icon-jiedianleizhukongzhongxin1:before { content: "\e9d0"; } diff --git a/web_src/static/css/iconfont.woff2 b/web_src/static/css/iconfont.woff2 index 7204137aaf543d0e818cfe56aaed1056f957ea87..c2fdf694df2667d55a1e15d7657c3698423d112a 100644 GIT binary patch literal 54780 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 literal 54140 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