Commit 6b3732b8c43165342b7521b1e3ea788e471d58e8

Authored by 648540858
2 parents 319cdd21 8cf5b65e

Merge branch '2.6.8' into wvp-28181-2.0

# Conflicts:
#	src/main/java/com/genersoft/iot/vmp/conf/UserSetting.java
#	src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java
#	src/main/java/com/genersoft/iot/vmp/gb28181/utils/XmlUtil.java
#	src/main/java/com/genersoft/iot/vmp/service/impl/DeviceServiceImpl.java
#	src/main/java/com/genersoft/iot/vmp/storager/dao/DeviceChannelMapper.java
#	src/main/java/com/genersoft/iot/vmp/storager/impl/VideoManagerStorageImpl.java
#	src/main/resources/all-application.yml
#	web_src/package-lock.json
Showing 21 changed files with 849 additions and 531 deletions

Too many changes to show.

To preserve performance only 21 of 28 files are displayed.

src/main/java/com/genersoft/iot/vmp/common/CivilCodePo.java 0 → 100644
  1 +package com.genersoft.iot.vmp.common;
  2 +
  3 +public class CivilCodePo {
  4 +
  5 + private String code;
  6 +
  7 + private String name;
  8 +
  9 + private String parentCode;
  10 +
  11 + public static CivilCodePo getInstance(String[] infoArray) {
  12 + CivilCodePo civilCodePo = new CivilCodePo();
  13 + civilCodePo.setCode(infoArray[0]);
  14 + civilCodePo.setName(infoArray[1]);
  15 + civilCodePo.setParentCode(infoArray[2]);
  16 + return civilCodePo;
  17 + }
  18 +
  19 + public String getCode() {
  20 + return code;
  21 + }
  22 +
  23 + public void setCode(String code) {
  24 + this.code = code;
  25 + }
  26 +
  27 + public String getName() {
  28 + return name;
  29 + }
  30 +
  31 + public void setName(String name) {
  32 + this.name = name;
  33 + }
  34 +
  35 + public String getParentCode() {
  36 + return parentCode;
  37 + }
  38 +
  39 + public void setParentCode(String parentCode) {
  40 + this.parentCode = parentCode;
  41 + }
  42 +}
src/main/java/com/genersoft/iot/vmp/conf/CivilCodeFileConf.java 0 → 100644
  1 +package com.genersoft.iot.vmp.conf;
  2 +
  3 +import com.genersoft.iot.vmp.common.CivilCodePo;
  4 +import org.ehcache.impl.internal.concurrent.ConcurrentHashMap;
  5 +import org.slf4j.Logger;
  6 +import org.slf4j.LoggerFactory;
  7 +import org.springframework.beans.factory.annotation.Autowired;
  8 +import org.springframework.boot.CommandLineRunner;
  9 +import org.springframework.context.annotation.Configuration;
  10 +import org.springframework.context.annotation.Lazy;
  11 +import org.springframework.core.annotation.Order;
  12 +import org.springframework.core.io.ClassPathResource;
  13 +import org.springframework.util.ObjectUtils;
  14 +
  15 +import java.io.*;
  16 +import java.nio.file.Files;
  17 +import java.util.Map;
  18 +
  19 +/**
  20 + * 启动时读取行政区划表
  21 + */
  22 +@Configuration
  23 +@Order(value=14)
  24 +public class CivilCodeFileConf implements CommandLineRunner {
  25 +
  26 + private final static Logger logger = LoggerFactory.getLogger(CivilCodeFileConf.class);
  27 +
  28 + private final Map<String, CivilCodePo> civilCodeMap= new ConcurrentHashMap<>();
  29 +
  30 + @Autowired
  31 + @Lazy
  32 + private UserSetting userSetting;
  33 +
  34 + @Override
  35 + public void run(String... args) throws Exception {
  36 + if (ObjectUtils.isEmpty(userSetting.getCivilCodeFile())) {
  37 + logger.warn("[行政区划] 文件未设置,可能造成目录刷新结果不完整");
  38 + return;
  39 + }
  40 + InputStream inputStream;
  41 + if (userSetting.getCivilCodeFile().startsWith("classpath:")){
  42 + String filePath = userSetting.getCivilCodeFile().substring("classpath:".length());
  43 + ClassPathResource civilCodeFile = new ClassPathResource(filePath);
  44 + if (!civilCodeFile.exists()) {
  45 + logger.warn("[行政区划] 文件<{}>不存在,可能造成目录刷新结果不完整", userSetting.getCivilCodeFile());
  46 + return;
  47 + }
  48 + inputStream = civilCodeFile.getInputStream();
  49 +
  50 + }else {
  51 + File civilCodeFile = new File(userSetting.getCivilCodeFile());
  52 + if (!civilCodeFile.exists()) {
  53 + logger.warn("[行政区划] 文件<{}>不存在,可能造成目录刷新结果不完整", userSetting.getCivilCodeFile());
  54 + return;
  55 + }
  56 + inputStream = Files.newInputStream(civilCodeFile.toPath());
  57 + }
  58 +
  59 + BufferedReader inputStreamReader = new BufferedReader(new InputStreamReader(inputStream));
  60 + int index = -1;
  61 + String line;
  62 + while ((line = inputStreamReader.readLine()) != null) {
  63 + index ++;
  64 + if (index == 0) {
  65 + continue;
  66 + }
  67 + String[] infoArray = line.split(",");
  68 + CivilCodePo civilCodePo = CivilCodePo.getInstance(infoArray);
  69 + civilCodeMap.put(civilCodePo.getCode(), civilCodePo);
  70 + }
  71 + inputStreamReader.close();
  72 + inputStream.close();
  73 + if (civilCodeMap.size() == 0) {
  74 + logger.warn("[行政区划] 文件内容为空,可能造成目录刷新结果不完整");
  75 + }else {
  76 + logger.info("[行政区划] 加载成功,共加载数据{}条", civilCodeMap.size());
  77 + }
  78 + }
  79 +
  80 + public CivilCodePo getParentCode(String code) {
  81 + if (code.length() > 8) {
  82 + return null;
  83 + }
  84 + if (code.length() == 8) {
  85 + String parentCode = code.substring(0, 6);
  86 + return civilCodeMap.get(parentCode);
  87 + }else {
  88 + CivilCodePo civilCodePo = civilCodeMap.get(code);
  89 + if (civilCodePo == null){
  90 + return null;
  91 + }
  92 + String parentCode = civilCodePo.getParentCode();
  93 + if (parentCode == null) {
  94 + return null;
  95 + }
  96 + return civilCodeMap.get(parentCode);
  97 + }
  98 +
  99 + }
  100 +
  101 +}
