Commit 019d95cfba07f0231bd5b385f6736883c6e90623

Authored by 648540858
2 parents 100252a2 2d2832db

Merge branch 'wvp-28181-2.0'

# Conflicts:
#	src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java
Showing 42 changed files with 553 additions and 128 deletions
doc/_content/introduction/compile.md
@@ -69,7 +69,7 @@ git clone https://github.com/648540858/wvp-GB28181-pro.git @@ -69,7 +69,7 @@ git clone https://github.com/648540858/wvp-GB28181-pro.git
69 ### 5.2 编译前端页面 69 ### 5.2 编译前端页面
70 ```shell script 70 ```shell script
71 cd wvp-GB28181-pro/web_src/ 71 cd wvp-GB28181-pro/web_src/
72 -npm --registry=https://registry.npm.taobao.org install 72 +npm --registry=https://registry.npmmirror.com install
73 npm run build 73 npm run build
74 ``` 74 ```
75 编译如果报错, 一般都是网络问题, 导致的依赖包下载失败 75 编译如果报错, 一般都是网络问题, 导致的依赖包下载失败
src/main/java/com/genersoft/iot/vmp/common/VideoManagerConstants.java
@@ -139,4 +139,15 @@ public class VideoManagerConstants { @@ -139,4 +139,15 @@ public class VideoManagerConstants {
139 public static final String WVP_STREAM_GB_ID_PREFIX = "memberNo_"; 139 public static final String WVP_STREAM_GB_ID_PREFIX = "memberNo_";
140 public static final String WVP_STREAM_GPS_MSG_PREFIX = "WVP_STREAM_GPS_MSG_"; 140 public static final String WVP_STREAM_GPS_MSG_PREFIX = "WVP_STREAM_GPS_MSG_";
141 141
  142 + /**
  143 + * Redis Const
  144 + * 设备录像信息结果前缀
  145 + */
  146 + public static final String REDIS_RECORD_INFO_RES_PRE = "GB_RECORD_INFO_RES_";
  147 + /**
  148 + * Redis Const
  149 + * 设备录像信息结果前缀
  150 + */
  151 + public static final String REDIS_RECORD_INFO_RES_COUNT_PRE = "GB_RECORD_INFO_RES_COUNT:";
  152 +
142 } 153 }
src/main/java/com/genersoft/iot/vmp/conf/MediaConfig.java
@@ -2,6 +2,7 @@ package com.genersoft.iot.vmp.conf; @@ -2,6 +2,7 @@ package com.genersoft.iot.vmp.conf;
2 2
3 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; 3 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
4 import com.genersoft.iot.vmp.utils.DateUtil; 4 import com.genersoft.iot.vmp.utils.DateUtil;
  5 +import org.junit.jupiter.api.Order;
5 import org.slf4j.Logger; 6 import org.slf4j.Logger;
6 import org.slf4j.LoggerFactory; 7 import org.slf4j.LoggerFactory;
7 import org.springframework.beans.factory.annotation.Value; 8 import org.springframework.beans.factory.annotation.Value;
@@ -14,6 +15,7 @@ import java.util.regex.Pattern; @@ -14,6 +15,7 @@ import java.util.regex.Pattern;
14 15
15 16
16 @Configuration("mediaConfig") 17 @Configuration("mediaConfig")
  18 +@Order(0)
