优化国标级联的目录创建以及推送规则,优化接收目录规则,更加规范

This commit is contained in:
648540858 2023-06-19 18:42:36 +08:00
parent 8f5bbfa5c2
commit 8942ab0112
26 changed files with 8818 additions and 16508 deletions

View File

@ -0,0 +1,42 @@
package com.genersoft.iot.vmp.common;
public class CivilCodePo {
private String code;
private String name;
private String parentCode;
public static CivilCodePo getInstance(String[] infoArray) {
CivilCodePo civilCodePo = new CivilCodePo();
civilCodePo.setCode(infoArray[0]);
civilCodePo.setName(infoArray[1]);
civilCodePo.setParentCode(infoArray[2]);
return civilCodePo;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getParentCode() {
return parentCode;
}
public void setParentCode(String parentCode) {
this.parentCode = parentCode;
}
}

View File

@ -0,0 +1,101 @@
package com.genersoft.iot.vmp.conf;
import com.genersoft.iot.vmp.common.CivilCodePo;
import org.ehcache.impl.internal.concurrent.ConcurrentHashMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;
import org.springframework.core.annotation.Order;
import org.springframework.core.io.ClassPathResource;
import org.springframework.util.ObjectUtils;
import java.io.*;
import java.nio.file.Files;
import java.util.Map;
/**
* 启动时读取行政区划表
*/
@Configuration
@Order(value=14)
public class CivilCodeFileConf implements CommandLineRunner {
private final static Logger logger = LoggerFactory.getLogger(CivilCodeFileConf.class);
private final Map<String, CivilCodePo> civilCodeMap= new ConcurrentHashMap<>();
@Autowired
@Lazy
private UserSetting userSetting;
@Override
public void run(String... args) throws Exception {
if (ObjectUtils.isEmpty(userSetting.getCivilCodeFile())) {
logger.warn("[行政区划] 文件未设置,可能造成目录刷新结果不完整");
return;
}
InputStream inputStream;
if (userSetting.getCivilCodeFile().startsWith("classpath:")){
String filePath = userSetting.getCivilCodeFile().substring("classpath:".length());
ClassPathResource civilCodeFile = new ClassPathResource(filePath);
if (!civilCodeFile.exists()) {
logger.warn("[行政区划] 文件<{}>不存在,可能造成目录刷新结果不完整", userSetting.getCivilCodeFile());
return;
}
inputStream = civilCodeFile.getInputStream();
}else {
File civilCodeFile = new File(userSetting.getCivilCodeFile());
if (!civilCodeFile.exists()) {
logger.warn("[行政区划] 文件<{}>不存在,可能造成目录刷新结果不完整", userSetting.getCivilCodeFile());
return;
}
inputStream = Files.newInputStream(civilCodeFile.toPath());
}
BufferedReader inputStreamReader = new BufferedReader(new InputStreamReader(inputStream));
int index = -1;
String line;
while ((line = inputStreamReader.readLine()) != null) {
index ++;
if (index == 0) {
continue;
}
String[] infoArray = line.split(",");
CivilCodePo civilCodePo = CivilCodePo.getInstance(infoArray);
civilCodeMap.put(civilCodePo.getCode(), civilCodePo);
}
inputStreamReader.close();
inputStream.close();
if (civilCodeMap.size() == 0) {
logger.warn("[行政区划] 文件内容为空,可能造成目录刷新结果不完整");
}else {
logger.info("[行政区划] 加载成功,共加载数据{}条", civilCodeMap.size());
}
}
public CivilCodePo getParentCode(String code) {
if (code.length() > 8) {
return null;
}
if (code.length() == 8) {
String parentCode = code.substring(0, 6);
return civilCodeMap.get(parentCode);
}else {
CivilCodePo civilCodePo = civilCodeMap.get(code);
if (civilCodePo == null){
return null;
}
String parentCode = civilCodePo.getParentCode();
if (parentCode == null) {
return null;
}
return civilCodeMap.get(parentCode);
}
}
}

View File

@ -60,6 +60,8 @@ public class UserSetting {
private String thirdPartyGBIdReg = "[\\s\\S]*";
private String civilCodeFile = "classpath:civilCode.csv";
private List<String> interfaceAuthenticationExcludes = new ArrayList<>();
private List<String> allowedOrigins = new ArrayList<>();
@ -277,4 +279,12 @@ public class UserSetting {
public void setDeviceStatusNotify(Boolean deviceStatusNotify) {
this.deviceStatusNotify = deviceStatusNotify;
}
public String getCivilCodeFile() {
return civilCodeFile;
}
public void setCivilCodeFile(String civilCodeFile) {
this.civilCodeFile = civilCodeFile;
}
}

View File

@ -1,10 +0,0 @@
package com.genersoft.iot.vmp.gb28181.bean;
/**
* 目录结构类型
* @author lin
*/
public class TreeType {
public static final String BUSINESS_GROUP = "BusinessGroup";
public static final String CIVIL_CODE = "CivilCode";
}

View File

@ -209,59 +209,149 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
// 行政区划分组只需要这两项就可以
catalogXml.append("<DeviceID>" + channel.getChannelId() + "</DeviceID>\r\n");
catalogXml.append("<Name>" + channel.getName() + "</Name>\r\n");
if (channel.getParentId() != null) {
// 业务分组加上这一项即可提高兼容性
catalogXml.append("<ParentID>" + channel.getParentId() + "</ParentID>\r\n");
// catalogXml.append("<ParentID>" + parentPlatform.getDeviceGBId() + "/" + channel.getParentId() + "</ParentID>\r\n");
}
if (channel.getChannelId().length() == 20 && Integer.parseInt(channel.getChannelId().substring(10, 13)) == 216) {
// 虚拟组织增加BusinessGroupID字段
catalogXml.append("<BusinessGroupID>" + channel.getParentId() + "</BusinessGroupID>\r\n");
}
if (!channel.getChannelId().equals(parentPlatform.getDeviceGBId())) {
catalogXml.append("<Parental>" + channel.getParental() + "</Parental>\r\n");
if (channel.getParental() == 0) {
catalogXml.append("<Status>" + (channel.getStatus() == 0 ? "OFF" : "ON") + "</Status>\r\n");
if (channel.getChannelId().length() <= 8) {
catalogXml.append("</Item>\r\n");
continue;
}else {
if (channel.getChannelId().length() != 20) {
continue;
}
}
if (channel.getParental() == 0) {
// 通道项
catalogXml.append("<Manufacturer>" + channel.getManufacture() + "</Manufacturer>\r\n");
catalogXml.append("<Secrecy>" + channel.getSecrecy() + "</Secrecy>\r\n");
catalogXml.append("<RegisterWay>" + channel.getRegisterWay() + "</RegisterWay>\r\n");
String civilCode = channel.getCivilCode() == null?parentPlatform.getAdministrativeDivision() : channel.getCivilCode();
if (channel.getChannelType() != 2) { // 业务分组/虚拟组织/行政区划 不设置以下属性
catalogXml.append("<Model>" + channel.getModel() + "</Model>\r\n");
catalogXml.append("<Owner>" + parentPlatform.getDeviceGBId()+ "</Owner>\r\n");
catalogXml.append("<CivilCode>" + civilCode + "</CivilCode>\r\n");
if (channel.getAddress() == null) {
catalogXml.append("<Address></Address>\r\n");
}else {
catalogXml.append("<Address>" + channel.getAddress() + "</Address>\r\n");
}
catalogXml.append("<Block>" + channel.getBlock() + "</Block>\r\n");
catalogXml.append("<SafetyWay>" + channel.getSafetyWay() + "</SafetyWay>\r\n");
catalogXml.append("<CertNum>" + channel.getCertNum() + "</CertNum>\r\n");
catalogXml.append("<Certifiable>" + channel.getCertifiable() + "</Certifiable>\r\n");
catalogXml.append("<ErrCode>" + channel.getErrCode() + "</ErrCode>\r\n");
catalogXml.append("<EndTime>" + channel.getEndTime() + "</EndTime>\r\n");
catalogXml.append("<Secrecy>" + channel.getSecrecy() + "</Secrecy>\r\n");
catalogXml.append("<IPAddress>" + channel.getIpAddress() + "</IPAddress>\r\n");
catalogXml.append("<Port>" + channel.getPort() + "</Port>\r\n");
catalogXml.append("<Password>" + channel.getPort() + "</Password>\r\n");
catalogXml.append("<PTZType>" + channel.getPTZType() + "</PTZType>\r\n");
catalogXml.append("<Status>" + (channel.getStatus() == 1?"ON":"OFF") + "</Status>\r\n");
catalogXml.append("<Longitude>" +
(channel.getLongitudeWgs84() != 0? channel.getLongitudeWgs84():channel.getLongitude())
+ "</Longitude>\r\n");
catalogXml.append("<Latitude>" +
(channel.getLatitudeWgs84() != 0? channel.getLatitudeWgs84():channel.getLatitude())
+ "</Latitude>\r\n");
switch (Integer.parseInt(channel.getChannelId().substring(10, 13))){
case 200:
// catalogXml.append("<Manufacturer>三永华通</Manufacturer>\r\n");
// GitUtil gitUtil = SpringBeanFactory.getBean("gitUtil");
// String model = (gitUtil == null || gitUtil.getBuildVersion() == null)?"1.0": gitUtil.getBuildVersion();
// catalogXml.append("<Model>" + model + "</Manufacturer>\r\n");
// catalogXml.append("<Owner>三永华通</Owner>\r\n");
if (channel.getCivilCode() != null) {
catalogXml.append("<CivilCode>"+channel.getCivilCode()+"</CivilCode>\r\n");
}else {
catalogXml.append("<CivilCode></CivilCode>\r\n");
}
catalogXml.append("<RegisterWay>1</RegisterWay>\r\n");
catalogXml.append("<Secrecy>0</Secrecy>\r\n");
break;
case 215:
if (!ObjectUtils.isEmpty(channel.getParentId())) {
catalogXml.append("<ParentID>" + channel.getParentId() + "</ParentID>\r\n");
}
break;
case 216:
if (!ObjectUtils.isEmpty(channel.getParentId())) {
catalogXml.append("<ParentID>" + channel.getParentId() + "</ParentID>\r\n");
}else {
catalogXml.append("<ParentID></ParentID>\r\n");
}
if (!ObjectUtils.isEmpty(channel.getBusinessGroupId())) {
catalogXml.append("<BusinessGroupID>" + channel.getBusinessGroupId() + "</BusinessGroupID>\r\n");
}else {
catalogXml.append("<BusinessGroupID></BusinessGroupID>\r\n");
}
break;
default:
// 通道项
if (channel.getManufacture() != null) {
catalogXml.append("<Manufacturer>" + channel.getManufacture() + "</Manufacturer>\r\n");
}else {
catalogXml.append("<Manufacturer></Manufacturer>\r\n");
}
if (channel.getSecrecy() != null) {
catalogXml.append("<Secrecy>" + channel.getSecrecy() + "</Secrecy>\r\n");
}else {
catalogXml.append("<Secrecy></Secrecy>\r\n");
}
catalogXml.append("<RegisterWay>" + channel.getRegisterWay() + "</RegisterWay>\r\n");
if (channel.getModel() != null) {
catalogXml.append("<Model>" + channel.getModel() + "</Model>\r\n");
}else {
catalogXml.append("<Model></Model>\r\n");
}
if (channel.getOwner() != null) {
catalogXml.append("<Owner>" + channel.getOwner()+ "</Owner>\r\n");
}else {
catalogXml.append("<Owner></Owner>\r\n");
}
if (channel.getCivilCode() != null) {
catalogXml.append("<CivilCode>" + channel.getCivilCode() + "</CivilCode>\r\n");
}else {
catalogXml.append("<CivilCode></CivilCode>\r\n");
}
if (channel.getAddress() == null) {
catalogXml.append("<Address></Address>\r\n");
}else {
catalogXml.append("<Address>" + channel.getAddress() + "</Address>\r\n");
}
if (!ObjectUtils.isEmpty(channel.getParentId())) {
catalogXml.append("<ParentID>" + channel.getParentId() + "</ParentID>\r\n");
}else {
catalogXml.append("<ParentID></ParentID>\r\n");
}
if (!ObjectUtils.isEmpty(channel.getBlock())) {
catalogXml.append("<Block>" + channel.getBlock() + "</Block>\r\n");
}else {
catalogXml.append("<Block></Block>\r\n");
}
if (!ObjectUtils.isEmpty(channel.getSafetyWay())) {
catalogXml.append("<SafetyWay>" + channel.getSafetyWay() + "</SafetyWay>\r\n");
}else {
catalogXml.append("<SafetyWay></SafetyWay>\r\n");
}
if (!ObjectUtils.isEmpty(channel.getCertNum())) {
catalogXml.append("<CertNum>" + channel.getCertNum() + "</CertNum>\r\n");
}else {
catalogXml.append("<CertNum></CertNum>\r\n");
}
if (!ObjectUtils.isEmpty(channel.getCertifiable())) {
catalogXml.append("<Certifiable>" + channel.getCertifiable() + "</Certifiable>\r\n");
}else {
catalogXml.append("<Certifiable></Certifiable>\r\n");
}
if (!ObjectUtils.isEmpty(channel.getErrCode())) {
catalogXml.append("<ErrCode>" + channel.getErrCode() + "</ErrCode>\r\n");
}else {
catalogXml.append("<ErrCode></ErrCode>\r\n");
}
if (!ObjectUtils.isEmpty(channel.getEndTime())) {
catalogXml.append("<EndTime>" + channel.getEndTime() + "</EndTime>\r\n");
}else {
catalogXml.append("<EndTime></EndTime>\r\n");
}
if (!ObjectUtils.isEmpty(channel.getSecrecy())) {
catalogXml.append("<Secrecy>" + channel.getSecrecy() + "</Secrecy>\r\n");
}else {
catalogXml.append("<Secrecy></Secrecy>\r\n");
}
if (!ObjectUtils.isEmpty(channel.getIpAddress())) {
catalogXml.append("<IPAddress>" + channel.getIpAddress() + "</IPAddress>\r\n");
}else {
catalogXml.append("<IPAddress></IPAddress>\r\n");
}
catalogXml.append("<Port>" + channel.getPort() + "</Port>\r\n");
if (!ObjectUtils.isEmpty(channel.getPassword())) {
catalogXml.append("<Password>" + channel.getPassword() + "</Password>\r\n");
}else {
catalogXml.append("<Password></Password>\r\n");
}
if (!ObjectUtils.isEmpty(channel.getPTZType())) {
catalogXml.append("<PTZType>" + channel.getPTZType() + "</PTZType>\r\n");
}else {
catalogXml.append("<PTZType></PTZType>\r\n");
}
catalogXml.append("<Status>" + (channel.getStatus() == 1?"ON":"OFF") + "</Status>\r\n");
catalogXml.append("<Longitude>" +
(channel.getLongitudeWgs84() != 0? channel.getLongitudeWgs84():channel.getLongitude())
+ "</Longitude>\r\n");
catalogXml.append("<Latitude>" +
(channel.getLatitudeWgs84() != 0? channel.getLatitudeWgs84():channel.getLatitude())
+ "</Latitude>\r\n");
break;
}
catalogXml.append("</Item>\r\n");
}
catalogXml.append("</Item>\r\n");
}
}

View File

@ -191,6 +191,8 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
logger.error("[命令发送失败] invite GONE: {}", e.getMessage());
}
return;
}else {
// TODO 可能漏回复消息
}
}
} else {

View File

@ -1,5 +1,6 @@
package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl;
import com.genersoft.iot.vmp.conf.CivilCodeFileConf;
import com.genersoft.iot.vmp.conf.DynamicTask;
import com.genersoft.iot.vmp.conf.UserSetting;
import com.genersoft.iot.vmp.gb28181.bean.Device;
@ -20,7 +21,10 @@ import org.springframework.stereotype.Component;
import javax.sip.RequestEvent;
import javax.sip.header.FromHeader;
import java.util.*;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
@ -56,6 +60,9 @@ public class NotifyRequestForCatalogProcessor extends SIPRequestProcessorParent
@Autowired
private DynamicTask dynamicTask;
@Autowired
private CivilCodeFileConf civilCodeFileConf;
private final static String talkKey = "notify-request-for-catalog-task";
public void process(RequestEvent evt) {
@ -96,7 +103,7 @@ public class NotifyRequestForCatalogProcessor extends SIPRequestProcessorParent
}else {
event = eventElement.getText().toUpperCase();
}
DeviceChannel channel = XmlUtil.channelContentHander(itemDevice, device, event);
DeviceChannel channel = XmlUtil.channelContentHandler(itemDevice, device, event, civilCodeFileConf);
channel.setDeviceId(device.getDeviceId());
logger.info("[收到目录订阅]{}/{}", device.getDeviceId(), channel.getChannelId());

View File

@ -1,6 +1,7 @@
package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl;
import com.alibaba.fastjson2.JSONObject;
import com.genersoft.iot.vmp.conf.CivilCodeFileConf;
import com.genersoft.iot.vmp.conf.SipConfig;
import com.genersoft.iot.vmp.conf.UserSetting;
import com.genersoft.iot.vmp.gb28181.bean.*;
@ -79,6 +80,9 @@ public class NotifyRequestProcessor extends SIPRequestProcessorParent implements
@Autowired
private NotifyRequestForCatalogProcessor notifyRequestForCatalogProcessor;
@Autowired
private CivilCodeFileConf civilCodeFileConf;
private ConcurrentLinkedQueue<HandlerCatchData> taskQueue = new ConcurrentLinkedQueue<>();
@Qualifier("taskExecutor")
@ -403,7 +407,7 @@ public class NotifyRequestProcessor extends SIPRequestProcessorParent implements
}else {
event = eventElement.getText().toUpperCase();
}
DeviceChannel channel = XmlUtil.channelContentHander(itemDevice, device, event);
DeviceChannel channel = XmlUtil.channelContentHandler(itemDevice, device, event, civilCodeFileConf);
channel.setDeviceId(device.getDeviceId());
logger.info("[收到目录订阅]{}/{}", device.getDeviceId(), channel.getChannelId());
switch (event) {

View File

@ -1,5 +1,6 @@
package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.response.cmd;
import com.genersoft.iot.vmp.conf.CivilCodeFileConf;
import com.genersoft.iot.vmp.gb28181.bean.*;
import com.genersoft.iot.vmp.gb28181.session.CatalogDataCatch;
import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent;
@ -53,6 +54,9 @@ public class CatalogResponseMessageHandler extends SIPRequestProcessorParent imp
@Autowired
private ThreadPoolTaskExecutor taskExecutor;
@Autowired
private CivilCodeFileConf civilCodeFileConf;
@Override
public void afterPropertiesSet() throws Exception {
responseMessageHandler.addHandler(cmdType, this);
@ -100,6 +104,7 @@ public class CatalogResponseMessageHandler extends SIPRequestProcessorParent imp
Iterator<Element> deviceListIterator = deviceListElement.elementIterator();
if (deviceListIterator != null) {
List<DeviceChannel> channelList = new ArrayList<>();
List<String> parentChannelIds = new ArrayList<>();
// 遍历DeviceList
while (deviceListIterator.hasNext()) {
Element itemDevice = deviceListIterator.next();
@ -107,7 +112,7 @@ public class CatalogResponseMessageHandler extends SIPRequestProcessorParent imp
if (channelDeviceElement == null) {
continue;
}
DeviceChannel deviceChannel = XmlUtil.channelContentHander(itemDevice, device, null);
DeviceChannel deviceChannel = XmlUtil.channelContentHandler(itemDevice, device, null, civilCodeFileConf);
deviceChannel = SipUtils.updateGps(deviceChannel, device.getGeoCoordSys());
deviceChannel.setDeviceId(take.getDevice().getDeviceId());

View File

@ -2,6 +2,8 @@ package com.genersoft.iot.vmp.gb28181.utils;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.genersoft.iot.vmp.common.CivilCodePo;
import com.genersoft.iot.vmp.conf.CivilCodeFileConf;
import com.genersoft.iot.vmp.gb28181.bean.Device;
import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
import com.genersoft.iot.vmp.gb28181.event.subscribe.catalog.CatalogEvent;
@ -192,7 +194,7 @@ public class XmlUtil {
CivilCode, BusinessGroup,VirtualOrganization,Other
}
public static DeviceChannel channelContentHander(Element itemDevice, Device device, String event){
public static DeviceChannel channelContentHandler(Element itemDevice, Device device, String event, CivilCodeFileConf civilCodeFileConf){
DeviceChannel deviceChannel = new DeviceChannel();
deviceChannel.setDeviceId(device.getDeviceId());
Element channdelIdElement = itemDevice.element("DeviceID");
@ -210,208 +212,353 @@ public class XmlUtil {
// 除了ADD和update情况下需要识别全部内容
return deviceChannel;
}
ChannelType channelType = ChannelType.Other;
if (channelId.length() <= 8) {
channelType = ChannelType.CivilCode;
Element nameElement = itemDevice.element("Name");
if (nameElement != null) {
deviceChannel.setName(nameElement.getText());
}
if(channelId.length() <= 8) {
deviceChannel.setHasAudio(false);
}else {
if (channelId.length() == 20) {
int code = Integer.parseInt(channelId.substring(10, 13));
switch (code){
case 215:
channelType = ChannelType.BusinessGroup;
deviceChannel.setHasAudio(false);
break;
case 216:
channelType = ChannelType.VirtualOrganization;
deviceChannel.setHasAudio(false);
break;
case 136:
case 137:
case 138:
deviceChannel.setHasAudio(true);
break;
default:
deviceChannel.setHasAudio(false);
break;
}
}
}
Element channdelNameElement = itemDevice.element("Name");
String channelName = channdelNameElement != null ? channdelNameElement.getTextTrim() : "";
deviceChannel.setName(channelName);
String civilCode = XmlUtil.getText(itemDevice, "CivilCode");
deviceChannel.setCivilCode(civilCode);
if (channelType == ChannelType.CivilCode && civilCode == null) {
deviceChannel.setParental(1);
// 行政区划如果没有传递具体值则推测一个
if (channelId.length() > 2) {
deviceChannel.setCivilCode(channelId.substring(0, channelId.length() - 2));
}
}
if (channelType.equals(ChannelType.CivilCode)) {
// 行政区划其他字段没必要识别了默认在线即可
deviceChannel.setStatus(1);
deviceChannel.setParental(1);
deviceChannel.setCreateTime(DateUtil.getNow());
deviceChannel.setUpdateTime(DateUtil.getNow());
return deviceChannel;
}
/**
* 行政区划展示设备树与业务分组展示设备树是两种不同的模式
* 行政区划展示设备树 各个目录之间主要靠deviceId做关联,摄像头通过CivilCode指定其属于那个行政区划;都是不超过十位的编号; 结构如下:
* 河北省
* --> 石家庄市
* --> 摄像头
*String parentId = XmlUtil.getText(itemDevice, "ParentID");
if (parentId != null) {
if (parentId.contains("/")) {
String lastParentId = parentId.substring(parentId.lastIndexOf("/") + 1);
String businessGroup = parentId.substring(0, parentId.indexOf("/"));
deviceChannel.setParentId(lastParentId);
}else {
deviceChannel.setParentId(parentId);
}
}
deviceCh --> 正定县
* --> 摄像头
* --> 摄像头
*
* 业务分组展示设备树是顶级是业务分组,其下的虚拟组织靠BusinessGroupID指定其所属的业务分组;摄像头通过ParentId来指定其所属于的虚拟组织:
* 业务分组
* --> 虚拟组织
* --> 摄像头
* --> 虚拟组织
* --> 摄像头
* --> 摄像头
*/
String parentId = XmlUtil.getText(itemDevice, "ParentID");
String businessGroupID = XmlUtil.getText(itemDevice, "BusinessGroupID");
if (parentId != null) {
if (parentId.contains("/")) {
String lastParentId = parentId.substring(parentId.lastIndexOf("/") + 1);
if (businessGroupID == null) {
businessGroupID = parentId.substring(0, parentId.indexOf("/"));
}
deviceChannel.setParentId(lastParentId);
CivilCodePo parentCode = civilCodeFileConf.getParentCode(channelId);
if (parentCode != null) {
deviceChannel.setParentId(parentCode.getCode());
deviceChannel.setCivilCode(parentCode.getCode());
}else {
deviceChannel.setParentId(parentId);
logger.warn("[xml解析] 无法确定行政区划{}的上级行政区划", channelId);
}
// 兼容设备通道信息中自己为自己父节点的情况
if (deviceChannel.getParentId().equals(deviceChannel.getChannelId())) {
deviceChannel.setParentId(null);
}
}
deviceChannel.setBusinessGroupId(businessGroupID);
if (channelType.equals(ChannelType.BusinessGroup) || channelType.equals(ChannelType.VirtualOrganization)) {
// 业务分组和虚拟组织 其他字段没必要识别了默认在线即可
deviceChannel.setStatus(1);
deviceChannel.setParental(1);
deviceChannel.setCreateTime(DateUtil.getNow());
deviceChannel.setUpdateTime(DateUtil.getNow());
return deviceChannel;
}
Element statusElement = itemDevice.element("Status");
if (statusElement != null) {
String status = statusElement.getTextTrim().trim();
// ONLINE OFFLINE HIKVISION DS-7716N-E4 NVR的兼容性处理
if (status.equals("ON") || status.equals("On") || status.equals("ONLINE") || status.equals("OK")) {
deviceChannel.setStatus(1);
}
if (status.equals("OFF") || status.equals("Off") || status.equals("OFFLINE")) {
deviceChannel.setStatus(0);
}
}else {
deviceChannel.setStatus(1);
}
// 识别自带的目录标识
String parental = XmlUtil.getText(itemDevice, "Parental");
// 由于海康会错误的发送65535作为这里的取值,所以这里除非是0否则认为是1
if (!ObjectUtils.isEmpty(parental) && parental.length() == 1 && Integer.parseInt(parental) == 0) {
deviceChannel.setParental(0);
}else {
deviceChannel.setParental(1);
}
deviceChannel.setManufacture(XmlUtil.getText(itemDevice, "Manufacturer"));
deviceChannel.setModel(XmlUtil.getText(itemDevice, "Model"));
deviceChannel.setOwner(XmlUtil.getText(itemDevice, "Owner"));
deviceChannel.setCertNum(XmlUtil.getText(itemDevice, "CertNum"));
deviceChannel.setBlock(XmlUtil.getText(itemDevice, "Block"));
deviceChannel.setAddress(XmlUtil.getText(itemDevice, "Address"));
deviceChannel.setPassword(XmlUtil.getText(itemDevice, "Password"));
String safetyWay = XmlUtil.getText(itemDevice, "SafetyWay");
if (ObjectUtils.isEmpty(safetyWay)) {
deviceChannel.setSafetyWay(0);
} else {
deviceChannel.setSafetyWay(Integer.parseInt(safetyWay));
}
String registerWay = XmlUtil.getText(itemDevice, "RegisterWay");
if (ObjectUtils.isEmpty(registerWay)) {
deviceChannel.setRegisterWay(1);
} else {
deviceChannel.setRegisterWay(Integer.parseInt(registerWay));
}
if (XmlUtil.getText(itemDevice, "Certifiable") == null
|| XmlUtil.getText(itemDevice, "Certifiable") == "") {
deviceChannel.setCertifiable(0);
} else {
deviceChannel.setCertifiable(Integer.parseInt(XmlUtil.getText(itemDevice, "Certifiable")));
}
if (XmlUtil.getText(itemDevice, "ErrCode") == null
|| XmlUtil.getText(itemDevice, "ErrCode") == "") {
deviceChannel.setErrCode(0);
} else {
deviceChannel.setErrCode(Integer.parseInt(XmlUtil.getText(itemDevice, "ErrCode")));
}
deviceChannel.setEndTime(XmlUtil.getText(itemDevice, "EndTime"));
deviceChannel.setSecrecy(XmlUtil.getText(itemDevice, "Secrecy"));
deviceChannel.setIpAddress(XmlUtil.getText(itemDevice, "IPAddress"));
if (XmlUtil.getText(itemDevice, "Port") == null || XmlUtil.getText(itemDevice, "Port") == "") {
deviceChannel.setPort(0);
} else {
deviceChannel.setPort(Integer.parseInt(XmlUtil.getText(itemDevice, "Port")));
}
String longitude = XmlUtil.getText(itemDevice, "Longitude");
if (NumericUtil.isDouble(longitude)) {
deviceChannel.setLongitude(Double.parseDouble(longitude));
} else {
deviceChannel.setLongitude(0.00);
}
String latitude = XmlUtil.getText(itemDevice, "Latitude");
if (NumericUtil.isDouble(latitude)) {
deviceChannel.setLatitude(Double.parseDouble(latitude));
} else {
deviceChannel.setLatitude(0.00);
}
deviceChannel.setGpsTime(DateUtil.getNow());
if (XmlUtil.getText(itemDevice, "PTZType") == null || "".equals(XmlUtil.getText(itemDevice, "PTZType"))) {
//兼容INFO中的信息
Element info = itemDevice.element("Info");
if(XmlUtil.getText(info, "PTZType") == null || "".equals(XmlUtil.getText(info, "PTZType"))){
deviceChannel.setPTZType(0);
}else{
deviceChannel.setPTZType(Integer.parseInt(XmlUtil.getText(info, "PTZType")));
if(channelId.length() != 20) {
logger.warn("[xml解析] 失败编号不符合国标28181定义 {}", channelId);
return null;
}
int code = Integer.parseInt(channelId.substring(10, 13));
if (code == 136 || code == 137 || code == 138) {
deviceChannel.setHasAudio(true);
}else {
deviceChannel.setHasAudio(false);
}
// 设备厂商
String manufacturer = getText(itemDevice, "Manufacturer");
// 设备型号
String model = getText(itemDevice, "Model");
// 设备归属
String owner = getText(itemDevice, "Owner");
// 行政区域
String civilCode = getText(itemDevice, "CivilCode");
// 虚拟组织所属的业务分组ID,业务分组根据特定的业务需求制定,一个业务分组包含一组特定的虚拟组织
String businessGroupID = getText(itemDevice, "BusinessGroupID");
// 父设备/区域/系统ID
String parentID = getText(itemDevice, "ParentID");
if (parentID != null && parentID.equalsIgnoreCase("null")) {
parentID = null;
}
// 注册方式(必选)缺省为1;1:符合IETFRFC3261标准的认证注册模式;2:基于口令的双向认证注册模式;3:基于数字证书的双向认证注册模式
String registerWay = getText(itemDevice, "RegisterWay");
// 保密属性(必选)缺省为0;0:不涉密,1:涉密
String secrecy = getText(itemDevice, "Secrecy");
// 安装地址
String address = getText(itemDevice, "Address");
switch (code){
case 200:
// 系统目录
if (!ObjectUtils.isEmpty(manufacturer)) {
deviceChannel.setManufacture(manufacturer);
}
if (!ObjectUtils.isEmpty(model)) {
deviceChannel.setModel(model);
}
if (!ObjectUtils.isEmpty(owner)) {
deviceChannel.setOwner(owner);
}
if (!ObjectUtils.isEmpty(civilCode)) {
deviceChannel.setCivilCode(civilCode);
deviceChannel.setParentId(civilCode);
}else {
if (!ObjectUtils.isEmpty(parentID)) {
deviceChannel.setParentId(parentID);
}
}
if (!ObjectUtils.isEmpty(address)) {
deviceChannel.setAddress(address);
}
deviceChannel.setStatus(1);
if (!ObjectUtils.isEmpty(registerWay)) {
try {
deviceChannel.setRegisterWay(Integer.parseInt(registerWay));
}catch (NumberFormatException exception) {
logger.warn("[xml解析] 从通道数据获取registerWay失败 {}", registerWay);
}
}
if (!ObjectUtils.isEmpty(secrecy)) {
deviceChannel.setSecrecy(secrecy);
}
return deviceChannel;
case 215:
// 业务分组
deviceChannel.setStatus(1);
if (!ObjectUtils.isEmpty(parentID)) {
if (!parentID.trim().equalsIgnoreCase(device.getDeviceId())) {
deviceChannel.setParentId(parentID);
}
}else {
logger.warn("[xml解析] 业务分组数据中缺少关键信息->ParentId");
if (!ObjectUtils.isEmpty(civilCode)) {
deviceChannel.setCivilCode(civilCode);
}
}
break;
case 216:
// 虚拟组织
deviceChannel.setStatus(1);
if (!ObjectUtils.isEmpty(businessGroupID)) {
deviceChannel.setBusinessGroupId(businessGroupID);
}
if (!ObjectUtils.isEmpty(parentID)) {
if (parentID.contains("/")) {
String[] parentIdArray = parentID.split("/");
parentID = parentIdArray[parentIdArray.length - 1];
}
deviceChannel.setParentId(parentID);
}else {
if (!ObjectUtils.isEmpty(businessGroupID)) {
deviceChannel.setParentId(businessGroupID);
}
}
break;
default:
// 设备目录
if (!ObjectUtils.isEmpty(manufacturer)) {
deviceChannel.setManufacture(manufacturer);
}
if (!ObjectUtils.isEmpty(model)) {
deviceChannel.setModel(model);
}
if (!ObjectUtils.isEmpty(owner)) {
deviceChannel.setOwner(owner);
}
if (!ObjectUtils.isEmpty(civilCode)) {
deviceChannel.setCivilCode(civilCode);
}
if (!ObjectUtils.isEmpty(businessGroupID)) {
deviceChannel.setBusinessGroupId(businessGroupID);
}
// 警区
String block = getText(itemDevice, "Block");
if (!ObjectUtils.isEmpty(block)) {
deviceChannel.setBlock(block);
}
if (!ObjectUtils.isEmpty(address)) {
deviceChannel.setAddress(address);
}
if (!ObjectUtils.isEmpty(secrecy)) {
deviceChannel.setSecrecy(secrecy);
}
// 当为设备时,是否有子设备(必选)1有,0没有
String parental = getText(itemDevice, "Parental");
if (!ObjectUtils.isEmpty(parental)) {
try {
// 由于海康会错误的发送65535作为这里的取值,所以这里除非是0否则认为是1
if (!ObjectUtils.isEmpty(parental) && parental.length() == 1 && Integer.parseInt(parental) == 0) {
deviceChannel.setParental(0);
}else {
deviceChannel.setParental(1);
}
}catch (NumberFormatException e) {
logger.warn("[xml解析] 从通道数据获取 parental失败 {}", parental);
}
}
// 父设备/区域/系统ID
String realParentId = parentID;
if (!ObjectUtils.isEmpty(parentID)) {
if (parentID.contains("/")) {
String[] parentIdArray = parentID.split("/");
realParentId = parentIdArray[parentIdArray.length - 1];
}
deviceChannel.setParentId(realParentId);
}else {
if (!ObjectUtils.isEmpty(businessGroupID)) {
deviceChannel.setParentId(businessGroupID);
}else {
if (!ObjectUtils.isEmpty(civilCode)) {
deviceChannel.setParentId(civilCode);
}
}
}
// 注册方式
if (!ObjectUtils.isEmpty(registerWay)) {
try {
int registerWayInt = Integer.parseInt(registerWay);
deviceChannel.setRegisterWay(registerWayInt);
}catch (NumberFormatException exception) {
logger.warn("[xml解析] 从通道数据获取registerWay失败 {}", registerWay);
deviceChannel.setRegisterWay(1);
}
}else {
deviceChannel.setRegisterWay(1);
}
// 信令安全模式(可选)缺省为0; 0:不采用;2:S/MIME 签名方式;3:S/MIME加密签名同时采用方式;4:数字摘要方式
String safetyWay = getText(itemDevice, "SafetyWay");
if (!ObjectUtils.isEmpty(safetyWay)) {
try {
deviceChannel.setSafetyWay(Integer.parseInt(safetyWay));
}catch (NumberFormatException e) {
logger.warn("[xml解析] 从通道数据获取 safetyWay失败 {}", safetyWay);
}
}
// 证书序列号(有证书的设备必选)
String certNum = getText(itemDevice, "CertNum");
if (!ObjectUtils.isEmpty(certNum)) {
deviceChannel.setCertNum(certNum);
}
// 证书有效标识(有证书的设备必选)缺省为0;证书有效标识:0:无效 1:有效
String certifiable = getText(itemDevice, "Certifiable");
if (!ObjectUtils.isEmpty(certifiable)) {
try {
deviceChannel.setCertifiable(Integer.parseInt(certifiable));
}catch (NumberFormatException e) {
logger.warn("[xml解析] 从通道数据获取 Certifiable失败 {}", certifiable);
}
}
// 无效原因码(有证书且证书无效的设备必选)
String errCode = getText(itemDevice, "ErrCode");
if (!ObjectUtils.isEmpty(errCode)) {
try {
deviceChannel.setErrCode(Integer.parseInt(errCode));
}catch (NumberFormatException e) {
logger.warn("[xml解析] 从通道数据获取 ErrCode失败 {}", errCode);
}
}
// 证书终止有效期(有证书的设备必选)
String endTime = getText(itemDevice, "EndTime");
if (!ObjectUtils.isEmpty(endTime)) {
deviceChannel.setEndTime(endTime);
}
// 设备/区域/系统IP地址
String ipAddress = getText(itemDevice, "IPAddress");
if (!ObjectUtils.isEmpty(ipAddress)) {
deviceChannel.setIpAddress(ipAddress);
}
// 设备/区域/系统端口
String port = getText(itemDevice, "Port");
if (!ObjectUtils.isEmpty(port)) {
try {
deviceChannel.setPort(Integer.parseInt(port));
}catch (NumberFormatException e) {
logger.warn("[xml解析] 从通道数据获取 Port失败 {}", port);
}
}
// 设备口令
String password = getText(itemDevice, "Password");
if (!ObjectUtils.isEmpty(password)) {
deviceChannel.setPassword(password);
}
// 设备状态
String status = getText(itemDevice, "Status");
if (status != null) {
// ONLINE OFFLINE HIKVISION DS-7716N-E4 NVR的兼容性处理
if (status.equals("ON") || status.equals("On") || status.equals("ONLINE") || status.equals("OK")) {
deviceChannel.setStatus(1);
}
if (status.equals("OFF") || status.equals("Off") || status.equals("OFFLINE")) {
deviceChannel.setStatus(0);
}
}else {
deviceChannel.setStatus(1);
}
// 经度
String longitude = getText(itemDevice, "Longitude");
if (NumericUtil.isDouble(longitude)) {
deviceChannel.setLongitude(Double.parseDouble(longitude));
} else {
deviceChannel.setLongitude(0.00);
}
// 纬度
String latitude = getText(itemDevice, "Latitude");
if (NumericUtil.isDouble(latitude)) {
deviceChannel.setLatitude(Double.parseDouble(latitude));
} else {
deviceChannel.setLatitude(0.00);
}
deviceChannel.setGpsTime(DateUtil.getNow());
// -摄像机类型扩展,标识摄像机类型:1-球机;2-半球;3-固定枪机;4-遥控枪机当目录项为摄像机时可选
String ptzType = getText(itemDevice, "PTZType");
if (ObjectUtils.isEmpty(ptzType)) {
//兼容INFO中的信息
Element info = itemDevice.element("Info");
String ptzTypeFromInfo = XmlUtil.getText(info, "PTZType");
if(!ObjectUtils.isEmpty(ptzTypeFromInfo)){
try {
deviceChannel.setPTZType(Integer.parseInt(ptzTypeFromInfo));
}catch (NumberFormatException e){
logger.warn("[xml解析] 从通道数据info中获取PTZType失败 {}", ptzTypeFromInfo);
}
}
} else {
try {
deviceChannel.setPTZType(Integer.parseInt(ptzType));
}catch (NumberFormatException e){
logger.warn("[xml解析] 从通道数据中获取PTZType失败 {}", ptzType);
}
}
// TODO 摄像机位置类型扩展
// 1-省际检查站
// 2-党政机关
// 3-车站码头
// 4-中心广场
// 5-体育场馆
// 6-商业中心
// 7-宗教场所
// 8-校园周边
// 9-治安复杂区域
// 10-交通干线
// String positionType = getText(itemDevice, "PositionType");
// TODO 摄像机安装位置室外室内属性1-室外2-室内
// String roomType = getText(itemDevice, "RoomType");
// TODO 摄像机用途属性
// String useType = getText(itemDevice, "UseType");
// TODO 摄像机补光属性1-无补光2-红外补光3-白光补光
// String supplyLightType = getText(itemDevice, "SupplyLightType");
// TODO 摄像机监视方位属性1-2-西3-4-5-东南6-东北7-西南8-西北
// String directionType = getText(itemDevice, "DirectionType");
// TODO 摄像机支持的分辨率,可有多个分辨率值,各个取值间以/分隔分辨率取值参见附录 F中SDPf字段规定
// String resolution = getText(itemDevice, "Resolution");
// TODO 下载倍速范围(可选),各可选参数以/分隔,如设备支持1,2,4倍速下载则应写为1/2/4
// String downloadSpeed = getText(itemDevice, "DownloadSpeed");
// TODO 空域编码能力,取值0:不支持;1:1级增强(1个增强层);2:2级增强(2个增强层);3:3级增强(3个增强层)
// String svcSpaceSupportMode = getText(itemDevice, "SVCSpaceSupportMode");
// TODO 时域编码能力,取值0:不支持;1:1级增强;2:2级增强;3:3级增强
// String svcTimeSupportMode = getText(itemDevice, "SVCTimeSupportMode");
deviceChannel.setSecrecy(secrecy);
break;
}
} else {
deviceChannel.setPTZType(Integer.parseInt(XmlUtil.getText(itemDevice, "PTZType")));
}
return deviceChannel;

View File

@ -45,8 +45,6 @@ public class DeviceChannelServiceImpl implements IDeviceChannelService {
device = deviceMapper.getDeviceByDeviceId(deviceChannel.getDeviceId());
}
if ("WGS84".equals(device.getGeoCoordSys())) {
deviceChannel.setLongitudeWgs84(deviceChannel.getLongitude());
deviceChannel.setLatitudeWgs84(deviceChannel.getLatitude());
@ -252,4 +250,6 @@ public class DeviceChannelServiceImpl implements IDeviceChannelService {
}
}
}
}

View File

@ -376,63 +376,11 @@ public class DeviceServiceImpl implements IDeviceService {
if (device == null) {
return null;
}
if (parentId == null || parentId.equals(deviceId)) {
// 字根节点开始查询
List<DeviceChannel> rootNodes = getRootNodes(deviceId, TreeType.CIVIL_CODE.equals(device.getTreeType()), true, !onlyCatalog);
return transportChannelsToTree(rootNodes, "");
if (ObjectUtils.isEmpty(parentId) || parentId.equals(deviceId)) {
parentId = null;
}
if (TreeType.CIVIL_CODE.equals(device.getTreeType())) {
if (parentId.length()%2 != 0) {
return null;
}
// 使用行政区划展示树
// if (parentId.length() > 10) {
// // TODO 可能是行政区划与业务分组混杂的情形
// return null;
// }
if (parentId.length() == 10 ) {
if (onlyCatalog) {
return null;
}
// parentId为行业编码 其下不会再有行政区划
List<DeviceChannel> channels = deviceChannelMapper.getChannelsByCivilCode(deviceId, parentId);
List<BaseTree<DeviceChannel>> trees = transportChannelsToTree(channels, parentId);
return trees;
}
// 查询其下的行政区划和摄像机
List<DeviceChannel> channelsForCivilCode = deviceChannelMapper.getChannelsWithCivilCodeAndLength(deviceId, parentId, parentId.length() + 2);
if (!onlyCatalog) {
List<DeviceChannel> channels = deviceChannelMapper.getChannelsByCivilCode(deviceId, parentId);
for(DeviceChannel channel : channels) {
boolean flag = false;
for(DeviceChannel deviceChannel : channelsForCivilCode) {
if(channel.getChannelId().equals(deviceChannel.getChannelId())) {
flag = true;
}
}
if(!flag) {
channelsForCivilCode.add(channel);
}
}
}
List<BaseTree<DeviceChannel>> trees = transportChannelsToTree(channelsForCivilCode, parentId);
return trees;
}
// 使用业务分组展示树
if (TreeType.BUSINESS_GROUP.equals(device.getTreeType())) {
if (parentId.length() < 14 ) {
return null;
}
List<DeviceChannel> deviceChannels = deviceChannelMapper.queryChannels(deviceId, parentId, null, null, null,null);
List<BaseTree<DeviceChannel>> trees = transportChannelsToTree(deviceChannels, parentId);
return trees;
}
return null;
List<DeviceChannel> rootNodes = deviceChannelMapper.getSubChannelsByDeviceId(deviceId, parentId, onlyCatalog);
return transportChannelsToTree(rootNodes, "");
}
@Override
@ -441,42 +389,11 @@ public class DeviceServiceImpl implements IDeviceService {
if (device == null) {
return null;
}
if (parentId == null || parentId.equals(deviceId)) {
// 字根节点开始查询
List<DeviceChannel> rootNodes = getRootNodes(deviceId, TreeType.CIVIL_CODE.equals(device.getTreeType()), false, true);
return rootNodes;
if (ObjectUtils.isEmpty(parentId) || parentId.equals(deviceId)) {
return deviceChannelMapper.getSubChannelsByDeviceId(deviceId, null, false);
}else {
return deviceChannelMapper.getSubChannelsByDeviceId(deviceId, parentId, false);
}
if (TreeType.CIVIL_CODE.equals(device.getTreeType())) {
if (parentId.length()%2 != 0) {
return null;
}
// 使用行政区划展示树
if (parentId.length() > 10) {
// TODO 可能是行政区划与业务分组混杂的情形
return null;
}
if (parentId.length() == 10 ) {
// parentId为行业编码 其下不会再有行政区划
List<DeviceChannel> channels = deviceChannelMapper.getChannelsByCivilCode(deviceId, parentId);
return channels;
}
// 查询其下的行政区划和摄像机
List<DeviceChannel> channels = deviceChannelMapper.getChannelsByCivilCode(deviceId, parentId);
return channels;
}
// 使用业务分组展示树
if (TreeType.BUSINESS_GROUP.equals(device.getTreeType())) {
if (parentId.length() < 14 ) {
return null;
}
List<DeviceChannel> deviceChannels = deviceChannelMapper.queryChannels(deviceId, parentId, null, null, null,null);
return deviceChannels;
}
return null;
}
private List<BaseTree<DeviceChannel>> transportChannelsToTree(List<DeviceChannel> channels, String parentId) {
@ -496,11 +413,21 @@ public class DeviceServiceImpl implements IDeviceService {
node.setPid(parentId);
node.setBasicData(channel);
node.setParent(false);
if (channel.getChannelId().length() > 8) {
String gbCodeType = channel.getChannelId().substring(10, 13);
node.setParent(gbCodeType.equals(ChannelIdType.BUSINESS_GROUP) || gbCodeType.equals(ChannelIdType.VIRTUAL_ORGANIZATION) );
}else {
if (channel.getChannelId().length() <= 8) {
node.setParent(true);
}else {
if (channel.getChannelId().length() != 20) {
node.setParent(channel.getParental() == 1);
}else {
try {
int type = Integer.parseInt(channel.getChannelId().substring(10, 13));
if (type == 215 || type == 216 || type == 200) {
node.setParent(true);
}
}catch (NumberFormatException e) {
node.setParent(false);
}
}
}
treeNotes.add(node);
}
@ -508,53 +435,6 @@ public class DeviceServiceImpl implements IDeviceService {
return treeNotes;
}
private List<DeviceChannel> getRootNodes(String deviceId, boolean isCivilCode, boolean haveCatalog, boolean haveChannel) {
if (!haveCatalog && !haveChannel) {
return null;
}
List<DeviceChannel> result = new ArrayList<>();
if (isCivilCode) {
// 使用行政区划
Integer length= deviceChannelMapper.getChannelMinLength(deviceId);
if (length == null) {
return null;
}
if (length <= 10) {
if (haveCatalog) {
List<DeviceChannel> provinceNode = deviceChannelMapper.getChannelsWithCivilCodeAndLength(deviceId, null, length);
if (provinceNode != null && provinceNode.size() > 0) {
result.addAll(provinceNode);
}
}
if (haveChannel) {
// 查询那些civilCode不在通道中的不规范通道放置在根目录
List<DeviceChannel> nonstandardNode = deviceChannelMapper.getChannelWithoutCiviCode(deviceId);
if (nonstandardNode != null && nonstandardNode.size() > 0) {
result.addAll(nonstandardNode);
}
}
}else {
if (haveChannel) {
List<DeviceChannel> deviceChannels = deviceChannelMapper.queryChannels(deviceId, null, null, null, null,null);
if (deviceChannels != null && deviceChannels.size() > 0) {
result.addAll(deviceChannels);
}
}
}
}else {
// 使用业务分组+虚拟组织
// 只获取业务分组
List<DeviceChannel> deviceChannels = deviceChannelMapper.getBusinessGroups(deviceId, ChannelIdType.BUSINESS_GROUP);
if (deviceChannels != null && deviceChannels.size() > 0) {
result.addAll(deviceChannels);
}
}
return result;
}
@Override
public boolean isExist(String deviceId) {
return deviceMapper.getDeviceByDeviceId(deviceId) != null;

View File

@ -113,20 +113,15 @@ public class GbStreamServiceImpl implements IGbStreamService {
deviceChannel.setStatus(gbStream.isStatus()?1:0);
deviceChannel.setRegisterWay(1);
deviceChannel.setCivilCode(platform.getAdministrativeDivision());
if (platform.getTreeType().equals(TreeType.CIVIL_CODE)){
deviceChannel.setCivilCode(catalogId);
}else if (platform.getTreeType().equals(TreeType.BUSINESS_GROUP)){
PlatformCatalog catalog = catalogMapper.select(catalogId);
if (catalog == null) {
deviceChannel.setParentId(platform.getDeviceGBId());
deviceChannel.setBusinessGroupId(null);
}else {
deviceChannel.setParentId(catalog.getId());
deviceChannel.setBusinessGroupId(catalog.getBusinessGroupId());
}
PlatformCatalog catalog = catalogMapper.select(catalogId);
if (catalog != null) {
deviceChannel.setCivilCode(catalog.getCivilCode());
deviceChannel.setParentId(catalog.getParentId());
deviceChannel.setBusinessGroupId(catalog.getBusinessGroupId());
}else {
deviceChannel.setCivilCode(platform.getAdministrativeDivision());
deviceChannel.setParentId(platform.getDeviceGBId());
}
deviceChannel.setModel("live");
@ -221,20 +216,14 @@ public class GbStreamServiceImpl implements IGbStreamService {
deviceChannel.setStatus((status != null && status )?1:0);
deviceChannel.setRegisterWay(1);
deviceChannel.setCivilCode(platform.getAdministrativeDivision());
if (platform.getTreeType().equals(TreeType.CIVIL_CODE)){
deviceChannel.setCivilCode(catalogId);
}else if (platform.getTreeType().equals(TreeType.BUSINESS_GROUP)){
PlatformCatalog catalog = catalogMapper.select(catalogId);
if (catalog == null) {
deviceChannel.setParentId(platform.getDeviceGBId());
deviceChannel.setBusinessGroupId(null);
}else {
deviceChannel.setParentId(catalog.getId());
deviceChannel.setBusinessGroupId(catalog.getBusinessGroupId());
}
PlatformCatalog catalog = catalogMapper.select(catalogId);
if (catalog != null) {
deviceChannel.setCivilCode(catalog.getCivilCode());
deviceChannel.setParentId(catalog.getParentId());
deviceChannel.setBusinessGroupId(catalog.getBusinessGroupId());
}else {
deviceChannel.setCivilCode(platform.getAdministrativeDivision());
deviceChannel.setParentId(platform.getDeviceGBId());
}
deviceChannel.setModel("live");

View File

@ -126,22 +126,17 @@ public class PlatformChannelServiceImpl implements IPlatformChannelService {
List<DeviceChannel> deviceChannelList = new ArrayList<>();
if (channelReduces.size() > 0){
PlatformCatalog catalog = catalogManager.select(catalogId);
if (catalog == null && !catalogId.equals(platform.getDeviceGBId())) {
if (catalog == null || !catalogId.equals(platform.getDeviceGBId())) {
logger.warn("未查询到目录{}的信息", catalogId);
return null;
}
for (ChannelReduce channelReduce : channelReduces) {
DeviceChannel deviceChannel = deviceChannelMapper.queryChannel(channelReduce.getDeviceId(), channelReduce.getChannelId());
deviceChannel.setParental(0);
deviceChannel.setCivilCode(catalog.getCivilCode());
deviceChannel.setParentId(catalog.getParentId());
deviceChannel.setBusinessGroupId(catalog.getBusinessGroupId());
deviceChannelList.add(deviceChannel);
if (platform.getTreeType().equals(TreeType.CIVIL_CODE)){
deviceChannel.setCivilCode(catalogId);
}else if (platform.getTreeType().equals(TreeType.BUSINESS_GROUP)){
deviceChannel.setParentId(catalogId);
if (catalog != null) {
deviceChannel.setBusinessGroupId(catalog.getBusinessGroupId());
}
}
}
}
return deviceChannelList;

View File

@ -124,18 +124,12 @@ public class PlatformServiceImpl implements IPlatformService {
@Override
public boolean update(ParentPlatform parentPlatform) {
logger.info("[国标级联]更新平台 {}", parentPlatform.getDeviceGBId());
// TODO 后续版本去除
parentPlatform.setTreeType("");
parentPlatform.setCharacterSet(parentPlatform.getCharacterSet().toUpperCase());
ParentPlatform parentPlatformOld = platformMapper.getParentPlatById(parentPlatform.getId());
ParentPlatformCatch parentPlatformCatchOld = redisCatchStorage.queryPlatformCatchInfo(parentPlatformOld.getServerGBId());
parentPlatform.setUpdateTime(DateUtil.getNow());
if (!parentPlatformOld.getTreeType().equals(parentPlatform.getTreeType())) {
// 目录结构发生变化清空之前的关联关系
logger.info("保存平台{}时发现目录结构变化,清空关联关系", parentPlatform.getDeviceGBId());
catalogMapper.delByPlatformId(parentPlatformOld.getServerGBId());
platformChannelMapper.delByPlatformId(parentPlatformOld.getServerGBId());
platformGbStreamMapper.delByPlatformId(parentPlatformOld.getServerGBId());
}
// 停止心跳定时
final String keepaliveTaskKey = KEEPALIVE_KEY_PREFIX + parentPlatformOld.getServerGBId();

View File

@ -447,7 +447,7 @@ public interface DeviceChannelMapper {
List<DeviceChannel> getBusinessGroups(String deviceId, String typeCode);
@Select("select dc.id, dc.channelId, dc.deviceId, dc.name, dc.manufacture,dc.model,dc.owner, pc.civilCode,dc.block, " +
" dc.address, '0' as parental,'0' as channelType, pc.id as parentId, dc.safetyWay, dc.registerWay,dc.certNum, dc.certifiable, " +
" dc.address, '0' as parental,'0' as channelType, pc.id as parentId, pc.businessGroupId as businessGroupId, dc.safetyWay, dc.registerWay,dc.certNum, dc.certifiable, " +
" dc.errCode,dc.endTime, dc.secrecy, dc.ipAddress, dc.port, dc.PTZType, dc.password, dc.status, " +
" dc.longitudeWgs84 as longitude, dc.latitudeWgs84 as latitude, pc.businessGroupId " +
" from device_channel dc" +
@ -501,4 +501,14 @@ public interface DeviceChannelMapper {
"</foreach>" +
"</script>"})
int batchOffline(List<DeviceChannel> channels);
@Select(value = {" <script>" +
"select * " +
"from device_channel " +
"where deviceId=#{deviceId}" +
" <if test='parentId != null '> and parentId = #{parentId} </if>" +
" <if test='parentId == null '> and parentId is null </if>" +
" <if test='onlyCatalog == true '> and parental = 1 </if>" +
" </script>"})
List<DeviceChannel> getSubChannelsByDeviceId(String deviceId, String parentId, boolean onlyCatalog);
}

View File

@ -125,47 +125,50 @@ public class VideoManagerStorageImpl implements IVideoManagerStorage {
List<DeviceChannel> channels = new ArrayList<>();
StringBuilder stringBuilder = new StringBuilder();
Map<String, Integer> subContMap = new HashMap<>();
if (deviceChannelList.size() > 0) {
// 数据去重
Set<String> gbIdSet = new HashSet<>();
for (DeviceChannel deviceChannel : deviceChannelList) {
if (!gbIdSet.contains(deviceChannel.getChannelId())) {
gbIdSet.add(deviceChannel.getChannelId());
if (allChannelMap.containsKey(deviceChannel.getChannelId())) {
deviceChannel.setStreamId(allChannelMap.get(deviceChannel.getChannelId()).getStreamId());
deviceChannel.setHasAudio(allChannelMap.get(deviceChannel.getChannelId()).isHasAudio());
if (allChannelMap.get(deviceChannel.getChannelId()).getStatus() !=deviceChannel.getStatus()){
List<String> strings = platformChannelMapper.queryParentPlatformByChannelId(deviceChannel.getChannelId());
if (!CollectionUtils.isEmpty(strings)){
strings.forEach(platformId->{
eventPublisher.catalogEventPublish(platformId, deviceChannel, deviceChannel.getStatus()==1?CatalogEvent.ON:CatalogEvent.OFF);
});
}
}
}
channels.add(deviceChannel);
if (!ObjectUtils.isEmpty(deviceChannel.getParentId())) {
if (subContMap.get(deviceChannel.getParentId()) == null) {
subContMap.put(deviceChannel.getParentId(), 1);
}else {
Integer count = subContMap.get(deviceChannel.getParentId());
subContMap.put(deviceChannel.getParentId(), count++);
}
// 数据去重
Set<String> gbIdSet = new HashSet<>();
for (DeviceChannel deviceChannel : deviceChannelList) {
if (gbIdSet.contains(deviceChannel.getChannelId())) {
stringBuilder.append(deviceChannel.getChannelId()).append(",");
continue;
}
gbIdSet.add(deviceChannel.getChannelId());
if (allChannelMap.containsKey(deviceChannel.getChannelId())) {
deviceChannel.setStreamId(allChannelMap.get(deviceChannel.getChannelId()).getStreamId());
deviceChannel.setHasAudio(allChannelMap.get(deviceChannel.getChannelId()).isHasAudio());
if (allChannelMap.get(deviceChannel.getChannelId()).getStatus() !=deviceChannel.getStatus()){
List<String> strings = platformChannelMapper.queryParentPlatformByChannelId(deviceChannel.getChannelId());
if (!CollectionUtils.isEmpty(strings)){
strings.forEach(platformId->{
eventPublisher.catalogEventPublish(platformId, deviceChannel, deviceChannel.getStatus()==1?CatalogEvent.ON:CatalogEvent.OFF);
});
}
}
}
channels.add(deviceChannel);
if (!ObjectUtils.isEmpty(deviceChannel.getParentId())) {
if (subContMap.get(deviceChannel.getParentId()) == null) {
subContMap.put(deviceChannel.getParentId(), 1);
}else {
stringBuilder.append(deviceChannel.getChannelId()).append(",");
Integer count = subContMap.get(deviceChannel.getParentId());
subContMap.put(deviceChannel.getParentId(), count++);
}
}
if (channels.size() > 0) {
for (DeviceChannel channel : channels) {
if (subContMap.get(channel.getChannelId()) != null){
channel.setSubCount(subContMap.get(channel.getChannelId()));
}
if (channels.size() > 0) {
for (DeviceChannel channel : channels) {
if (subContMap.get(channel.getChannelId()) != null){
Integer count = subContMap.get(channel.getChannelId());
if (count > 0) {
channel.setSubCount(count);
channel.setParental(1);
}
}
}
}
if (stringBuilder.length() > 0) {
logger.info("[目录查询]收到的数据存在重复: {}" , stringBuilder);
}
@ -773,25 +776,49 @@ public class VideoManagerStorageImpl implements IVideoManagerStorage {
if (platform == null) {
return 0;
}
if (platform.getTreeType().equals(TreeType.BUSINESS_GROUP)) {
if (platform.getDeviceGBId().equals(platformCatalog.getParentId())) {
// 第一层节点
platformCatalog.setBusinessGroupId(platformCatalog.getId());
platformCatalog.setParentId(platform.getDeviceGBId());
}else {
// 获取顶层的
PlatformCatalog topCatalog = getTopCatalog(platformCatalog.getParentId(), platform.getDeviceGBId());
platformCatalog.setBusinessGroupId(topCatalog.getId());
if (platformCatalog.getId().length() <= 8) {
platformCatalog.setCivilCode(platformCatalog.getParentId());
}else {
if (platformCatalog.getId().length() != 20) {
return 0;
}
if (platformCatalog.getParentId() != null) {
switch (Integer.parseInt(platformCatalog.getId().substring(10, 13))){
case 200:
case 215:
if (platformCatalog.getParentId().length() <= 8) {
platformCatalog.setCivilCode(platformCatalog.getParentId());
}else {
PlatformCatalog catalog = catalogMapper.select(platformCatalog.getParentId());
if (catalog != null) {
platformCatalog.setCivilCode(catalog.getCivilCode());
}
}
break;
case 216:
if (platformCatalog.getParentId().length() <= 8) {
platformCatalog.setCivilCode(platformCatalog.getParentId());
}else {
PlatformCatalog catalog = catalogMapper.select(platformCatalog.getParentId());
if (catalog == null) {
logger.warn("[添加目录] 无法获取目录{}的CivilCode和BusinessGroupId", platformCatalog.getPlatformId());
break;
}
platformCatalog.setCivilCode(catalog.getCivilCode());
if (Integer.parseInt(platformCatalog.getParentId().substring(10, 13)) == 215) {
platformCatalog.setBusinessGroupId(platformCatalog.getParentId());
}else {
if (Integer.parseInt(platformCatalog.getParentId().substring(10, 13)) == 216) {
platformCatalog.setBusinessGroupId(catalog.getBusinessGroupId());
}
}
}
break;
default:
break;
}
}
}
if (platform.getTreeType().equals(TreeType.CIVIL_CODE)) {
platformCatalog.setCivilCode(platformCatalog.getId());
if (platformCatalog.getPlatformId().equals(platformCatalog.getParentId())) {
// 第一层节点
platformCatalog.setParentId(platform.getDeviceGBId());
}
}
int result = catalogMapper.add(platformCatalog);
if (result > 0) {
DeviceChannel deviceChannel = getDeviceChannelByCatalog(platformCatalog);
@ -915,19 +942,14 @@ public class VideoManagerStorageImpl implements IVideoManagerStorage {
DeviceChannel deviceChannel = new DeviceChannel();
deviceChannel.setChannelId(catalog.getId());
deviceChannel.setName(catalog.getName());
deviceChannel.setLongitude(0.0);
deviceChannel.setLatitude(0.0);
deviceChannel.setDeviceId(platform.getDeviceGBId());
deviceChannel.setManufacture("wvp-pro");
deviceChannel.setStatus(1);
deviceChannel.setParental(1);
deviceChannel.setRegisterWay(1);
// 行政区划应该是Domain的前八位
if (platform.getTreeType().equals(TreeType.BUSINESS_GROUP)) {
deviceChannel.setParentId(catalog.getParentId());
deviceChannel.setBusinessGroupId(catalog.getBusinessGroupId());
}
deviceChannel.setParentId(catalog.getParentId());
deviceChannel.setBusinessGroupId(catalog.getBusinessGroupId());
deviceChannel.setModel("live");
deviceChannel.setOwner("wvp-pro");

View File

@ -403,8 +403,12 @@ public class PlatformController {
if (platform == null) {
throw new ControllerException(ErrorCode.ERROR100.getCode(), "平台未找到");
}
if (platformId.equals(parentId)) {
parentId = platform.getDeviceGBId();
// if (platformId.equals(parentId)) {
// parentId = platform.getDeviceGBId();
// }
if (platformId.equals(platform.getDeviceGBId())) {
parentId = null;
}
return storager.getChildrenCatalogByPlatform(platformId, parentId);

File diff suppressed because it is too large Load Diff

20719
web_src/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -144,7 +144,7 @@ export default {
},
chooseChannel: function(platform) {
console.log("platform.name: " + platform.name)
this.$refs.chooseChannelDialog.openDialog(platform.serverGBId,platform.deviceGBId, platform.name, platform.catalogId, platform.treeType, this.initData)
this.$refs.chooseChannelDialog.openDialog(platform.serverGBId,platform.deviceGBId, platform.name, platform.catalogId, this.initData)
},
initData: function() {
this.getPlatformList();

View File

@ -46,12 +46,11 @@
export default {
name: "catalogEdit",
computed: {},
props: ['platformId'],
props: ['platformId', 'platformDeviceId'],
created() {},
data() {
let checkId = (rule, value, callback) => {
console.log("checkId")
console.log(this.treeType)
console.log(rule)
console.log(value)
console.log(value.length)
@ -59,21 +58,34 @@ export default {
if (!value) {
return callback(new Error('编号不能为空'));
}
if (this.treeType === "BusinessGroup" && value.length !== 20) {
return callback(new Error('编号必须由20位数字组成'));
}
if (this.treeType === "CivilCode" && value.length <= 8 && value.length%2 !== 0) {
return callback(new Error('行政区划必须是八位以下的偶数个数字组成'));
}
if (this.treeType === "BusinessGroup") {
if (value.trim().length <= 8) {
if (value.trim().length%2 !== 0) {
return callback(new Error('行政区划编号必须为2/4/6/8位'));
}
if (this.form.parentId !== this.platformDeviceId && this.form.parentId.length >= value.trim().length) {
return callback(new Error('行政区划编号长度应该每次两位递增'));
}
}else {
if (value.trim().length !== 20) {
return callback(new Error('编号必须为2/4/6/8位的行政区划或20位的虚拟组织/业务分组'));
}
let catalogType = value.substring(10, 13);
console.log(catalogType)
// 216 215
if (this.level === 1 && catalogType !== "215") {
return callback(new Error('业务分组模式下第一层目录的编号11到13位必须为215'));
if (catalogType !== "215" && catalogType !== "216") {
return callback(new Error('编号错误业务分组11-13位为215虚拟组织11-13位为216'));
}
if (this.level > 1 && catalogType !== "216") {
return callback(new Error('业务分组模式下第一层以下目录的编号11到13位必须为216'));
if (catalogType === "216") {
if (this.form.parentId !== this.platformDeviceId){
if (this.form.parentId.length <= 8) {
return callback(new Error('编号错误建立虚拟组织前必须先建立业务分组11-13位为215'));
}
}
}
if (catalogType === "215") {
if (this.form.parentId.length === "215") {
return callback(new Error('编号错误业务分组下只能建立虚拟组织11-13位为216'));
}
}
}
callback();
@ -83,7 +95,6 @@ export default {
showDialog: false,
isLoging: false,
isEdit: false,
treeType: null,
level: 0,
form: {
id: null,
@ -98,7 +109,7 @@ export default {
};
},
methods: {
openDialog: function (isEdit, id, name, parentId, treeType, level, callback) {
openDialog: function (isEdit, id, name, parentId, level, callback) {
console.log("parentId: " + parentId)
console.log(this.form)
this.isEdit = isEdit;
@ -108,7 +119,6 @@ export default {
this.form.parentId = parentId;
this.showDialog = true;
this.submitCallback = callback;
this.treeType = treeType;
this.level = level;
},
onSubmit: function () {

View File

@ -8,7 +8,7 @@
<el-tab-pane label="目录结构" name="catalog">
<el-container>
<el-main v-bind:style="{backgroundColor: '#FFF', maxHeight: winHeight + 'px'}">
<chooseChannelForCatalog ref="chooseChannelForCatalog" :platformId=platformId :platformDeviceId=platformDeviceId :platformName=platformName :defaultCatalogId=defaultCatalogId :catalogIdChange="catalogIdChange" :treeType=treeType ></chooseChannelForCatalog>
<chooseChannelForCatalog ref="chooseChannelForCatalog" :platformId=platformId :platformDeviceId=platformDeviceId :platformName=platformName :defaultCatalogId=defaultCatalogId :catalogIdChange="catalogIdChange" ></chooseChannelForCatalog>
</el-main>
</el-container>
</el-tab-pane>
@ -67,14 +67,13 @@ export default {
platformName: "",
defaultCatalogId: "",
showDialog: false,
treeType: null,
chooseData: {},
winHeight: window.innerHeight - 250,
};
},
methods: {
openDialog(platformId, platformDeviceId, platformName, defaultCatalogId, treeType, closeCallback) {
openDialog(platformId, platformDeviceId, platformName, defaultCatalogId, closeCallback) {
console.log("defaultCatalogId: " + defaultCatalogId)
this.platformId = platformId
this.platformDeviceId = platformDeviceId
@ -82,7 +81,6 @@ export default {
this.defaultCatalogId = defaultCatalogId
this.showDialog = true
this.closeCallback = closeCallback
this.treeType = treeType
},
tabClick (tab, event){

View File

@ -28,7 +28,7 @@
</span>
</el-tree>
</div>
<catalogEdit ref="catalogEdit" :platformId="platformId"></catalogEdit>
<catalogEdit ref="catalogEdit" :platformId="platformId" :platformDeviceId="platformDeviceId"></catalogEdit>
</div>
</template>
@ -38,7 +38,7 @@
import catalogEdit from './catalogEdit.vue'
export default {
name: 'chooseChannelForCatalog',
props: ['platformId', 'platformDeviceId', 'platformName', 'defaultCatalogId', 'catalogIdChange', 'treeType'],
props: ['platformId', 'platformDeviceId', 'platformName', 'defaultCatalogId', 'catalogIdChange'],
created() {
this.chooseId = this.defaultCatalogId;
this.defaultCatalogIdSign = this.defaultCatalogId;
@ -101,9 +101,10 @@ export default {
},
addCatalog: function (parentId, node){
let that = this;
console.log(this.treeType)
console.log(this.platformId)
console.log(parentId)
//
that.$refs.catalogEdit.openDialog(false, null, null, parentId, this.treeType, node.level, ()=>{
that.$refs.catalogEdit.openDialog(false, null, null, parentId, node.level, ()=>{
node.loaded = false
node.expand();
});

View File

@ -49,12 +49,6 @@
<el-option key="GCJ02" label="GCJ02" value="GCJ02"></el-option>
</el-select>
</el-form-item>
<el-form-item label="目录结构" prop="treeType" >
<el-select v-model="form.treeType" style="float: left; width: 100%" >
<el-option key="WGS84" label="行政区划" value="CivilCode"></el-option>
<el-option key="GCJ02" label="业务分组" value="BusinessGroup"></el-option>
</el-select>
</el-form-item>
<el-form-item v-if="this.isEdit" label="目录订阅" title="0为取消订阅" prop="subscribeCycleForCatalog" >
<el-input v-model="form.subscribeCycleForCatalog" clearable ></el-input>
</el-form-item>

View File

@ -78,12 +78,6 @@
<el-option label="8" value="8"></el-option>
</el-select>
</el-form-item>
<el-form-item label="目录结构" prop="treeType" >
<el-select v-model="platform.treeType" style="width: 100%" @change="treeTypeChange">
<el-option key="WGS84" label="行政区划" value="CivilCode"></el-option>
<el-option key="GCJ02" label="业务分组" value="BusinessGroup"></el-option>
</el-select>
</el-form-item>
<el-form-item label="字符集" prop="characterSet">
<el-select
v-model="platform.characterSet"
@ -164,7 +158,6 @@ export default {
startOfflinePush: false,
catalogGroup: 1,
administrativeDivision: null,
treeType: "BusinessGroup",
},
rules: {
name: [{ required: true, message: "请输入平台名称", trigger: "blur" }],
@ -203,7 +196,6 @@ export default {
that.platform.devicePort = res.data.data.devicePort;
that.platform.username = res.data.data.username;
that.platform.password = res.data.data.password;
that.platform.treeType = "BusinessGroup";
that.platform.administrativeDivision = res.data.data.username.substr(0, 6);
}
@ -234,7 +226,6 @@ export default {
this.platform.startOfflinePush = platform.startOfflinePush;
this.platform.catalogGroup = platform.catalogGroup;
this.platform.administrativeDivision = platform.administrativeDivision;
this.platform.treeType = platform.treeType;
this.onSubmit_text = "保存";
this.saveUrl = "/api/platform/save";
}
@ -252,7 +243,6 @@ export default {
if (this.platform.administrativeDivision == null) {
this.platform.administrativeDivision = this.platform.deviceGBId.substr(0, 6);
}
},
onSubmit: function () {
this.saveForm()
@ -309,7 +299,6 @@ export default {
keepTimeout: 60,
transport: "UDP",
characterSet: "GB2312",
treeType: "BusinessGroup",
startOfflinePush: false,
catalogGroup: 1,
}
@ -344,13 +333,6 @@ export default {
});
}
},
treeTypeChange: function (){
this.$message({
showClose: true,
message: "修改目录结构会导致关联目录与通道数据被清空,保存后生效",
type: "warning",
});
}
},
};
</script>