src/main/java/com/genersoft/iot/vmp/conf/DynamicTask.java
@@ -45,6 +45,7 @@ public class DynamicTask { @@ -45,6 +45,7 @@ public class DynamicTask {
45 * @return 45 * @return
46 */ 46 */
47 public void startCron(String key, Runnable task, int cycleForCatalog) { 47 public void startCron(String key, Runnable task, int cycleForCatalog) {
  48 + System.out.println(cycleForCatalog);
48 ScheduledFuture<?> future = futureMap.get(key); 49 ScheduledFuture<?> future = futureMap.get(key);
49 if (future != null) { 50 if (future != null) {
50 if (future.isCancelled()) { 51 if (future.isCancelled()) {
src/main/java/com/genersoft/iot/vmp/conf/SipPlatformRunner.java
@@ -56,7 +56,7 @@ public class SipPlatformRunner implements CommandLineRunner { @@ -56,7 +56,7 @@ public class SipPlatformRunner implements CommandLineRunner {
56 } 56 }
57 57
58 // 设置所有平台离线 58 // 设置所有平台离线
59 - platformService.offline(parentPlatform, true); 59 + platformService.offline(parentPlatform, false);
60 } 60 }
61 } 61 }
62 } 62 }
src/main/java/com/genersoft/iot/vmp/conf/UserSetting.java
@@ -62,12 +62,18 @@ public class UserSetting { @@ -62,12 +62,18 @@ public class UserSetting {
62 62
63 private String thirdPartyGBIdReg = "[\\s\\S]*"; 63 private String thirdPartyGBIdReg = "[\\s\\S]*";
64 64
  65 + private String civilCodeFile = "classpath:civilCode.csv";
  66 +
65 private List<String> interfaceAuthenticationExcludes = new ArrayList<>(); 67 private List<String> interfaceAuthenticationExcludes = new ArrayList<>();
66 68
67 private List<String> allowedOrigins = new ArrayList<>(); 69 private List<String> allowedOrigins = new ArrayList<>();
68 70
69 private int maxNotifyCountQueue = 10000; 71 private int maxNotifyCountQueue = 10000;
70 72
  73 + private int registerAgainAfterTime = 60;
  74 +
  75 + private boolean registerKeepIntDialog = false;
  76 +
71 public Boolean getSavePositionHistory() { 77 public Boolean getSavePositionHistory() {
72 return savePositionHistory; 78 return savePositionHistory;
73 } 79 }
@@ -295,4 +301,28 @@ public class UserSetting { @@ -295,4 +301,28 @@ public class UserSetting {
295 public void setSqlLog(Boolean sqlLog) { 301 public void setSqlLog(Boolean sqlLog) {
296 this.sqlLog = sqlLog; 302 this.sqlLog = sqlLog;
297 } 303 }
  304 +
  305 + public String getCivilCodeFile() {
  306 + return civilCodeFile;
  307 + }
  308 +
  309 + public void setCivilCodeFile(String civilCodeFile) {
  310 + this.civilCodeFile = civilCodeFile;
  311 + }
  312 +
  313 + public int getRegisterAgainAfterTime() {
  314 + return registerAgainAfterTime;
  315 + }
  316 +
  317 + public void setRegisterAgainAfterTime(int registerAgainAfterTime) {
  318 + this.registerAgainAfterTime = registerAgainAfterTime;
  319 + }
  320 +
  321 + public boolean isRegisterKeepIntDialog() {
  322 + return registerKeepIntDialog;
  323 + }
  324 +
  325 + public void setRegisterKeepIntDialog(boolean registerKeepIntDialog) {
  326 + this.registerKeepIntDialog = registerKeepIntDialog;
  327 + }
298 } 328 }
src/main/java/com/genersoft/iot/vmp/gb28181/bean/TreeType.java deleted 100644 → 0
1 -package com.genersoft.iot.vmp.gb28181.bean;  
2 -  
3 -/**  
4 - * 目录结构类型  
5 - * @author lin  
6 - */  
7 -public class TreeType {  
8 - public static final String BUSINESS_GROUP = "BusinessGroup";  
9 - public static final String CIVIL_CODE = "CivilCode";  
10 -}  
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java
@@ -209,59 +209,149 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { @@ -209,59 +209,149 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
209 // 行政区划分组只需要这两项就可以 209 // 行政区划分组只需要这两项就可以
210 catalogXml.append("<DeviceID>" + channel.getChannelId() + "</DeviceID>\r\n"); 210 catalogXml.append("<DeviceID>" + channel.getChannelId() + "</DeviceID>\r\n");
211 catalogXml.append("<Name>" + channel.getName() + "</Name>\r\n"); 211 catalogXml.append("<Name>" + channel.getName() + "</Name>\r\n");
212 - if (channel.getParentId() != null) {  
213 - // 业务分组加上这一项即可,提高兼容性,  
214 - catalogXml.append("<ParentID>" + channel.getParentId() + "</ParentID>\r\n");  
215 -// catalogXml.append("<ParentID>" + parentPlatform.getDeviceGBId() + "/" + channel.getParentId() + "</ParentID>\r\n");  
216 - }  
217 - if (channel.getChannelId().length() == 20 && Integer.parseInt(channel.getChannelId().substring(10, 13)) == 216) {  
218 - // 虚拟组织增加BusinessGroupID字段  
219 - catalogXml.append("<BusinessGroupID>" + channel.getParentId() + "</BusinessGroupID>\r\n");  
220 - }  
221 - if (!channel.getChannelId().equals(parentPlatform.getDeviceGBId())) {  
222 - catalogXml.append("<Parental>" + channel.getParental() + "</Parental>\r\n");  
223 - if (channel.getParental() == 0) {  
224 - catalogXml.append("<Status>" + (channel.isStatus() ? "ON" : "OFF") + "</Status>\r\n"); 212 + if (channel.getChannelId().length() <= 8) {
  213 + catalogXml.append("</Item>\r\n");
  214 + continue;
  215 + }else {
  216 + if (channel.getChannelId().length() != 20) {
  217 + continue;
225 } 218 }
226 - }  
227 - if (channel.getParental() == 0) {  
228 - // 通道项  
229 - catalogXml.append("<Manufacturer>" + channel.getManufacture() + "</Manufacturer>\r\n");  
230 - catalogXml.append("<Secrecy>" + channel.getSecrecy() + "</Secrecy>\r\n");  
231 - catalogXml.append("<RegisterWay>" + channel.getRegisterWay() + "</RegisterWay>\r\n");  
232 - String civilCode = channel.getCivilCode() == null?parentPlatform.getAdministrativeDivision() : channel.getCivilCode();  
233 - if (channel.getChannelType() != 2) { // 业务分组/虚拟组织/行政区划 不设置以下属性  
234 - catalogXml.append("<Model>" + channel.getModel() + "</Model>\r\n");  
235 - catalogXml.append("<Owner>" + parentPlatform.getDeviceGBId()+ "</Owner>\r\n");  
236 - catalogXml.append("<CivilCode>" + civilCode + "</CivilCode>\r\n");  
237 - if (channel.getAddress() == null) {  
238 - catalogXml.append("<Address></Address>\r\n");  
239 - }else {  
240 - catalogXml.append("<Address>" + channel.getAddress() + "</Address>\r\n");  
241 - }  
242 - catalogXml.append("<Block>" + channel.getBlock() + "</Block>\r\n");  
243 - catalogXml.append("<SafetyWay>" + channel.getSafetyWay() + "</SafetyWay>\r\n");  
244 - catalogXml.append("<CertNum>" + channel.getCertNum() + "</CertNum>\r\n");  
245 - catalogXml.append("<Certifiable>" + channel.getCertifiable() + "</Certifiable>\r\n");  
246 - catalogXml.append("<ErrCode>" + channel.getErrCode() + "</ErrCode>\r\n");  
247 - catalogXml.append("<EndTime>" + channel.getEndTime() + "</EndTime>\r\n");  
248 - catalogXml.append("<Secrecy>" + channel.getSecrecy() + "</Secrecy>\r\n");  
249 - catalogXml.append("<IPAddress>" + channel.getIpAddress() + "</IPAddress>\r\n");  
250 - catalogXml.append("<Port>" + channel.getPort() + "</Port>\r\n");  
251 - catalogXml.append("<Password>" + channel.getPort() + "</Password>\r\n");  
252 - catalogXml.append("<PTZType>" + channel.getPTZType() + "</PTZType>\r\n");  
253 - catalogXml.append("<Status>" + (channel.isStatus() ? "ON":"OFF") + "</Status>\r\n");  
254 - catalogXml.append("<Longitude>" +  
255 - (channel.getLongitudeWgs84() != 0? channel.getLongitudeWgs84():channel.getLongitude())  
256 - + "</Longitude>\r\n");  
257 - catalogXml.append("<Latitude>" +  
258 - (channel.getLatitudeWgs84() != 0? channel.getLatitudeWgs84():channel.getLatitude())  
259 - + "</Latitude>\r\n");  
260 - 219 + switch (Integer.parseInt(channel.getChannelId().substring(10, 13))){
  220 + case 200:
  221 +// catalogXml.append("<Manufacturer>三永华通</Manufacturer>\r\n");
  222 +// GitUtil gitUtil = SpringBeanFactory.getBean("gitUtil");
  223 +// String model = (gitUtil == null || gitUtil.getBuildVersion() == null)?"1.0": gitUtil.getBuildVersion();
  224 +// catalogXml.append("<Model>" + model + "</Manufacturer>\r\n");
  225 +// catalogXml.append("<Owner>三永华通</Owner>\r\n");
  226 + if (channel.getCivilCode() != null) {
  227 + catalogXml.append("<CivilCode>"+channel.getCivilCode()+"</CivilCode>\r\n");
  228 + }else {
  229 + catalogXml.append("<CivilCode></CivilCode>\r\n");
  230 + }
  231 +
  232 + catalogXml.append("<RegisterWay>1</RegisterWay>\r\n");
  233 + catalogXml.append("<Secrecy>0</Secrecy>\r\n");
  234 + break;
  235 + case 215:
  236 + if (!ObjectUtils.isEmpty(channel.getParentId())) {
  237 + catalogXml.append("<ParentID>" + channel.getParentId() + "</ParentID>\r\n");
  238 + }
  239 +
  240 + break;
  241 + case 216:
  242 + if (!ObjectUtils.isEmpty(channel.getParentId())) {
  243 + catalogXml.append("<ParentID>" + channel.getParentId() + "</ParentID>\r\n");
  244 + }else {
  245 + catalogXml.append("<ParentID></ParentID>\r\n");
  246 + }
  247 + if (!ObjectUtils.isEmpty(channel.getBusinessGroupId())) {
  248 + catalogXml.append("<BusinessGroupID>" + channel.getBusinessGroupId() + "</BusinessGroupID>\r\n");
  249 + }else {
  250 + catalogXml.append("<BusinessGroupID></BusinessGroupID>\r\n");
  251 + }
  252 + break;
  253 + default:
  254 + // 通道项
  255 + if (channel.getManufacture() != null) {
  256 + catalogXml.append("<Manufacturer>" + channel.getManufacture() + "</Manufacturer>\r\n");
  257 + }else {
  258 + catalogXml.append("<Manufacturer></Manufacturer>\r\n");
  259 + }
  260 + if (channel.getSecrecy() != null) {
  261 + catalogXml.append("<Secrecy>" + channel.getSecrecy() + "</Secrecy>\r\n");
  262 + }else {
  263 + catalogXml.append("<Secrecy></Secrecy>\r\n");
  264 + }
  265 + catalogXml.append("<RegisterWay>" + channel.getRegisterWay() + "</RegisterWay>\r\n");
  266 + if (channel.getModel() != null) {
  267 + catalogXml.append("<Model>" + channel.getModel() + "</Model>\r\n");
  268 + }else {
  269 + catalogXml.append("<Model></Model>\r\n");
  270 + }
  271 + if (channel.getOwner() != null) {
  272 + catalogXml.append("<Owner>" + channel.getOwner()+ "</Owner>\r\n");
  273 + }else {
  274 + catalogXml.append("<Owner></Owner>\r\n");
  275 + }
  276 + if (channel.getCivilCode() != null) {
  277 + catalogXml.append("<CivilCode>" + channel.getCivilCode() + "</CivilCode>\r\n");
  278 + }else {
  279 + catalogXml.append("<CivilCode></CivilCode>\r\n");
  280 + }
  281 + if (channel.getAddress() == null) {
  282 + catalogXml.append("<Address></Address>\r\n");
  283 + }else {
  284 + catalogXml.append("<Address>" + channel.getAddress() + "</Address>\r\n");
  285 + }
  286 + if (!ObjectUtils.isEmpty(channel.getParentId())) {
  287 + catalogXml.append("<ParentID>" + channel.getParentId() + "</ParentID>\r\n");
  288 + }else {
  289 + catalogXml.append("<ParentID></ParentID>\r\n");
  290 + }
  291 + if (!ObjectUtils.isEmpty(channel.getBlock())) {
  292 + catalogXml.append("<Block>" + channel.getBlock() + "</Block>\r\n");
  293 + }else {
  294 + catalogXml.append("<Block></Block>\r\n");
  295 + }
  296 + if (!ObjectUtils.isEmpty(channel.getSafetyWay())) {
  297 + catalogXml.append("<SafetyWay>" + channel.getSafetyWay() + "</SafetyWay>\r\n");
  298 + }else {
  299 + catalogXml.append("<SafetyWay></SafetyWay>\r\n");
  300 + }
  301 + if (!ObjectUtils.isEmpty(channel.getCertNum())) {
  302 + catalogXml.append("<CertNum>" + channel.getCertNum() + "</CertNum>\r\n");
  303 + }else {
  304 + catalogXml.append("<CertNum></CertNum>\r\n");
  305 + }
  306 + if (!ObjectUtils.isEmpty(channel.getCertifiable())) {
  307 + catalogXml.append("<Certifiable>" + channel.getCertifiable() + "</Certifiable>\r\n");
  308 + }else {
  309 + catalogXml.append("<Certifiable></Certifiable>\r\n");
  310 + }
  311 + if (!ObjectUtils.isEmpty(channel.getErrCode())) {
  312 + catalogXml.append("<ErrCode>" + channel.getErrCode() + "</ErrCode>\r\n");
  313 + }else {
  314 + catalogXml.append("<ErrCode></ErrCode>\r\n");
  315 + }
  316 + if (!ObjectUtils.isEmpty(channel.getEndTime())) {
  317 + catalogXml.append("<EndTime>" + channel.getEndTime() + "</EndTime>\r\n");
  318 + }else {
  319 + catalogXml.append("<EndTime></EndTime>\r\n");
  320 + }
  321 + if (!ObjectUtils.isEmpty(channel.getSecrecy())) {
  322 + catalogXml.append("<Secrecy>" + channel.getSecrecy() + "</Secrecy>\r\n");
  323 + }else {
  324 + catalogXml.append("<Secrecy></Secrecy>\r\n");
  325 + }
  326 + if (!ObjectUtils.isEmpty(channel.getIpAddress())) {
  327 + catalogXml.append("<IPAddress>" + channel.getIpAddress() + "</IPAddress>\r\n");
  328 + }else {
  329 + catalogXml.append("<IPAddress></IPAddress>\r\n");
  330 + }
  331 + catalogXml.append("<Port>" + channel.getPort() + "</Port>\r\n");
  332 + if (!ObjectUtils.isEmpty(channel.getPassword())) {
  333 + catalogXml.append("<Password>" + channel.getPassword() + "</Password>\r\n");
  334 + }else {
  335 + catalogXml.append("<Password></Password>\r\n");
  336 + }
  337 + if (!ObjectUtils.isEmpty(channel.getPTZType())) {
  338 + catalogXml.append("<PTZType>" + channel.getPTZType() + "</PTZType>\r\n");
  339 + }else {
  340 + catalogXml.append("<PTZType></PTZType>\r\n");
  341 + }
  342 + catalogXml.append("<Status>" + (channel.getStatus() == 1?"ON":"OFF") + "</Status>\r\n");
  343 +
  344 + catalogXml.append("<Longitude>" +
  345 + (channel.getLongitudeWgs84() != 0? channel.getLongitudeWgs84():channel.getLongitude())
  346 + + "</Longitude>\r\n");
  347 + catalogXml.append("<Latitude>" +
  348 + (channel.getLatitudeWgs84() != 0? channel.getLatitudeWgs84():channel.getLatitude())
  349 + + "</Latitude>\r\n");
  350 + break;
261 351
262 } 352 }
  353 + catalogXml.append("</Item>\r\n");
263 } 354 }
264 - catalogXml.append("</Item>\r\n");  
265 } 355 }
266 } 356 }
267 357
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java
@@ -188,6 +188,8 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements @@ -188,6 +188,8 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
188 logger.error("[命令发送失败] invite GONE: {}", e.getMessage()); 188 logger.error("[命令发送失败] invite GONE: {}", e.getMessage());
189 } 189 }
190 return; 190 return;
  191 + }else {
  192 + // TODO 可能漏回复消息
191 } 193 }
192 } 194 }
193 } else { 195 } else {
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/NotifyRequestForCatalogProcessor.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.CivilCodeFileConf;
3 import com.genersoft.iot.vmp.conf.DynamicTask; 4 import com.genersoft.iot.vmp.conf.DynamicTask;
4 import com.genersoft.iot.vmp.conf.UserSetting; 5 import com.genersoft.iot.vmp.conf.UserSetting;
5 import com.genersoft.iot.vmp.gb28181.bean.Device; 6 import com.genersoft.iot.vmp.gb28181.bean.Device;
@@ -20,7 +21,10 @@ import org.springframework.stereotype.Component; @@ -20,7 +21,10 @@ import org.springframework.stereotype.Component;
20 21
21 import javax.sip.RequestEvent; 22 import javax.sip.RequestEvent;
22 import javax.sip.header.FromHeader; 23 import javax.sip.header.FromHeader;
23 -import java.util.*; 24 +import java.util.ArrayList;
  25 +import java.util.Iterator;
  26 +import java.util.List;
  27 +import java.util.Map;
24 import java.util.concurrent.ConcurrentHashMap; 28 import java.util.concurrent.ConcurrentHashMap;
25 import java.util.concurrent.CopyOnWriteArrayList; 29 import java.util.concurrent.CopyOnWriteArrayList;
26 30
@@ -56,6 +60,9 @@ public class NotifyRequestForCatalogProcessor extends SIPRequestProcessorParent @@ -56,6 +60,9 @@ public class NotifyRequestForCatalogProcessor extends SIPRequestProcessorParent
56 @Autowired 60 @Autowired
57 private DynamicTask dynamicTask; 61 private DynamicTask dynamicTask;
58 62
  63 + @Autowired
  64 + private CivilCodeFileConf civilCodeFileConf;
  65 +
59 private final static String talkKey = "notify-request-for-catalog-task"; 66 private final static String talkKey = "notify-request-for-catalog-task";
60 67
61 public void process(RequestEvent evt) { 68 public void process(RequestEvent evt) {
@@ -96,7 +103,7 @@ public class NotifyRequestForCatalogProcessor extends SIPRequestProcessorParent @@ -96,7 +103,7 @@ public class NotifyRequestForCatalogProcessor extends SIPRequestProcessorParent
96 }else { 103 }else {
97 event = eventElement.getText().toUpperCase(); 104 event = eventElement.getText().toUpperCase();
98 } 105 }
99 - DeviceChannel channel = XmlUtil.channelContentHander(itemDevice, device, event); 106 + DeviceChannel channel = XmlUtil.channelContentHandler(itemDevice, device, event, civilCodeFileConf);
100 107
101 channel.setDeviceId(device.getDeviceId()); 108 channel.setDeviceId(device.getDeviceId());
102 logger.info("[收到目录订阅]:{}/{}", device.getDeviceId(), channel.getChannelId()); 109 logger.info("[收到目录订阅]:{}/{}", device.getDeviceId(), channel.getChannelId());
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/NotifyRequestProcessor.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.alibaba.fastjson2.JSONObject; 3 import com.alibaba.fastjson2.JSONObject;
  4 +import com.genersoft.iot.vmp.conf.CivilCodeFileConf;
4 import com.genersoft.iot.vmp.conf.SipConfig; 5 import com.genersoft.iot.vmp.conf.SipConfig;
5 import com.genersoft.iot.vmp.conf.UserSetting; 6 import com.genersoft.iot.vmp.conf.UserSetting;
6 import com.genersoft.iot.vmp.gb28181.bean.*; 7 import com.genersoft.iot.vmp.gb28181.bean.*;
@@ -79,6 +80,9 @@ public class NotifyRequestProcessor extends SIPRequestProcessorParent implements @@ -79,6 +80,9 @@ public class NotifyRequestProcessor extends SIPRequestProcessorParent implements
79 @Autowired 80 @Autowired
80 private NotifyRequestForCatalogProcessor notifyRequestForCatalogProcessor; 81 private NotifyRequestForCatalogProcessor notifyRequestForCatalogProcessor;
81 82
  83 + @Autowired
  84 + private CivilCodeFileConf civilCodeFileConf;
  85 +
82 private ConcurrentLinkedQueue<HandlerCatchData> taskQueue = new ConcurrentLinkedQueue<>(); 86 private ConcurrentLinkedQueue<HandlerCatchData> taskQueue = new ConcurrentLinkedQueue<>();
83 87
84 @Qualifier("taskExecutor") 88 @Qualifier("taskExecutor")
@@ -408,7 +412,7 @@ public class NotifyRequestProcessor extends SIPRequestProcessorParent implements @@ -408,7 +412,7 @@ public class NotifyRequestProcessor extends SIPRequestProcessorParent implements
408 }else { 412 }else {
409 event = eventElement.getText().toUpperCase(); 413 event = eventElement.getText().toUpperCase();
410 } 414 }
411 - DeviceChannel channel = XmlUtil.channelContentHander(itemDevice, device, event); 415 + DeviceChannel channel = XmlUtil.channelContentHandler(itemDevice, device, event, civilCodeFileConf);
412 channel.setDeviceId(device.getDeviceId()); 416 channel.setDeviceId(device.getDeviceId());
413 logger.info("[收到目录订阅]:{}/{}", device.getDeviceId(), channel.getChannelId()); 417 logger.info("[收到目录订阅]:{}/{}", device.getDeviceId(), channel.getChannelId());
414 switch (event) { 418 switch (event) {
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/CatalogResponseMessageHandler.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.conf.CivilCodeFileConf;
3 import com.genersoft.iot.vmp.gb28181.bean.*; 4 import com.genersoft.iot.vmp.gb28181.bean.*;
4 import com.genersoft.iot.vmp.gb28181.session.CatalogDataCatch; 5 import com.genersoft.iot.vmp.gb28181.session.CatalogDataCatch;
5 import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent; 6 import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent;
@@ -53,6 +54,9 @@ public class CatalogResponseMessageHandler extends SIPRequestProcessorParent imp @@ -53,6 +54,9 @@ public class CatalogResponseMessageHandler extends SIPRequestProcessorParent imp
53 @Autowired 54 @Autowired
54 private ThreadPoolTaskExecutor taskExecutor; 55 private ThreadPoolTaskExecutor taskExecutor;
55 56
  57 + @Autowired
  58 + private CivilCodeFileConf civilCodeFileConf;
  59 +
56 @Override 60 @Override
57 public void afterPropertiesSet() throws Exception { 61 public void afterPropertiesSet() throws Exception {
58 responseMessageHandler.addHandler(cmdType, this); 62 responseMessageHandler.addHandler(cmdType, this);
@@ -100,6 +104,7 @@ public class CatalogResponseMessageHandler extends SIPRequestProcessorParent imp @@ -100,6 +104,7 @@ public class CatalogResponseMessageHandler extends SIPRequestProcessorParent imp
100 Iterator<Element> deviceListIterator = deviceListElement.elementIterator(); 104 Iterator<Element> deviceListIterator = deviceListElement.elementIterator();
101 if (deviceListIterator != null) { 105 if (deviceListIterator != null) {
102 List<DeviceChannel> channelList = new ArrayList<>(); 106 List<DeviceChannel> channelList = new ArrayList<>();
  107 + List<String> parentChannelIds = new ArrayList<>();
103 // 遍历DeviceList 108 // 遍历DeviceList
104 while (deviceListIterator.hasNext()) { 109 while (deviceListIterator.hasNext()) {
105 Element itemDevice = deviceListIterator.next(); 110 Element itemDevice = deviceListIterator.next();
@@ -107,7 +112,7 @@ public class CatalogResponseMessageHandler extends SIPRequestProcessorParent imp @@ -107,7 +112,7 @@ public class CatalogResponseMessageHandler extends SIPRequestProcessorParent imp
107 if (channelDeviceElement == null) { 112 if (channelDeviceElement == null) {
108 continue; 113 continue;
109 } 114 }
110 - DeviceChannel deviceChannel = XmlUtil.channelContentHander(itemDevice, device, null); 115 + DeviceChannel deviceChannel = XmlUtil.channelContentHandler(itemDevice, device, null, civilCodeFileConf);
111 deviceChannel = SipUtils.updateGps(deviceChannel, device.getGeoCoordSys()); 116 deviceChannel = SipUtils.updateGps(deviceChannel, device.getGeoCoordSys());
112 deviceChannel.setDeviceId(take.getDevice().getDeviceId()); 117 deviceChannel.setDeviceId(take.getDevice().getDeviceId());
113 118
src/main/java/com/genersoft/iot/vmp/gb28181/utils/XmlUtil.java
@@ -2,6 +2,8 @@ package com.genersoft.iot.vmp.gb28181.utils; @@ -2,6 +2,8 @@ package com.genersoft.iot.vmp.gb28181.utils;
2 2
3 import com.alibaba.fastjson2.JSONArray; 3 import com.alibaba.fastjson2.JSONArray;
4 import com.alibaba.fastjson2.JSONObject; 4 import com.alibaba.fastjson2.JSONObject;
  5 +import com.genersoft.iot.vmp.common.CivilCodePo;
  6 +import com.genersoft.iot.vmp.conf.CivilCodeFileConf;
5 import com.genersoft.iot.vmp.gb28181.bean.Device; 7 import com.genersoft.iot.vmp.gb28181.bean.Device;
6 import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; 8 import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
7 import com.genersoft.iot.vmp.gb28181.event.subscribe.catalog.CatalogEvent; 9 import com.genersoft.iot.vmp.gb28181.event.subscribe.catalog.CatalogEvent;
@@ -192,7 +194,7 @@ public class XmlUtil { @@ -192,7 +194,7 @@ public class XmlUtil {
192 CivilCode, BusinessGroup,VirtualOrganization,Other 194 CivilCode, BusinessGroup,VirtualOrganization,Other
193 } 195 }
194 196
195 - public static DeviceChannel channelContentHander(Element itemDevice, Device device, String event){ 197 + public static DeviceChannel channelContentHandler(Element itemDevice, Device device, String event, CivilCodeFileConf civilCodeFileConf){
196 DeviceChannel deviceChannel = new DeviceChannel(); 198 DeviceChannel deviceChannel = new DeviceChannel();
197 deviceChannel.setDeviceId(device.getDeviceId()); 199 deviceChannel.setDeviceId(device.getDeviceId());
198 Element channdelIdElement = itemDevice.element("DeviceID"); 200 Element channdelIdElement = itemDevice.element("DeviceID");
@@ -210,208 +212,353 @@ public class XmlUtil { @@ -210,208 +212,353 @@ public class XmlUtil {
210 // 除了ADD和update情况下需要识别全部内容, 212 // 除了ADD和update情况下需要识别全部内容,
211 return deviceChannel; 213 return deviceChannel;
212 } 214 }
213 -  
214 - ChannelType channelType = ChannelType.Other;  
215 - if (channelId.length() <= 8) {  
216 - channelType = ChannelType.CivilCode; 215 + Element nameElement = itemDevice.element("Name");
  216 + if (nameElement != null) {
  217 + deviceChannel.setName(nameElement.getText());
  218 + }
  219 + if(channelId.length() <= 8) {
217 deviceChannel.setHasAudio(false); 220 deviceChannel.setHasAudio(false);
  221 + CivilCodePo parentCode = civilCodeFileConf.getParentCode(channelId);
  222 + if (parentCode != null) {
  223 + deviceChannel.setParentId(parentCode.getCode());
  224 + deviceChannel.setCivilCode(parentCode.getCode());
  225 + }else {
  226 + logger.warn("[xml解析] 无法确定行政区划{}的上级行政区划", channelId);
  227 + }
  228 + deviceChannel.setStatus(1);
  229 + return deviceChannel;
218 }else { 230 }else {
219 - if (channelId.length() == 20) {  
220 - int code = Integer.parseInt(channelId.substring(10, 13));  
221 - switch (code){  
222 - case 215:  
223 - channelType = ChannelType.BusinessGroup;  
224 - deviceChannel.setHasAudio(false);  
225 - break;  
226 - case 216:  
227 - channelType = ChannelType.VirtualOrganization;  
228 - deviceChannel.setHasAudio(false);  
229 - break;  
230 - case 136:  
231 - case 137:  
232 - case 138:  
233 - deviceChannel.setHasAudio(true);  
234 - break;  
235 - default:  
236 - deviceChannel.setHasAudio(false);  
237 - break;  
238 -  
239 - } 231 + if(channelId.length() != 20) {
  232 + logger.warn("[xml解析] 失败,编号不符合国标28181定义: {}", channelId);
  233 + return null;
240 } 234 }
241 - }  
242 235
243 - Element channdelNameElement = itemDevice.element("Name");  
244 - String channelName = channdelNameElement != null ? channdelNameElement.getTextTrim() : "";  
245 - deviceChannel.setName(channelName);  
246 -  
247 - String civilCode = XmlUtil.getText(itemDevice, "CivilCode");  
248 - deviceChannel.setCivilCode(civilCode);  
249 - if (channelType == ChannelType.CivilCode && civilCode == null) {  
250 - deviceChannel.setParental(1);  
251 - // 行政区划如果没有传递具体值,则推测一个  
252 - if (channelId.length() > 2) {  
253 - deviceChannel.setCivilCode(channelId.substring(0, channelId.length() - 2));  
254 - }  
255 - }  
256 - if (channelType.equals(ChannelType.CivilCode)) {  
257 - // 行政区划其他字段没必要识别了,默认在线即可  
258 - deviceChannel.setStatus(true);  
259 - deviceChannel.setParental(1);  
260 - deviceChannel.setCreateTime(DateUtil.getNow());  
261 - deviceChannel.setUpdateTime(DateUtil.getNow());  
262 - return deviceChannel;  
263 - }  
264 - /**  
265 - * 行政区划展示设备树与业务分组展示设备树是两种不同的模式  
266 - * 行政区划展示设备树 各个目录之间主要靠deviceId做关联,摄像头通过CivilCode指定其属于那个行政区划;都是不超过十位的编号; 结构如下:  
267 - * 河北省  
268 - * --> 石家庄市  
269 - * --> 摄像头  
270 - *String parentId = XmlUtil.getText(itemDevice, "ParentID");  
271 - if (parentId != null) {  
272 - if (parentId.contains("/")) {  
273 - String lastParentId = parentId.substring(parentId.lastIndexOf("/") + 1);  
274 - String businessGroup = parentId.substring(0, parentId.indexOf("/"));  
275 - deviceChannel.setParentId(lastParentId);  
276 - }else {  
277 - deviceChannel.setParentId(parentId);  
278 - }  
279 - }  
280 - deviceCh --> 正定县  
281 - * --> 摄像头  
282 - * --> 摄像头  
283 - *  
284 - * 业务分组展示设备树是顶级是业务分组,其下的虚拟组织靠BusinessGroupID指定其所属的业务分组;摄像头通过ParentId来指定其所属于的虚拟组织:  
285 - * 业务分组  
286 - * --> 虚拟组织  
287 - * --> 摄像头  
288 - * --> 虚拟组织  
289 - * --> 摄像头  
290 - * --> 摄像头  
291 - */  
292 - String parentId = XmlUtil.getText(itemDevice, "ParentID");  
293 - String businessGroupID = XmlUtil.getText(itemDevice, "BusinessGroupID");  
294 - if (parentId != null) {  
295 - if (parentId.contains("/")) {  
296 - String lastParentId = parentId.substring(parentId.lastIndexOf("/") + 1);  
297 - if (businessGroupID == null) {  
298 - businessGroupID = parentId.substring(0, parentId.indexOf("/"));  
299 - }  
300 - deviceChannel.setParentId(lastParentId); 236 + int code = Integer.parseInt(channelId.substring(10, 13));
  237 + if (code == 136 || code == 137 || code == 138) {
  238 + deviceChannel.setHasAudio(true);
301 }else { 239 }else {
302 - deviceChannel.setParentId(parentId); 240 + deviceChannel.setHasAudio(false);
303 } 241 }
304 - // 兼容设备通道信息中自己为自己父节点的情况  
305 - if (deviceChannel.getParentId().equals(deviceChannel.getChannelId())) {  
306 - deviceChannel.setParentId(null); 242 + // 设备厂商
  243 + String manufacturer = getText(itemDevice, "Manufacturer");
  244 + // 设备型号
  245 + String model = getText(itemDevice, "Model");
  246 + // 设备归属
  247 + String owner = getText(itemDevice, "Owner");
  248 + // 行政区域
  249 + String civilCode = getText(itemDevice, "CivilCode");
  250 + // 虚拟组织所属的业务分组ID,业务分组根据特定的业务需求制定,一个业务分组包含一组特定的虚拟组织
  251 + String businessGroupID = getText(itemDevice, "BusinessGroupID");
  252 + // 父设备/区域/系统ID
  253 + String parentID = getText(itemDevice, "ParentID");
  254 + if (parentID != null && parentID.equalsIgnoreCase("null")) {
  255 + parentID = null;
307 } 256 }
308 - }  
309 - deviceChannel.setBusinessGroupId(businessGroupID);  
310 - if (channelType.equals(ChannelType.BusinessGroup) || channelType.equals(ChannelType.VirtualOrganization)) {  
311 - // 业务分组和虚拟组织 其他字段没必要识别了,默认在线即可  
312 - deviceChannel.setStatus(true);  
313 - deviceChannel.setParental(1);  
314 - deviceChannel.setCreateTime(DateUtil.getNow());  
315 - deviceChannel.setUpdateTime(DateUtil.getNow());  
316 - return deviceChannel;  
317 - } 257 + // 注册方式(必选)缺省为1;1:符合IETFRFC3261标准的认证注册模式;2:基于口令的双向认证注册模式;3:基于数字证书的双向认证注册模式
  258 + String registerWay = getText(itemDevice, "RegisterWay");
  259 + // 保密属性(必选)缺省为0;0:不涉密,1:涉密
  260 + String secrecy = getText(itemDevice, "Secrecy");
  261 + // 安装地址
  262 + String address = getText(itemDevice, "Address");
  263 +
  264 + switch (code){
  265 + case 200:
  266 + // 系统目录
  267 + if (!ObjectUtils.isEmpty(manufacturer)) {
  268 + deviceChannel.setManufacture(manufacturer);
  269 + }
  270 + if (!ObjectUtils.isEmpty(model)) {
  271 + deviceChannel.setModel(model);
  272 + }
  273 + if (!ObjectUtils.isEmpty(owner)) {
  274 + deviceChannel.setOwner(owner);
  275 + }
  276 + if (!ObjectUtils.isEmpty(civilCode)) {
  277 + deviceChannel.setCivilCode(civilCode);
  278 + deviceChannel.setParentId(civilCode);
  279 + }else {
  280 + if (!ObjectUtils.isEmpty(parentID)) {
  281 + deviceChannel.setParentId(parentID);
  282 + }
  283 + }
  284 + if (!ObjectUtils.isEmpty(address)) {
  285 + deviceChannel.setAddress(address);
  286 + }
  287 + deviceChannel.setStatus(1);
  288 + if (!ObjectUtils.isEmpty(registerWay)) {
  289 + try {
  290 + deviceChannel.setRegisterWay(Integer.parseInt(registerWay));
  291 + }catch (NumberFormatException exception) {
  292 + logger.warn("[xml解析] 从通道数据获取registerWay失败: {}", registerWay);
  293 + }
  294 + }
  295 + if (!ObjectUtils.isEmpty(secrecy)) {
  296 + deviceChannel.setSecrecy(secrecy);
  297 + }
  298 + return deviceChannel;
  299 + case 215:
  300 + // 业务分组
  301 + deviceChannel.setStatus(1);
  302 + if (!ObjectUtils.isEmpty(parentID)) {
  303 + if (!parentID.trim().equalsIgnoreCase(device.getDeviceId())) {
  304 + deviceChannel.setParentId(parentID);
  305 + }
  306 + }else {
  307 + logger.warn("[xml解析] 业务分组数据中缺少关键信息->ParentId");
  308 + if (!ObjectUtils.isEmpty(civilCode)) {
  309 + deviceChannel.setCivilCode(civilCode);
  310 + }
  311 + }
  312 + break;
  313 + case 216:
  314 + // 虚拟组织
  315 + deviceChannel.setStatus(1);
  316 + if (!ObjectUtils.isEmpty(businessGroupID)) {
  317 + deviceChannel.setBusinessGroupId(businessGroupID);
  318 + }
318 319
319 - Element statusElement = itemDevice.element("Status");  
320 320
321 - if (statusElement != null) {  
322 - String status = statusElement.getTextTrim().trim();  
323 - // ONLINE OFFLINE HIKVISION DS-7716N-E4 NVR的兼容性处理  
324 - if (status.equals("ON") || status.equals("On") || status.equals("ONLINE") || status.equals("OK")) {  
325 - deviceChannel.setStatus(true);  
326 - }  
327 - if (status.equals("OFF") || status.equals("Off") || status.equals("OFFLINE")) {  
328 - deviceChannel.setStatus(false);  
329 - }  
330 - }else {  
331 - deviceChannel.setStatus(true);  
332 - }  
333 - // 识别自带的目录标识  
334 - String parental = XmlUtil.getText(itemDevice, "Parental");  
335 - // 由于海康会错误的发送65535作为这里的取值,所以这里除非是0否则认为是1  
336 - if (!ObjectUtils.isEmpty(parental) && parental.length() == 1 && Integer.parseInt(parental) == 0) {  
337 - deviceChannel.setParental(0);  
338 - }else {  
339 - deviceChannel.setParental(1);  
340 - } 321 + if (!ObjectUtils.isEmpty(parentID)) {
  322 + if (parentID.contains("/")) {
  323 + String[] parentIdArray = parentID.split("/");
  324 + parentID = parentIdArray[parentIdArray.length - 1];
  325 + }
  326 + deviceChannel.setParentId(parentID);
  327 + }else {
  328 + if (!ObjectUtils.isEmpty(businessGroupID)) {
  329 + deviceChannel.setParentId(businessGroupID);
  330 + }
  331 + }
  332 + break;
  333 + default:
  334 + // 设备目录
  335 + if (!ObjectUtils.isEmpty(manufacturer)) {
  336 + deviceChannel.setManufacture(manufacturer);
  337 + }
  338 + if (!ObjectUtils.isEmpty(model)) {
  339 + deviceChannel.setModel(model);
  340 + }
  341 + if (!ObjectUtils.isEmpty(owner)) {
  342 + deviceChannel.setOwner(owner);
  343 + }
  344 + if (!ObjectUtils.isEmpty(civilCode)) {
  345 + deviceChannel.setCivilCode(civilCode);
  346 + }
  347 + if (!ObjectUtils.isEmpty(businessGroupID)) {
  348 + deviceChannel.setBusinessGroupId(businessGroupID);
  349 + }
341 350
  351 + // 警区
  352 + String block = getText(itemDevice, "Block");
  353 + if (!ObjectUtils.isEmpty(block)) {
  354 + deviceChannel.setBlock(block);
  355 + }
  356 + if (!ObjectUtils.isEmpty(address)) {
  357 + deviceChannel.setAddress(address);
  358 + }
342 359
343 - deviceChannel.setManufacture(XmlUtil.getText(itemDevice, "Manufacturer"));  
344 - deviceChannel.setModel(XmlUtil.getText(itemDevice, "Model"));  
345 - deviceChannel.setOwner(XmlUtil.getText(itemDevice, "Owner"));  
346 - deviceChannel.setCertNum(XmlUtil.getText(itemDevice, "CertNum"));  
347 - deviceChannel.setBlock(XmlUtil.getText(itemDevice, "Block"));  
348 - deviceChannel.setAddress(XmlUtil.getText(itemDevice, "Address"));  
349 - deviceChannel.setPassword(XmlUtil.getText(itemDevice, "Password")); 360 + if (!ObjectUtils.isEmpty(secrecy)) {
  361 + deviceChannel.setSecrecy(secrecy);
  362 + }
350 363
351 - String safetyWay = XmlUtil.getText(itemDevice, "SafetyWay");  
352 - if (ObjectUtils.isEmpty(safetyWay)) {  
353 - deviceChannel.setSafetyWay(0);  
354 - } else {  
355 - deviceChannel.setSafetyWay(Integer.parseInt(safetyWay));  
356 - } 364 + // 当为设备时,是否有子设备(必选)1有,0没有
  365 + String parental = getText(itemDevice, "Parental");
  366 + if (!ObjectUtils.isEmpty(parental)) {
  367 + try {
  368 + // 由于海康会错误的发送65535作为这里的取值,所以这里除非是0否则认为是1
  369 + if (!ObjectUtils.isEmpty(parental) && parental.length() == 1 && Integer.parseInt(parental) == 0) {
  370 + deviceChannel.setParental(0);
  371 + }else {
  372 + deviceChannel.setParental(1);
  373 + }
  374 + }catch (NumberFormatException e) {
  375 + logger.warn("[xml解析] 从通道数据获取 parental失败: {}", parental);
  376 + }
  377 + }
  378 + // 父设备/区域/系统ID
  379 + String realParentId = parentID;
  380 + if (!ObjectUtils.isEmpty(parentID)) {
  381 + if (parentID.contains("/")) {
  382 + String[] parentIdArray = parentID.split("/");
  383 + realParentId = parentIdArray[parentIdArray.length - 1];
  384 + }
  385 + deviceChannel.setParentId(realParentId);
  386 + }else {
  387 + if (!ObjectUtils.isEmpty(businessGroupID)) {
  388 + deviceChannel.setParentId(businessGroupID);
  389 + }else {
  390 + if (!ObjectUtils.isEmpty(civilCode)) {
  391 + deviceChannel.setParentId(civilCode);
  392 + }
  393 + }
  394 + }
  395 + // 注册方式
  396 + if (!ObjectUtils.isEmpty(registerWay)) {
  397 + try {
  398 + int registerWayInt = Integer.parseInt(registerWay);
  399 + deviceChannel.setRegisterWay(registerWayInt);
  400 + }catch (NumberFormatException exception) {
  401 + logger.warn("[xml解析] 从通道数据获取registerWay失败: {}", registerWay);
  402 + deviceChannel.setRegisterWay(1);
  403 + }
  404 + }else {
  405 + deviceChannel.setRegisterWay(1);
  406 + }
357 407
358 - String registerWay = XmlUtil.getText(itemDevice, "RegisterWay");  
359 - if (ObjectUtils.isEmpty(registerWay)) {  
360 - deviceChannel.setRegisterWay(1);  
361 - } else {  
362 - deviceChannel.setRegisterWay(Integer.parseInt(registerWay));  
363 - } 408 + // 信令安全模式(可选)缺省为0; 0:不采用;2:S/MIME 签名方式;3:S/MIME加密签名同时采用方式;4:数字摘要方式
  409 + String safetyWay = getText(itemDevice, "SafetyWay");
  410 + if (!ObjectUtils.isEmpty(safetyWay)) {
  411 + try {
  412 + deviceChannel.setSafetyWay(Integer.parseInt(safetyWay));
  413 + }catch (NumberFormatException e) {
  414 + logger.warn("[xml解析] 从通道数据获取 safetyWay失败: {}", safetyWay);
  415 + }
  416 + }
364 417
365 - if (XmlUtil.getText(itemDevice, "Certifiable") == null  
366 - || XmlUtil.getText(itemDevice, "Certifiable") == "") {  
367 - deviceChannel.setCertifiable(0);  
368 - } else {  
369 - deviceChannel.setCertifiable(Integer.parseInt(XmlUtil.getText(itemDevice, "Certifiable")));  
370 - } 418 + // 证书序列号(有证书的设备必选)
  419 + String certNum = getText(itemDevice, "CertNum");
  420 + if (!ObjectUtils.isEmpty(certNum)) {
  421 + deviceChannel.setCertNum(certNum);
  422 + }
371 423
372 - if (XmlUtil.getText(itemDevice, "ErrCode") == null  
373 - || XmlUtil.getText(itemDevice, "ErrCode") == "") {  
374 - deviceChannel.setErrCode(0);  
375 - } else {  
376 - deviceChannel.setErrCode(Integer.parseInt(XmlUtil.getText(itemDevice, "ErrCode")));  
377 - } 424 + // 证书有效标识(有证书的设备必选)缺省为0;证书有效标识:0:无效 1:有效
  425 + String certifiable = getText(itemDevice, "Certifiable");
  426 + if (!ObjectUtils.isEmpty(certifiable)) {
  427 + try {
  428 + deviceChannel.setCertifiable(Integer.parseInt(certifiable));
  429 + }catch (NumberFormatException e) {
  430 + logger.warn("[xml解析] 从通道数据获取 Certifiable失败: {}", certifiable);
  431 + }
  432 + }
378 433
379 - deviceChannel.setEndTime(XmlUtil.getText(itemDevice, "EndTime"));  
380 - deviceChannel.setSecrecy(XmlUtil.getText(itemDevice, "Secrecy"));  
381 - deviceChannel.setIpAddress(XmlUtil.getText(itemDevice, "IPAddress"));  
382 - if (XmlUtil.getText(itemDevice, "Port") == null || XmlUtil.getText(itemDevice, "Port") == "") {  
383 - deviceChannel.setPort(0);  
384 - } else {  
385 - deviceChannel.setPort(Integer.parseInt(XmlUtil.getText(itemDevice, "Port")));  
386 - } 434 + // 无效原因码(有证书且证书无效的设备必选)
  435 + String errCode = getText(itemDevice, "ErrCode");
  436 + if (!ObjectUtils.isEmpty(errCode)) {
  437 + try {
  438 + deviceChannel.setErrCode(Integer.parseInt(errCode));
  439 + }catch (NumberFormatException e) {
  440 + logger.warn("[xml解析] 从通道数据获取 ErrCode失败: {}", errCode);
  441 + }
  442 + }
387 443
  444 + // 证书终止有效期(有证书的设备必选)
  445 + String endTime = getText(itemDevice, "EndTime");
  446 + if (!ObjectUtils.isEmpty(endTime)) {
  447 + deviceChannel.setEndTime(endTime);
  448 + }
388 449
389 - String longitude = XmlUtil.getText(itemDevice, "Longitude");  
390 - if (NumericUtil.isDouble(longitude)) {  
391 - deviceChannel.setLongitude(Double.parseDouble(longitude));  
392 - } else {  
393 - deviceChannel.setLongitude(0.00);  
394 - }  
395 - String latitude = XmlUtil.getText(itemDevice, "Latitude");  
396 - if (NumericUtil.isDouble(latitude)) {  
397 - deviceChannel.setLatitude(Double.parseDouble(latitude));  
398 - } else {  
399 - deviceChannel.setLatitude(0.00);  
400 - }  
401 450
402 - deviceChannel.setGpsTime(DateUtil.getNow()); 451 + // 设备/区域/系统IP地址
  452 + String ipAddress = getText(itemDevice, "IPAddress");
  453 + if (!ObjectUtils.isEmpty(ipAddress)) {
  454 + deviceChannel.setIpAddress(ipAddress);
  455 + }
  456 +
  457 + // 设备/区域/系统端口
  458 + String port = getText(itemDevice, "Port");
  459 + if (!ObjectUtils.isEmpty(port)) {
  460 + try {
  461 + deviceChannel.setPort(Integer.parseInt(port));
  462 + }catch (NumberFormatException e) {
  463 + logger.warn("[xml解析] 从通道数据获取 Port失败: {}", port);
  464 + }
  465 + }
  466 +
  467 + // 设备口令
  468 + String password = getText(itemDevice, "Password");
  469 + if (!ObjectUtils.isEmpty(password)) {
  470 + deviceChannel.setPassword(password);
  471 + }
403 472
404 473
405 - if (XmlUtil.getText(itemDevice, "PTZType") == null || "".equals(XmlUtil.getText(itemDevice, "PTZType"))) {  
406 - //兼容INFO中的信息  
407 - Element info = itemDevice.element("Info");  
408 - if(XmlUtil.getText(info, "PTZType") == null || "".equals(XmlUtil.getText(info, "PTZType"))){  
409 - deviceChannel.setPTZType(0);  
410 - }else{  
411 - deviceChannel.setPTZType(Integer.parseInt(XmlUtil.getText(info, "PTZType"))); 474 + // 设备状态
  475 + String status = getText(itemDevice, "Status");
  476 + if (status != null) {
  477 + // ONLINE OFFLINE HIKVISION DS-7716N-E4 NVR的兼容性处理
  478 + if (status.equals("ON") || status.equals("On") || status.equals("ONLINE") || status.equals("OK")) {
  479 + deviceChannel.setStatus(1);
  480 + }
  481 + if (status.equals("OFF") || status.equals("Off") || status.equals("OFFLINE")) {
  482 + deviceChannel.setStatus(0);
  483 + }
  484 + }else {
  485 + deviceChannel.setStatus(1);
  486 + }
  487 +
  488 + // 经度
  489 + String longitude = getText(itemDevice, "Longitude");
  490 + if (NumericUtil.isDouble(longitude)) {
  491 + deviceChannel.setLongitude(Double.parseDouble(longitude));
  492 + } else {
  493 + deviceChannel.setLongitude(0.00);
  494 + }
  495 +
  496 + // 纬度
  497 + String latitude = getText(itemDevice, "Latitude");
  498 + if (NumericUtil.isDouble(latitude)) {
  499 + deviceChannel.setLatitude(Double.parseDouble(latitude));
  500 + } else {
  501 + deviceChannel.setLatitude(0.00);
  502 + }
  503 +
  504 + deviceChannel.setGpsTime(DateUtil.getNow());
  505 +
  506 + // -摄像机类型扩展,标识摄像机类型:1-球机;2-半球;3-固定枪机;4-遥控枪机。当目录项为摄像机时可选
  507 + String ptzType = getText(itemDevice, "PTZType");
  508 + if (ObjectUtils.isEmpty(ptzType)) {
  509 + //兼容INFO中的信息
  510 + Element info = itemDevice.element("Info");
  511 + String ptzTypeFromInfo = XmlUtil.getText(info, "PTZType");
  512 + if(!ObjectUtils.isEmpty(ptzTypeFromInfo)){
  513 + try {
  514 + deviceChannel.setPTZType(Integer.parseInt(ptzTypeFromInfo));
  515 + }catch (NumberFormatException e){
  516 + logger.warn("[xml解析] 从通道数据info中获取PTZType失败: {}", ptzTypeFromInfo);
  517 + }
  518 + }
  519 + } else {
  520 + try {
  521 + deviceChannel.setPTZType(Integer.parseInt(ptzType));
  522 + }catch (NumberFormatException e){
  523 + logger.warn("[xml解析] 从通道数据中获取PTZType失败: {}", ptzType);
  524 + }
  525 + }
  526 +
  527 + // TODO 摄像机位置类型扩展。
  528 + // 1-省际检查站、
  529 + // 2-党政机关、
  530 + // 3-车站码头、
  531 + // 4-中心广场、
  532 + // 5-体育场馆、
  533 + // 6-商业中心、
  534 + // 7-宗教场所、
  535 + // 8-校园周边、
  536 + // 9-治安复杂区域、
  537 + // 10-交通干线。
  538 + // String positionType = getText(itemDevice, "PositionType");
  539 +
  540 + // TODO 摄像机安装位置室外、室内属性。1-室外、2-室内。
  541 + // String roomType = getText(itemDevice, "RoomType");
  542 + // TODO 摄像机用途属性
  543 + // String useType = getText(itemDevice, "UseType");
  544 + // TODO 摄像机补光属性。1-无补光、2-红外补光、3-白光补光
  545 + // String supplyLightType = getText(itemDevice, "SupplyLightType");
  546 + // TODO 摄像机监视方位属性。1-东、2-西、3-南、4-北、5-东南、6-东北、7-西南、8-西北。
  547 + // String directionType = getText(itemDevice, "DirectionType");
  548 + // TODO 摄像机支持的分辨率,可有多个分辨率值,各个取值间以“/”分隔。分辨率取值参见附录 F中SDPf字段规定
  549 + // String resolution = getText(itemDevice, "Resolution");
  550 +
  551 + // TODO 下载倍速范围(可选),各可选参数以“/”分隔,如设备支持1,2,4倍速下载则应写为“1/2/4
  552 + // String downloadSpeed = getText(itemDevice, "DownloadSpeed");
  553 + // TODO 空域编码能力,取值0:不支持;1:1级增强(1个增强层);2:2级增强(2个增强层);3:3级增强(3个增强层)
  554 + // String svcSpaceSupportMode = getText(itemDevice, "SVCSpaceSupportMode");
  555 + // TODO 时域编码能力,取值0:不支持;1:1级增强;2:2级增强;3:3级增强
  556 + // String svcTimeSupportMode = getText(itemDevice, "SVCTimeSupportMode");
  557 +
  558 +
  559 + deviceChannel.setSecrecy(secrecy);
  560 + break;
412 } 561 }
413 - } else {  
414 - deviceChannel.setPTZType(Integer.parseInt(XmlUtil.getText(itemDevice, "PTZType")));  
415 } 562 }
416 563
417 return deviceChannel; 564 return deviceChannel;
src/main/java/com/genersoft/iot/vmp/service/impl/DeviceChannelServiceImpl.java
@@ -50,8 +50,6 @@ public class DeviceChannelServiceImpl implements IDeviceChannelService { @@ -50,8 +50,6 @@ public class DeviceChannelServiceImpl implements IDeviceChannelService {
50 device = deviceMapper.getDeviceByDeviceId(deviceChannel.getDeviceId()); 50 device = deviceMapper.getDeviceByDeviceId(deviceChannel.getDeviceId());
51 } 51 }
52 52
53 -  
54 -  
55 if ("WGS84".equals(device.getGeoCoordSys())) { 53 if ("WGS84".equals(device.getGeoCoordSys())) {
56 deviceChannel.setLongitudeWgs84(deviceChannel.getLongitude()); 54 deviceChannel.setLongitudeWgs84(deviceChannel.getLongitude());
57 deviceChannel.setLatitudeWgs84(deviceChannel.getLatitude()); 55 deviceChannel.setLatitudeWgs84(deviceChannel.getLatitude());
@@ -262,4 +260,6 @@ public class DeviceChannelServiceImpl implements IDeviceChannelService { @@ -262,4 +260,6 @@ public class DeviceChannelServiceImpl implements IDeviceChannelService {
262 } 260 }
263 } 261 }
264 } 262 }
  263 +
  264 +
265 } 265 }
src/main/java/com/genersoft/iot/vmp/service/impl/DeviceServiceImpl.java
@@ -380,63 +380,11 @@ public class DeviceServiceImpl implements IDeviceService { @@ -380,63 +380,11 @@ public class DeviceServiceImpl implements IDeviceService {
380 if (device == null) { 380 if (device == null) {
381 return null; 381 return null;
382 } 382 }
383 - if (parentId == null || parentId.equals(deviceId)) {  
384 - // 字根节点开始查询  
385 - List<DeviceChannel> rootNodes = getRootNodes(deviceId, TreeType.CIVIL_CODE.equals(device.getTreeType()), true, !onlyCatalog);  
386 - return transportChannelsToTree(rootNodes, ""); 383 + if (ObjectUtils.isEmpty(parentId) || parentId.equals(deviceId)) {
  384 + parentId = null;
387 } 385 }
388 -  
389 - if (TreeType.CIVIL_CODE.equals(device.getTreeType())) {  
390 - if (parentId.length()%2 != 0) {  
391 - return null;  
392 - }  
393 - // 使用行政区划展示树  
394 -// if (parentId.length() > 10) {  
395 -// // TODO 可能是行政区划与业务分组混杂的情形  
396 -// return null;  
397 -// }  
398 -  
399 - if (parentId.length() == 10 ) {  
400 - if (onlyCatalog) {  
401 - return null;  
402 - }  
403 - // parentId为行业编码, 其下不会再有行政区划  
404 - List<DeviceChannel> channels = deviceChannelMapper.getChannelsByCivilCode(deviceId, parentId);  
405 - List<BaseTree<DeviceChannel>> trees = transportChannelsToTree(channels, parentId);  
406 - return trees;  
407 - }  
408 - // 查询其下的行政区划和摄像机  
409 - List<DeviceChannel> channelsForCivilCode = deviceChannelMapper.getChannelsWithCivilCodeAndLength(deviceId, parentId, parentId.length() + 2);  
410 - if (!onlyCatalog) {  
411 - List<DeviceChannel> channels = deviceChannelMapper.getChannelsByCivilCode(deviceId, parentId);  
412 -  
413 - for(DeviceChannel channel : channels) {  
414 - boolean flag = false;  
415 - for(DeviceChannel deviceChannel : channelsForCivilCode) {  
416 - if(channel.getChannelId().equals(deviceChannel.getChannelId())) {  
417 - flag = true;  
418 - }  
419 - }  
420 - if(!flag) {  
421 - channelsForCivilCode.add(channel);  
422 - }  
423 - }  
424 - }  
425 - List<BaseTree<DeviceChannel>> trees = transportChannelsToTree(channelsForCivilCode, parentId);  
426 - return trees;  
427 -  
428 - }  
429 - // 使用业务分组展示树  
430 - if (TreeType.BUSINESS_GROUP.equals(device.getTreeType())) {  
431 - if (parentId.length() < 14 ) {  
432 - return null;  
433 - }  
434 - List<DeviceChannel> deviceChannels = deviceChannelMapper.queryChannels(deviceId, parentId, null, null, null,null);  
435 - List<BaseTree<DeviceChannel>> trees = transportChannelsToTree(deviceChannels, parentId);  
436 - return trees;  
437 - }  
438 -  
439 - return null; 386 + List<DeviceChannel> rootNodes = deviceChannelMapper.getSubChannelsByDeviceId(deviceId, parentId, onlyCatalog);
  387 + return transportChannelsToTree(rootNodes, "");
440 } 388 }
441 389
442 @Override 390 @Override
@@ -445,42 +393,11 @@ public class DeviceServiceImpl implements IDeviceService { @@ -445,42 +393,11 @@ public class DeviceServiceImpl implements IDeviceService {
445 if (device == null) { 393 if (device == null) {
446 return null; 394 return null;
447 } 395 }
448 - if (parentId == null || parentId.equals(deviceId)) {  
449 - // 字根节点开始查询  
450 - List<DeviceChannel> rootNodes = getRootNodes(deviceId, TreeType.CIVIL_CODE.equals(device.getTreeType()), false, true);  
451 - return rootNodes;  
452 - }  
453 -  
454 - if (TreeType.CIVIL_CODE.equals(device.getTreeType())) {  
455 - if (parentId.length()%2 != 0) {  
456 - return null;  
457 - }  
458 - // 使用行政区划展示树  
459 - if (parentId.length() > 10) {  
460 - // TODO 可能是行政区划与业务分组混杂的情形  
461 - return null;  
462 - }  
463 -  
464 - if (parentId.length() == 10 ) {  
465 - // parentId为行业编码, 其下不会再有行政区划  
466 - List<DeviceChannel> channels = deviceChannelMapper.getChannelsByCivilCode(deviceId, parentId);  
467 - return channels;  
468 - }  
469 - // 查询其下的行政区划和摄像机  
470 - List<DeviceChannel> channels = deviceChannelMapper.getChannelsByCivilCode(deviceId, parentId);  
471 - return channels;  
472 -  
473 - }  
474 - // 使用业务分组展示树  
475 - if (TreeType.BUSINESS_GROUP.equals(device.getTreeType())) {  
476 - if (parentId.length() < 14 ) {  
477 - return null;  
478 - }  
479 - List<DeviceChannel> deviceChannels = deviceChannelMapper.queryChannels(deviceId, parentId, null, null, null,null);  
480 - return deviceChannels; 396 + if (ObjectUtils.isEmpty(parentId) || parentId.equals(deviceId)) {
  397 + return deviceChannelMapper.getSubChannelsByDeviceId(deviceId, null, false);
  398 + }else {
  399 + return deviceChannelMapper.getSubChannelsByDeviceId(deviceId, parentId, false);
481 } 400 }
482 -  
483 - return null;  
484 } 401 }
485 402
486 private List<BaseTree<DeviceChannel>> transportChannelsToTree(List<DeviceChannel> channels, String parentId) { 403 private List<BaseTree<DeviceChannel>> transportChannelsToTree(List<DeviceChannel> channels, String parentId) {
@@ -500,65 +417,26 @@ public class DeviceServiceImpl implements IDeviceService { @@ -500,65 +417,26 @@ public class DeviceServiceImpl implements IDeviceService {
500 node.setPid(parentId); 417 node.setPid(parentId);
501 node.setBasicData(channel); 418 node.setBasicData(channel);
502 node.setParent(false); 419 node.setParent(false);
503 - if (channel.getChannelId().length() > 8) {  
504 - if (channel.getChannelId().length() > 13) {  
505 - String gbCodeType = channel.getChannelId().substring(10, 13);  
506 - node.setParent(gbCodeType.equals(ChannelIdType.BUSINESS_GROUP) || gbCodeType.equals(ChannelIdType.VIRTUAL_ORGANIZATION) );  
507 - }  
508 - }else { 420 + if (channel.getChannelId().length() <= 8) {
509 node.setParent(true); 421 node.setParent(true);
510 - }  
511 - treeNotes.add(node);  
512 - }  
513 - Collections.sort(treeNotes);  
514 - return treeNotes;  
515 - }  
516 -  
517 - private List<DeviceChannel> getRootNodes(String deviceId, boolean isCivilCode, boolean haveCatalog, boolean haveChannel) {  
518 - if (!haveCatalog && !haveChannel) {  
519 - return null;  
520 - }  
521 - List<DeviceChannel> result = new ArrayList<>();  
522 - if (isCivilCode) {  
523 - // 使用行政区划  
524 - Integer length= deviceChannelMapper.getChannelMinLength(deviceId);  
525 - if (length == null) {  
526 - return null;  
527 - }  
528 - if (length <= 10) {  
529 - if (haveCatalog) {  
530 - List<DeviceChannel> provinceNode = deviceChannelMapper.getChannelsWithCivilCodeAndLength(deviceId, null, length);  
531 - if (provinceNode != null && provinceNode.size() > 0) {  
532 - result.addAll(provinceNode);  
533 - }  
534 - }  
535 -  
536 - if (haveChannel) {  
537 - // 查询那些civilCode不在通道中的不规范通道,放置在根目录  
538 - List<DeviceChannel> nonstandardNode = deviceChannelMapper.getChannelWithoutCivilCode(deviceId);  
539 - if (nonstandardNode != null && nonstandardNode.size() > 0) {  
540 - result.addAll(nonstandardNode);  
541 - }  
542 - }  
543 }else { 422 }else {
544 - if (haveChannel) {  
545 - List<DeviceChannel> deviceChannels = deviceChannelMapper.queryChannels(deviceId, null, null, null, null,null);  
546 - if (deviceChannels != null && deviceChannels.size() > 0) {  
547 - result.addAll(deviceChannels); 423 + if (channel.getChannelId().length() != 20) {
  424 + node.setParent(channel.getParental() == 1);
  425 + }else {
  426 + try {
  427 + int type = Integer.parseInt(channel.getChannelId().substring(10, 13));
  428 + if (type == 215 || type == 216 || type == 200) {
  429 + node.setParent(true);
  430 + }
  431 + }catch (NumberFormatException e) {
  432 + node.setParent(false);
548 } 433 }
549 } 434 }
550 } 435 }
551 -  
552 - }else {  
553 - // 使用业务分组+虚拟组织  
554 -  
555 - // 只获取业务分组  
556 - List<DeviceChannel> deviceChannels = deviceChannelMapper.getBusinessGroups(deviceId, ChannelIdType.BUSINESS_GROUP);  
557 - if (deviceChannels != null && deviceChannels.size() > 0) {  
558 - result.addAll(deviceChannels);  
559 - } 436 + treeNotes.add(node);
560 } 437 }
561 - return result; 438 + Collections.sort(treeNotes);
  439 + return treeNotes;
562 } 440 }
563 441
564 @Override 442 @Override
src/main/java/com/genersoft/iot/vmp/service/impl/GbStreamServiceImpl.java
@@ -113,20 +113,15 @@ public class GbStreamServiceImpl implements IGbStreamService { @@ -113,20 +113,15 @@ public class GbStreamServiceImpl implements IGbStreamService {
113 deviceChannel.setStatus(gbStream.isStatus()); 113 deviceChannel.setStatus(gbStream.isStatus());
114 114
115 deviceChannel.setRegisterWay(1); 115 deviceChannel.setRegisterWay(1);
116 - deviceChannel.setCivilCode(platform.getAdministrativeDivision());  
117 -  
118 - if (platform.getTreeType().equals(TreeType.CIVIL_CODE)){  
119 - deviceChannel.setCivilCode(catalogId);  
120 - }else if (platform.getTreeType().equals(TreeType.BUSINESS_GROUP)){  
121 - PlatformCatalog catalog = catalogMapper.select(catalogId);  
122 - if (catalog == null) {  
123 - deviceChannel.setParentId(platform.getDeviceGBId());  
124 - deviceChannel.setBusinessGroupId(null);  
125 - }else {  
126 - deviceChannel.setParentId(catalog.getId());  
127 - deviceChannel.setBusinessGroupId(catalog.getBusinessGroupId());  
128 - }  
129 116
  117 + PlatformCatalog catalog = catalogMapper.select(catalogId);
  118 + if (catalog != null) {
  119 + deviceChannel.setCivilCode(catalog.getCivilCode());
  120 + deviceChannel.setParentId(catalog.getParentId());
  121 + deviceChannel.setBusinessGroupId(catalog.getBusinessGroupId());
  122 + }else {
  123 + deviceChannel.setCivilCode(platform.getAdministrativeDivision());
  124 + deviceChannel.setParentId(platform.getDeviceGBId());
130 } 125 }
131 126
132 deviceChannel.setModel("live"); 127 deviceChannel.setModel("live");
@@ -221,20 +216,14 @@ public class GbStreamServiceImpl implements IGbStreamService { @@ -221,20 +216,14 @@ public class GbStreamServiceImpl implements IGbStreamService {
221 deviceChannel.setStatus(status != null && status); 216 deviceChannel.setStatus(status != null && status);
222 217
223 deviceChannel.setRegisterWay(1); 218 deviceChannel.setRegisterWay(1);
224 - deviceChannel.setCivilCode(platform.getAdministrativeDivision());  
225 -  
226 - if (platform.getTreeType().equals(TreeType.CIVIL_CODE)){  
227 - deviceChannel.setCivilCode(catalogId);  
228 - }else if (platform.getTreeType().equals(TreeType.BUSINESS_GROUP)){  
229 - PlatformCatalog catalog = catalogMapper.select(catalogId);  
230 - if (catalog == null) {  
231 - deviceChannel.setParentId(platform.getDeviceGBId());  
232 - deviceChannel.setBusinessGroupId(null);  
233 - }else {  
234 - deviceChannel.setParentId(catalog.getId());  
235 - deviceChannel.setBusinessGroupId(catalog.getBusinessGroupId());  
236 - }  
237 - 219 + PlatformCatalog catalog = catalogMapper.select(catalogId);
  220 + if (catalog != null) {
  221 + deviceChannel.setCivilCode(catalog.getCivilCode());
  222 + deviceChannel.setParentId(catalog.getParentId());
  223 + deviceChannel.setBusinessGroupId(catalog.getBusinessGroupId());
  224 + }else {
  225 + deviceChannel.setCivilCode(platform.getAdministrativeDivision());
  226 + deviceChannel.setParentId(platform.getDeviceGBId());
238 } 227 }
239 228
240 deviceChannel.setModel("live"); 229 deviceChannel.setModel("live");
src/main/java/com/genersoft/iot/vmp/service/impl/PlatformChannelServiceImpl.java
@@ -126,22 +126,17 @@ public class PlatformChannelServiceImpl implements IPlatformChannelService { @@ -126,22 +126,17 @@ public class PlatformChannelServiceImpl implements IPlatformChannelService {
126 List<DeviceChannel> deviceChannelList = new ArrayList<>(); 126 List<DeviceChannel> deviceChannelList = new ArrayList<>();
127 if (channelReduces.size() > 0){ 127 if (channelReduces.size() > 0){
128 PlatformCatalog catalog = catalogManager.select(catalogId); 128 PlatformCatalog catalog = catalogManager.select(catalogId);
129 - if (catalog == null && !catalogId.equals(platform.getDeviceGBId())) { 129 + if (catalog == null || !catalogId.equals(platform.getDeviceGBId())) {
130 logger.warn("未查询到目录{}的信息", catalogId); 130 logger.warn("未查询到目录{}的信息", catalogId);
131 return null; 131 return null;
132 } 132 }
133 for (ChannelReduce channelReduce : channelReduces) { 133 for (ChannelReduce channelReduce : channelReduces) {
134 DeviceChannel deviceChannel = deviceChannelMapper.queryChannel(channelReduce.getDeviceId(), channelReduce.getChannelId()); 134 DeviceChannel deviceChannel = deviceChannelMapper.queryChannel(channelReduce.getDeviceId(), channelReduce.getChannelId());
135 deviceChannel.setParental(0); 135 deviceChannel.setParental(0);
  136 + deviceChannel.setCivilCode(catalog.getCivilCode());
  137 + deviceChannel.setParentId(catalog.getParentId());
  138 + deviceChannel.setBusinessGroupId(catalog.getBusinessGroupId());
136 deviceChannelList.add(deviceChannel); 139 deviceChannelList.add(deviceChannel);
137 - if (platform.getTreeType().equals(TreeType.CIVIL_CODE)){  
138 - deviceChannel.setCivilCode(catalogId);  
139 - }else if (platform.getTreeType().equals(TreeType.BUSINESS_GROUP)){  
140 - deviceChannel.setParentId(catalogId);  
141 - if (catalog != null) {  
142 - deviceChannel.setBusinessGroupId(catalog.getBusinessGroupId());  
143 - }  
144 - }  
145 } 140 }
146 } 141 }
147 return deviceChannelList; 142 return deviceChannelList;
src/main/java/com/genersoft/iot/vmp/service/impl/PlatformServiceImpl.java
@@ -35,6 +35,8 @@ import java.util.Map; @@ -35,6 +35,8 @@ import java.util.Map;
35 public class PlatformServiceImpl implements IPlatformService { 35 public class PlatformServiceImpl implements IPlatformService {
36 36
37 private final static String REGISTER_KEY_PREFIX = "platform_register_"; 37 private final static String REGISTER_KEY_PREFIX = "platform_register_";
  38 +
  39 + private final static String REGISTER_FAIL_AGAIN_KEY_PREFIX = "platform_register_fail_again_";
38 private final static String KEEPALIVE_KEY_PREFIX = "platform_keepalive_"; 40 private final static String KEEPALIVE_KEY_PREFIX = "platform_keepalive_";
39 41
40 private final static Logger logger = LoggerFactory.getLogger(PlatformServiceImpl.class); 42 private final static Logger logger = LoggerFactory.getLogger(PlatformServiceImpl.class);
@@ -128,18 +130,12 @@ public class PlatformServiceImpl implements IPlatformService { @@ -128,18 +130,12 @@ public class PlatformServiceImpl implements IPlatformService {
128 @Override 130 @Override
129 public boolean update(ParentPlatform parentPlatform) { 131 public boolean update(ParentPlatform parentPlatform) {
130 logger.info("[国标级联]更新平台 {}", parentPlatform.getDeviceGBId()); 132 logger.info("[国标级联]更新平台 {}", parentPlatform.getDeviceGBId());
  133 + // TODO 后续版本去除
  134 + parentPlatform.setTreeType("");
131 parentPlatform.setCharacterSet(parentPlatform.getCharacterSet().toUpperCase()); 135 parentPlatform.setCharacterSet(parentPlatform.getCharacterSet().toUpperCase());
132 ParentPlatform parentPlatformOld = platformMapper.getParentPlatById(parentPlatform.getId()); 136 ParentPlatform parentPlatformOld = platformMapper.getParentPlatById(parentPlatform.getId());
133 ParentPlatformCatch parentPlatformCatchOld = redisCatchStorage.queryPlatformCatchInfo(parentPlatformOld.getServerGBId()); 137 ParentPlatformCatch parentPlatformCatchOld = redisCatchStorage.queryPlatformCatchInfo(parentPlatformOld.getServerGBId());
134 parentPlatform.setUpdateTime(DateUtil.getNow()); 138 parentPlatform.setUpdateTime(DateUtil.getNow());
135 - if (!parentPlatformOld.getTreeType().equals(parentPlatform.getTreeType())) {  
136 - // 目录结构发生变化,清空之前的关联关系  
137 - logger.info("保存平台{}时发现目录结构变化,清空关联关系", parentPlatform.getDeviceGBId());  
138 - catalogMapper.delByPlatformId(parentPlatformOld.getServerGBId());  
139 - platformChannelMapper.delByPlatformId(parentPlatformOld.getServerGBId());  
140 - platformGbStreamMapper.delByPlatformId(parentPlatformOld.getServerGBId());  
141 - }  
142 -  
143 139
144 // 停止心跳定时 140 // 停止心跳定时
145 final String keepaliveTaskKey = KEEPALIVE_KEY_PREFIX + parentPlatformOld.getServerGBId(); 141 final String keepaliveTaskKey = KEEPALIVE_KEY_PREFIX + parentPlatformOld.getServerGBId();
@@ -150,12 +146,11 @@ public class PlatformServiceImpl implements IPlatformService { @@ -150,12 +146,11 @@ public class PlatformServiceImpl implements IPlatformService {
150 // 注销旧的 146 // 注销旧的
151 try { 147 try {
152 if (parentPlatformOld.isStatus()) { 148 if (parentPlatformOld.isStatus()) {
153 - logger.info("保存平台{}时发现平台在线,发送注销命令", parentPlatformOld.getServerGBId()); 149 + logger.info("保存平台{}时发现平台在线,发送注销命令", parentPlatformOld.getServerGBId());
154 commanderForPlatform.unregister(parentPlatformOld, parentPlatformCatchOld.getSipTransactionInfo(), null, eventResult -> { 150 commanderForPlatform.unregister(parentPlatformOld, parentPlatformCatchOld.getSipTransactionInfo(), null, eventResult -> {
155 logger.info("[国标级联] 注销成功, 平台:{}", parentPlatformOld.getServerGBId()); 151 logger.info("[国标级联] 注销成功, 平台:{}", parentPlatformOld.getServerGBId());
156 }); 152 });
157 } 153 }
158 -  
159 } catch (InvalidArgumentException | ParseException | SipException e) { 154 } catch (InvalidArgumentException | ParseException | SipException e) {
160 logger.error("[命令发送失败] 国标级联 注销: {}", e.getMessage()); 155 logger.error("[命令发送失败] 国标级联 注销: {}", e.getMessage());
161 } 156 }
@@ -188,9 +183,6 @@ public class PlatformServiceImpl implements IPlatformService { @@ -188,9 +183,6 @@ public class PlatformServiceImpl implements IPlatformService {
188 logger.error("[命令发送失败] 国标级联: {}", e.getMessage()); 183 logger.error("[命令发送失败] 国标级联: {}", e.getMessage());
189 } 184 }
190 } 185 }
191 - // 重新开启定时注册, 使用续订消息  
192 - // 重新开始心跳保活  
193 -  
194 186
195 return false; 187 return false;
196 } 188 }
@@ -199,6 +191,9 @@ public class PlatformServiceImpl implements IPlatformService { @@ -199,6 +191,9 @@ public class PlatformServiceImpl implements IPlatformService {
199 @Override 191 @Override
200 public void online(ParentPlatform parentPlatform, SipTransactionInfo sipTransactionInfo) { 192 public void online(ParentPlatform parentPlatform, SipTransactionInfo sipTransactionInfo) {
201 logger.info("[国标级联]:{}, 平台上线", parentPlatform.getServerGBId()); 193 logger.info("[国标级联]:{}, 平台上线", parentPlatform.getServerGBId());
  194 + final String registerFailAgainTaskKey = REGISTER_FAIL_AGAIN_KEY_PREFIX + parentPlatform.getServerGBId();
  195 + dynamicTask.stop(registerFailAgainTaskKey);
  196 +
202 platformMapper.updateParentPlatformStatus(parentPlatform.getServerGBId(), true); 197 platformMapper.updateParentPlatformStatus(parentPlatform.getServerGBId(), true);
203 ParentPlatformCatch parentPlatformCatch = redisCatchStorage.queryPlatformCatchInfo(parentPlatform.getServerGBId()); 198 ParentPlatformCatch parentPlatformCatch = redisCatchStorage.queryPlatformCatchInfo(parentPlatform.getServerGBId());
204 if (parentPlatformCatch == null) { 199 if (parentPlatformCatch == null) {
@@ -239,15 +234,9 @@ public class PlatformServiceImpl implements IPlatformService { @@ -239,15 +234,9 @@ public class PlatformServiceImpl implements IPlatformService {
239 // 此时是第三次心跳超时, 平台离线 234 // 此时是第三次心跳超时, 平台离线
240 if (platformCatch.getKeepAliveReply() == 2) { 235 if (platformCatch.getKeepAliveReply() == 2) {
241 // 设置平台离线,并重新注册 236 // 设置平台离线,并重新注册
242 - logger.info("[国标级联] {},三次心跳超时后再次发起注册", parentPlatform.getServerGBId());  
243 - try {  
244 - commanderForPlatform.register(parentPlatform, eventResult1 -> {  
245 - logger.info("[国标级联] {},三次心跳超时后再次发起注册仍然失败,开始定时发起注册,间隔为1分钟", parentPlatform.getServerGBId());  
246 - offline(parentPlatform, false);  
247 - }, null);  
248 - } catch (InvalidArgumentException | ParseException | SipException e) {  
249 - logger.error("[命令发送失败] 国标级联 注册: {}", e.getMessage());  
250 - } 237 + logger.info("[国标级联] 三次心跳超时, 平台{}({})离线", parentPlatform.getName(), parentPlatform.getServerGBId());
  238 + offline(parentPlatform, false);
  239 +
251 } 240 }
252 241
253 }else { 242 }else {
@@ -273,21 +262,22 @@ public class PlatformServiceImpl implements IPlatformService { @@ -273,21 +262,22 @@ public class PlatformServiceImpl implements IPlatformService {
273 262
274 private void registerTask(ParentPlatform parentPlatform, SipTransactionInfo sipTransactionInfo){ 263 private void registerTask(ParentPlatform parentPlatform, SipTransactionInfo sipTransactionInfo){
275 try { 264 try {
276 - // 设置超时重发, 后续从底层支持消息重发  
277 - String key = KEEPALIVE_KEY_PREFIX + parentPlatform.getServerGBId() + "_timeout";  
278 - if (dynamicTask.isAlive(key)) {  
279 - return; 265 + // 不在同一个会话中续订则每次全新注册
  266 + if (!userSetting.isRegisterKeepIntDialog()) {
  267 + sipTransactionInfo = null;
  268 + }
  269 +
  270 + if (sipTransactionInfo == null) {
  271 + logger.info("[国标级联] 平台:{}注册即将到期,开始重新注册", parentPlatform.getServerGBId());
  272 + }else {
  273 + logger.info("[国标级联] 平台:{}注册即将到期,开始续订", parentPlatform.getServerGBId());
280 } 274 }
281 - dynamicTask.startDelay(key, ()->{  
282 - registerTask(parentPlatform, sipTransactionInfo);  
283 - }, 1000);  
284 - logger.info("[国标级联] 平台:{}注册即将到期,开始续订", parentPlatform.getServerGBId()); 275 +
285 commanderForPlatform.register(parentPlatform, sipTransactionInfo, eventResult -> { 276 commanderForPlatform.register(parentPlatform, sipTransactionInfo, eventResult -> {
286 - dynamicTask.stop(key); 277 + logger.info("[国标级联] 平台:{}注册失败,{}:{}", parentPlatform.getServerGBId(),
  278 + eventResult.statusCode, eventResult.msg);
287 offline(parentPlatform, false); 279 offline(parentPlatform, false);
288 - },eventResult -> {  
289 - dynamicTask.stop(key);  
290 - }); 280 + }, null);
291 } catch (InvalidArgumentException | ParseException | SipException e) { 281 } catch (InvalidArgumentException | ParseException | SipException e) {
292 logger.error("[命令发送失败] 国标级联定时注册: {}", e.getMessage()); 282 logger.error("[命令发送失败] 国标级联定时注册: {}", e.getMessage());
293 } 283 }
@@ -308,24 +298,35 @@ public class PlatformServiceImpl implements IPlatformService { @@ -308,24 +298,35 @@ public class PlatformServiceImpl implements IPlatformService {
308 // 停止所有推流 298 // 停止所有推流
309 logger.info("[平台离线] {}, 停止所有推流", parentPlatform.getServerGBId()); 299 logger.info("[平台离线] {}, 停止所有推流", parentPlatform.getServerGBId());
310 stopAllPush(parentPlatform.getServerGBId()); 300 stopAllPush(parentPlatform.getServerGBId());
311 - if (stopRegister) {  
312 - // 清除注册定时  
313 - logger.info("[平台离线] {}, 停止定时注册任务", parentPlatform.getServerGBId());  
314 - final String registerTaskKey = REGISTER_KEY_PREFIX + parentPlatform.getServerGBId();  
315 - if (dynamicTask.contains(registerTaskKey)) {  
316 - dynamicTask.stop(registerTaskKey);  
317 - } 301 +
  302 + // 清除注册定时
  303 + logger.info("[平台离线] {}, 停止定时注册任务", parentPlatform.getServerGBId());
  304 + final String registerTaskKey = REGISTER_KEY_PREFIX + parentPlatform.getServerGBId();
  305 + if (dynamicTask.contains(registerTaskKey)) {
  306 + dynamicTask.stop(registerTaskKey);
318 } 307 }
319 // 清除心跳定时 308 // 清除心跳定时
320 logger.info("[平台离线] {}, 停止定时发送心跳任务", parentPlatform.getServerGBId()); 309 logger.info("[平台离线] {}, 停止定时发送心跳任务", parentPlatform.getServerGBId());
321 final String keepaliveTaskKey = KEEPALIVE_KEY_PREFIX + parentPlatform.getServerGBId(); 310 final String keepaliveTaskKey = KEEPALIVE_KEY_PREFIX + parentPlatform.getServerGBId();
322 if (dynamicTask.contains(keepaliveTaskKey)) { 311 if (dynamicTask.contains(keepaliveTaskKey)) {
323 - // 添加心跳任务 312 + // 清除心跳任务
324 dynamicTask.stop(keepaliveTaskKey); 313 dynamicTask.stop(keepaliveTaskKey);
325 } 314 }
326 // 停止目录订阅回复 315 // 停止目录订阅回复
327 logger.info("[平台离线] {}, 停止订阅回复", parentPlatform.getServerGBId()); 316 logger.info("[平台离线] {}, 停止订阅回复", parentPlatform.getServerGBId());
328 subscribeHolder.removeAllSubscribe(parentPlatform.getServerGBId()); 317 subscribeHolder.removeAllSubscribe(parentPlatform.getServerGBId());
  318 + // 发起定时自动重新注册
  319 + if (!stopRegister) {
  320 + // 设置为60秒自动尝试重新注册
  321 + final String registerFailAgainTaskKey = REGISTER_FAIL_AGAIN_KEY_PREFIX + parentPlatform.getServerGBId();
  322 + ParentPlatform platform = platformMapper.getParentPlatById(parentPlatform.getId());
  323 + if (platform.isEnable()) {
  324 + dynamicTask.startCron(registerFailAgainTaskKey,
  325 + ()-> registerTask(platform, null),
  326 + userSetting.getRegisterAgainAfterTime() * 1000);
  327 + }
  328 +
  329 + }
329 } 330 }
330 331
331 private void stopAllPush(String platformId) { 332 private void stopAllPush(String platformId) {
src/main/java/com/genersoft/iot/vmp/storager/dao/DeviceChannelMapper.java
@@ -450,4 +450,14 @@ public interface DeviceChannelMapper { @@ -450,4 +450,14 @@ public interface DeviceChannelMapper {
450 450
451 @Select("select count(1) from wvp_device_channel") 451 @Select("select count(1) from wvp_device_channel")
452 int getAllChannelCount(); 452 int getAllChannelCount();
  453 +
  454 + @Select(value = {" <script>" +
  455 + "select * " +
  456 + "from device_channel " +
  457 + "where device_id=#{deviceId}" +
  458 + " <if test='parentId != null '> and parent_id = #{parentId} </if>" +
  459 + " <if test='parentId == null '> and parent_id is null </if>" +
  460 + " <if test='onlyCatalog == true '> and parental = 1 </if>" +
  461 + " </script>"})
  462 + List<DeviceChannel> getSubChannelsByDeviceId(String deviceId, String parentId, boolean onlyCatalog);
453 } 463 }
src/main/java/com/genersoft/iot/vmp/storager/impl/VideoManagerStorageImpl.java
@@ -128,51 +128,50 @@ public class VideoManagerStorageImpl implements IVideoManagerStorage { @@ -128,51 +128,50 @@ public class VideoManagerStorageImpl implements IVideoManagerStorage {
128 List<DeviceChannel> addChannels = new ArrayList<>(); 128 List<DeviceChannel> addChannels = new ArrayList<>();
129 StringBuilder stringBuilder = new StringBuilder(); 129 StringBuilder stringBuilder = new StringBuilder();
130 Map<String, Integer> subContMap = new HashMap<>(); 130 Map<String, Integer> subContMap = new HashMap<>();
131 - if (deviceChannelList.size() > 0) {  
132 - // 数据去重  
133 - Set<String> gbIdSet = new HashSet<>();  
134 - for (DeviceChannel deviceChannel : deviceChannelList) {  
135 - if (!gbIdSet.contains(deviceChannel.getChannelId())) {  
136 - gbIdSet.add(deviceChannel.getChannelId());  
137 - deviceChannel.setUpdateTime(DateUtil.getNow());  
138 - if (allChannelMap.containsKey(deviceChannel.getChannelId())) {  
139 - deviceChannel.setStreamId(allChannelMap.get(deviceChannel.getChannelId()).getStreamId());  
140 - deviceChannel.setHasAudio(allChannelMap.get(deviceChannel.getChannelId()).isHasAudio());  
141 - if (allChannelMap.get(deviceChannel.getChannelId()).isStatus() !=deviceChannel.isStatus()){  
142 - List<String> strings = platformChannelMapper.queryParentPlatformByChannelId(deviceChannel.getChannelId());  
143 - if (!CollectionUtils.isEmpty(strings)){  
144 - strings.forEach(platformId->{  
145 - eventPublisher.catalogEventPublish(platformId, deviceChannel, deviceChannel.isStatus()?CatalogEvent.ON:CatalogEvent.OFF);  
146 - });  
147 - }  
148 - }  
149 - updateChannels.add(deviceChannel);  
150 - }else {  
151 - deviceChannel.setCreateTime(DateUtil.getNow());  
152 - addChannels.add(deviceChannel);  
153 - }  
154 - channels.add(deviceChannel);  
155 - if (!ObjectUtils.isEmpty(deviceChannel.getParentId())) {  
156 - if (subContMap.get(deviceChannel.getParentId()) == null) {  
157 - subContMap.put(deviceChannel.getParentId(), 1);  
158 - }else {  
159 - Integer count = subContMap.get(deviceChannel.getParentId());  
160 - subContMap.put(deviceChannel.getParentId(), count++);  
161 - } 131 +
  132 + // 数据去重
  133 + Set<String> gbIdSet = new HashSet<>();
  134 + for (DeviceChannel deviceChannel : deviceChannelList) {
  135 + if (gbIdSet.contains(deviceChannel.getChannelId())) {
  136 + stringBuilder.append(deviceChannel.getChannelId()).append(",");
  137 + continue;
  138 + }
  139 + gbIdSet.add(deviceChannel.getChannelId());
  140 + if (allChannelMap.containsKey(deviceChannel.getChannelId())) {
  141 + deviceChannel.setStreamId(allChannelMap.get(deviceChannel.getChannelId()).getStreamId());
  142 + deviceChannel.setHasAudio(allChannelMap.get(deviceChannel.getChannelId()).isHasAudio());
  143 + if (allChannelMap.get(deviceChannel.getChannelId()).getStatus() !=deviceChannel.getStatus()){
  144 + List<String> strings = platformChannelMapper.queryParentPlatformByChannelId(deviceChannel.getChannelId());
  145 + if (!CollectionUtils.isEmpty(strings)){
  146 + strings.forEach(platformId->{
  147 + eventPublisher.catalogEventPublish(platformId, deviceChannel, deviceChannel.getStatus()==1?CatalogEvent.ON:CatalogEvent.OFF);
  148 + });
162 } 149 }
  150 +
  151 + }
  152 + }
  153 + channels.add(deviceChannel);
  154 + if (!ObjectUtils.isEmpty(deviceChannel.getParentId())) {
  155 + if (subContMap.get(deviceChannel.getParentId()) == null) {
  156 + subContMap.put(deviceChannel.getParentId(), 1);
163 }else { 157 }else {
164 - stringBuilder.append(deviceChannel.getChannelId()).append(","); 158 + Integer count = subContMap.get(deviceChannel.getParentId());
  159 + subContMap.put(deviceChannel.getParentId(), count++);
165 } 160 }
166 } 161 }
167 - if (channels.size() > 0) {  
168 - for (DeviceChannel channel : channels) {  
169 - if (subContMap.get(channel.getChannelId()) != null){  
170 - channel.setSubCount(subContMap.get(channel.getChannelId())); 162 + }
  163 + if (channels.size() > 0) {
  164 + for (DeviceChannel channel : channels) {
  165 + if (subContMap.get(channel.getChannelId()) != null){
  166 + Integer count = subContMap.get(channel.getChannelId());
  167 + if (count > 0) {
  168 + channel.setSubCount(count);
  169 + channel.setParental(1);
171 } 170 }
172 } 171 }
173 } 172 }
174 -  
175 } 173 }
  174 +
176 if (stringBuilder.length() > 0) { 175 if (stringBuilder.length() > 0) {
177 logger.info("[目录查询]收到的数据存在重复: {}" , stringBuilder); 176 logger.info("[目录查询]收到的数据存在重复: {}" , stringBuilder);
178 } 177 }
@@ -795,25 +794,49 @@ public class VideoManagerStorageImpl implements IVideoManagerStorage { @@ -795,25 +794,49 @@ public class VideoManagerStorageImpl implements IVideoManagerStorage {
795 if (platform == null) { 794 if (platform == null) {
796 return 0; 795 return 0;
797 } 796 }
798 - if (platform.getTreeType().equals(TreeType.BUSINESS_GROUP)) {  
799 - if (platform.getDeviceGBId().equals(platformCatalog.getParentId())) {  
800 - // 第一层节点  
801 - platformCatalog.setBusinessGroupId(platformCatalog.getId());  
802 - platformCatalog.setParentId(platform.getDeviceGBId());  
803 - }else {  
804 - // 获取顶层的  
805 - PlatformCatalog topCatalog = getTopCatalog(platformCatalog.getParentId(), platform.getDeviceGBId());  
806 - platformCatalog.setBusinessGroupId(topCatalog.getId()); 797 + if (platformCatalog.getId().length() <= 8) {
  798 + platformCatalog.setCivilCode(platformCatalog.getParentId());
  799 + }else {
  800 + if (platformCatalog.getId().length() != 20) {
  801 + return 0;
807 } 802 }
808 - }  
809 - if (platform.getTreeType().equals(TreeType.CIVIL_CODE)) {  
810 - platformCatalog.setCivilCode(platformCatalog.getId());  
811 - if (platformCatalog.getPlatformId().equals(platformCatalog.getParentId())) {  
812 - // 第一层节点  
813 - platformCatalog.setParentId(platform.getDeviceGBId()); 803 + if (platformCatalog.getParentId() != null) {
  804 + switch (Integer.parseInt(platformCatalog.getId().substring(10, 13))){
  805 + case 200:
  806 + case 215:
  807 + if (platformCatalog.getParentId().length() <= 8) {
  808 + platformCatalog.setCivilCode(platformCatalog.getParentId());
  809 + }else {
  810 + PlatformCatalog catalog = catalogMapper.select(platformCatalog.getParentId());
  811 + if (catalog != null) {
  812 + platformCatalog.setCivilCode(catalog.getCivilCode());
  813 + }
  814 + }
  815 + break;
  816 + case 216:
  817 + if (platformCatalog.getParentId().length() <= 8) {
  818 + platformCatalog.setCivilCode(platformCatalog.getParentId());
  819 + }else {
  820 + PlatformCatalog catalog = catalogMapper.select(platformCatalog.getParentId());
  821 + if (catalog == null) {
  822 + logger.warn("[添加目录] 无法获取目录{}的CivilCode和BusinessGroupId", platformCatalog.getPlatformId());
  823 + break;
  824 + }
  825 + platformCatalog.setCivilCode(catalog.getCivilCode());
  826 + if (Integer.parseInt(platformCatalog.getParentId().substring(10, 13)) == 215) {
  827 + platformCatalog.setBusinessGroupId(platformCatalog.getParentId());
  828 + }else {
  829 + if (Integer.parseInt(platformCatalog.getParentId().substring(10, 13)) == 216) {
  830 + platformCatalog.setBusinessGroupId(catalog.getBusinessGroupId());
  831 + }
  832 + }
  833 + }
  834 + break;
  835 + default:
  836 + break;
  837 + }
814 } 838 }
815 } 839 }
816 -  
817 int result = catalogMapper.add(platformCatalog); 840 int result = catalogMapper.add(platformCatalog);
818 if (result > 0) { 841 if (result > 0) {
819 DeviceChannel deviceChannel = getDeviceChannelByCatalog(platformCatalog); 842 DeviceChannel deviceChannel = getDeviceChannelByCatalog(platformCatalog);
@@ -937,19 +960,14 @@ public class VideoManagerStorageImpl implements IVideoManagerStorage { @@ -937,19 +960,14 @@ public class VideoManagerStorageImpl implements IVideoManagerStorage {
937 DeviceChannel deviceChannel = new DeviceChannel(); 960 DeviceChannel deviceChannel = new DeviceChannel();
938 deviceChannel.setChannelId(catalog.getId()); 961 deviceChannel.setChannelId(catalog.getId());
939 deviceChannel.setName(catalog.getName()); 962 deviceChannel.setName(catalog.getName());
940 - deviceChannel.setLongitude(0.0);  
941 - deviceChannel.setLatitude(0.0);  
942 deviceChannel.setDeviceId(platform.getDeviceGBId()); 963 deviceChannel.setDeviceId(platform.getDeviceGBId());
943 deviceChannel.setManufacture("wvp-pro"); 964 deviceChannel.setManufacture("wvp-pro");
944 deviceChannel.setStatus(true); 965 deviceChannel.setStatus(true);
945 deviceChannel.setParental(1); 966 deviceChannel.setParental(1);
946 967
947 deviceChannel.setRegisterWay(1); 968 deviceChannel.setRegisterWay(1);
948 - // 行政区划应该是Domain的前八位  
949 - if (platform.getTreeType().equals(TreeType.BUSINESS_GROUP)) {  
950 - deviceChannel.setParentId(catalog.getParentId());  
951 - deviceChannel.setBusinessGroupId(catalog.getBusinessGroupId());  
952 - } 969 + deviceChannel.setParentId(catalog.getParentId());
  970 + deviceChannel.setBusinessGroupId(catalog.getBusinessGroupId());
953 971
954 deviceChannel.setModel("live"); 972 deviceChannel.setModel("live");
955 deviceChannel.setOwner("wvp-pro"); 973 deviceChannel.setOwner("wvp-pro");
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/platform/PlatformController.java
@@ -403,8 +403,12 @@ public class PlatformController { @@ -403,8 +403,12 @@ public class PlatformController {
403 if (platform == null) { 403 if (platform == null) {
404 throw new ControllerException(ErrorCode.ERROR100.getCode(), "平台未找到"); 404 throw new ControllerException(ErrorCode.ERROR100.getCode(), "平台未找到");
405 } 405 }
406 - if (platformId.equals(parentId)) {  
407 - parentId = platform.getDeviceGBId(); 406 +// if (platformId.equals(parentId)) {
  407 +// parentId = platform.getDeviceGBId();
  408 +// }
  409 +
  410 + if (platformId.equals(platform.getDeviceGBId())) {
  411 + parentId = null;
408 } 412 }
409 413
410 return storager.getChildrenCatalogByPlatform(platformId, parentId); 414 return storager.getChildrenCatalogByPlatform(platformId, parentId);
src/main/resources/all-application.yml
@@ -202,6 +202,10 @@ user-settings: @@ -202,6 +202,10 @@ user-settings:
202 device-status-notify: false 202 device-status-notify: false
203 # 上级平台点播时不使用上级平台指定的ssrc,使用自定义的ssrc,参考国标文档-点播外域设备媒体流SSRC处理方式 203 # 上级平台点播时不使用上级平台指定的ssrc,使用自定义的ssrc,参考国标文档-点播外域设备媒体流SSRC处理方式
204 use-custom-ssrc-for-parent-invite: true 204 use-custom-ssrc-for-parent-invite: true
  205 + # 国标级联离线后多久重试一次注册
  206 + register-again-after-time: 60
  207 + # 国标续订方式,true为续订,每次注册在同一个会话里,false为重新注册,每次使用新的会话
  208 + register-keep-int-dialog: false
205 # 跨域配置,配置你访问前端页面的地址即可, 可以配置多个 209 # 跨域配置,配置你访问前端页面的地址即可, 可以配置多个
206 allowed-origins: 210 allowed-origins:
207 - http://localhost:8008 211 - http://localhost:8008