17 public class MediaConfig{ 19 public class MediaConfig{
18 20
19 private final static Logger logger = LoggerFactory.getLogger(MediaConfig.class); 21 private final static Logger logger = LoggerFactory.getLogger(MediaConfig.class);
src/main/java/com/genersoft/iot/vmp/conf/ProxyServletConfig.java
@@ -5,6 +5,7 @@ import com.genersoft.iot.vmp.service.IMediaServerService; @@ -5,6 +5,7 @@ import com.genersoft.iot.vmp.service.IMediaServerService;
5 import org.apache.http.HttpHost; 5 import org.apache.http.HttpHost;
6 import org.apache.http.HttpRequest; 6 import org.apache.http.HttpRequest;
7 import org.apache.http.HttpResponse; 7 import org.apache.http.HttpResponse;
  8 +import org.junit.jupiter.api.Order;
8 import org.mitre.dsmiley.httpproxy.ProxyServlet; 9 import org.mitre.dsmiley.httpproxy.ProxyServlet;
9 import org.slf4j.Logger; 10 import org.slf4j.Logger;
10 import org.slf4j.LoggerFactory; 11 import org.slf4j.LoggerFactory;
@@ -25,6 +26,7 @@ import java.net.ConnectException; @@ -25,6 +26,7 @@ import java.net.ConnectException;
25 */ 26 */
26 @SuppressWarnings(value = {"rawtypes", "unchecked"}) 27 @SuppressWarnings(value = {"rawtypes", "unchecked"})
27 @Configuration 28 @Configuration
  29 +@Order(1)
28 public class ProxyServletConfig { 30 public class ProxyServletConfig {
29 31
30 private final static Logger logger = LoggerFactory.getLogger(ProxyServletConfig.class); 32 private final static Logger logger = LoggerFactory.getLogger(ProxyServletConfig.class);
src/main/java/com/genersoft/iot/vmp/conf/SipConfig.java
1 package com.genersoft.iot.vmp.conf; 1 package com.genersoft.iot.vmp.conf;
2 2
3 3
  4 +import org.junit.jupiter.api.Order;
4 import org.springframework.boot.context.properties.ConfigurationProperties; 5 import org.springframework.boot.context.properties.ConfigurationProperties;
5 import org.springframework.stereotype.Component; 6 import org.springframework.stereotype.Component;
6 import org.springframework.util.ObjectUtils; 7 import org.springframework.util.ObjectUtils;
7 8
8 @Component 9 @Component
9 @ConfigurationProperties(prefix = "sip", ignoreInvalidFields = true) 10 @ConfigurationProperties(prefix = "sip", ignoreInvalidFields = true)
  11 +@Order(0)
10 public class SipConfig { 12 public class SipConfig {
11 13
12 private String ip; 14 private String ip;
src/main/java/com/genersoft/iot/vmp/conf/SipPlatformRunner.java
@@ -18,7 +18,7 @@ import java.util.List; @@ -18,7 +18,7 @@ import java.util.List;
18 * @author lin 18 * @author lin
19 */ 19 */
20 @Component 20 @Component
21 -@Order(value=3) 21 +@Order(value=13)
22 public class SipPlatformRunner implements CommandLineRunner { 22 public class SipPlatformRunner implements CommandLineRunner {
23 23
24 @Autowired 24 @Autowired
src/main/java/com/genersoft/iot/vmp/conf/SpringDocConfig.java
1 package com.genersoft.iot.vmp.conf; 1 package com.genersoft.iot.vmp.conf;
2 2
3 -import io.swagger.v3.oas.models.ExternalDocumentation;  
4 import io.swagger.v3.oas.models.OpenAPI; 3 import io.swagger.v3.oas.models.OpenAPI;
5 import io.swagger.v3.oas.models.info.Contact; 4 import io.swagger.v3.oas.models.info.Contact;
6 import io.swagger.v3.oas.models.info.Info; 5 import io.swagger.v3.oas.models.info.Info;
7 import io.swagger.v3.oas.models.info.License; 6 import io.swagger.v3.oas.models.info.License;
8 -import io.swagger.v3.oas.models.media.StringSchema;  
9 -import io.swagger.v3.oas.models.parameters.HeaderParameter; 7 +import org.junit.jupiter.api.Order;
10 import org.springdoc.core.GroupedOpenApi; 8 import org.springdoc.core.GroupedOpenApi;
11 -import org.springdoc.core.SpringDocConfigProperties;  
12 import org.springframework.beans.factory.annotation.Value; 9 import org.springframework.beans.factory.annotation.Value;
13 import org.springframework.context.annotation.Bean; 10 import org.springframework.context.annotation.Bean;
14 import org.springframework.context.annotation.Configuration; 11 import org.springframework.context.annotation.Configuration;
@@ -17,6 +14,7 @@ import org.springframework.context.annotation.Configuration; @@ -17,6 +14,7 @@ import org.springframework.context.annotation.Configuration;
17 * @author lin 14 * @author lin
18 */ 15 */
19 @Configuration 16 @Configuration
  17 +@Order(1)
20 public class SpringDocConfig { 18 public class SpringDocConfig {
21 19
22 @Value("${doc.enabled: true}") 20 @Value("${doc.enabled: true}")
src/main/java/com/genersoft/iot/vmp/conf/ThreadPoolTaskConfig.java
1 package com.genersoft.iot.vmp.conf; 1 package com.genersoft.iot.vmp.conf;
2 2
  3 +import org.junit.jupiter.api.Order;
3 import org.springframework.context.annotation.Bean; 4 import org.springframework.context.annotation.Bean;
4 import org.springframework.context.annotation.Configuration; 5 import org.springframework.context.annotation.Configuration;
5 import org.springframework.scheduling.annotation.EnableAsync; 6 import org.springframework.scheduling.annotation.EnableAsync;
@@ -12,6 +13,7 @@ import java.util.concurrent.ThreadPoolExecutor; @@ -12,6 +13,7 @@ import java.util.concurrent.ThreadPoolExecutor;
12 * @author lin 13 * @author lin
13 */ 14 */
14 @Configuration 15 @Configuration
  16 +@Order(1)
15 @EnableAsync(proxyTargetClass = true) 17 @EnableAsync(proxyTargetClass = true)
16 public class ThreadPoolTaskConfig { 18 public class ThreadPoolTaskConfig {
17 19
src/main/java/com/genersoft/iot/vmp/conf/UserSetting.java
1 package com.genersoft.iot.vmp.conf; 1 package com.genersoft.iot.vmp.conf;
2 2
  3 +import org.junit.jupiter.api.Order;
3 import org.springframework.boot.context.properties.ConfigurationProperties; 4 import org.springframework.boot.context.properties.ConfigurationProperties;
4 import org.springframework.stereotype.Component; 5 import org.springframework.stereotype.Component;
5 6
@@ -11,6 +12,7 @@ import java.util.List; @@ -11,6 +12,7 @@ import java.util.List;
11 */ 12 */
12 @Component 13 @Component
13 @ConfigurationProperties(prefix = "user-settings", ignoreInvalidFields = true) 14 @ConfigurationProperties(prefix = "user-settings", ignoreInvalidFields = true)
  15 +@Order(0)
14 public class UserSetting { 16 public class UserSetting {
15 17
16 private Boolean savePositionHistory = Boolean.FALSE; 18 private Boolean savePositionHistory = Boolean.FALSE;
src/main/java/com/genersoft/iot/vmp/conf/VersionConfig.java
1 package com.genersoft.iot.vmp.conf; 1 package com.genersoft.iot.vmp.conf;
2 2
  3 +import org.junit.jupiter.api.Order;
3 import org.springframework.boot.context.properties.ConfigurationProperties; 4 import org.springframework.boot.context.properties.ConfigurationProperties;
4 import org.springframework.stereotype.Component; 5 import org.springframework.stereotype.Component;
5 6
6 @Component 7 @Component
7 @ConfigurationProperties(prefix = "version") 8 @ConfigurationProperties(prefix = "version")
  9 +@Order(0)
8 public class VersionConfig { 10 public class VersionConfig {
9 11
10 private String version; 12 private String version;
src/main/java/com/genersoft/iot/vmp/conf/redis/RedisConfig.java
@@ -8,6 +8,7 @@ import org.springframework.beans.factory.annotation.Autowired; @@ -8,6 +8,7 @@ import org.springframework.beans.factory.annotation.Autowired;
8 import org.springframework.cache.annotation.CachingConfigurerSupport; 8 import org.springframework.cache.annotation.CachingConfigurerSupport;
9 import org.springframework.context.annotation.Bean; 9 import org.springframework.context.annotation.Bean;
10 import org.springframework.context.annotation.Configuration; 10 import org.springframework.context.annotation.Configuration;
  11 +import org.springframework.core.annotation.Order;
11 import org.springframework.data.redis.connection.RedisConnectionFactory; 12 import org.springframework.data.redis.connection.RedisConnectionFactory;
12 import org.springframework.data.redis.core.RedisTemplate; 13 import org.springframework.data.redis.core.RedisTemplate;
13 import org.springframework.data.redis.listener.PatternTopic; 14 import org.springframework.data.redis.listener.PatternTopic;
@@ -22,6 +23,7 @@ import org.springframework.data.redis.serializer.StringRedisSerializer; @@ -22,6 +23,7 @@ import org.springframework.data.redis.serializer.StringRedisSerializer;
22 * 23 *
23 */ 24 */
24 @Configuration 25 @Configuration
  26 +@Order(value=1)
25 public class RedisConfig extends CachingConfigurerSupport { 27 public class RedisConfig extends CachingConfigurerSupport {
26 28
27 @Autowired 29 @Autowired
src/main/java/com/genersoft/iot/vmp/conf/security/WebSecurityConfig.java
1 package com.genersoft.iot.vmp.conf.security; 1 package com.genersoft.iot.vmp.conf.security;
2 2
3 import com.genersoft.iot.vmp.conf.UserSetting; 3 import com.genersoft.iot.vmp.conf.UserSetting;
  4 +import org.junit.jupiter.api.Order;
4 import org.slf4j.Logger; 5 import org.slf4j.Logger;
5 import org.slf4j.LoggerFactory; 6 import org.slf4j.LoggerFactory;
6 import org.springframework.beans.factory.annotation.Autowired; 7 import org.springframework.beans.factory.annotation.Autowired;
@@ -25,6 +26,7 @@ import java.util.List; @@ -25,6 +26,7 @@ import java.util.List;
25 @Configuration 26 @Configuration
26 @EnableWebSecurity 27 @EnableWebSecurity
27 @EnableGlobalMethodSecurity(prePostEnabled = true) 28 @EnableGlobalMethodSecurity(prePostEnabled = true)
  29 +@Order(1)
28 public class WebSecurityConfig extends WebSecurityConfigurerAdapter { 30 public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
29 31
30 private final static Logger logger = LoggerFactory.getLogger(WebSecurityConfig.class); 32 private final static Logger logger = LoggerFactory.getLogger(WebSecurityConfig.class);
src/main/java/com/genersoft/iot/vmp/gb28181/SipLayer.java
@@ -19,7 +19,7 @@ import java.util.*; @@ -19,7 +19,7 @@ import java.util.*;
19 import java.util.concurrent.ConcurrentHashMap; 19 import java.util.concurrent.ConcurrentHashMap;
20 20
21 @Component 21 @Component
22 -@Order(value=1) 22 +@Order(value=10)
23 public class SipLayer implements CommandLineRunner { 23 public class SipLayer implements CommandLineRunner {
24 24
25 private final static Logger logger = LoggerFactory.getLogger(SipLayer.class); 25 private final static Logger logger = LoggerFactory.getLogger(SipLayer.class);
src/main/java/com/genersoft/iot/vmp/gb28181/task/SipRunner.java
@@ -28,7 +28,7 @@ import java.util.Map; @@ -28,7 +28,7 @@ import java.util.Map;
28 * @author lin 28 * @author lin
29 */ 29 */
30 @Component 30 @Component
31 -@Order(value=4) 31 +@Order(value=14)
32 public class SipRunner implements CommandLineRunner { 32 public class SipRunner implements CommandLineRunner {
33 33
34 @Autowired 34 @Autowired
@@ -69,6 +69,26 @@ public class SipRunner implements CommandLineRunner { @@ -69,6 +69,26 @@ public class SipRunner implements CommandLineRunner {
69 // 重置cseq计数 69 // 重置cseq计数
70 redisCatchStorage.resetAllCSEQ(); 70 redisCatchStorage.resetAllCSEQ();
71 // 清理redis 71 // 清理redis
  72 + // 清理数据库不存在但是redis中存在的数据
  73 + List<Device> devicesInDb = deviceService.getAll();
  74 + if (devicesInDb.size() == 0) {
  75 + redisCatchStorage.removeAllDevice();
  76 + }else {
  77 + List<Device> devicesInRedis = redisCatchStorage.getAllDevices();
  78 + if (devicesInRedis.size() > 0) {
  79 + Map<String, Device> deviceMapInDb = new HashMap<>();
  80 + devicesInDb.parallelStream().forEach(device -> {
  81 + deviceMapInDb.put(device.getDeviceId(), device);
  82 + });
  83 + devicesInRedis.parallelStream().forEach(device -> {
  84 + if (deviceMapInDb.get(device.getDeviceId()) == null) {
  85 + redisCatchStorage.removeDevice(device.getDeviceId());
  86 + }
  87 + });
  88 + }
  89 + }
  90 +
  91 +
72 // 查找国标推流 92 // 查找国标推流
73 List<SendRtpItem> sendRtpItems = redisCatchStorage.queryAllSendRTPServer(); 93 List<SendRtpItem> sendRtpItems = redisCatchStorage.queryAllSendRTPServer();
74 if (sendRtpItems.size() > 0) { 94 if (sendRtpItems.size() > 0) {
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java
@@ -215,6 +215,25 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { @@ -215,6 +215,25 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
215 }else { 215 }else {
216 catalogXml.append("<Address>" + channel.getAddress() + "</Address>\r\n"); 216 catalogXml.append("<Address>" + channel.getAddress() + "</Address>\r\n");
217 } 217 }
  218 + catalogXml.append("<Block>" + channel.getBlock() + "</Block>\r\n");
  219 + catalogXml.append("<SafetyWay>" + channel.getSafetyWay() + "</SafetyWay>\r\n");
  220 + catalogXml.append("<CertNum>" + channel.getCertNum() + "</CertNum>\r\n");
  221 + catalogXml.append("<Certifiable>" + channel.getCertifiable() + "</Certifiable>\r\n");
  222 + catalogXml.append("<ErrCode>" + channel.getErrCode() + "</ErrCode>\r\n");
  223 + catalogXml.append("<EndTime>" + channel.getEndTime() + "</EndTime>\r\n");
  224 + catalogXml.append("<Secrecy>" + channel.getSecrecy() + "</Secrecy>\r\n");
  225 + catalogXml.append("<IPAddress>" + channel.getIpAddress() + "</IPAddress>\r\n");
  226 + catalogXml.append("<Port>" + channel.getPort() + "</Port>\r\n");
  227 + catalogXml.append("<Password>" + channel.getPort() + "</Password>\r\n");
  228 + catalogXml.append("<Status>" + (channel.getStatus() == 1?"ON":"OFF") + "</Status>\r\n");
  229 + catalogXml.append("<Longitude>" +
  230 + (channel.getLongitudeWgs84() != 0? channel.getLongitudeWgs84():channel.getLongitude())
  231 + + "</Longitude>\r\n");
  232 + catalogXml.append("<Latitude>" +
  233 + (channel.getLatitudeWgs84() != 0? channel.getLatitudeWgs84():channel.getLatitude())
  234 + + "</Latitude>\r\n");
  235 +
  236 +
218 } 237 }
219 } 238 }
220 catalogXml.append("</Item>\r\n"); 239 catalogXml.append("</Item>\r\n");
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java
@@ -360,7 +360,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements @@ -360,7 +360,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
360 return; 360 return;
361 } 361 }
362 String username = sdp.getOrigin().getUsername(); 362 String username = sdp.getOrigin().getUsername();
363 - String addressStr = sdp.getOrigin().getAddress(); 363 + String addressStr = sdp.getConnection().getAddress();
364 364
365 logger.info("[上级点播]用户:{}, 通道:{}, 地址:{}:{}, ssrc:{}", username, channelId, addressStr, port, ssrc); 365 logger.info("[上级点播]用户:{}, 通道:{}, 地址:{}:{}, ssrc:{}", username, channelId, addressStr, port, ssrc);
366 Device device = null; 366 Device device = null;
@@ -982,7 +982,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements @@ -982,7 +982,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
982 } 982 }
983 return; 983 return;
984 } 984 }
985 - String addressStr = sdp.getOrigin().getAddress(); 985 + String addressStr = sdp.getConnection().getAddress();
986 logger.info("设备{}请求语音流,地址:{}:{},ssrc:{}, {}", requesterId, addressStr, port, ssrc, 986 logger.info("设备{}请求语音流,地址:{}:{},ssrc:{}, {}", requesterId, addressStr, port, ssrc,
987 mediaTransmissionTCP ? (tcpActive? "TCP主动":"TCP被动") : "UDP"); 987 mediaTransmissionTCP ? (tcpActive? "TCP主动":"TCP被动") : "UDP");
988 988
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/NotifyRequestProcessor.java
@@ -38,6 +38,7 @@ import javax.sip.header.FromHeader; @@ -38,6 +38,7 @@ import javax.sip.header.FromHeader;
38 import javax.sip.message.Response; 38 import javax.sip.message.Response;
39 import java.text.ParseException; 39 import java.text.ParseException;
40 import java.util.Iterator; 40 import java.util.Iterator;
  41 +import java.util.List;
41 import java.util.concurrent.ConcurrentLinkedQueue; 42 import java.util.concurrent.ConcurrentLinkedQueue;
42 43
43 /** 44 /**
@@ -154,6 +155,17 @@ public class NotifyRequestProcessor extends SIPRequestProcessorParent implements @@ -154,6 +155,17 @@ public class NotifyRequestProcessor extends SIPRequestProcessorParent implements
154 Element deviceIdElement = rootElement.element("DeviceID"); 155 Element deviceIdElement = rootElement.element("DeviceID");
155 String channelId = deviceIdElement.getTextTrim().toString(); 156 String channelId = deviceIdElement.getTextTrim().toString();
156 Device device = redisCatchStorage.getDevice(deviceId); 157 Device device = redisCatchStorage.getDevice(deviceId);
  158 +
  159 + if (device == null) {
  160 + // 根据通道id查询设备Id
  161 + List<Device> deviceList = deviceChannelService.getDeviceByChannelId(channelId);
  162 + if (deviceList.size() > 0) {
  163 + device = deviceList.get(0);
  164 + }else {
  165 + logger.warn("[mobilePosition移动位置Notify] 未找到通道{}所属的设备", channelId);
  166 + return;
  167 + }
  168 + }
157 if (device != null) { 169 if (device != null) {
158 if (!ObjectUtils.isEmpty(device.getName())) { 170 if (!ObjectUtils.isEmpty(device.getName())) {
159 mobilePosition.setDeviceName(device.getName()); 171 mobilePosition.setDeviceName(device.getName());
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/RegisterRequestProcessor.java
1 package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl; 1 package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl;
2 2
3 -import com.genersoft.iot.vmp.conf.ServiceInfo;  
4 import com.genersoft.iot.vmp.conf.SipConfig; 3 import com.genersoft.iot.vmp.conf.SipConfig;
5 import com.genersoft.iot.vmp.conf.UserSetting; 4 import com.genersoft.iot.vmp.conf.UserSetting;
6 import com.genersoft.iot.vmp.gb28181.auth.DigestServerAuthenticationHelper; 5 import com.genersoft.iot.vmp.gb28181.auth.DigestServerAuthenticationHelper;
@@ -95,7 +94,7 @@ public class RegisterRequestProcessor extends SIPRequestProcessorParent implemen @@ -95,7 +94,7 @@ public class RegisterRequestProcessor extends SIPRequestProcessorParent implemen
95 // } 94 // }
96 // } 95 // }
97 96
98 - System.out.println(ServiceInfo.getServerPort()); 97 +// System.out.println(ServiceInfo.getServerPort());
99 SIPRequest request = (SIPRequest)evt.getRequest(); 98 SIPRequest request = (SIPRequest)evt.getRequest();
100 Response response = null; 99 Response response = null;
101 boolean passwordCorrect = false; 100 boolean passwordCorrect = false;
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/CatalogResponseMessageHandler.java
@@ -5,6 +5,7 @@ import com.genersoft.iot.vmp.gb28181.session.CatalogDataCatch; @@ -5,6 +5,7 @@ import com.genersoft.iot.vmp.gb28181.session.CatalogDataCatch;
5 import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent; 5 import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent;
6 import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.IMessageHandler; 6 import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.IMessageHandler;
7 import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.response.ResponseMessageHandler; 7 import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.response.ResponseMessageHandler;
  8 +import com.genersoft.iot.vmp.gb28181.utils.SipUtils;
8 import com.genersoft.iot.vmp.gb28181.utils.XmlUtil; 9 import com.genersoft.iot.vmp.gb28181.utils.XmlUtil;
9 import com.genersoft.iot.vmp.storager.IVideoManagerStorage; 10 import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
10 import gov.nist.javax.sip.message.SIPRequest; 11 import gov.nist.javax.sip.message.SIPRequest;
@@ -108,6 +109,7 @@ public class CatalogResponseMessageHandler extends SIPRequestProcessorParent imp @@ -108,6 +109,7 @@ public class CatalogResponseMessageHandler extends SIPRequestProcessorParent imp
108 continue; 109 continue;
109 } 110 }
110 DeviceChannel deviceChannel = XmlUtil.channelContentHander(itemDevice, device, null); 111 DeviceChannel deviceChannel = XmlUtil.channelContentHander(itemDevice, device, null);
  112 + deviceChannel = SipUtils.updateGps(deviceChannel, device.getGeoCoordSys());
111 deviceChannel.setDeviceId(take.getDevice().getDeviceId()); 113 deviceChannel.setDeviceId(take.getDevice().getDeviceId());
112 114
113 channelList.add(deviceChannel); 115 channelList.add(deviceChannel);
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/RecordInfoResponseMessageHandler.java
1 package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.response.cmd; 1 package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.response.cmd;
2 2
  3 +import com.genersoft.iot.vmp.common.VideoManagerConstants;
3 import com.genersoft.iot.vmp.gb28181.bean.*; 4 import com.genersoft.iot.vmp.gb28181.bean.*;
4 import com.genersoft.iot.vmp.gb28181.event.EventPublisher; 5 import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
5 -import com.genersoft.iot.vmp.gb28181.session.RecordDataCatch;  
6 import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder; 6 import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder;
7 import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage; 7 import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage;
8 import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent; 8 import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent;
9 import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.IMessageHandler; 9 import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.IMessageHandler;
10 import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.response.ResponseMessageHandler; 10 import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.response.ResponseMessageHandler;
11 import com.genersoft.iot.vmp.utils.DateUtil; 11 import com.genersoft.iot.vmp.utils.DateUtil;
  12 +import com.genersoft.iot.vmp.utils.UJson;
  13 +import com.genersoft.iot.vmp.utils.redis.RedisUtil;
12 import gov.nist.javax.sip.message.SIPRequest; 14 import gov.nist.javax.sip.message.SIPRequest;
13 -import org.dom4j.DocumentException;  
14 import org.dom4j.Element; 15 import org.dom4j.Element;
15 import org.slf4j.Logger; 16 import org.slf4j.Logger;
16 import org.slf4j.LoggerFactory; 17 import org.slf4j.LoggerFactory;
@@ -26,11 +27,9 @@ import javax.sip.RequestEvent; @@ -26,11 +27,9 @@ import javax.sip.RequestEvent;
26 import javax.sip.SipException; 27 import javax.sip.SipException;
27 import javax.sip.message.Response; 28 import javax.sip.message.Response;
28 import java.text.ParseException; 29 import java.text.ParseException;
29 -import java.util.ArrayList;  
30 -import java.util.Collections;  
31 -import java.util.Iterator;  
32 -import java.util.List; 30 +import java.util.*;
33 import java.util.concurrent.ConcurrentLinkedQueue; 31 import java.util.concurrent.ConcurrentLinkedQueue;
  32 +import java.util.stream.Collectors;
34 33
35 import static com.genersoft.iot.vmp.gb28181.utils.XmlUtil.getText; 34 import static com.genersoft.iot.vmp.gb28181.utils.XmlUtil.getText;
36 35
@@ -49,9 +48,6 @@ public class RecordInfoResponseMessageHandler extends SIPRequestProcessorParent @@ -49,9 +48,6 @@ public class RecordInfoResponseMessageHandler extends SIPRequestProcessorParent
49 private ResponseMessageHandler responseMessageHandler; 48 private ResponseMessageHandler responseMessageHandler;
50 49
51 @Autowired 50 @Autowired
52 - private RecordDataCatch recordDataCatch;  
53 -  
54 - @Autowired  
55 private DeferredResultHolder deferredResultHolder; 51 private DeferredResultHolder deferredResultHolder;
56 52
57 @Autowired 53 @Autowired
@@ -61,6 +57,8 @@ public class RecordInfoResponseMessageHandler extends SIPRequestProcessorParent @@ -61,6 +57,8 @@ public class RecordInfoResponseMessageHandler extends SIPRequestProcessorParent
61 @Autowired 57 @Autowired
62 private ThreadPoolTaskExecutor taskExecutor; 58 private ThreadPoolTaskExecutor taskExecutor;
63 59
  60 + private Long recordInfoTtl = 1800L;
  61 +
64 @Override 62 @Override
65 public void afterPropertiesSet() throws Exception { 63 public void afterPropertiesSet() throws Exception {
66 responseMessageHandler.addHandler(cmdType, this); 64 responseMessageHandler.addHandler(cmdType, this);
@@ -68,93 +66,93 @@ public class RecordInfoResponseMessageHandler extends SIPRequestProcessorParent @@ -68,93 +66,93 @@ public class RecordInfoResponseMessageHandler extends SIPRequestProcessorParent
68 66
69 @Override 67 @Override
70 public void handForDevice(RequestEvent evt, Device device, Element rootElement) { 68 public void handForDevice(RequestEvent evt, Device device, Element rootElement) {
71 - boolean isEmpty = taskQueue.isEmpty();  
72 try { 69 try {
73 // 回复200 OK 70 // 回复200 OK
74 responseAck((SIPRequest) evt.getRequest(), Response.OK); 71 responseAck((SIPRequest) evt.getRequest(), Response.OK);
75 }catch (SipException | InvalidArgumentException | ParseException e) { 72 }catch (SipException | InvalidArgumentException | ParseException e) {
76 logger.error("[命令发送失败] 国标级联 国标录像: {}", e.getMessage()); 73 logger.error("[命令发送失败] 国标级联 国标录像: {}", e.getMessage());
77 } 74 }
78 - taskQueue.offer(new HandlerCatchData(evt, device, rootElement));  
79 - if (isEmpty) {  
80 - taskExecutor.execute(()->{  
81 - while (!taskQueue.isEmpty()) {  
82 - try {  
83 - HandlerCatchData take = taskQueue.poll();  
84 - Element rootElementForCharset = getRootElement(take.getEvt(), take.getDevice().getCharset());  
85 - if (rootElement == null) {  
86 - logger.warn("[ 国标录像 ] content cannot be null, {}", evt.getRequest());  
87 - continue; 75 + taskExecutor.execute(()->{
  76 + try {
  77 +
  78 + String sn = getText(rootElement, "SN");
  79 + String channelId = getText(rootElement, "DeviceID");
  80 + RecordInfo recordInfo = new RecordInfo();
  81 + recordInfo.setChannelId(channelId);
  82 + recordInfo.setDeviceId(device.getDeviceId());
  83 + recordInfo.setSn(sn);
  84 + recordInfo.setName(getText(rootElement, "Name"));
  85 + String sumNumStr = getText(rootElement, "SumNum");
  86 + int sumNum = 0;
  87 + if (!ObjectUtils.isEmpty(sumNumStr)) {
  88 + sumNum = Integer.parseInt(sumNumStr);
  89 + }
  90 + recordInfo.setSumNum(sumNum);
  91 + Element recordListElement = rootElement.element("RecordList");
  92 + if (recordListElement == null || sumNum == 0) {
  93 + logger.info("无录像数据");
  94 + recordInfo.setCount(sumNum);
  95 + eventPublisher.recordEndEventPush(recordInfo);
  96 + releaseRequest(device.getDeviceId(), sn,recordInfo);
  97 + } else {
  98 + Iterator<Element> recordListIterator = recordListElement.elementIterator();
  99 + if (recordListIterator != null) {
  100 + List<RecordItem> recordList = new ArrayList<>();
  101 + // 遍历DeviceList
  102 + while (recordListIterator.hasNext()) {
  103 + Element itemRecord = recordListIterator.next();
  104 + Element recordElement = itemRecord.element("DeviceID");
  105 + if (recordElement == null) {
  106 + logger.info("记录为空,下一个...");
  107 + continue;
  108 + }
  109 + RecordItem record = new RecordItem();
  110 + record.setDeviceId(getText(itemRecord, "DeviceID"));
  111 + record.setName(getText(itemRecord, "Name"));
  112 + record.setFilePath(getText(itemRecord, "FilePath"));
  113 + record.setFileSize(getText(itemRecord, "FileSize"));
  114 + record.setAddress(getText(itemRecord, "Address"));
  115 +
  116 + String startTimeStr = getText(itemRecord, "StartTime");
  117 + record.setStartTime(DateUtil.ISO8601Toyyyy_MM_dd_HH_mm_ss(startTimeStr));
  118 +
  119 + String endTimeStr = getText(itemRecord, "EndTime");
  120 + record.setEndTime(DateUtil.ISO8601Toyyyy_MM_dd_HH_mm_ss(endTimeStr));
  121 +
  122 + record.setSecrecy(itemRecord.element("Secrecy") == null ? 0
  123 + : Integer.parseInt(getText(itemRecord, "Secrecy")));
  124 + record.setType(getText(itemRecord, "Type"));
  125 + record.setRecorderId(getText(itemRecord, "RecorderID"));
  126 + recordList.add(record);
88 } 127 }
89 - String sn = getText(rootElementForCharset, "SN");  
90 - String channelId = getText(rootElementForCharset, "DeviceID");  
91 - RecordInfo recordInfo = new RecordInfo();  
92 - recordInfo.setChannelId(channelId);  
93 - recordInfo.setDeviceId(take.getDevice().getDeviceId());  
94 - recordInfo.setSn(sn);  
95 - recordInfo.setName(getText(rootElementForCharset, "Name"));  
96 - String sumNumStr = getText(rootElementForCharset, "SumNum");  
97 - int sumNum = 0;  
98 - if (!ObjectUtils.isEmpty(sumNumStr)) {  
99 - sumNum = Integer.parseInt(sumNumStr); 128 + Map<String, String> map = recordList.stream()
  129 + .filter(record -> record.getDeviceId() != null)
  130 + .collect(Collectors.toMap(record -> record.getStartTime()+ record.getEndTime(), UJson::writeJson));
  131 + // 获取任务结果数据
  132 + String resKey = VideoManagerConstants.REDIS_RECORD_INFO_RES_PRE + channelId + sn;
  133 + RedisUtil.hmset(resKey, map, recordInfoTtl);
  134 + String resCountKey = VideoManagerConstants.REDIS_RECORD_INFO_RES_COUNT_PRE + channelId + sn;
  135 + long incr = RedisUtil.incr(resCountKey, map.size());
  136 + RedisUtil.expire(resCountKey, recordInfoTtl);
  137 + recordInfo.setRecordList(recordList);
  138 + recordInfo.setCount(Math.toIntExact(incr));
  139 + eventPublisher.recordEndEventPush(recordInfo);
  140 + if (incr < sumNum) {
  141 + return;
100 } 142 }
101 - recordInfo.setSumNum(sumNum);  
102 - Element recordListElement = rootElementForCharset.element("RecordList");  
103 - if (recordListElement == null || sumNum == 0) {  
104 - logger.info("无录像数据");  
105 - int count = recordDataCatch.put(take.getDevice().getDeviceId(),channelId, sn, sumNum, new ArrayList<>());  
106 - recordInfo.setCount(count);  
107 - eventPublisher.recordEndEventPush(recordInfo);  
108 - releaseRequest(take.getDevice().getDeviceId(), sn);  
109 - } else {  
110 - Iterator<Element> recordListIterator = recordListElement.elementIterator();  
111 - if (recordListIterator != null) {  
112 - List<RecordItem> recordList = new ArrayList<>();  
113 - // 遍历DeviceList  
114 - while (recordListIterator.hasNext()) {  
115 - Element itemRecord = recordListIterator.next();  
116 - Element recordElement = itemRecord.element("DeviceID");  
117 - if (recordElement == null) {  
118 - logger.info("记录为空,下一个...");  
119 - continue;  
120 - }  
121 - RecordItem record = new RecordItem();  
122 - record.setDeviceId(getText(itemRecord, "DeviceID"));  
123 - record.setName(getText(itemRecord, "Name"));  
124 - record.setFilePath(getText(itemRecord, "FilePath"));  
125 - record.setFileSize(getText(itemRecord, "FileSize"));  
126 - record.setAddress(getText(itemRecord, "Address"));  
127 -  
128 - String startTimeStr = getText(itemRecord, "StartTime");  
129 - record.setStartTime(DateUtil.ISO8601Toyyyy_MM_dd_HH_mm_ss(startTimeStr));  
130 -  
131 - String endTimeStr = getText(itemRecord, "EndTime");  
132 - record.setEndTime(DateUtil.ISO8601Toyyyy_MM_dd_HH_mm_ss(endTimeStr));  
133 -  
134 - record.setSecrecy(itemRecord.element("Secrecy") == null ? 0  
135 - : Integer.parseInt(getText(itemRecord, "Secrecy")));  
136 - record.setType(getText(itemRecord, "Type"));  
137 - record.setRecorderId(getText(itemRecord, "RecorderID"));  
138 - recordList.add(record);  
139 - }  
140 - recordInfo.setRecordList(recordList);  
141 - int count = recordDataCatch.put(take.getDevice().getDeviceId(),channelId, sn, sumNum, recordList);recordInfo.setCount(count);  
142 - logger.info("[国标录像], {}->{}: {}/{}", take.getDevice().getDeviceId(), sn, count, sumNum);  
143 - // 发送消息,如果是上级查询此录像,则会通过这里通知给上级  
144 - eventPublisher.recordEndEventPush(recordInfo);  
145 - }  
146 - if (recordDataCatch.isComplete(take.getDevice().getDeviceId(), sn)){  
147 - releaseRequest(take.getDevice().getDeviceId(), sn);  
148 - } 143 + // 已接收完成
  144 + List<RecordItem> resList = RedisUtil.hmget(resKey).values().stream().map(e -> UJson.readJson(e.toString(), RecordItem.class)).collect(Collectors.toList());
  145 + if (resList.size() < sumNum) {
  146 + return;
149 } 147 }
150 - } catch (DocumentException e) {  
151 - logger.error("xml解析异常: ", e);  
152 - } catch (Exception e) {  
153 - logger.warn("[国标录像] 发现未处理的异常, {}\r\n{}",e.getMessage(), evt.getRequest()); 148 + recordInfo.setRecordList(resList);
  149 + releaseRequest(device.getDeviceId(), sn,recordInfo);
154 } 150 }
155 } 151 }
156 - });  
157 - } 152 + } catch (Exception e) {
  153 + logger.error("[国标录像] 发现未处理的异常, "+e.getMessage(), e);
  154 + }
  155 + });
158 } 156 }
159 157
160 @Override 158 @Override
@@ -162,15 +160,14 @@ public class RecordInfoResponseMessageHandler extends SIPRequestProcessorParent @@ -162,15 +160,14 @@ public class RecordInfoResponseMessageHandler extends SIPRequestProcessorParent
162 160
163 } 161 }
164 162
165 - public void releaseRequest(String deviceId, String sn){ 163 + public void releaseRequest(String deviceId, String sn,RecordInfo recordInfo){
166 String key = DeferredResultHolder.CALLBACK_CMD_RECORDINFO + deviceId + sn; 164 String key = DeferredResultHolder.CALLBACK_CMD_RECORDINFO + deviceId + sn;
167 // 对数据进行排序 165 // 对数据进行排序
168 - Collections.sort(recordDataCatch.getRecordInfo(deviceId, sn).getRecordList()); 166 + Collections.sort(recordInfo.getRecordList());
169 167
170 RequestMessage msg = new RequestMessage(); 168 RequestMessage msg = new RequestMessage();
171 msg.setKey(key); 169 msg.setKey(key);
172 - msg.setData(recordDataCatch.getRecordInfo(deviceId, sn)); 170 + msg.setData(recordInfo);
173 deferredResultHolder.invokeAllResult(msg); 171 deferredResultHolder.invokeAllResult(msg);
174 - recordDataCatch.remove(deviceId, sn);  
175 } 172 }
176 } 173 }
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/response/impl/InviteResponseProcessor.java
@@ -80,8 +80,8 @@ public class InviteResponseProcessor extends SIPResponseProcessorAbstract { @@ -80,8 +80,8 @@ public class InviteResponseProcessor extends SIPResponseProcessorAbstract {
80 */ 80 */
81 @Override 81 @Override
82 public void process(ResponseEvent evt ){ 82 public void process(ResponseEvent evt ){
  83 + logger.debug("接收到消息:" + evt.getResponse());
83 try { 84 try {
84 -  
85 SIPResponse response = (SIPResponse)evt.getResponse(); 85 SIPResponse response = (SIPResponse)evt.getResponse();
86 int statusCode = response.getStatusCode(); 86 int statusCode = response.getStatusCode();
87 // trying不会回复 87 // trying不会回复
src/main/java/com/genersoft/iot/vmp/gb28181/utils/SipUtils.java
1 package com.genersoft.iot.vmp.gb28181.utils; 1 package com.genersoft.iot.vmp.gb28181.utils;
2 2
  3 +import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
3 import com.genersoft.iot.vmp.gb28181.bean.RemoteAddressInfo; 4 import com.genersoft.iot.vmp.gb28181.bean.RemoteAddressInfo;
4 import com.genersoft.iot.vmp.utils.GitUtil; 5 import com.genersoft.iot.vmp.utils.GitUtil;
5 import gov.nist.javax.sip.address.AddressImpl; 6 import gov.nist.javax.sip.address.AddressImpl;
@@ -168,4 +169,37 @@ public class SipUtils { @@ -168,4 +169,37 @@ public class SipUtils {
168 169
169 return new RemoteAddressInfo(remoteAddress, remotePort); 170 return new RemoteAddressInfo(remoteAddress, remotePort);
170 } 171 }
  172 +
  173 + public static DeviceChannel updateGps(DeviceChannel deviceChannel, String geoCoordSys) {
  174 + if (deviceChannel.getLongitude()*deviceChannel.getLatitude() > 0) {
  175 +
  176 + if (geoCoordSys == null) {
  177 + geoCoordSys = "WGS84";
  178 + }
  179 + if ("WGS84".equals(geoCoordSys)) {
  180 + deviceChannel.setLongitudeWgs84(deviceChannel.getLongitude());
  181 + deviceChannel.setLatitudeWgs84(deviceChannel.getLatitude());
  182 + Double[] position = Coordtransform.WGS84ToGCJ02(deviceChannel.getLongitude(), deviceChannel.getLatitude());
  183 + deviceChannel.setLongitudeGcj02(position[0]);
  184 + deviceChannel.setLatitudeGcj02(position[1]);
  185 + }else if ("GCJ02".equals(geoCoordSys)) {
  186 + deviceChannel.setLongitudeGcj02(deviceChannel.getLongitude());
  187 + deviceChannel.setLatitudeGcj02(deviceChannel.getLatitude());
  188 + Double[] position = Coordtransform.GCJ02ToWGS84(deviceChannel.getLongitude(), deviceChannel.getLatitude());
  189 + deviceChannel.setLongitudeWgs84(position[0]);
  190 + deviceChannel.setLatitudeWgs84(position[1]);
  191 + }else {
  192 + deviceChannel.setLongitudeGcj02(0.00);
  193 + deviceChannel.setLatitudeGcj02(0.00);
  194 + deviceChannel.setLongitudeWgs84(0.00);
  195 + deviceChannel.setLatitudeWgs84(0.00);
  196 + }
  197 + }else {
  198 + deviceChannel.setLongitudeGcj02(deviceChannel.getLongitude());
  199 + deviceChannel.setLatitudeGcj02(deviceChannel.getLatitude());
  200 + deviceChannel.setLongitudeWgs84(deviceChannel.getLongitude());
  201 + deviceChannel.setLatitudeWgs84(deviceChannel.getLatitude());
  202 + }
  203 + return deviceChannel;
  204 + }
171 } 205 }
src/main/java/com/genersoft/iot/vmp/gb28181/utils/XmlUtil.java
1 package com.genersoft.iot.vmp.gb28181.utils; 1 package com.genersoft.iot.vmp.gb28181.utils;
2 2
3 -import com.alibaba.fastjson2.JSON;  
4 import com.alibaba.fastjson2.JSONArray; 3 import com.alibaba.fastjson2.JSONArray;
5 import com.alibaba.fastjson2.JSONObject; 4 import com.alibaba.fastjson2.JSONObject;
6 import com.genersoft.iot.vmp.gb28181.bean.Device; 5 import com.genersoft.iot.vmp.gb28181.bean.Device;
7 import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; 6 import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
8 -import com.genersoft.iot.vmp.gb28181.bean.TreeType;  
9 import com.genersoft.iot.vmp.gb28181.event.subscribe.catalog.CatalogEvent; 7 import com.genersoft.iot.vmp.gb28181.event.subscribe.catalog.CatalogEvent;
10 import com.genersoft.iot.vmp.utils.DateUtil; 8 import com.genersoft.iot.vmp.utils.DateUtil;
11 import org.dom4j.Attribute; 9 import org.dom4j.Attribute;
@@ -400,6 +398,7 @@ public class XmlUtil { @@ -400,6 +398,7 @@ public class XmlUtil {
400 } else { 398 } else {
401 deviceChannel.setLatitude(0.00); 399 deviceChannel.setLatitude(0.00);
402 } 400 }
  401 +
403 deviceChannel.setGpsTime(DateUtil.getNow()); 402 deviceChannel.setGpsTime(DateUtil.getNow());
404 403
405 404
@@ -414,6 +413,7 @@ public class XmlUtil { @@ -414,6 +413,7 @@ public class XmlUtil {
414 } else { 413 } else {
415 deviceChannel.setPTZType(Integer.parseInt(XmlUtil.getText(itemDevice, "PTZType"))); 414 deviceChannel.setPTZType(Integer.parseInt(XmlUtil.getText(itemDevice, "PTZType")));
416 } 415 }
  416 +
417 return deviceChannel; 417 return deviceChannel;
418 } 418 }
419 419
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRunner.java
@@ -25,7 +25,7 @@ import java.util.Set; @@ -25,7 +25,7 @@ import java.util.Set;
25 import java.util.concurrent.ConcurrentHashMap; 25 import java.util.concurrent.ConcurrentHashMap;
26 26
27 @Component 27 @Component
28 -@Order(value=2) 28 +@Order(value=12)
29 public class ZLMRunner implements CommandLineRunner { 29 public class ZLMRunner implements CommandLineRunner {
30 30
31 private final static Logger logger = LoggerFactory.getLogger(ZLMRunner.class); 31 private final static Logger logger = LoggerFactory.getLogger(ZLMRunner.class);
src/main/java/com/genersoft/iot/vmp/service/IDeviceChannelService.java
@@ -46,4 +46,14 @@ public interface IDeviceChannelService { @@ -46,4 +46,14 @@ public interface IDeviceChannelService {
46 * @return 46 * @return
47 */ 47 */
48 List<ChannelReduce> queryAllChannelList(String platformId); 48 List<ChannelReduce> queryAllChannelList(String platformId);
  49 +
  50 + /**
  51 + * 数据位置信息格式处理
  52 + */
  53 + boolean updateAllGps(Device device);
  54 +
  55 + /**
  56 + * 查询通道所属的设备
  57 + */
  58 + List<Device> getDeviceByChannelId(String channelId);
49 } 59 }
src/main/java/com/genersoft/iot/vmp/service/IDeviceService.java
@@ -163,4 +163,8 @@ public interface IDeviceService { @@ -163,4 +163,8 @@ public interface IDeviceService {
163 */ 163 */
164 ResourceBaceInfo getOverview(); 164 ResourceBaceInfo getOverview();
165 165
  166 + /**
  167 + * 获取所有设备
  168 + */
  169 + List<Device> getAll();
166 } 170 }
src/main/java/com/genersoft/iot/vmp/service/impl/DeviceChannelServiceImpl.java
@@ -19,6 +19,7 @@ import org.springframework.stereotype.Service; @@ -19,6 +19,7 @@ import org.springframework.stereotype.Service;
19 import java.util.ArrayList; 19 import java.util.ArrayList;
20 import java.util.HashMap; 20 import java.util.HashMap;
21 import java.util.List; 21 import java.util.List;
  22 +import java.util.concurrent.CopyOnWriteArrayList;
22 23
23 /** 24 /**
24 * @author lin 25 * @author lin
@@ -176,5 +177,36 @@ public class DeviceChannelServiceImpl implements IDeviceChannelService { @@ -176,5 +177,36 @@ public class DeviceChannelServiceImpl implements IDeviceChannelService {
176 return channelMapper.queryChannelListInAll(null, null, null, platformId, null); 177 return channelMapper.queryChannelListInAll(null, null, null, platformId, null);
177 } 178 }
178 179
  180 + @Override
  181 + public boolean updateAllGps(Device device) {
  182 + List<DeviceChannel> deviceChannels = channelMapper.getChannelsWithoutTransform(device.getDeviceId());
  183 + List<DeviceChannel> result = new CopyOnWriteArrayList<>();
  184 + if (deviceChannels.size() == 0) {
  185 + return true;
  186 + }
  187 + String now = DateUtil.getNow();
  188 + deviceChannels.parallelStream().forEach(deviceChannel -> {
  189 + deviceChannel.setUpdateTime(now);
  190 + result.add(updateGps(deviceChannel, device));
  191 + });
  192 + int limitCount = 300;
  193 + if (result.size() > limitCount) {
  194 + for (int i = 0; i < result.size(); i += limitCount) {
  195 + int toIndex = i + limitCount;
  196 + if (i + limitCount > result.size()) {
  197 + toIndex = result.size();
  198 + }
  199 + channelMapper.batchUpdate(result.subList(i, toIndex));
  200 + }
  201 + }else {
  202 + channelMapper.batchUpdate(result);
  203 + }
  204 +
  205 + return true;
  206 + }
179 207
  208 + @Override
  209 + public List<Device> getDeviceByChannelId(String channelId) {
  210 + return channelMapper.getDeviceByChannelId(channelId);
  211 + }
180 } 212 }
src/main/java/com/genersoft/iot/vmp/service/impl/DeviceServiceImpl.java
@@ -655,4 +655,9 @@ public class DeviceServiceImpl implements IDeviceService { @@ -655,4 +655,9 @@ public class DeviceServiceImpl implements IDeviceService {
655 public ResourceBaceInfo getOverview() { 655 public ResourceBaceInfo getOverview() {
656 return deviceMapper.getOverview(); 656 return deviceMapper.getOverview();
657 } 657 }
  658 +
  659 + @Override
  660 + public List<Device> getAll() {
  661 + return deviceMapper.getAll();
  662 + }
658 } 663 }
src/main/java/com/genersoft/iot/vmp/service/impl/StreamPushServiceImpl.java
@@ -366,7 +366,7 @@ public class StreamPushServiceImpl implements IStreamPushService { @@ -366,7 +366,7 @@ public class StreamPushServiceImpl implements IStreamPushService {
366 // 存储数据到stream_push表 366 // 存储数据到stream_push表
367 streamPushMapper.addAll(streamPushItems); 367 streamPushMapper.addAll(streamPushItems);
368 List<StreamPushItem> streamPushItemForGbStream = streamPushItems.stream() 368 List<StreamPushItem> streamPushItemForGbStream = streamPushItems.stream()
369 - .filter(streamPushItem-> streamPushItem.getId() != null) 369 + .filter(streamPushItem-> streamPushItem.getGbId() != null)
370 .collect(Collectors.toList()); 370 .collect(Collectors.toList());
371 // 存储数据到gb_stream表, id会返回到streamPushItemForGbStream里 371 // 存储数据到gb_stream表, id会返回到streamPushItemForGbStream里
372 if (streamPushItemForGbStream.size() > 0) { 372 if (streamPushItemForGbStream.size() > 0) {
src/main/java/com/genersoft/iot/vmp/storager/IRedisCatchStorage.java
@@ -258,4 +258,7 @@ public interface IRedisCatchStorage { @@ -258,4 +258,7 @@ public interface IRedisCatchStorage {
258 258
259 List<SendRtpItem> queryAllSendRTPServer(); 259 List<SendRtpItem> queryAllSendRTPServer();
260 260
  261 + List<Device> getAllDevices();
  262 +
  263 + void removeAllDevice();
261 } 264 }
src/main/java/com/genersoft/iot/vmp/storager/IVideoManagerStorage.java
@@ -56,7 +56,7 @@ public interface IVideoManagerStorage { @@ -56,7 +56,7 @@ public interface IVideoManagerStorage {
56 * @param count 每页数量 56 * @param count 每页数量
57 * @return 57 * @return
58 */ 58 */
59 - public PageInfo queryChannelsByDeviceId(String deviceId, String query, Boolean hasSubChannel, Boolean online, Boolean catalogUnderDevice, int page, int count); 59 + public PageInfo<DeviceChannel> queryChannelsByDeviceId(String deviceId, String query, Boolean hasSubChannel, Boolean online, Boolean catalogUnderDevice, int page, int count);
60 60
61 public List<DeviceChannel> queryChannelsByDeviceIdWithStartAndLimit(String deviceId, String query, Boolean hasSubChannel, Boolean online, int start, int limit,List<String> channelIds); 61 public List<DeviceChannel> queryChannelsByDeviceIdWithStartAndLimit(String deviceId, String query, Boolean hasSubChannel, Boolean online, int start, int limit,List<String> channelIds);
62 62
src/main/java/com/genersoft/iot/vmp/storager/dao/DeviceChannelMapper.java
1 package com.genersoft.iot.vmp.storager.dao; 1 package com.genersoft.iot.vmp.storager.dao;
2 2
  3 +import com.genersoft.iot.vmp.gb28181.bean.Device;
3 import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; 4 import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
4 import com.genersoft.iot.vmp.gb28181.bean.DeviceChannelInPlatform; 5 import com.genersoft.iot.vmp.gb28181.bean.DeviceChannelInPlatform;
5 import com.genersoft.iot.vmp.vmanager.bean.ResourceBaceInfo; 6 import com.genersoft.iot.vmp.vmanager.bean.ResourceBaceInfo;
@@ -357,4 +358,21 @@ public interface DeviceChannelMapper { @@ -357,4 +358,21 @@ public interface DeviceChannelMapper {
357 358
358 @Select("select count(1) as total, sum(status) as online from device_channel") 359 @Select("select count(1) as total, sum(status) as online from device_channel")
359 ResourceBaceInfo getOverview(); 360 ResourceBaceInfo getOverview();
  361 +
  362 + @Select("select channelId" +
  363 + ", deviceId" +
  364 + ", latitude" +
  365 + ", longitude" +
  366 + ", latitudeWgs84" +
  367 + ", longitudeWgs84" +
  368 + ", latitudeGcj02" +
  369 + ", longitudeGcj02 " +
  370 + "from device_channel where deviceId = #{deviceId} " +
  371 + "and latitude != 0 " +
  372 + "and longitude != 0 " +
  373 + "and (latitudeGcj02 = 0 or latitudeWgs84 = 0 or longitudeWgs84 = 0 or longitudeGcj02 = 0)")
  374 + List<DeviceChannel> getChannelsWithoutTransform(String deviceId);
  375 +
  376 + @Select("select de.* from device de left join device_channel dc on de.deviceId = dc.deviceId where dc.channelId=#{channelId}")
  377 + List<Device> getDeviceByChannelId(String channelId);
360 } 378 }
src/main/java/com/genersoft/iot/vmp/storager/dao/DeviceMapper.java
@@ -280,4 +280,6 @@ public interface DeviceMapper { @@ -280,4 +280,6 @@ public interface DeviceMapper {
280 @Select("select count(1) as total, sum(online) as online from device") 280 @Select("select count(1) as total, sum(online) as online from device")
281 ResourceBaceInfo getOverview(); 281 ResourceBaceInfo getOverview();
282 282
  283 + @Select("select * from device")
  284 + List<Device> getAll();
283 } 285 }
src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java
@@ -665,6 +665,31 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage { @@ -665,6 +665,31 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage {
665 } 665 }
666 666
667 @Override 667 @Override
  668 + public void removeAllDevice() {
  669 + String scanKey = VideoManagerConstants.DEVICE_PREFIX + userSetting.getServerId() + "_*";
  670 + List<Object> keys = RedisUtil.scan(scanKey);
  671 + for (Object key : keys) {
  672 + RedisUtil.del((String) key);
  673 + }
  674 + }
  675 +
  676 + @Override
  677 + public List<Device> getAllDevices() {
  678 + String scanKey = VideoManagerConstants.DEVICE_PREFIX + userSetting.getServerId() + "_*";
  679 + List<Device> result = new ArrayList<>();
  680 + List<Object> keys = RedisUtil.scan(scanKey);
  681 + for (Object o : keys) {
  682 + String key = (String) o;
  683 + Device device = JsonUtil.redisJsonToObject(key, Device.class);
  684 + if (Objects.nonNull(device)) { // 只取没有存过得
  685 + result.add(JsonUtil.redisJsonToObject(key, Device.class));
  686 + }
  687 + }
  688 +
  689 + return result;
  690 + }
  691 +
  692 + @Override
668 public Device getDevice(String deviceId) { 693 public Device getDevice(String deviceId) {
669 String key = VideoManagerConstants.DEVICE_PREFIX + userSetting.getServerId() + "_" + deviceId; 694 String key = VideoManagerConstants.DEVICE_PREFIX + userSetting.getServerId() + "_" + deviceId;
670 return JsonUtil.redisJsonToObject(key, Device.class); 695 return JsonUtil.redisJsonToObject(key, Device.class);
src/main/java/com/genersoft/iot/vmp/storager/impl/VideoManagerStorageImpl.java
@@ -226,8 +226,10 @@ public class VideoManagerStorageImpl implements IVideoManagerStorage { @@ -226,8 +226,10 @@ public class VideoManagerStorageImpl implements IVideoManagerStorage {
226 if (allChannelMap.containsKey(deviceChannel.getChannelId())) { 226 if (allChannelMap.containsKey(deviceChannel.getChannelId())) {
227 deviceChannel.setStreamId(allChannelMap.get(deviceChannel.getChannelId()).getStreamId()); 227 deviceChannel.setStreamId(allChannelMap.get(deviceChannel.getChannelId()).getStreamId());
228 deviceChannel.setHasAudio(allChannelMap.get(deviceChannel.getChannelId()).isHasAudio()); 228 deviceChannel.setHasAudio(allChannelMap.get(deviceChannel.getChannelId()).isHasAudio());
  229 + deviceChannel.setUpdateTime(DateUtil.getNow());
229 updateChannels.add(deviceChannel); 230 updateChannels.add(deviceChannel);
230 }else { 231 }else {
  232 + deviceChannel.setCreateTime(DateUtil.getNow());
231 addChannels.add(deviceChannel); 233 addChannels.add(deviceChannel);
232 } 234 }
233 if (!ObjectUtils.isEmpty(deviceChannel.getParentId())) { 235 if (!ObjectUtils.isEmpty(deviceChannel.getParentId())) {
src/main/java/com/genersoft/iot/vmp/utils/UJson.java 0 → 100644
  1 +package com.genersoft.iot.vmp.utils;
  2 +
  3 +import com.fasterxml.jackson.databind.DeserializationFeature;
  4 +import com.fasterxml.jackson.databind.JsonNode;
  5 +import com.fasterxml.jackson.databind.ObjectMapper;
  6 +import com.fasterxml.jackson.databind.node.ObjectNode;
  7 +import org.apache.commons.lang3.StringUtils;
  8 +import org.slf4j.Logger;
  9 +import org.slf4j.LoggerFactory;
  10 +
  11 +import java.util.Iterator;
  12 +import java.util.Map;
  13 +import java.util.Objects;
  14 +
  15 +/**
  16 + * @author gaofuwang
  17 + * @version 1.0
  18 + * @date 2022/3/11 10:17
  19 + */
  20 +public class UJson {
  21 +
  22 + private static Logger logger = LoggerFactory.getLogger(UJson.class);
  23 + public static final ObjectMapper JSON_MAPPER = new ObjectMapper();
  24 +
  25 + static {
  26 + JSON_MAPPER.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES,false);
  27 + }
  28 +
  29 + private ObjectNode node;
  30 +
  31 + public UJson(){
  32 + this.node = JSON_MAPPER.createObjectNode();
  33 + }
  34 +
  35 + public UJson(String json){
  36 + if(StringUtils.isBlank(json)){
  37 + this.node = JSON_MAPPER.createObjectNode();
  38 + }else{
  39 + try {
  40 + this.node = JSON_MAPPER.readValue(json, ObjectNode.class);
  41 + }catch (Exception e){
  42 + logger.error(e.getMessage(), e);
  43 + this.node = JSON_MAPPER.createObjectNode();
  44 + }
  45 + }
  46 + }
  47 +
  48 + public UJson(ObjectNode node){
  49 + this.node = node;
  50 + }
  51 +
  52 + public String asText(String key){
  53 + JsonNode jsonNode = node.get(key);
  54 + if(Objects.isNull(jsonNode)){
  55 + return "";
  56 + }
  57 + return jsonNode.asText();
  58 + }
  59 +
  60 + public String asText(String key, String defaultVal){
  61 + JsonNode jsonNode = node.get(key);
  62 + if(Objects.isNull(jsonNode)){
  63 + return "";
  64 + }
  65 + return jsonNode.asText(defaultVal);
  66 + }
  67 +
  68 + public UJson put(String key, String value){
  69 + this.node.put(key, value);
  70 + return this;
  71 + }
  72 +
  73 + public UJson put(String key, Integer value){
  74 + this.node.put(key, value);
  75 + return this;
  76 + }
  77 +
  78 + public static UJson json(){
  79 + return new UJson();
  80 + }
  81 +
  82 + public static UJson json(String json){
  83 + return new UJson(json);
  84 + }
  85 +
  86 + public static <T> T readJson(String json, Class<T> clazz){
  87 + if(StringUtils.isBlank(json)){
  88 + return null;
  89 + }
  90 + try {
  91 + return JSON_MAPPER.readValue(json, clazz);
  92 + }catch (Exception e){
  93 + logger.error(e.getMessage(), e);
  94 + return null;
  95 + }
  96 + }
  97 +
  98 + public static String writeJson(Object object) {
  99 + try{
  100 + return JSON_MAPPER.writeValueAsString(object);
  101 + }catch (Exception e){
  102 + logger.error(e.getMessage(), e);
  103 + return "";
  104 + }
  105 + }
  106 +
  107 + @Override
  108 + public String toString() {
  109 + return node.toString();
  110 + }
  111 +
  112 + public int asInt(String key, int defValue) {
  113 + JsonNode jsonNode = this.node.get(key);
  114 + if(Objects.isNull(jsonNode)){
  115 + return defValue;
  116 + }
  117 + return jsonNode.asInt(defValue);
  118 + }
  119 +
  120 + public UJson getSon(String key) {
  121 + JsonNode sonNode = this.node.get(key);
  122 + if(Objects.isNull(sonNode)){
  123 + return new UJson();
  124 + }
  125 + return new UJson((ObjectNode) sonNode);
  126 + }
  127 +
  128 + public UJson set(String key, ObjectNode sonNode) {
  129 + this.node.set(key, sonNode);
  130 + return this;
  131 + }
  132 +
  133 + public UJson set(String key, UJson sonNode) {
  134 + this.node.set(key, sonNode.node);
  135 + return this;
  136 + }
  137 +
  138 + public Iterator<Map.Entry<String, JsonNode>> fields() {
  139 + return this.node.fields();
  140 + }
  141 +
  142 + public ObjectNode getNode() {
  143 + return this.node;
  144 + }
  145 +
  146 + public UJson setAll(UJson json) {
  147 + this.node.setAll(json.node);
  148 + return this;
  149 + }
  150 +}
src/main/java/com/genersoft/iot/vmp/utils/redis/RedisUtil.java
@@ -238,7 +238,7 @@ public class RedisUtil { @@ -238,7 +238,7 @@ public class RedisUtil {
238 * @param time 时间 238 * @param time 时间
239 * @return true / false 239 * @return true / false
240 */ 240 */
241 - public static boolean hmset(String key, Map<Object, Object> map, long time) { 241 + public static boolean hmset(String key, Map<?, ?> map, long time) {
242 if (redisTemplate == null) { 242 if (redisTemplate == null) {
243 redisTemplate = SpringBeanFactory.getBean("redisTemplate"); 243 redisTemplate = SpringBeanFactory.getBean("redisTemplate");
244 } 244 }
src/main/java/com/genersoft/iot/vmp/vmanager/bean/StreamContent.java
1 package com.genersoft.iot.vmp.vmanager.bean; 1 package com.genersoft.iot.vmp.vmanager.bean;
2 2
3 import com.genersoft.iot.vmp.common.StreamInfo; 3 import com.genersoft.iot.vmp.common.StreamInfo;
  4 +import io.swagger.v3.oas.annotations.media.Schema;
4 5
  6 +@Schema(description = "流信息")
5 public class StreamContent { 7 public class StreamContent {
6 8
  9 + @Schema(description = "应用名")
7 private String app; 10 private String app;
  11 +
  12 + @Schema(description = "流ID")
8 private String stream; 13 private String stream;
9 14
  15 + @Schema(description = "IP")
10 private String ip; 16 private String ip;
11 17
  18 + @Schema(description = "HTTP-FLV流地址")
12 private String flv; 19 private String flv;
13 20
  21 + @Schema(description = "HTTPS-FLV流地址")
14 private String https_flv; 22 private String https_flv;
  23 +
  24 + @Schema(description = "Websocket-FLV流地址")
15 private String ws_flv; 25 private String ws_flv;
  26 +
  27 + @Schema(description = "Websockets-FLV流地址")
16 private String wss_flv; 28 private String wss_flv;
  29 +
  30 + @Schema(description = "HTTP-FMP4流地址")
17 private String fmp4; 31 private String fmp4;
  32 +
  33 + @Schema(description = "HTTPS-FMP4流地址")
18 private String https_fmp4; 34 private String https_fmp4;
  35 +
  36 + @Schema(description = "Websocket-FMP4流地址")
19 private String ws_fmp4; 37 private String ws_fmp4;
  38 +
  39 + @Schema(description = "Websockets-FMP4流地址")
20 private String wss_fmp4; 40 private String wss_fmp4;
  41 +
  42 + @Schema(description = "HLS流地址")
21 private String hls; 43 private String hls;
  44 +
  45 + @Schema(description = "HTTPS-HLS流地址")
22 private String https_hls; 46 private String https_hls;
  47 +
  48 + @Schema(description = "Websocket-HLS流地址")
23 private String ws_hls; 49 private String ws_hls;
  50 +
  51 + @Schema(description = "Websockets-HLS流地址")
24 private String wss_hls; 52 private String wss_hls;
  53 +
  54 + @Schema(description = "HTTP-TS流地址")
25 private String ts; 55 private String ts;
  56 +
  57 + @Schema(description = "HTTPS-TS流地址")
26 private String https_ts; 58 private String https_ts;
  59 +
  60 + @Schema(description = "Websocket-TS流地址")
27 private String ws_ts; 61 private String ws_ts;
  62 +
  63 + @Schema(description = "Websockets-TS流地址")
28 private String wss_ts; 64 private String wss_ts;
  65 +
  66 + @Schema(description = "RTMP流地址")
29 private String rtmp; 67 private String rtmp;
  68 +
  69 + @Schema(description = "RTMPS流地址")
30 private String rtmps; 70 private String rtmps;
  71 +
  72 + @Schema(description = "RTSP流地址")
31 private String rtsp; 73 private String rtsp;
  74 +
  75 + @Schema(description = "RTSPS流地址")
32 private String rtsps; 76 private String rtsps;
  77 +
  78 + @Schema(description = "RTC流地址")
33 private String rtc; 79 private String rtc;
34 80
  81 + @Schema(description = "RTCS流地址")
35 private String rtcs; 82 private String rtcs;
  83 +
  84 + @Schema(description = "流媒体ID")
36 private String mediaServerId; 85 private String mediaServerId;
  86 +
  87 + @Schema(description = "流编码信息")
37 private Object tracks; 88 private Object tracks;
38 89
  90 + @Schema(description = "开始时间")
39 private String startTime; 91 private String startTime;
40 92
  93 + @Schema(description = "结束时间")
41 private String endTime; 94 private String endTime;
42 95
43 private double progress; 96 private double progress;
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/MobilePosition/MobilePositionController.java
1 package com.genersoft.iot.vmp.vmanager.gb28181.MobilePosition; 1 package com.genersoft.iot.vmp.vmanager.gb28181.MobilePosition;
2 2
3 -import java.text.ParseException;  
4 -import java.util.List;  
5 -import java.util.UUID;  
6 -  
7 import com.genersoft.iot.vmp.conf.exception.ControllerException; 3 import com.genersoft.iot.vmp.conf.exception.ControllerException;
8 import com.genersoft.iot.vmp.gb28181.bean.Device; 4 import com.genersoft.iot.vmp.gb28181.bean.Device;
9 import com.genersoft.iot.vmp.gb28181.bean.MobilePosition; 5 import com.genersoft.iot.vmp.gb28181.bean.MobilePosition;
10 import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder; 6 import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder;
11 import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage; 7 import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage;
12 import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander; 8 import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
  9 +import com.genersoft.iot.vmp.service.IDeviceChannelService;
13 import com.genersoft.iot.vmp.service.IDeviceService; 10 import com.genersoft.iot.vmp.service.IDeviceService;
14 import com.genersoft.iot.vmp.storager.IVideoManagerStorage; 11 import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
15 import com.genersoft.iot.vmp.vmanager.bean.ErrorCode; 12 import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;
16 -import com.genersoft.iot.vmp.vmanager.bean.WVPResult;  
17 import com.github.pagehelper.util.StringUtil; 13 import com.github.pagehelper.util.StringUtil;
18 -  
19 import io.swagger.v3.oas.annotations.Operation; 14 import io.swagger.v3.oas.annotations.Operation;
20 import io.swagger.v3.oas.annotations.Parameter; 15 import io.swagger.v3.oas.annotations.Parameter;
21 import io.swagger.v3.oas.annotations.tags.Tag; 16 import io.swagger.v3.oas.annotations.tags.Tag;
22 import org.slf4j.Logger; 17 import org.slf4j.Logger;
23 import org.slf4j.LoggerFactory; 18 import org.slf4j.LoggerFactory;
24 import org.springframework.beans.factory.annotation.Autowired; 19 import org.springframework.beans.factory.annotation.Autowired;
25 -import org.springframework.http.HttpStatus;  
26 -import org.springframework.http.ResponseEntity;  
27 -import org.springframework.web.bind.annotation.CrossOrigin;  
28 -import org.springframework.web.bind.annotation.GetMapping;  
29 -import org.springframework.web.bind.annotation.PathVariable;  
30 -import org.springframework.web.bind.annotation.RequestMapping;  
31 -import org.springframework.web.bind.annotation.RequestParam;  
32 -import org.springframework.web.bind.annotation.RestController; 20 +import org.springframework.web.bind.annotation.*;
33 import org.springframework.web.context.request.async.DeferredResult; 21 import org.springframework.web.context.request.async.DeferredResult;
34 22
35 import javax.sip.InvalidArgumentException; 23 import javax.sip.InvalidArgumentException;
36 import javax.sip.SipException; 24 import javax.sip.SipException;
  25 +import java.text.ParseException;
  26 +import java.util.List;
  27 +import java.util.UUID;
37 28
38 /** 29 /**
39 * 位置信息管理 30 * 位置信息管理
@@ -58,6 +49,9 @@ public class MobilePositionController { @@ -58,6 +49,9 @@ public class MobilePositionController {
58 @Autowired 49 @Autowired
59 private IDeviceService deviceService; 50 private IDeviceService deviceService;
60 51
  52 + @Autowired
  53 + private IDeviceChannelService deviceChannelService;
  54 +
61 /** 55 /**
62 * 查询历史轨迹 56 * 查询历史轨迹
63 * @param deviceId 设备ID 57 * @param deviceId 设备ID
@@ -162,4 +156,24 @@ public class MobilePositionController { @@ -162,4 +156,24 @@ public class MobilePositionController {
162 throw new ControllerException(ErrorCode.ERROR100); 156 throw new ControllerException(ErrorCode.ERROR100);
163 } 157 }
164 } 158 }
  159 +
  160 + /**
  161 + * 数据位置信息格式处理
  162 + * @param deviceId 设备ID
  163 + * @return true = 命令发送成功
  164 + */
  165 + @Operation(summary = "数据位置信息格式处理")
  166 + @Parameter(name = "deviceId", description = "设备国标编号", required = true)
  167 + @GetMapping("/transform/{deviceId}")
  168 + public void positionTransform(@PathVariable String deviceId) {
  169 +
  170 + Device device = deviceService.getDevice(deviceId);
  171 + if (device == null) {
  172 + throw new ControllerException(ErrorCode.ERROR400.getCode(), "未找到设备: " + deviceId);
  173 + }
  174 + boolean result = deviceChannelService.updateAllGps(device);
  175 + if (!result) {
  176 + throw new ControllerException(ErrorCode.ERROR100);
  177 + }
  178 + }
165 } 179 }
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/device/DeviceQuery.java
@@ -123,7 +123,7 @@ public class DeviceQuery { @@ -123,7 +123,7 @@ public class DeviceQuery {
123 @Parameter(name = "online", description = "是否在线") 123 @Parameter(name = "online", description = "是否在线")
124 @Parameter(name = "channelType", description = "设备/子目录-> false/true") 124 @Parameter(name = "channelType", description = "设备/子目录-> false/true")
125 @Parameter(name = "catalogUnderDevice", description = "是否直属与设备的目录") 125 @Parameter(name = "catalogUnderDevice", description = "是否直属与设备的目录")
126 - public PageInfo channels(@PathVariable String deviceId, 126 + public PageInfo<DeviceChannel> channels(@PathVariable String deviceId,
127 int page, int count, 127 int page, int count,
128 @RequestParam(required = false) String query, 128 @RequestParam(required = false) String query,
129 @RequestParam(required = false) Boolean online, 129 @RequestParam(required = false) Boolean online,
@@ -223,7 +223,7 @@ public class DeviceQuery { @@ -223,7 +223,7 @@ public class DeviceQuery {
223 @Parameter(name = "online", description = "是否在线") 223 @Parameter(name = "online", description = "是否在线")
224 @Parameter(name = "channelType", description = "设备/子目录-> false/true") 224 @Parameter(name = "channelType", description = "设备/子目录-> false/true")
225 @GetMapping("/sub_channels/{deviceId}/{channelId}/channels") 225 @GetMapping("/sub_channels/{deviceId}/{channelId}/channels")
226 - public PageInfo subChannels(@PathVariable String deviceId, 226 + public PageInfo<DeviceChannel> subChannels(@PathVariable String deviceId,
227 @PathVariable String channelId, 227 @PathVariable String channelId,
228 int page, 228 int page,
229 int count, 229 int count,
@@ -237,8 +237,7 @@ public class DeviceQuery { @@ -237,8 +237,7 @@ public class DeviceQuery {
237 return deviceChannelPageResult; 237 return deviceChannelPageResult;
238 } 238 }
239 239
240 - PageInfo pageResult = storager.querySubChannels(deviceId, channelId, query, channelType, online, page, count);  
241 - return pageResult; 240 + return storager.querySubChannels(deviceId, channelId, query, channelType, online, page, count);
242 } 241 }
243 242
244 /** 243 /**
src/main/resources/logback-spring-local.xml
@@ -4,7 +4,7 @@ @@ -4,7 +4,7 @@
4 <springProperty scop="context" name="spring.application.name" source="spring.application.name" defaultValue=""/> 4 <springProperty scop="context" name="spring.application.name" source="spring.application.name" defaultValue=""/>
5 <property name="LOG_HOME" value="logs" /> 5 <property name="LOG_HOME" value="logs" />
6 6
7 - <substitutionProperty name="log.pattern" value="%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(%5p) %clr(---){faint} %clr(%-80.80logger{79}){cyan} %clr(:){faint} %m%n%wEx"/> 7 + <substitutionProperty name="log.pattern" value="%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(%5p) %clr(---){faint} %clr(%-1.30logger{0}){cyan} %clr(:){faint} %m%n%wEx"/>
8 8
9 <conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter"/> 9 <conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter"/>
10 <conversionRule conversionWord="wex" converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter"/> 10 <conversionRule conversionWord="wex" converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter"/>
web_src/src/components/CloudRecordDetail.vue
@@ -115,7 +115,7 @@ @@ -115,7 +115,7 @@
115 props: ['recordFile', 'mediaServerId', 'dateFiles', 'mediaServerPath'], 115 props: ['recordFile', 'mediaServerId', 'dateFiles', 'mediaServerPath'],
116 data() { 116 data() {
117 return { 117 return {
118 - basePath: `${this.mediaServerPath}/record`, 118 + basePath: `${this.mediaServerPath}`,
119 dateFilesObj: [], 119 dateFilesObj: [],
120 detailFiles: [], 120 detailFiles: [],
121 chooseDate: null, 121 chooseDate: null,