diff --git a/sql/2.6.8升级2.6.9.sql b/sql/2.6.8升级2.6.9.sql index a6b9f12c..3734bcd4 100644 --- a/sql/2.6.8升级2.6.9.sql +++ b/sql/2.6.8升级2.6.9.sql @@ -38,7 +38,7 @@ alter table device change geoCoordSys geo_coord_sys varchar(50) not null; alter table device - change treeType tree_type varchar(50) not null; + drop column treeType; alter table device change mediaServerId media_server_id varchar(50) default 'auto' null; @@ -297,7 +297,7 @@ alter table parent_platform change updateTime update_time varchar(50) null; alter table parent_platform - change treeType tree_type varchar(50) not null; + drop column treeType; alter table parent_platform change asMessageChannel as_message_channel bool default false; diff --git a/sql/初始化.sql b/sql/初始化.sql index f29a9242..d61c47cc 100644 --- a/sql/初始化.sql +++ b/sql/初始化.sql @@ -24,7 +24,6 @@ create table wvp_device ( charset character varying(50), ssrc_check bool default false, geo_coord_sys character varying(50), - tree_type character varying(50), media_server_id character varying(50), custom_name character varying(255), sdp_ip character varying(50), @@ -187,7 +186,6 @@ create table wvp_platform ( catalog_group integer, create_time character varying(50), update_time character varying(50), - tree_type character varying(50), as_message_channel bool default false, constraint uk_platform_unique_server_gb_id unique (server_gb_id) ); diff --git a/src/main/java/com/genersoft/iot/vmp/common/CivilCodePo.java b/src/main/java/com/genersoft/iot/vmp/common/CivilCodePo.java new file mode 100644 index 00000000..452c12ef --- /dev/null +++ b/src/main/java/com/genersoft/iot/vmp/common/CivilCodePo.java @@ -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; + } +} diff --git a/src/main/java/com/genersoft/iot/vmp/conf/CivilCodeFileConf.java b/src/main/java/com/genersoft/iot/vmp/conf/CivilCodeFileConf.java new file mode 100644 index 00000000..39e0a70a --- /dev/null +++ b/src/main/java/com/genersoft/iot/vmp/conf/CivilCodeFileConf.java @@ -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 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); + } + + } + +} diff --git a/src/main/java/com/genersoft/iot/vmp/conf/DynamicTask.java b/src/main/java/com/genersoft/iot/vmp/conf/DynamicTask.java index 041d7388..95a2499b 100644 --- a/src/main/java/com/genersoft/iot/vmp/conf/DynamicTask.java +++ b/src/main/java/com/genersoft/iot/vmp/conf/DynamicTask.java @@ -45,6 +45,7 @@ public class DynamicTask { * @return */ public void startCron(String key, Runnable task, int cycleForCatalog) { + System.out.println(cycleForCatalog); ScheduledFuture future = futureMap.get(key); if (future != null) { if (future.isCancelled()) { diff --git a/src/main/java/com/genersoft/iot/vmp/conf/SipPlatformRunner.java b/src/main/java/com/genersoft/iot/vmp/conf/SipPlatformRunner.java index 55363efb..eb1b157a 100644 --- a/src/main/java/com/genersoft/iot/vmp/conf/SipPlatformRunner.java +++ b/src/main/java/com/genersoft/iot/vmp/conf/SipPlatformRunner.java @@ -56,7 +56,7 @@ public class SipPlatformRunner implements CommandLineRunner { } // 设置所有平台离线 - platformService.offline(parentPlatform, true); + platformService.offline(parentPlatform, false); } } } diff --git a/src/main/java/com/genersoft/iot/vmp/conf/UserSetting.java b/src/main/java/com/genersoft/iot/vmp/conf/UserSetting.java index f508de74..bd998c7a 100644 --- a/src/main/java/com/genersoft/iot/vmp/conf/UserSetting.java +++ b/src/main/java/com/genersoft/iot/vmp/conf/UserSetting.java @@ -63,7 +63,7 @@ public class UserSetting { private String thirdPartyGBIdReg = "[\\s\\S]*"; - + private String civilCodeFile = "classpath:civilCode.csv"; private List interfaceAuthenticationExcludes = new ArrayList<>(); @@ -71,6 +71,10 @@ public class UserSetting { private int maxNotifyCountQueue = 10000; + private int registerAgainAfterTime = 60; + + private boolean registerKeepIntDialog = false; + public Boolean getSavePositionHistory() { return savePositionHistory; } @@ -299,9 +303,27 @@ public class UserSetting { this.sqlLog = sqlLog; } + public String getCivilCodeFile() { + return civilCodeFile; + } + public void setCivilCodeFile(String civilCodeFile) { + this.civilCodeFile = civilCodeFile; + } + public int getRegisterAgainAfterTime() { + return registerAgainAfterTime; + } + public void setRegisterAgainAfterTime(int registerAgainAfterTime) { + this.registerAgainAfterTime = registerAgainAfterTime; + } + public boolean isRegisterKeepIntDialog() { + return registerKeepIntDialog; + } + public void setRegisterKeepIntDialog(boolean registerKeepIntDialog) { + this.registerKeepIntDialog = registerKeepIntDialog; + } } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/Device.java b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/Device.java index a294ab14..1318c59c 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/Device.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/Device.java @@ -173,12 +173,6 @@ public class Device { @Schema(description = "地理坐标系, 目前支持 WGS84,GCJ02") private String geoCoordSys; - /** - * 树类型 国标规定了两种树的展现方式 行政区划:CivilCode 和业务分组:BusinessGroup - */ - @Schema(description = "树类型 国标规定了两种树的展现方式 行政区划:CivilCode 和业务分组:BusinessGroup") - private String treeType; - @Schema(description = "密码") private String password; @@ -408,14 +402,6 @@ public class Device { this.geoCoordSys = geoCoordSys; } - public String getTreeType() { - return treeType; - } - - public void setTreeType(String treeType) { - this.treeType = treeType; - } - public String getPassword() { return password; } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/ParentPlatform.java b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/ParentPlatform.java index 01a11eb6..fbc95ed9 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/ParentPlatform.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/ParentPlatform.java @@ -183,12 +183,6 @@ public class ParentPlatform { @Schema(description = "创建时间") private String createTime; - /** - * 树类型 国标规定了两种树的展现方式 行政区划 CivilCode 和业务分组:BusinessGroup - */ - @Schema(description = "树类型 国标规定了两种树的展现方式 行政区划 CivilCode 和业务分组:BusinessGrou") - private String treeType; - @Schema(description = "是否作为消息通道") private boolean asMessageChannel; @@ -424,14 +418,6 @@ public class ParentPlatform { this.createTime = createTime; } - public String getTreeType() { - return treeType; - } - - public void setTreeType(String treeType) { - this.treeType = treeType; - } - public boolean isAsMessageChannel() { return asMessageChannel; } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/TreeType.java b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/TreeType.java deleted file mode 100644 index bb684e1a..00000000 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/TreeType.java +++ /dev/null @@ -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"; -} diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java index b1e21963..0a929206 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java @@ -209,59 +209,149 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { // 行政区划分组只需要这两项就可以 catalogXml.append("" + channel.getChannelId() + "\r\n"); catalogXml.append("" + channel.getName() + "\r\n"); - if (channel.getParentId() != null) { - // 业务分组加上这一项即可,提高兼容性, - catalogXml.append("" + channel.getParentId() + "\r\n"); -// catalogXml.append("" + parentPlatform.getDeviceGBId() + "/" + channel.getParentId() + "\r\n"); - } - if (channel.getChannelId().length() == 20 && Integer.parseInt(channel.getChannelId().substring(10, 13)) == 216) { - // 虚拟组织增加BusinessGroupID字段 - catalogXml.append("" + channel.getParentId() + "\r\n"); - } - if (!channel.getChannelId().equals(parentPlatform.getDeviceGBId())) { - catalogXml.append("" + channel.getParental() + "\r\n"); - if (channel.getParental() == 0) { - catalogXml.append("" + (channel.isStatus() ? "ON" : "OFF") + "\r\n"); + if (channel.getChannelId().length() <= 8) { + catalogXml.append("\r\n"); + continue; + }else { + if (channel.getChannelId().length() != 20) { + continue; } - } - if (channel.getParental() == 0) { - // 通道项 - catalogXml.append("" + channel.getManufacture() + "\r\n"); - catalogXml.append("" + channel.getSecrecy() + "\r\n"); - catalogXml.append("" + channel.getRegisterWay() + "\r\n"); - String civilCode = channel.getCivilCode() == null?parentPlatform.getAdministrativeDivision() : channel.getCivilCode(); - if (channel.getChannelType() != 2) { // 业务分组/虚拟组织/行政区划 不设置以下属性 - catalogXml.append("" + channel.getModel() + "\r\n"); - catalogXml.append("" + parentPlatform.getDeviceGBId()+ "\r\n"); - catalogXml.append("" + civilCode + "\r\n"); - if (channel.getAddress() == null) { - catalogXml.append("
\r\n"); - }else { - catalogXml.append("
" + channel.getAddress() + "
\r\n"); - } - catalogXml.append("" + channel.getBlock() + "\r\n"); - catalogXml.append("" + channel.getSafetyWay() + "\r\n"); - catalogXml.append("" + channel.getCertNum() + "\r\n"); - catalogXml.append("" + channel.getCertifiable() + "\r\n"); - catalogXml.append("" + channel.getErrCode() + "\r\n"); - catalogXml.append("" + channel.getEndTime() + "\r\n"); - catalogXml.append("" + channel.getSecrecy() + "\r\n"); - catalogXml.append("" + channel.getIpAddress() + "\r\n"); - catalogXml.append("" + channel.getPort() + "\r\n"); - catalogXml.append("" + channel.getPort() + "\r\n"); - catalogXml.append("" + channel.getPTZType() + "\r\n"); - catalogXml.append("" + (channel.isStatus() ? "ON":"OFF") + "\r\n"); - catalogXml.append("" + - (channel.getLongitudeWgs84() != 0? channel.getLongitudeWgs84():channel.getLongitude()) - + "\r\n"); - catalogXml.append("" + - (channel.getLatitudeWgs84() != 0? channel.getLatitudeWgs84():channel.getLatitude()) - + "\r\n"); + switch (Integer.parseInt(channel.getChannelId().substring(10, 13))){ + case 200: +// catalogXml.append("三永华通\r\n"); +// GitUtil gitUtil = SpringBeanFactory.getBean("gitUtil"); +// String model = (gitUtil == null || gitUtil.getBuildVersion() == null)?"1.0": gitUtil.getBuildVersion(); +// catalogXml.append("" + model + "\r\n"); +// catalogXml.append("三永华通\r\n"); + if (channel.getCivilCode() != null) { + catalogXml.append(""+channel.getCivilCode()+"\r\n"); + }else { + catalogXml.append("\r\n"); + } + catalogXml.append("1\r\n"); + catalogXml.append("0\r\n"); + break; + case 215: + if (!ObjectUtils.isEmpty(channel.getParentId())) { + catalogXml.append("" + channel.getParentId() + "\r\n"); + } + + break; + case 216: + if (!ObjectUtils.isEmpty(channel.getParentId())) { + catalogXml.append("" + channel.getParentId() + "\r\n"); + }else { + catalogXml.append("\r\n"); + } + if (!ObjectUtils.isEmpty(channel.getBusinessGroupId())) { + catalogXml.append("" + channel.getBusinessGroupId() + "\r\n"); + }else { + catalogXml.append("\r\n"); + } + break; + default: + // 通道项 + if (channel.getManufacture() != null) { + catalogXml.append("" + channel.getManufacture() + "\r\n"); + }else { + catalogXml.append("\r\n"); + } + if (channel.getSecrecy() != null) { + catalogXml.append("" + channel.getSecrecy() + "\r\n"); + }else { + catalogXml.append("\r\n"); + } + catalogXml.append("" + channel.getRegisterWay() + "\r\n"); + if (channel.getModel() != null) { + catalogXml.append("" + channel.getModel() + "\r\n"); + }else { + catalogXml.append("\r\n"); + } + if (channel.getOwner() != null) { + catalogXml.append("" + channel.getOwner()+ "\r\n"); + }else { + catalogXml.append("\r\n"); + } + if (channel.getCivilCode() != null) { + catalogXml.append("" + channel.getCivilCode() + "\r\n"); + }else { + catalogXml.append("\r\n"); + } + if (channel.getAddress() == null) { + catalogXml.append("
\r\n"); + }else { + catalogXml.append("
" + channel.getAddress() + "
\r\n"); + } + if (!ObjectUtils.isEmpty(channel.getParentId())) { + catalogXml.append("" + channel.getParentId() + "\r\n"); + }else { + catalogXml.append("\r\n"); + } + if (!ObjectUtils.isEmpty(channel.getBlock())) { + catalogXml.append("" + channel.getBlock() + "\r\n"); + }else { + catalogXml.append("\r\n"); + } + if (!ObjectUtils.isEmpty(channel.getSafetyWay())) { + catalogXml.append("" + channel.getSafetyWay() + "\r\n"); + }else { + catalogXml.append("\r\n"); + } + if (!ObjectUtils.isEmpty(channel.getCertNum())) { + catalogXml.append("" + channel.getCertNum() + "\r\n"); + }else { + catalogXml.append("\r\n"); + } + if (!ObjectUtils.isEmpty(channel.getCertifiable())) { + catalogXml.append("" + channel.getCertifiable() + "\r\n"); + }else { + catalogXml.append("\r\n"); + } + if (!ObjectUtils.isEmpty(channel.getErrCode())) { + catalogXml.append("" + channel.getErrCode() + "\r\n"); + }else { + catalogXml.append("\r\n"); + } + if (!ObjectUtils.isEmpty(channel.getEndTime())) { + catalogXml.append("" + channel.getEndTime() + "\r\n"); + }else { + catalogXml.append("\r\n"); + } + if (!ObjectUtils.isEmpty(channel.getSecrecy())) { + catalogXml.append("" + channel.getSecrecy() + "\r\n"); + }else { + catalogXml.append("\r\n"); + } + if (!ObjectUtils.isEmpty(channel.getIpAddress())) { + catalogXml.append("" + channel.getIpAddress() + "\r\n"); + }else { + catalogXml.append("\r\n"); + } + catalogXml.append("" + channel.getPort() + "\r\n"); + if (!ObjectUtils.isEmpty(channel.getPassword())) { + catalogXml.append("" + channel.getPassword() + "\r\n"); + }else { + catalogXml.append("\r\n"); + } + if (!ObjectUtils.isEmpty(channel.getPTZType())) { + catalogXml.append("" + channel.getPTZType() + "\r\n"); + }else { + catalogXml.append("\r\n"); + } + catalogXml.append("" + (channel.isStatus() ?"ON":"OFF") + "\r\n"); + + catalogXml.append("" + + (channel.getLongitudeWgs84() != 0? channel.getLongitudeWgs84():channel.getLongitude()) + + "\r\n"); + catalogXml.append("" + + (channel.getLatitudeWgs84() != 0? channel.getLatitudeWgs84():channel.getLatitude()) + + "\r\n"); + break; } + catalogXml.append("\r\n"); } - catalogXml.append("\r\n"); } } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java index a1591890..2d28a219 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java @@ -188,6 +188,8 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements logger.error("[命令发送失败] invite GONE: {}", e.getMessage()); } return; + }else { + // TODO 可能漏回复消息 } } } else { diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/NotifyRequestForCatalogProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/NotifyRequestForCatalogProcessor.java index c0b1be4c..e2aee4a2 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/NotifyRequestForCatalogProcessor.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/NotifyRequestForCatalogProcessor.java @@ -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()); diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/NotifyRequestProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/NotifyRequestProcessor.java index e97b720b..bc34bbd3 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/NotifyRequestProcessor.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/NotifyRequestProcessor.java @@ -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 taskQueue = new ConcurrentLinkedQueue<>(); @Qualifier("taskExecutor") @@ -408,7 +412,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) { diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/RegisterRequestProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/RegisterRequestProcessor.java index 6e3cf677..6eea02ff 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/RegisterRequestProcessor.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/RegisterRequestProcessor.java @@ -164,7 +164,6 @@ public class RegisterRequestProcessor extends SIPRequestProcessorParent implemen device.setStreamMode("UDP"); device.setCharset("GB2312"); device.setGeoCoordSys("WGS84"); - device.setTreeType("CivilCode"); device.setDeviceId(deviceId); device.setOnLine(false); } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/CatalogResponseMessageHandler.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/CatalogResponseMessageHandler.java index eb8555a4..2d8af9b1 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/CatalogResponseMessageHandler.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/CatalogResponseMessageHandler.java @@ -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 deviceListIterator = deviceListElement.elementIterator(); if (deviceListIterator != null) { List channelList = new ArrayList<>(); + List 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()); diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/utils/XmlUtil.java b/src/main/java/com/genersoft/iot/vmp/gb28181/utils/XmlUtil.java index 750cd8b0..7914ffac 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/utils/XmlUtil.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/utils/XmlUtil.java @@ -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(true); - 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(true); - 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(true); - } - if (status.equals("OFF") || status.equals("Off") || status.equals("OFFLINE")) { - deviceChannel.setStatus(false); - } }else { - deviceChannel.setStatus(true); - } - // 识别自带的目录标识 - 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(true); + 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(true); + 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(true); + 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(true); + } + if (status.equals("OFF") || status.equals("Off") || status.equals("OFFLINE")) { + deviceChannel.setStatus(false); + } + }else { + deviceChannel.setStatus(true); + } + + // 经度 + 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; diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/DeviceChannelServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/DeviceChannelServiceImpl.java index 45405f70..76a50872 100644 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/DeviceChannelServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/DeviceChannelServiceImpl.java @@ -50,8 +50,6 @@ public class DeviceChannelServiceImpl implements IDeviceChannelService { device = deviceMapper.getDeviceByDeviceId(deviceChannel.getDeviceId()); } - - if ("WGS84".equals(device.getGeoCoordSys())) { deviceChannel.setLongitudeWgs84(deviceChannel.getLongitude()); deviceChannel.setLatitudeWgs84(deviceChannel.getLatitude()); @@ -262,4 +260,6 @@ public class DeviceChannelServiceImpl implements IDeviceChannelService { } } } + + } diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/DeviceServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/DeviceServiceImpl.java index cc237c96..fe98d067 100644 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/DeviceServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/DeviceServiceImpl.java @@ -122,9 +122,10 @@ public class DeviceServiceImpl implements IDeviceService { } // 第一次上线 或则设备之前是离线状态--进行通道同步和设备信息查询 - if (device.getCreateTime() == null) { + if (deviceInDb == null) { device.setOnLine(true); device.setCreateTime(now); + device.setUpdateTime(now); logger.info("[设备上线,首次注册]: {},查询设备信息以及通道信息", device.getDeviceId()); deviceMapper.add(device); redisCatchStorage.updateDevice(device); @@ -389,63 +390,11 @@ public class DeviceServiceImpl implements IDeviceService { if (device == null) { return null; } - if (parentId == null || parentId.equals(deviceId)) { - // 字根节点开始查询 - List 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 channels = deviceChannelMapper.getChannelsByCivilCode(deviceId, parentId); - List> trees = transportChannelsToTree(channels, parentId); - return trees; - } - // 查询其下的行政区划和摄像机 - List channelsForCivilCode = deviceChannelMapper.getChannelsWithCivilCodeAndLength(deviceId, parentId, parentId.length() + 2); - if (!onlyCatalog) { - List channels = deviceChannelMapper.getChannelsByCivilCode(deviceId, parentId); - - 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> trees = transportChannelsToTree(channelsForCivilCode, parentId); - return trees; - - } - // 使用业务分组展示树 - if (TreeType.BUSINESS_GROUP.equals(device.getTreeType())) { - if (parentId.length() < 14 ) { - return null; - } - List deviceChannels = deviceChannelMapper.queryChannels(deviceId, parentId, null, null, null,null); - List> trees = transportChannelsToTree(deviceChannels, parentId); - return trees; - } - - return null; + List rootNodes = deviceChannelMapper.getSubChannelsByDeviceId(deviceId, parentId, onlyCatalog); + return transportChannelsToTree(rootNodes, ""); } @Override @@ -454,42 +403,11 @@ public class DeviceServiceImpl implements IDeviceService { if (device == null) { return null; } - if (parentId == null || parentId.equals(deviceId)) { - // 字根节点开始查询 - List 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 channels = deviceChannelMapper.getChannelsByCivilCode(deviceId, parentId); - return channels; - } - // 查询其下的行政区划和摄像机 - List channels = deviceChannelMapper.getChannelsByCivilCode(deviceId, parentId); - return channels; - - } - // 使用业务分组展示树 - if (TreeType.BUSINESS_GROUP.equals(device.getTreeType())) { - if (parentId.length() < 14 ) { - return null; - } - List deviceChannels = deviceChannelMapper.queryChannels(deviceId, parentId, null, null, null,null); - return deviceChannels; - } - - return null; } private List> transportChannelsToTree(List channels, String parentId) { @@ -509,13 +427,21 @@ public class DeviceServiceImpl implements IDeviceService { node.setPid(parentId); node.setBasicData(channel); node.setParent(false); - if (channel.getChannelId().length() > 8) { - if (channel.getChannelId().length() > 13) { - 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); } @@ -523,53 +449,6 @@ public class DeviceServiceImpl implements IDeviceService { return treeNotes; } - private List getRootNodes(String deviceId, boolean isCivilCode, boolean haveCatalog, boolean haveChannel) { - if (!haveCatalog && !haveChannel) { - return null; - } - List result = new ArrayList<>(); - if (isCivilCode) { - // 使用行政区划 - Integer length= deviceChannelMapper.getChannelMinLength(deviceId); - if (length == null) { - return null; - } - if (length <= 10) { - if (haveCatalog) { - List provinceNode = deviceChannelMapper.getChannelsWithCivilCodeAndLength(deviceId, null, length); - if (provinceNode != null && provinceNode.size() > 0) { - result.addAll(provinceNode); - } - } - - if (haveChannel) { - // 查询那些civilCode不在通道中的不规范通道,放置在根目录 - List nonstandardNode = deviceChannelMapper.getChannelWithoutCivilCode(deviceId); - if (nonstandardNode != null && nonstandardNode.size() > 0) { - result.addAll(nonstandardNode); - } - } - }else { - if (haveChannel) { - List deviceChannels = deviceChannelMapper.queryChannels(deviceId, null, null, null, null,null); - if (deviceChannels != null && deviceChannels.size() > 0) { - result.addAll(deviceChannels); - } - } - } - - }else { - // 使用业务分组+虚拟组织 - - // 只获取业务分组 - List deviceChannels = deviceChannelMapper.getBusinessGroups(deviceId, ChannelIdType.BUSINESS_GROUP); - if (deviceChannels != null && deviceChannels.size() > 0) { - result.addAll(deviceChannels); - } - } - return result; - } - @Override public boolean isExist(String deviceId) { return deviceMapper.getDeviceByDeviceId(deviceId) != null; @@ -617,7 +496,6 @@ public class DeviceServiceImpl implements IDeviceService { } deviceInStore.setSdpIp(device.getSdpIp()); deviceInStore.setCharset(device.getCharset()); - deviceInStore.setTreeType(device.getTreeType()); // 目录订阅相关的信息 if (device.getSubscribeCycleForCatalog() > 0) { @@ -673,6 +551,9 @@ public class DeviceServiceImpl implements IDeviceService { }catch (Exception e) { dataSourceTransactionManager.rollback(transactionStatus); } + if (result) { + redisCatchStorage.removeDevice(deviceId); + } return result; } diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/GbStreamServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/GbStreamServiceImpl.java index 0cde5fe9..3fb2f93c 100644 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/GbStreamServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/GbStreamServiceImpl.java @@ -113,20 +113,15 @@ public class GbStreamServiceImpl implements IGbStreamService { deviceChannel.setStatus(gbStream.isStatus()); 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); 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"); diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/PlatformChannelServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/PlatformChannelServiceImpl.java index 7d827d73..eeea29a7 100644 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/PlatformChannelServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/PlatformChannelServiceImpl.java @@ -126,22 +126,17 @@ public class PlatformChannelServiceImpl implements IPlatformChannelService { List 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; diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/PlatformServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/PlatformServiceImpl.java index 63999b7c..e2e83c35 100644 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/PlatformServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/PlatformServiceImpl.java @@ -35,6 +35,8 @@ import java.util.Map; public class PlatformServiceImpl implements IPlatformService { private final static String REGISTER_KEY_PREFIX = "platform_register_"; + + private final static String REGISTER_FAIL_AGAIN_KEY_PREFIX = "platform_register_fail_again_"; private final static String KEEPALIVE_KEY_PREFIX = "platform_keepalive_"; private final static Logger logger = LoggerFactory.getLogger(PlatformServiceImpl.class); @@ -132,14 +134,6 @@ public class PlatformServiceImpl implements IPlatformService { 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(); @@ -150,12 +144,11 @@ public class PlatformServiceImpl implements IPlatformService { // 注销旧的 try { if (parentPlatformOld.isStatus()) { - logger.info("保存平台{}时发现救平台在线,发送注销命令", parentPlatformOld.getServerGBId()); + logger.info("保存平台{}时发现旧平台在线,发送注销命令", parentPlatformOld.getServerGBId()); commanderForPlatform.unregister(parentPlatformOld, parentPlatformCatchOld.getSipTransactionInfo(), null, eventResult -> { logger.info("[国标级联] 注销成功, 平台:{}", parentPlatformOld.getServerGBId()); }); } - } catch (InvalidArgumentException | ParseException | SipException e) { logger.error("[命令发送失败] 国标级联 注销: {}", e.getMessage()); } @@ -188,9 +181,6 @@ public class PlatformServiceImpl implements IPlatformService { logger.error("[命令发送失败] 国标级联: {}", e.getMessage()); } } - // 重新开启定时注册, 使用续订消息 - // 重新开始心跳保活 - return false; } @@ -199,6 +189,9 @@ public class PlatformServiceImpl implements IPlatformService { @Override public void online(ParentPlatform parentPlatform, SipTransactionInfo sipTransactionInfo) { logger.info("[国标级联]:{}, 平台上线", parentPlatform.getServerGBId()); + final String registerFailAgainTaskKey = REGISTER_FAIL_AGAIN_KEY_PREFIX + parentPlatform.getServerGBId(); + dynamicTask.stop(registerFailAgainTaskKey); + platformMapper.updateParentPlatformStatus(parentPlatform.getServerGBId(), true); ParentPlatformCatch parentPlatformCatch = redisCatchStorage.queryPlatformCatchInfo(parentPlatform.getServerGBId()); if (parentPlatformCatch == null) { @@ -239,15 +232,9 @@ public class PlatformServiceImpl implements IPlatformService { // 此时是第三次心跳超时, 平台离线 if (platformCatch.getKeepAliveReply() == 2) { // 设置平台离线,并重新注册 - logger.info("[国标级联] {},三次心跳超时后再次发起注册", parentPlatform.getServerGBId()); - try { - commanderForPlatform.register(parentPlatform, eventResult1 -> { - logger.info("[国标级联] {},三次心跳超时后再次发起注册仍然失败,开始定时发起注册,间隔为1分钟", parentPlatform.getServerGBId()); - offline(parentPlatform, false); - }, null); - } catch (InvalidArgumentException | ParseException | SipException e) { - logger.error("[命令发送失败] 国标级联 注册: {}", e.getMessage()); - } + logger.info("[国标级联] 三次心跳超时, 平台{}({})离线", parentPlatform.getName(), parentPlatform.getServerGBId()); + offline(parentPlatform, false); + } }else { @@ -273,21 +260,22 @@ public class PlatformServiceImpl implements IPlatformService { private void registerTask(ParentPlatform parentPlatform, SipTransactionInfo sipTransactionInfo){ try { - // 设置超时重发, 后续从底层支持消息重发 - String key = KEEPALIVE_KEY_PREFIX + parentPlatform.getServerGBId() + "_timeout"; - if (dynamicTask.isAlive(key)) { - return; + // 不在同一个会话中续订则每次全新注册 + if (!userSetting.isRegisterKeepIntDialog()) { + sipTransactionInfo = null; } - dynamicTask.startDelay(key, ()->{ - registerTask(parentPlatform, sipTransactionInfo); - }, 1000); - logger.info("[国标级联] 平台:{}注册即将到期,开始续订", parentPlatform.getServerGBId()); + + if (sipTransactionInfo == null) { + logger.info("[国标级联] 平台:{}注册即将到期,开始重新注册", parentPlatform.getServerGBId()); + }else { + logger.info("[国标级联] 平台:{}注册即将到期,开始续订", parentPlatform.getServerGBId()); + } + commanderForPlatform.register(parentPlatform, sipTransactionInfo, eventResult -> { - dynamicTask.stop(key); + logger.info("[国标级联] 平台:{}注册失败,{}:{}", parentPlatform.getServerGBId(), + eventResult.statusCode, eventResult.msg); offline(parentPlatform, false); - },eventResult -> { - dynamicTask.stop(key); - }); + }, null); } catch (InvalidArgumentException | ParseException | SipException e) { logger.error("[命令发送失败] 国标级联定时注册: {}", e.getMessage()); } @@ -308,24 +296,35 @@ public class PlatformServiceImpl implements IPlatformService { // 停止所有推流 logger.info("[平台离线] {}, 停止所有推流", parentPlatform.getServerGBId()); stopAllPush(parentPlatform.getServerGBId()); - if (stopRegister) { - // 清除注册定时 - logger.info("[平台离线] {}, 停止定时注册任务", parentPlatform.getServerGBId()); - final String registerTaskKey = REGISTER_KEY_PREFIX + parentPlatform.getServerGBId(); - if (dynamicTask.contains(registerTaskKey)) { - dynamicTask.stop(registerTaskKey); - } + + // 清除注册定时 + logger.info("[平台离线] {}, 停止定时注册任务", parentPlatform.getServerGBId()); + final String registerTaskKey = REGISTER_KEY_PREFIX + parentPlatform.getServerGBId(); + if (dynamicTask.contains(registerTaskKey)) { + dynamicTask.stop(registerTaskKey); } // 清除心跳定时 logger.info("[平台离线] {}, 停止定时发送心跳任务", parentPlatform.getServerGBId()); final String keepaliveTaskKey = KEEPALIVE_KEY_PREFIX + parentPlatform.getServerGBId(); if (dynamicTask.contains(keepaliveTaskKey)) { - // 添加心跳任务 + // 清除心跳任务 dynamicTask.stop(keepaliveTaskKey); } // 停止目录订阅回复 logger.info("[平台离线] {}, 停止订阅回复", parentPlatform.getServerGBId()); subscribeHolder.removeAllSubscribe(parentPlatform.getServerGBId()); + // 发起定时自动重新注册 + if (!stopRegister) { + // 设置为60秒自动尝试重新注册 + final String registerFailAgainTaskKey = REGISTER_FAIL_AGAIN_KEY_PREFIX + parentPlatform.getServerGBId(); + ParentPlatform platform = platformMapper.getParentPlatById(parentPlatform.getId()); + if (platform.isEnable()) { + dynamicTask.startCron(registerFailAgainTaskKey, + ()-> registerTask(platform, null), + userSetting.getRegisterAgainAfterTime() * 1000); + } + + } } private void stopAllPush(String platformId) { diff --git a/src/main/java/com/genersoft/iot/vmp/storager/dao/DeviceChannelMapper.java b/src/main/java/com/genersoft/iot/vmp/storager/dao/DeviceChannelMapper.java index abcfe9b1..333a3af6 100644 --- a/src/main/java/com/genersoft/iot/vmp/storager/dao/DeviceChannelMapper.java +++ b/src/main/java/com/genersoft/iot/vmp/storager/dao/DeviceChannelMapper.java @@ -451,10 +451,18 @@ public interface DeviceChannelMapper { @Select("select count(1) from wvp_device_channel") int getAllChannelCount(); - - /*=================设备主子码流逻辑START==============*/ + // 设备主子码流逻辑START @Update(value = {"UPDATE wvp_device_channel SET stream_id=null WHERE device_id=#{deviceId}"}) void clearPlay(String deviceId); - /*=================设备主子码流逻辑END==============*/ + // 设备主子码流逻辑END + @Select(value = {" "}) + List getSubChannelsByDeviceId(String deviceId, String parentId, boolean onlyCatalog); } diff --git a/src/main/java/com/genersoft/iot/vmp/storager/dao/DeviceMapper.java b/src/main/java/com/genersoft/iot/vmp/storager/dao/DeviceMapper.java index 8162df91..96773fe9 100644 --- a/src/main/java/com/genersoft/iot/vmp/storager/dao/DeviceMapper.java +++ b/src/main/java/com/genersoft/iot/vmp/storager/dao/DeviceMapper.java @@ -40,7 +40,6 @@ public interface DeviceMapper { "ssrc_check," + "as_message_channel," + "geo_coord_sys," + - "tree_type," + "on_line," + "media_server_id," + "switch_primary_sub_stream," + @@ -75,7 +74,6 @@ public interface DeviceMapper { "ssrc_check,"+ "as_message_channel,"+ "geo_coord_sys,"+ - "tree_type,"+ "on_line"+ ") VALUES (" + "#{deviceId}," + @@ -104,7 +102,6 @@ public interface DeviceMapper { "#{ssrcCheck}," + "#{asMessageChannel}," + "#{geoCoordSys}," + - "#{treeType}," + "#{onLine}" + ")") int add(Device device); @@ -159,7 +156,6 @@ public interface DeviceMapper { "ssrc_check,"+ "as_message_channel,"+ "geo_coord_sys,"+ - "tree_type,"+ "on_line,"+ "media_server_id,"+ "switch_primary_sub_stream switchPrimarySubStream,"+ @@ -201,7 +197,6 @@ public interface DeviceMapper { "ssrc_check,"+ "as_message_channel,"+ "geo_coord_sys,"+ - "tree_type,"+ "on_line"+ " FROM wvp_device WHERE on_line = true") List getOnlineDevices(); @@ -232,7 +227,6 @@ public interface DeviceMapper { "ssrc_check,"+ "as_message_channel,"+ "geo_coord_sys,"+ - "tree_type,"+ "on_line"+ " FROM wvp_device WHERE ip = #{host} AND port=#{port}") Device getDeviceByHostAndPort(String host, int port); @@ -254,7 +248,6 @@ public interface DeviceMapper { ", ssrc_check=#{ssrcCheck}" + ", as_message_channel=#{asMessageChannel}" + ", geo_coord_sys=#{geoCoordSys}" + - ", tree_type=#{treeType}" + ", switch_primary_sub_stream=#{switchPrimarySubStream}" + ", media_server_id=#{mediaServerId}" + "WHERE device_id=#{deviceId}"+ @@ -272,7 +265,6 @@ public interface DeviceMapper { "ssrc_check,"+ "as_message_channel,"+ "geo_coord_sys,"+ - "tree_type,"+ "on_line,"+ "media_server_id,"+ "switch_primary_sub_stream"+ @@ -287,7 +279,6 @@ public interface DeviceMapper { "#{ssrcCheck}," + "#{asMessageChannel}," + "#{geoCoordSys}," + - "#{treeType}," + "#{onLine}," + "#{mediaServerId}," + "#{switchPrimarySubStream}" + diff --git a/src/main/java/com/genersoft/iot/vmp/storager/dao/ParentPlatformMapper.java b/src/main/java/com/genersoft/iot/vmp/storager/dao/ParentPlatformMapper.java index 2c6852af..386d7dc0 100644 --- a/src/main/java/com/genersoft/iot/vmp/storager/dao/ParentPlatformMapper.java +++ b/src/main/java/com/genersoft/iot/vmp/storager/dao/ParentPlatformMapper.java @@ -16,10 +16,10 @@ public interface ParentPlatformMapper { @Insert("INSERT INTO wvp_platform (enable, name, server_gb_id, server_gb_domain, server_ip, server_port,device_gb_id,device_ip,"+ "device_port,username,password,expires,keep_timeout,transport,character_set,ptz,rtcp,as_message_channel,"+ - "status,start_offline_push,catalog_id,administrative_division,catalog_group,create_time,update_time,tree_type) " + + "status,start_offline_push,catalog_id,administrative_division,catalog_group,create_time,update_time) " + " VALUES (#{enable}, #{name}, #{serverGBId}, #{serverGBDomain}, #{serverIP}, #{serverPort}, #{deviceGBId}, #{deviceIp}, " + " #{devicePort}, #{username}, #{password}, #{expires}, #{keepTimeout}, #{transport}, #{characterSet}, #{ptz}, #{rtcp}, #{asMessageChannel}, " + - " #{status}, #{startOfflinePush}, #{catalogId}, #{administrativeDivision}, #{catalogGroup}, #{createTime}, #{updateTime}, #{treeType})") + " #{status}, #{startOfflinePush}, #{catalogId}, #{administrativeDivision}, #{catalogGroup}, #{createTime}, #{updateTime})") int addParentPlatform(ParentPlatform parentPlatform); @Update("UPDATE wvp_platform " + @@ -47,7 +47,6 @@ public interface ParentPlatformMapper { "administrative_division=#{administrativeDivision}, " + "create_time=#{createTime}, " + "update_time=#{updateTime}, " + - "tree_type=#{treeType}, " + "catalog_id=#{catalogId} " + "WHERE id=#{id}") int updateParentPlatform(ParentPlatform parentPlatform); diff --git a/src/main/java/com/genersoft/iot/vmp/storager/impl/VideoManagerStorageImpl.java b/src/main/java/com/genersoft/iot/vmp/storager/impl/VideoManagerStorageImpl.java index f73339d1..1d4c3553 100644 --- a/src/main/java/com/genersoft/iot/vmp/storager/impl/VideoManagerStorageImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/storager/impl/VideoManagerStorageImpl.java @@ -128,51 +128,56 @@ public class VideoManagerStorageImpl implements IVideoManagerStorage { List addChannels = new ArrayList<>(); StringBuilder stringBuilder = new StringBuilder(); Map subContMap = new HashMap<>(); - if (deviceChannelList.size() > 0) { - // 数据去重 - Set gbIdSet = new HashSet<>(); - for (DeviceChannel deviceChannel : deviceChannelList) { - if (!gbIdSet.contains(deviceChannel.getChannelId())) { - gbIdSet.add(deviceChannel.getChannelId()); - deviceChannel.setUpdateTime(DateUtil.getNow()); - if (allChannelMap.containsKey(deviceChannel.getChannelId())) { - deviceChannel.setStreamId(allChannelMap.get(deviceChannel.getChannelId()).getStreamId()); - deviceChannel.setHasAudio(allChannelMap.get(deviceChannel.getChannelId()).isHasAudio()); - if (allChannelMap.get(deviceChannel.getChannelId()).isStatus() !=deviceChannel.isStatus()){ - List strings = platformChannelMapper.queryParentPlatformByChannelId(deviceChannel.getChannelId()); - if (!CollectionUtils.isEmpty(strings)){ - strings.forEach(platformId->{ - eventPublisher.catalogEventPublish(platformId, deviceChannel, deviceChannel.isStatus()?CatalogEvent.ON:CatalogEvent.OFF); - }); - } - } - updateChannels.add(deviceChannel); - }else { - deviceChannel.setCreateTime(DateUtil.getNow()); - addChannels.add(deviceChannel); - } - 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++); - } - } - }else { - stringBuilder.append(deviceChannel.getChannelId()).append(","); - } - } - if (channels.size() > 0) { - for (DeviceChannel channel : channels) { - if (subContMap.get(channel.getChannelId()) != null){ - channel.setSubCount(subContMap.get(channel.getChannelId())); - } - } - } + // 数据去重 + Set 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()).isStatus() !=deviceChannel.isStatus()){ + List strings = platformChannelMapper.queryParentPlatformByChannelId(deviceChannel.getChannelId()); + if (!CollectionUtils.isEmpty(strings)){ + strings.forEach(platformId->{ + eventPublisher.catalogEventPublish(platformId, deviceChannel, deviceChannel.isStatus()?CatalogEvent.ON:CatalogEvent.OFF); + }); + } + + } + deviceChannel.setUpdateTime(DateUtil.getNow()); + updateChannels.add(deviceChannel); + }else { + deviceChannel.setCreateTime(DateUtil.getNow()); + deviceChannel.setUpdateTime(DateUtil.getNow()); + addChannels.add(deviceChannel); + } + 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++); + } + } } + 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); } @@ -795,25 +800,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); @@ -937,19 +966,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(true); 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"); diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/platform/PlatformController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/platform/PlatformController.java index 1b2a8f3f..7cf78e9c 100644 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/platform/PlatformController.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/platform/PlatformController.java @@ -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); diff --git a/src/main/resources/all-application.yml b/src/main/resources/all-application.yml index d67eac5a..0b079f10 100644 --- a/src/main/resources/all-application.yml +++ b/src/main/resources/all-application.yml @@ -202,6 +202,10 @@ user-settings: device-status-notify: false # 上级平台点播时不使用上级平台指定的ssrc,使用自定义的ssrc,参考国标文档-点播外域设备媒体流SSRC处理方式 use-custom-ssrc-for-parent-invite: true + # 国标级联离线后多久重试一次注册 + register-again-after-time: 60 + # 国标续订方式,true为续订,每次注册在同一个会话里,false为重新注册,每次使用新的会话 + register-keep-int-dialog: false # 跨域配置,配置你访问前端页面的地址即可, 可以配置多个 allowed-origins: - http://localhost:8008 diff --git a/src/main/resources/civilCode.csv b/src/main/resources/civilCode.csv new file mode 100644 index 00000000..7785924f --- /dev/null +++ b/src/main/resources/civilCode.csv @@ -0,0 +1,3220 @@ +编号,名称,上级 +11,北京市, +110101,东城区,11 +110102,西城区,11 +110105,朝阳区,11 +110106,丰台区,11 +110107,石景山区,11 +110108,海淀区,11 +110109,门头沟区,11 +110111,房山区,11 +110112,通州区,11 +110113,顺义区,11 +110114,昌平区,11 +110115,大兴区,11 +110116,怀柔区,11 +110117,平谷区,11 +110118,密云区,11 +110119,延庆区,11 +12,天津市, +120101,和平区,12 +120102,河东区,12 +120103,河西区,12 +120104,南开区,12 +120105,河北区,12 +120106,红桥区,12 +120110,东丽区,12 +120111,西青区,12 +120112,津南区,12 +120113,北辰区,12 +120114,武清区,12 +120115,宝坻区,12 +120116,滨海新区,12 +120117,宁河区,12 +120118,静海区,12 +120119,蓟州区,12 +13,河北省, +1301,石家庄市,13 +130102,长安区,1301 +130104,桥西区,1301 +130105,新华区,1301 +130107,井陉矿区,1301 +130108,裕华区,1301 +130109,藁城区,1301 +130110,鹿泉区,1301 +130111,栾城区,1301 +130121,井陉县,1301 +130123,正定县,1301 +130125,行唐县,1301 +130126,灵寿县,1301 +130127,高邑县,1301 +130128,深泽县,1301 +130129,赞皇县,1301 +130130,无极县,1301 +130131,平山县,1301 +130132,元氏县,1301 +130133,赵县,1301 +130181,辛集市,1301 +130183,晋州市,1301 +130184,新乐市,1301 +1302,唐山市,13 +130202,路南区,1302 +130203,路北区,1302 +130204,古冶区,1302 +130205,开平区,1302 +130207,丰南区,1302 +130208,丰润区,1302 +130209,曹妃甸区,1302 +130224,滦南县,1302 +130225,乐亭县,1302 +130227,迁西县,1302 +130229,玉田县,1302 +130281,遵化市,1302 +130283,迁安市,1302 +130284,滦州市,1302 +1303,秦皇岛市,13 +130302,海港区,1303 +130303,山海关区,1303 +130304,北戴河区,1303 +130306,抚宁区,1303 +130321,青龙满族自治县,1303 +130322,昌黎县,1303 +130324,卢龙县,1303 +1304,邯郸市,13 +130402,邯山区,1304 +130403,丛台区,1304 +130404,复兴区,1304 +130406,峰峰矿区,1304 +130407,肥乡区,1304 +130408,永年区,1304 +130423,临漳县,1304 +130424,成安县,1304 +130425,大名县,1304 +130426,涉县,1304 +130427,磁县,1304 +130430,邱县,1304 +130431,鸡泽县,1304 +130432,广平县,1304 +130433,馆陶县,1304 +130434,魏县,1304 +130435,曲周县,1304 +130481,武安市,1304 +1305,邢台市,13 +130502,桥东区,1305 +130503,桥西区,1305 +130521,邢台县,1305 +130522,临城县,1305 +130523,内丘县,1305 +130524,柏乡县,1305 +130525,隆尧县,1305 +130526,任县,1305 +130527,南和县,1305 +130528,宁晋县,1305 +130529,巨鹿县,1305 +130530,新河县,1305 +130531,广宗县,1305 +130532,平乡县,1305 +130533,威县,1305 +130534,清河县,1305 +130535,临西县,1305 +130581,南宫市,1305 +130582,沙河市,1305 +1306,保定市,13 +130602,竞秀区,1306 +130606,莲池区,1306 +130607,满城区,1306 +130608,清苑区,1306 +130609,徐水区,1306 +130623,涞水县,1306 +130624,阜平县,1306 +130626,定兴县,1306 +130627,唐县,1306 +130628,高阳县,1306 +130629,容城县,1306 +130630,涞源县,1306 +130631,望都县,1306 +130632,安新县,1306 +130633,易县,1306 +130634,曲阳县,1306 +130635,蠡县,1306 +130636,顺平县,1306 +130637,博野县,1306 +130638,雄县,1306 +130681,涿州市,1306 +130682,定州市,1306 +130683,安国市,1306 +130684,高碑店市,1306 +1307,张家口市,13 +130702,桥东区,1307 +130703,桥西区,1307 +130705,宣化区,1307 +130706,下花园区,1307 +130708,万全区,1307 +130709,崇礼区,1307 +130722,张北县,1307 +130723,康保县,1307 +130724,沽源县,1307 +130725,尚义县,1307 +130726,蔚县,1307 +130727,阳原县,1307 +130728,怀安县,1307 +130730,怀来县,1307 +130731,涿鹿县,1307 +130732,赤城县,1307 +1308,承德市,13 +130802,双桥区,1308 +130803,双滦区,1308 +130804,鹰手营子矿区,1308 +130821,承德县,1308 +130822,兴隆县,1308 +130824,滦平县,1308 +130825,隆化县,1308 +130826,丰宁满族自治县,1308 +130827,宽城满族自治县,1308 +130828,围场满族蒙古族自治县,1308 +130881,平泉市,1308 +1309,沧州市,13 +130902,新华区,1309 +130903,运河区,1309 +130921,沧县,1309 +130922,青县,1309 +130923,东光县,1309 +130924,海兴县,1309 +130925,盐山县,1309 +130926,肃宁县,1309 +130927,南皮县,1309 +130928,吴桥县,1309 +130929,献县,1309 +130930,孟村回族自治县,1309 +130981,泊头市,1309 +130982,任丘市,1309 +130983,黄骅市,1309 +130984,河间市,1309 +1310,廊坊市,13 +131002,安次区,1310 +131003,广阳区,1310 +131022,固安县,1310 +131023,永清县,1310 +131024,香河县,1310 +131025,大城县,1310 +131026,文安县,1310 +131028,大厂回族自治县,1310 +131081,霸州市,1310 +131082,三河市,1310 +1311,衡水市,13 +131102,桃城区,1311 +131103,冀州区,1311 +131121,枣强县,1311 +131122,武邑县,1311 +131123,武强县,1311 +131124,饶阳县,1311 +131125,安平县,1311 +131126,故城县,1311 +131127,景县,1311 +131128,阜城县,1311 +131182,深州市,1311 +14,山西省, +1401,太原市,14 +140105,小店区,1401 +140106,迎泽区,1401 +140107,杏花岭区,1401 +140108,尖草坪区,1401 +140109,万柏林区,1401 +140110,晋源区,1401 +140121,清徐县,1401 +140122,阳曲县,1401 +140123,娄烦县,1401 +140181,古交市,1401 +1402,大同市,14 +140212,新荣区,1402 +140213,平城区,1402 +140214,云冈区,1402 +140215,云州区,1402 +140221,阳高县,1402 +140222,天镇县,1402 +140223,广灵县,1402 +140224,灵丘县,1402 +140225,浑源县,1402 +140226,左云县,1402 +1403,阳泉市,14 +140302,城区,1403 +140303,矿区,1403 +140311,郊区,1403 +140321,平定县,1403 +140322,盂县,1403 +1404,长治市,14 +140403,潞州区,1404 +140404,上党区,1404 +140405,屯留区,1404 +140406,潞城区,1404 +140423,襄垣县,1404 +140425,平顺县,1404 +140426,黎城县,1404 +140427,壶关县,1404 +140428,长子县,1404 +140429,武乡县,1404 +140430,沁县,1404 +140431,沁源县,1404 +1405,晋城市,14 +140502,城区,1405 +140521,沁水县,1405 +140522,阳城县,1405 +140524,陵川县,1405 +140525,泽州县,1405 +140581,高平市,1405 +1406,朔州市,14 +140602,朔城区,1406 +140603,平鲁区,1406 +140621,山阴县,1406 +140622,应县,1406 +140623,右玉县,1406 +140681,怀仁市,1406 +1407,晋中市,14 +140702,榆次区,1407 +140721,榆社县,1407 +140722,左权县,1407 +140723,和顺县,1407 +140724,昔阳县,1407 +140725,寿阳县,1407 +140726,太谷县,1407 +140727,祁县,1407 +140728,平遥县,1407 +140729,灵石县,1407 +140781,介休市,1407 +1408,运城市,14 +140802,盐湖区,1408 +140821,临猗县,1408 +140822,万荣县,1408 +140823,闻喜县,1408 +140824,稷山县,1408 +140825,新绛县,1408 +140826,绛县,1408 +140827,垣曲县,1408 +140828,夏县,1408 +140829,平陆县,1408 +140830,芮城县,1408 +140881,永济市,1408 +140882,河津市,1408 +1409,忻州市,14 +140902,忻府区,1409 +140921,定襄县,1409 +140922,五台县,1409 +140923,代县,1409 +140924,繁峙县,1409 +140925,宁武县,1409 +140926,静乐县,1409 +140927,神池县,1409 +140928,五寨县,1409 +140929,岢岚县,1409 +140930,河曲县,1409 +140931,保德县,1409 +140932,偏关县,1409 +140981,原平市,1409 +1410,临汾市,14 +141002,尧都区,1410 +141021,曲沃县,1410 +141022,翼城县,1410 +141023,襄汾县,1410 +141024,洪洞县,1410 +141025,古县,1410 +141026,安泽县,1410 +141027,浮山县,1410 +141028,吉县,1410 +141029,乡宁县,1410 +141030,大宁县,1410 +141031,隰县,1410 +141032,永和县,1410 +141033,蒲县,1410 +141034,汾西县,1410 +141081,侯马市,1410 +141082,霍州市,1410 +1411,吕梁市,14 +141102,离石区,1411 +141121,文水县,1411 +141122,交城县,1411 +141123,兴县,1411 +141124,临县,1411 +141125,柳林县,1411 +141126,石楼县,1411 +141127,岚县,1411 +141128,方山县,1411 +141129,中阳县,1411 +141130,交口县,1411 +141181,孝义市,1411 +141182,汾阳市,1411 +15,内蒙古自治区, +1501,呼和浩特市,15 +150102,新城区,1501 +150103,回民区,1501 +150104,玉泉区,1501 +150105,赛罕区,1501 +150121,土默特左旗,1501 +150122,托克托县,1501 +150123,和林格尔县,1501 +150124,清水河县,1501 +150125,武川县,1501 +1502,包头市,15 +150202,东河区,1502 +150203,昆都仑区,1502 +150204,青山区,1502 +150205,石拐区,1502 +150206,白云鄂博矿区,1502 +150207,九原区,1502 +150221,土默特右旗,1502 +150222,固阳县,1502 +150223,达尔罕茂明安联合旗,1502 +1503,乌海市,15 +150302,海勃湾区,1503 +150303,海南区,1503 +150304,乌达区,1503 +1504,赤峰市,15 +150402,红山区,1504 +150403,元宝山区,1504 +150404,松山区,1504 +150421,阿鲁科尔沁旗,1504 +150422,巴林左旗,1504 +150423,巴林右旗,1504 +150424,林西县,1504 +150425,克什克腾旗,1504 +150426,翁牛特旗,1504 +150428,喀喇沁旗,1504 +150429,宁城县,1504 +150430,敖汉旗,1504 +1505,通辽市,15 +150502,科尔沁区,1505 +150521,科尔沁左翼中旗,1505 +150522,科尔沁左翼后旗,1505 +150523,开鲁县,1505 +150524,库伦旗,1505 +150525,奈曼旗,1505 +150526,扎鲁特旗,1505 +150581,霍林郭勒市,1505 +1506,鄂尔多斯市,15 +150602,东胜区,1506 +150603,康巴什区,1506 +150621,达拉特旗,1506 +150622,准格尔旗,1506 +150623,鄂托克前旗,1506 +150624,鄂托克旗,1506 +150625,杭锦旗,1506 +150626,乌审旗,1506 +150627,伊金霍洛旗,1506 +1507,呼伦贝尔市,15 +150702,海拉尔区,1507 +150703,扎赉诺尔区,1507 +150721,阿荣旗,1507 +150722,莫力达瓦达斡尔族自治旗,1507 +150723,鄂伦春自治旗,1507 +150724,鄂温克族自治旗,1507 +150725,陈巴尔虎旗,1507 +150726,新巴尔虎左旗,1507 +150727,新巴尔虎右旗,1507 +150781,满洲里市,1507 +150782,牙克石市,1507 +150783,扎兰屯市,1507 +150784,额尔古纳市,1507 +150785,根河市,1507 +1508,巴彦淖尔市,15 +150802,临河区,1508 +150821,五原县,1508 +150822,磴口县,1508 +150823,乌拉特前旗,1508 +150824,乌拉特中旗,1508 +150825,乌拉特后旗,1508 +150826,杭锦后旗,1508 +1509,乌兰察布市,15 +150902,集宁区,1509 +150921,卓资县,1509 +150922,化德县,1509 +150923,商都县,1509 +150924,兴和县,1509 +150925,凉城县,1509 +150926,察哈尔右翼前旗,1509 +150927,察哈尔右翼中旗,1509 +150928,察哈尔右翼后旗,1509 +150929,四子王旗,1509 +150981,丰镇市,1509 +1522,兴安盟,15 +152201,乌兰浩特市,1522 +152202,阿尔山市,1522 +152221,科尔沁右翼前旗,1522 +152222,科尔沁右翼中旗,1522 +152223,扎赉特旗,1522 +152224,突泉县,1522 +1525,锡林郭勒盟,15 +152501,二连浩特市,1525 +152502,锡林浩特市,1525 +152522,阿巴嘎旗,1525 +152523,苏尼特左旗,1525 +152524,苏尼特右旗,1525 +152525,东乌珠穆沁旗,1525 +152526,西乌珠穆沁旗,1525 +152527,太仆寺旗,1525 +152528,镶黄旗,1525 +152529,正镶白旗,1525 +152530,正蓝旗,1525 +152531,多伦县,1525 +1529,阿拉善盟,15 +152921,阿拉善左旗,1529 +152922,阿拉善右旗,1529 +152923,额济纳旗,1529 +21,辽宁省, +2101,沈阳市,21 +210102,和平区,2101 +210103,沈河区,2101 +210104,大东区,2101 +210105,皇姑区,2101 +210106,铁西区,2101 +210111,苏家屯区,2101 +210112,浑南区,2101 +210113,沈北新区,2101 +210114,于洪区,2101 +210115,辽中区,2101 +210123,康平县,2101 +210124,法库县,2101 +210181,新民市,2101 +2102,大连市,21 +210202,中山区,2102 +210203,西岗区,2102 +210204,沙河口区,2102 +210211,甘井子区,2102 +210212,旅顺口区,2102 +210213,金州区,2102 +210214,普兰店区,2102 +210224,长海县,2102 +210281,瓦房店市,2102 +210283,庄河市,2102 +2103,鞍山市,21 +210302,铁东区,2103 +210303,铁西区,2103 +210304,立山区,2103 +210311,千山区,2103 +210321,台安县,2103 +210323,岫岩满族自治县,2103 +210381,海城市,2103 +2104,抚顺市,21 +210402,新抚区,2104 +210403,东洲区,2104 +210404,望花区,2104 +210411,顺城区,2104 +210421,抚顺县,2104 +210422,新宾满族自治县,2104 +210423,清原满族自治县,2104 +2105,本溪市,21 +210502,平山区,2105 +210503,溪湖区,2105 +210504,明山区,2105 +210505,南芬区,2105 +210521,本溪满族自治县,2105 +210522,桓仁满族自治县,2105 +2106,丹东市,21 +210602,元宝区,2106 +210603,振兴区,2106 +210604,振安区,2106 +210624,宽甸满族自治县,2106 +210681,东港市,2106 +210682,凤城市,2106 +2107,锦州市,21 +210702,古塔区,2107 +210703,凌河区,2107 +210711,太和区,2107 +210726,黑山县,2107 +210727,义县,2107 +210781,凌海市,2107 +210782,北镇市,2107 +2108,营口市,21 +210802,站前区,2108 +210803,西市区,2108 +210804,鲅鱼圈区,2108 +210811,老边区,2108 +210881,盖州市,2108 +210882,大石桥市,2108 +2109,阜新市,21 +210902,海州区,2109 +210903,新邱区,2109 +210904,太平区,2109 +210905,清河门区,2109 +210911,细河区,2109 +210921,阜新蒙古族自治县,2109 +210922,彰武县,2109 +2110,辽阳市,21 +211002,白塔区,2110 +211003,文圣区,2110 +211004,宏伟区,2110 +211005,弓长岭区,2110 +211011,太子河区,2110 +211021,辽阳县,2110 +211081,灯塔市,2110 +2111,盘锦市,21 +211102,双台子区,2111 +211103,兴隆台区,2111 +211104,大洼区,2111 +211122,盘山县,2111 +2112,铁岭市,21 +211202,银州区,2112 +211204,清河区,2112 +211221,铁岭县,2112 +211223,西丰县,2112 +211224,昌图县,2112 +211281,调兵山市,2112 +211282,开原市,2112 +2113,朝阳市,21 +211302,双塔区,2113 +211303,龙城区,2113 +211321,朝阳县,2113 +211322,建平县,2113 +211324,喀喇沁左翼蒙古族自治县,2113 +211381,北票市,2113 +211382,凌源市,2113 +2114,葫芦岛市,21 +211402,连山区,2114 +211403,龙港区,2114 +211404,南票区,2114 +211421,绥中县,2114 +211422,建昌县,2114 +211481,兴城市,2114 +22,吉林省, +2201,长春市,22 +220102,南关区,2201 +220103,宽城区,2201 +220104,朝阳区,2201 +220105,二道区,2201 +220106,绿园区,2201 +220112,双阳区,2201 +220113,九台区,2201 +220122,农安县,2201 +220182,榆树市,2201 +220183,德惠市,2201 +2202,吉林市,22 +220202,昌邑区,2202 +220203,龙潭区,2202 +220204,船营区,2202 +220211,丰满区,2202 +220221,永吉县,2202 +220281,蛟河市,2202 +220282,桦甸市,2202 +220283,舒兰市,2202 +220284,磐石市,2202 +2203,四平市,22 +220302,铁西区,2203 +220303,铁东区,2203 +220322,梨树县,2203 +220323,伊通满族自治县,2203 +220381,公主岭市,2203 +220382,双辽市,2203 +2204,辽源市,22 +220402,龙山区,2204 +220403,西安区,2204 +220421,东丰县,2204 +220422,东辽县,2204 +2205,通化市,22 +220502,东昌区,2205 +220503,二道江区,2205 +220521,通化县,2205 +220523,辉南县,2205 +220524,柳河县,2205 +220581,梅河口市,2205 +220582,集安市,2205 +2206,白山市,22 +220602,浑江区,2206 +220605,江源区,2206 +220621,抚松县,2206 +220622,靖宇县,2206 +220623,长白朝鲜族自治县,2206 +220681,临江市,2206 +2207,松原市,22 +220702,宁江区,2207 +220721,前郭尔罗斯蒙古族自治县,2207 +220722,长岭县,2207 +220723,乾安县,2207 +220781,扶余市,2207 +2208,白城市,22 +220802,洮北区,2208 +220821,镇赉县,2208 +220822,通榆县,2208 +220881,洮南市,2208 +220882,大安市,2208 +2224,延边朝鲜族自治州,22 +222401,延吉市,2224 +222402,图们市,2224 +222403,敦化市,2224 +222404,珲春市,2224 +222405,龙井市,2224 +222406,和龙市,2224 +222424,汪清县,2224 +222426,安图县,2224 +23,黑龙江省, +2301,哈尔滨市,23 +230102,道里区,2301 +230103,南岗区,2301 +230104,道外区,2301 +230108,平房区,2301 +230109,松北区,2301 +230110,香坊区,2301 +230111,呼兰区,2301 +230112,阿城区,2301 +230113,双城区,2301 +230123,依兰县,2301 +230124,方正县,2301 +230125,宾县,2301 +230126,巴彦县,2301 +230127,木兰县,2301 +230128,通河县,2301 +230129,延寿县,2301 +230183,尚志市,2301 +230184,五常市,2301 +2302,齐齐哈尔市,23 +230202,龙沙区,2302 +230203,建华区,2302 +230204,铁锋区,2302 +230205,昂昂溪区,2302 +230206,富拉尔基区,2302 +230207,碾子山区,2302 +230208,梅里斯达斡尔族区,2302 +230221,龙江县,2302 +230223,依安县,2302 +230224,泰来县,2302 +230225,甘南县,2302 +230227,富裕县,2302 +230229,克山县,2302 +230230,克东县,2302 +230231,拜泉县,2302 +230281,讷河市,2302 +2303,鸡西市,23 +230302,鸡冠区,2303 +230303,恒山区,2303 +230304,滴道区,2303 +230305,梨树区,2303 +230306,城子河区,2303 +230307,麻山区,2303 +230321,鸡东县,2303 +230381,虎林市,2303 +230382,密山市,2303 +2304,鹤岗市,23 +230402,向阳区,2304 +230403,工农区,2304 +230404,南山区,2304 +230405,兴安区,2304 +230406,东山区,2304 +230407,兴山区,2304 +230421,萝北县,2304 +230422,绥滨县,2304 +2305,双鸭山市,23 +230502,尖山区,2305 +230503,岭东区,2305 +230505,四方台区,2305 +230506,宝山区,2305 +230521,集贤县,2305 +230522,友谊县,2305 +230523,宝清县,2305 +230524,饶河县,2305 +2306,大庆市,23 +230602,萨尔图区,2306 +230603,龙凤区,2306 +230604,让胡路区,2306 +230605,红岗区,2306 +230606,大同区,2306 +230621,肇州县,2306 +230622,肇源县,2306 +230623,林甸县,2306 +230624,杜尔伯特蒙古族自治县,2306 +2307,伊春市,23 +230702,伊春区,2307 +230703,南岔区,2307 +230704,友好区,2307 +230705,西林区,2307 +230706,翠峦区,2307 +230707,新青区,2307 +230708,美溪区,2307 +230709,金山屯区,2307 +230710,五营区,2307 +230711,乌马河区,2307 +230712,汤旺河区,2307 +230713,带岭区,2307 +230714,乌伊岭区,2307 +230715,红星区,2307 +230716,上甘岭区,2307 +230722,嘉荫县,2307 +230781,铁力市,2307 +2308,佳木斯市,23 +230803,向阳区,2308 +230804,前进区,2308 +230805,东风区,2308 +230811,郊区,2308 +230822,桦南县,2308 +230826,桦川县,2308 +230828,汤原县,2308 +230881,同江市,2308 +230882,富锦市,2308 +230883,抚远市,2308 +2309,七台河市,23 +230902,新兴区,2309 +230903,桃山区,2309 +230904,茄子河区,2309 +230921,勃利县,2309 +2310,牡丹江市,23 +231002,东安区,2310 +231003,阳明区,2310 +231004,爱民区,2310 +231005,西安区,2310 +231025,林口县,2310 +231081,绥芬河市,2310 +231083,海林市,2310 +231084,宁安市,2310 +231085,穆棱市,2310 +231086,东宁市,2310 +2311,黑河市,23 +231102,爱辉区,2311 +231121,嫩江县,2311 +231123,逊克县,2311 +231124,孙吴县,2311 +231181,北安市,2311 +231182,五大连池市,2311 +2312,绥化市,23 +231202,北林区,2312 +231221,望奎县,2312 +231222,兰西县,2312 +231223,青冈县,2312 +231224,庆安县,2312 +231225,明水县,2312 +231226,绥棱县,2312 +231281,安达市,2312 +231282,肇东市,2312 +231283,海伦市,2312 +2327,大兴安岭地区,23 +232701,漠河市,2327 +232721,呼玛县,2327 +232722,塔河县,2327 +31,上海市, +310101,黄浦区,31 +310104,徐汇区,31 +310105,长宁区,31 +310106,静安区,31 +310107,普陀区,31 +310109,虹口区,31 +310110,杨浦区,31 +310112,闵行区,31 +310113,宝山区,31 +310114,嘉定区,31 +310115,浦东新区,31 +310116,金山区,31 +310117,松江区,31 +310118,青浦区,31 +310120,奉贤区,31 +310151,崇明区,31 +32,江苏省, +3201,南京市,32 +320102,玄武区,3201 +320104,秦淮区,3201 +320105,建邺区,3201 +320106,鼓楼区,3201 +320111,浦口区,3201 +320113,栖霞区,3201 +320114,雨花台区,3201 +320115,江宁区,3201 +320116,六合区,3201 +320117,溧水区,3201 +320118,高淳区,3201 +3202,无锡市,32 +320205,锡山区,3202 +320206,惠山区,3202 +320211,滨湖区,3202 +320213,梁溪区,3202 +320214,新吴区,3202 +320281,江阴市,3202 +320282,宜兴市,3202 +3203,徐州市,32 +320302,鼓楼区,3203 +320303,云龙区,3203 +320305,贾汪区,3203 +320311,泉山区,3203 +320312,铜山区,3203 +320321,丰县,3203 +320322,沛县,3203 +320324,睢宁县,3203 +320381,新沂市,3203 +320382,邳州市,3203 +3204,常州市,32 +320402,天宁区,3204 +320404,钟楼区,3204 +320411,新北区,3204 +320412,武进区,3204 +320413,金坛区,3204 +320481,溧阳市,3204 +3205,苏州市,32 +320505,虎丘区,3205 +320506,吴中区,3205 +320507,相城区,3205 +320508,姑苏区,3205 +320509,吴江区,3205 +320581,常熟市,3205 +320582,张家港市,3205 +320583,昆山市,3205 +320585,太仓市,3205 +3206,南通市,32 +320602,崇川区,3206 +320611,港闸区,3206 +320612,通州区,3206 +320623,如东县,3206 +320681,启东市,3206 +320682,如皋市,3206 +320684,海门市,3206 +320685,海安市,3206 +3207,连云港市,32 +320703,连云区,3207 +320706,海州区,3207 +320707,赣榆区,3207 +320722,东海县,3207 +320723,灌云县,3207 +320724,灌南县,3207 +3208,淮安市,32 +320803,淮安区,3208 +320804,淮阴区,3208 +320812,清江浦区,3208 +320813,洪泽区,3208 +320826,涟水县,3208 +320830,盱眙县,3208 +320831,金湖县,3208 +3209,盐城市,32 +320902,亭湖区,3209 +320903,盐都区,3209 +320904,大丰区,3209 +320921,响水县,3209 +320922,滨海县,3209 +320923,阜宁县,3209 +320924,射阳县,3209 +320925,建湖县,3209 +320981,东台市,3209 +3210,扬州市,32 +321002,广陵区,3210 +321003,邗江区,3210 +321012,江都区,3210 +321023,宝应县,3210 +321081,仪征市,3210 +321084,高邮市,3210 +3211,镇江市,32 +321102,京口区,3211 +321111,润州区,3211 +321112,丹徒区,3211 +321181,丹阳市,3211 +321182,扬中市,3211 +321183,句容市,3211 +3212,泰州市,32 +321202,海陵区,3212 +321203,高港区,3212 +321204,姜堰区,3212 +321281,兴化市,3212 +321282,靖江市,3212 +321283,泰兴市,3212 +3213,宿迁市,32 +321302,宿城区,3213 +321311,宿豫区,3213 +321322,沭阳县,3213 +321323,泗阳县,3213 +321324,泗洪县,3213 +33,浙江省, +3301,杭州市,33 +330102,上城区,3301 +330103,下城区,3301 +330104,江干区,3301 +330105,拱墅区,3301 +330106,西湖区,3301 +330108,滨江区,3301 +330109,萧山区,3301 +330110,余杭区,3301 +330111,富阳区,3301 +330112,临安区,3301 +330122,桐庐县,3301 +330127,淳安县,3301 +330182,建德市,3301 +3302,宁波市,33 +330203,海曙区,3302 +330205,江北区,3302 +330206,北仑区,3302 +330211,镇海区,3302 +330212,鄞州区,3302 +330213,奉化区,3302 +330225,象山县,3302 +330226,宁海县,3302 +330281,余姚市,3302 +330282,慈溪市,3302 +3303,温州市,33 +330302,鹿城区,3303 +330303,龙湾区,3303 +330304,瓯海区,3303 +330305,洞头区,3303 +330324,永嘉县,3303 +330326,平阳县,3303 +330327,苍南县,3303 +330328,文成县,3303 +330329,泰顺县,3303 +330381,瑞安市,3303 +330382,乐清市,3303 +3304,嘉兴市,33 +330402,南湖区,3304 +330411,秀洲区,3304 +330421,嘉善县,3304 +330424,海盐县,3304 +330481,海宁市,3304 +330482,平湖市,3304 +330483,桐乡市,3304 +3305,湖州市,33 +330502,吴兴区,3305 +330503,南浔区,3305 +330521,德清县,3305 +330522,长兴县,3305 +330523,安吉县,3305 +3306,绍兴市,33 +330602,越城区,3306 +330603,柯桥区,3306 +330604,上虞区,3306 +330624,新昌县,3306 +330681,诸暨市,3306 +330683,嵊州市,3306 +3307,金华市,33 +330702,婺城区,3307 +330703,金东区,3307 +330723,武义县,3307 +330726,浦江县,3307 +330727,磐安县,3307 +330781,兰溪市,3307 +330782,义乌市,3307 +330783,东阳市,3307 +330784,永康市,3307 +3308,衢州市,33 +330802,柯城区,3308 +330803,衢江区,3308 +330822,常山县,3308 +330824,开化县,3308 +330825,龙游县,3308 +330881,江山市,3308 +3309,舟山市,33 +330902,定海区,3309 +330903,普陀区,3309 +330921,岱山县,3309 +330922,嵊泗县,3309 +3310,台州市,33 +331002,椒江区,3310 +331003,黄岩区,3310 +331004,路桥区,3310 +331022,三门县,3310 +331023,天台县,3310 +331024,仙居县,3310 +331081,温岭市,3310 +331082,临海市,3310 +331083,玉环市,3310 +3311,丽水市,33 +331102,莲都区,3311 +331121,青田县,3311 +331122,缙云县,3311 +331123,遂昌县,3311 +331124,松阳县,3311 +331125,云和县,3311 +331126,庆元县,3311 +331127,景宁畲族自治县,3311 +331181,龙泉市,3311 +34,安徽省, +3401,合肥市,34 +340102,瑶海区,3401 +340103,庐阳区,3401 +340104,蜀山区,3401 +340111,包河区,3401 +340121,长丰县,3401 +340122,肥东县,3401 +340123,肥西县,3401 +340124,庐江县,3401 +340181,巢湖市,3401 +3402,芜湖市,34 +340202,镜湖区,3402 +340203,弋江区,3402 +340207,鸠江区,3402 +340208,三山区,3402 +340221,芜湖县,3402 +340222,繁昌县,3402 +340223,南陵县,3402 +340225,无为县,3402 +3403,蚌埠市,34 +340302,龙子湖区,3403 +340303,蚌山区,3403 +340304,禹会区,3403 +340311,淮上区,3403 +340321,怀远县,3403 +340322,五河县,3403 +340323,固镇县,3403 +3404,淮南市,34 +340402,大通区,3404 +340403,田家庵区,3404 +340404,谢家集区,3404 +340405,八公山区,3404 +340406,潘集区,3404 +340421,凤台县,3404 +340422,寿县,3404 +3405,马鞍山市,34 +340503,花山区,3405 +340504,雨山区,3405 +340506,博望区,3405 +340521,当涂县,3405 +340522,含山县,3405 +340523,和县,3405 +3406,淮北市,34 +340602,杜集区,3406 +340603,相山区,3406 +340604,烈山区,3406 +340621,濉溪县,3406 +3407,铜陵市,34 +340705,铜官区,3407 +340706,义安区,3407 +340711,郊区,3407 +340722,枞阳县,3407 +3408,安庆市,34 +340802,迎江区,3408 +340803,大观区,3408 +340811,宜秀区,3408 +340822,怀宁县,3408 +340825,太湖县,3408 +340826,宿松县,3408 +340827,望江县,3408 +340828,岳西县,3408 +340881,桐城市,3408 +340882,潜山市,3408 +3410,黄山市,34 +341002,屯溪区,3410 +341003,黄山区,3410 +341004,徽州区,3410 +341021,歙县,3410 +341022,休宁县,3410 +341023,黟县,3410 +341024,祁门县,3410 +3411,滁州市,34 +341102,琅琊区,3411 +341103,南谯区,3411 +341122,来安县,3411 +341124,全椒县,3411 +341125,定远县,3411 +341126,凤阳县,3411 +341181,天长市,3411 +341182,明光市,3411 +3412,阜阳市,34 +341202,颍州区,3412 +341203,颍东区,3412 +341204,颍泉区,3412 +341221,临泉县,3412 +341222,太和县,3412 +341225,阜南县,3412 +341226,颍上县,3412 +341282,界首市,3412 +3413,宿州市,34 +341302,埇桥区,3413 +341321,砀山县,3413 +341322,萧县,3413 +341323,灵璧县,3413 +341324,泗县,3413 +3415,六安市,34 +341502,金安区,3415 +341503,裕安区,3415 +341504,叶集区,3415 +341522,霍邱县,3415 +341523,舒城县,3415 +341524,金寨县,3415 +341525,霍山县,3415 +3416,亳州市,34 +341602,谯城区,3416 +341621,涡阳县,3416 +341622,蒙城县,3416 +341623,利辛县,3416 +3417,池州市,34 +341702,贵池区,3417 +341721,东至县,3417 +341722,石台县,3417 +341723,青阳县,3417 +3418,宣城市,34 +341802,宣州区,3418 +341821,郎溪县,3418 +341822,广德县,3418 +341823,泾县,3418 +341824,绩溪县,3418 +341825,旌德县,3418 +341881,宁国市,3418 +35,福建省, +3501,福州市,35 +350102,鼓楼区,3501 +350103,台江区,3501 +350104,仓山区,3501 +350105,马尾区,3501 +350111,晋安区,3501 +350112,长乐区,3501 +350121,闽侯县,3501 +350122,连江县,3501 +350123,罗源县,3501 +350124,闽清县,3501 +350125,永泰县,3501 +350128,平潭县,3501 +350181,福清市,3501 +3502,厦门市,35 +350203,思明区,3502 +350205,海沧区,3502 +350206,湖里区,3502 +350211,集美区,3502 +350212,同安区,3502 +350213,翔安区,3502 +3503,莆田市,35 +350302,城厢区,3503 +350303,涵江区,3503 +350304,荔城区,3503 +350305,秀屿区,3503 +350322,仙游县,3503 +3504,三明市,35 +350402,梅列区,3504 +350403,三元区,3504 +350421,明溪县,3504 +350423,清流县,3504 +350424,宁化县,3504 +350425,大田县,3504 +350426,尤溪县,3504 +350427,沙县,3504 +350428,将乐县,3504 +350429,泰宁县,3504 +350430,建宁县,3504 +350481,永安市,3504 +3505,泉州市,35 +350502,鲤城区,3505 +350503,丰泽区,3505 +350504,洛江区,3505 +350505,泉港区,3505 +350521,惠安县,3505 +350524,安溪县,3505 +350525,永春县,3505 +350526,德化县,3505 +350527,金门县,3505 +350581,石狮市,3505 +350582,晋江市,3505 +350583,南安市,3505 +3506,漳州市,35 +350602,芗城区,3506 +350603,龙文区,3506 +350622,云霄县,3506 +350623,漳浦县,3506 +350624,诏安县,3506 +350625,长泰县,3506 +350626,东山县,3506 +350627,南靖县,3506 +350628,平和县,3506 +350629,华安县,3506 +350681,龙海市,3506 +3507,南平市,35 +350702,延平区,3507 +350703,建阳区,3507 +350721,顺昌县,3507 +350722,浦城县,3507 +350723,光泽县,3507 +350724,松溪县,3507 +350725,政和县,3507 +350781,邵武市,3507 +350782,武夷山市,3507 +350783,建瓯市,3507 +3508,龙岩市,35 +350802,新罗区,3508 +350803,永定区,3508 +350821,长汀县,3508 +350823,上杭县,3508 +350824,武平县,3508 +350825,连城县,3508 +350881,漳平市,3508 +3509,宁德市,35 +350902,蕉城区,3509 +350921,霞浦县,3509 +350922,古田县,3509 +350923,屏南县,3509 +350924,寿宁县,3509 +350925,周宁县,3509 +350926,柘荣县,3509 +350981,福安市,3509 +350982,福鼎市,3509 +36,江西省, +3601,南昌市,36 +360102,东湖区,3601 +360103,西湖区,3601 +360104,青云谱区,3601 +360105,湾里区,3601 +360111,青山湖区,3601 +360112,新建区,3601 +360121,南昌县,3601 +360123,安义县,3601 +360124,进贤县,3601 +3602,景德镇市,36 +360202,昌江区,3602 +360203,珠山区,3602 +360222,浮梁县,3602 +360281,乐平市,3602 +3603,萍乡市,36 +360302,安源区,3603 +360313,湘东区,3603 +360321,莲花县,3603 +360322,上栗县,3603 +360323,芦溪县,3603 +3604,九江市,36 +360402,濂溪区,3604 +360403,浔阳区,3604 +360404,柴桑区,3604 +360423,武宁县,3604 +360424,修水县,3604 +360425,永修县,3604 +360426,德安县,3604 +360428,都昌县,3604 +360429,湖口县,3604 +360430,彭泽县,3604 +360481,瑞昌市,3604 +360482,共青城市,3604 +360483,庐山市,3604 +3605,新余市,36 +360502,渝水区,3605 +360521,分宜县,3605 +3606,鹰潭市,36 +360602,月湖区,3606 +360603,余江区,3606 +360681,贵溪市,3606 +3607,赣州市,36 +360702,章贡区,3607 +360703,南康区,3607 +360704,赣县区,3607 +360722,信丰县,3607 +360723,大余县,3607 +360724,上犹县,3607 +360725,崇义县,3607 +360726,安远县,3607 +360727,龙南县,3607 +360728,定南县,3607 +360729,全南县,3607 +360730,宁都县,3607 +360731,于都县,3607 +360732,兴国县,3607 +360733,会昌县,3607 +360734,寻乌县,3607 +360735,石城县,3607 +360781,瑞金市,3607 +3608,吉安市,36 +360802,吉州区,3608 +360803,青原区,3608 +360821,吉安县,3608 +360822,吉水县,3608 +360823,峡江县,3608 +360824,新干县,3608 +360825,永丰县,3608 +360826,泰和县,3608 +360827,遂川县,3608 +360828,万安县,3608 +360829,安福县,3608 +360830,永新县,3608 +360881,井冈山市,3608 +3609,宜春市,36 +360902,袁州区,3609 +360921,奉新县,3609 +360922,万载县,3609 +360923,上高县,3609 +360924,宜丰县,3609 +360925,靖安县,3609 +360926,铜鼓县,3609 +360981,丰城市,3609 +360982,樟树市,3609 +360983,高安市,3609 +3610,抚州市,36 +361002,临川区,3610 +361003,东乡区,3610 +361021,南城县,3610 +361022,黎川县,3610 +361023,南丰县,3610 +361024,崇仁县,3610 +361025,乐安县,3610 +361026,宜黄县,3610 +361027,金溪县,3610 +361028,资溪县,3610 +361030,广昌县,3610 +3611,上饶市,36 +361102,信州区,3611 +361103,广丰区,3611 +361121,上饶县,3611 +361123,玉山县,3611 +361124,铅山县,3611 +361125,横峰县,3611 +361126,弋阳县,3611 +361127,余干县,3611 +361128,鄱阳县,3611 +361129,万年县,3611 +361130,婺源县,3611 +361181,德兴市,3611 +37,山东省, +3701,济南市,37 +370102,历下区,3701 +370103,市中区,3701 +370104,槐荫区,3701 +370105,天桥区,3701 +370112,历城区,3701 +370113,长清区,3701 +370114,章丘区,3701 +370115,济阳区,3701 +370124,平阴县,3701 +370126,商河县,3701 +3702,青岛市,37 +370202,市南区,3702 +370203,市北区,3702 +370211,黄岛区,3702 +370212,崂山区,3702 +370213,李沧区,3702 +370214,城阳区,3702 +370215,即墨区,3702 +370281,胶州市,3702 +370283,平度市,3702 +370285,莱西市,3702 +3703,淄博市,37 +370302,淄川区,3703 +370303,张店区,3703 +370304,博山区,3703 +370305,临淄区,3703 +370306,周村区,3703 +370321,桓台县,3703 +370322,高青县,3703 +370323,沂源县,3703 +3704,枣庄市,37 +370402,市中区,3704 +370403,薛城区,3704 +370404,峄城区,3704 +370405,台儿庄区,3704 +370406,山亭区,3704 +370481,滕州市,3704 +3705,东营市,37 +370502,东营区,3705 +370503,河口区,3705 +370505,垦利区,3705 +370522,利津县,3705 +370523,广饶县,3705 +3706,烟台市,37 +370602,芝罘区,3706 +370611,福山区,3706 +370612,牟平区,3706 +370613,莱山区,3706 +370634,长岛县,3706 +370681,龙口市,3706 +370682,莱阳市,3706 +370683,莱州市,3706 +370684,蓬莱市,3706 +370685,招远市,3706 +370686,栖霞市,3706 +370687,海阳市,3706 +3707,潍坊市,37 +370702,潍城区,3707 +370703,寒亭区,3707 +370704,坊子区,3707 +370705,奎文区,3707 +370724,临朐县,3707 +370725,昌乐县,3707 +370781,青州市,3707 +370782,诸城市,3707 +370783,寿光市,3707 +370784,安丘市,3707 +370785,高密市,3707 +370786,昌邑市,3707 +3708,济宁市,37 +370811,任城区,3708 +370812,兖州区,3708 +370826,微山县,3708 +370827,鱼台县,3708 +370828,金乡县,3708 +370829,嘉祥县,3708 +370830,汶上县,3708 +370831,泗水县,3708 +370832,梁山县,3708 +370881,曲阜市,3708 +370883,邹城市,3708 +3709,泰安市,37 +370902,泰山区,3709 +370911,岱岳区,3709 +370921,宁阳县,3709 +370923,东平县,3709 +370982,新泰市,3709 +370983,肥城市,3709 +3710,威海市,37 +371002,环翠区,3710 +371003,文登区,3710 +371082,荣成市,3710 +371083,乳山市,3710 +3711,日照市,37 +371102,东港区,3711 +371103,岚山区,3711 +371121,五莲县,3711 +371122,莒县,3711 +3712,莱芜市,37 +371202,莱城区,3712 +371203,钢城区,3712 +3713,临沂市,37 +371302,兰山区,3713 +371311,罗庄区,3713 +371312,河东区,3713 +371321,沂南县,3713 +371322,郯城县,3713 +371323,沂水县,3713 +371324,兰陵县,3713 +371325,费县,3713 +371326,平邑县,3713 +371327,莒南县,3713 +371328,蒙阴县,3713 +371329,临沭县,3713 +3714,德州市,37 +371402,德城区,3714 +371403,陵城区,3714 +371422,宁津县,3714 +371423,庆云县,3714 +371424,临邑县,3714 +371425,齐河县,3714 +371426,平原县,3714 +371427,夏津县,3714 +371428,武城县,3714 +371481,乐陵市,3714 +371482,禹城市,3714 +3715,聊城市,37 +371502,东昌府区,3715 +371521,阳谷县,3715 +371522,莘县,3715 +371523,茌平县,3715 +371524,东阿县,3715 +371525,冠县,3715 +371526,高唐县,3715 +371581,临清市,3715 +3716,滨州市,37 +371602,滨城区,3716 +371603,沾化区,3716 +371621,惠民县,3716 +371622,阳信县,3716 +371623,无棣县,3716 +371625,博兴县,3716 +371681,邹平市,3716 +3717,菏泽市,37 +371702,牡丹区,3717 +371703,定陶区,3717 +371721,曹县,3717 +371722,单县,3717 +371723,成武县,3717 +371724,巨野县,3717 +371725,郓城县,3717 +371726,鄄城县,3717 +371728,东明县,3717 +41,河南省, +4101,郑州市,41 +410102,中原区,4101 +410103,二七区,4101 +410104,管城回族区,4101 +410105,金水区,4101 +410106,上街区,4101 +410108,惠济区,4101 +410122,中牟县,4101 +410181,巩义市,4101 +410182,荥阳市,4101 +410183,新密市,4101 +410184,新郑市,4101 +410185,登封市,4101 +4102,开封市,41 +410202,龙亭区,4102 +410203,顺河回族区,4102 +410204,鼓楼区,4102 +410205,禹王台区,4102 +410212,祥符区,4102 +410221,杞县,4102 +410222,通许县,4102 +410223,尉氏县,4102 +410225,兰考县,4102 +4103,洛阳市,41 +410302,老城区,4103 +410303,西工区,4103 +410304,瀍河回族区,4103 +410305,涧西区,4103 +410306,吉利区,4103 +410311,洛龙区,4103 +410322,孟津县,4103 +410323,新安县,4103 +410324,栾川县,4103 +410325,嵩县,4103 +410326,汝阳县,4103 +410327,宜阳县,4103 +410328,洛宁县,4103 +410329,伊川县,4103 +410381,偃师市,4103 +4104,平顶山市,41 +410402,新华区,4104 +410403,卫东区,4104 +410404,石龙区,4104 +410411,湛河区,4104 +410421,宝丰县,4104 +410422,叶县,4104 +410423,鲁山县,4104 +410425,郏县,4104 +410481,舞钢市,4104 +410482,汝州市,4104 +4105,安阳市,41 +410502,文峰区,4105 +410503,北关区,4105 +410505,殷都区,4105 +410506,龙安区,4105 +410522,安阳县,4105 +410523,汤阴县,4105 +410526,滑县,4105 +410527,内黄县,4105 +410581,林州市,4105 +4106,鹤壁市,41 +410602,鹤山区,4106 +410603,山城区,4106 +410611,淇滨区,4106 +410621,浚县,4106 +410622,淇县,4106 +4107,新乡市,41 +410702,红旗区,4107 +410703,卫滨区,4107 +410704,凤泉区,4107 +410711,牧野区,4107 +410721,新乡县,4107 +410724,获嘉县,4107 +410725,原阳县,4107 +410726,延津县,4107 +410727,封丘县,4107 +410728,长垣县,4107 +410781,卫辉市,4107 +410782,辉县市,4107 +4108,焦作市,41 +410802,解放区,4108 +410803,中站区,4108 +410804,马村区,4108 +410811,山阳区,4108 +410821,修武县,4108 +410822,博爱县,4108 +410823,武陟县,4108 +410825,温县,4108 +410882,沁阳市,4108 +410883,孟州市,4108 +4109,濮阳市,41 +410902,华龙区,4109 +410922,清丰县,4109 +410923,南乐县,4109 +410926,范县,4109 +410927,台前县,4109 +410928,濮阳县,4109 +4110,许昌市,41 +411002,魏都区,4110 +411003,建安区,4110 +411024,鄢陵县,4110 +411025,襄城县,4110 +411081,禹州市,4110 +411082,长葛市,4110 +4111,漯河市,41 +411102,源汇区,4111 +411103,郾城区,4111 +411104,召陵区,4111 +411121,舞阳县,4111 +411122,临颍县,4111 +4112,三门峡市,41 +411202,湖滨区,4112 +411203,陕州区,4112 +411221,渑池县,4112 +411224,卢氏县,4112 +411281,义马市,4112 +411282,灵宝市,4112 +4113,南阳市,41 +411302,宛城区,4113 +411303,卧龙区,4113 +411321,南召县,4113 +411322,方城县,4113 +411323,西峡县,4113 +411324,镇平县,4113 +411325,内乡县,4113 +411326,淅川县,4113 +411327,社旗县,4113 +411328,唐河县,4113 +411329,新野县,4113 +411330,桐柏县,4113 +411381,邓州市,4113 +4114,商丘市,41 +411402,梁园区,4114 +411403,睢阳区,4114 +411421,民权县,4114 +411422,睢县,4114 +411423,宁陵县,4114 +411424,柘城县,4114 +411425,虞城县,4114 +411426,夏邑县,4114 +411481,永城市,4114 +4115,信阳市,41 +411502,浉河区,4115 +411503,平桥区,4115 +411521,罗山县,4115 +411522,光山县,4115 +411523,新县,4115 +411524,商城县,4115 +411525,固始县,4115 +411526,潢川县,4115 +411527,淮滨县,4115 +411528,息县,4115 +4116,周口市,41 +411602,川汇区,4116 +411621,扶沟县,4116 +411622,西华县,4116 +411623,商水县,4116 +411624,沈丘县,4116 +411625,郸城县,4116 +411626,淮阳县,4116 +411627,太康县,4116 +411628,鹿邑县,4116 +411681,项城市,4116 +4117,驻马店市,41 +411702,驿城区,4117 +411721,西平县,4117 +411722,上蔡县,4117 +411723,平舆县,4117 +411724,正阳县,4117 +411725,确山县,4117 +411726,泌阳县,4117 +411727,汝南县,4117 +411728,遂平县,4117 +411729,新蔡县,4117 +419001,济源市,41 +42,湖北省, +4201,武汉市,42 +420102,江岸区,4201 +420103,江汉区,4201 +420104,硚口区,4201 +420105,汉阳区,4201 +420106,武昌区,4201 +420107,青山区,4201 +420111,洪山区,4201 +420112,东西湖区,4201 +420113,汉南区,4201 +420114,蔡甸区,4201 +420115,江夏区,4201 +420116,黄陂区,4201 +420117,新洲区,4201 +4202,黄石市,42 +420202,黄石港区,4202 +420203,西塞山区,4202 +420204,下陆区,4202 +420205,铁山区,4202 +420222,阳新县,4202 +420281,大冶市,4202 +4203,十堰市,42 +420302,茅箭区,4203 +420303,张湾区,4203 +420304,郧阳区,4203 +420322,郧西县,4203 +420323,竹山县,4203 +420324,竹溪县,4203 +420325,房县,4203 +420381,丹江口市,4203 +4205,宜昌市,42 +420502,西陵区,4205 +420503,伍家岗区,4205 +420504,点军区,4205 +420505,猇亭区,4205 +420506,夷陵区,4205 +420525,远安县,4205 +420526,兴山县,4205 +420527,秭归县,4205 +420528,长阳土家族自治县,4205 +420529,五峰土家族自治县,4205 +420581,宜都市,4205 +420582,当阳市,4205 +420583,枝江市,4205 +4206,襄阳市,42 +420602,襄城区,4206 +420606,樊城区,4206 +420607,襄州区,4206 +420624,南漳县,4206 +420625,谷城县,4206 +420626,保康县,4206 +420682,老河口市,4206 +420683,枣阳市,4206 +420684,宜城市,4206 +4207,鄂州市,42 +420702,梁子湖区,4207 +420703,华容区,4207 +420704,鄂城区,4207 +4208,荆门市,42 +420802,东宝区,4208 +420804,掇刀区,4208 +420822,沙洋县,4208 +420881,钟祥市,4208 +420882,京山市,4208 +4209,孝感市,42 +420902,孝南区,4209 +420921,孝昌县,4209 +420922,大悟县,4209 +420923,云梦县,4209 +420981,应城市,4209 +420982,安陆市,4209 +420984,汉川市,4209 +4210,荆州市,42 +421002,沙市区,4210 +421003,荆州区,4210 +421022,公安县,4210 +421023,监利县,4210 +421024,江陵县,4210 +421081,石首市,4210 +421083,洪湖市,4210 +421087,松滋市,4210 +4211,黄冈市,42 +421102,黄州区,4211 +421121,团风县,4211 +421122,红安县,4211 +421123,罗田县,4211 +421124,英山县,4211 +421125,浠水县,4211 +421126,蕲春县,4211 +421127,黄梅县,4211 +421181,麻城市,4211 +421182,武穴市,4211 +4212,咸宁市,42 +421202,咸安区,4212 +421221,嘉鱼县,4212 +421222,通城县,4212 +421223,崇阳县,4212 +421224,通山县,4212 +421281,赤壁市,4212 +4213,随州市,42 +421303,曾都区,4213 +421321,随县,4213 +421381,广水市,4213 +4228,恩施土家族苗族自治州,42 +422801,恩施市,4228 +422802,利川市,4228 +422822,建始县,4228 +422823,巴东县,4228 +422825,宣恩县,4228 +422826,咸丰县,4228 +422827,来凤县,4228 +422828,鹤峰县,4228 +429004,仙桃市,42 +429005,潜江市,42 +429006,天门市,42 +429021,神农架林区,42 +43,湖南省, +4301,长沙市,43 +430102,芙蓉区,4301 +430103,天心区,4301 +430104,岳麓区,4301 +430105,开福区,4301 +430111,雨花区,4301 +430112,望城区,4301 +430121,长沙县,4301 +430181,浏阳市,4301 +430182,宁乡市,4301 +4302,株洲市,43 +430202,荷塘区,4302 +430203,芦淞区,4302 +430204,石峰区,4302 +430211,天元区,4302 +430212,渌口区,4302 +430223,攸县,4302 +430224,茶陵县,4302 +430225,炎陵县,4302 +430281,醴陵市,4302 +4303,湘潭市,43 +430302,雨湖区,4303 +430304,岳塘区,4303 +430321,湘潭县,4303 +430381,湘乡市,4303 +430382,韶山市,4303 +4304,衡阳市,43 +430405,珠晖区,4304 +430406,雁峰区,4304 +430407,石鼓区,4304 +430408,蒸湘区,4304 +430412,南岳区,4304 +430421,衡阳县,4304 +430422,衡南县,4304 +430423,衡山县,4304 +430424,衡东县,4304 +430426,祁东县,4304 +430481,耒阳市,4304 +430482,常宁市,4304 +4305,邵阳市,43 +430502,双清区,4305 +430503,大祥区,4305 +430511,北塔区,4305 +430521,邵东县,4305 +430522,新邵县,4305 +430523,邵阳县,4305 +430524,隆回县,4305 +430525,洞口县,4305 +430527,绥宁县,4305 +430528,新宁县,4305 +430529,城步苗族自治县,4305 +430581,武冈市,4305 +4306,岳阳市,43 +430602,岳阳楼区,4306 +430603,云溪区,4306 +430611,君山区,4306 +430621,岳阳县,4306 +430623,华容县,4306 +430624,湘阴县,4306 +430626,平江县,4306 +430681,汨罗市,4306 +430682,临湘市,4306 +4307,常德市,43 +430702,武陵区,4307 +430703,鼎城区,4307 +430721,安乡县,4307 +430722,汉寿县,4307 +430723,澧县,4307 +430724,临澧县,4307 +430725,桃源县,4307 +430726,石门县,4307 +430781,津市市,4307 +4308,张家界市,43 +430802,永定区,4308 +430811,武陵源区,4308 +430821,慈利县,4308 +430822,桑植县,4308 +4309,益阳市,43 +430902,资阳区,4309 +430903,赫山区,4309 +430921,南县,4309 +430922,桃江县,4309 +430923,安化县,4309 +430981,沅江市,4309 +4310,郴州市,43 +431002,北湖区,4310 +431003,苏仙区,4310 +431021,桂阳县,4310 +431022,宜章县,4310 +431023,永兴县,4310 +431024,嘉禾县,4310 +431025,临武县,4310 +431026,汝城县,4310 +431027,桂东县,4310 +431028,安仁县,4310 +431081,资兴市,4310 +4311,永州市,43 +431102,零陵区,4311 +431103,冷水滩区,4311 +431121,祁阳县,4311 +431122,东安县,4311 +431123,双牌县,4311 +431124,道县,4311 +431125,江永县,4311 +431126,宁远县,4311 +431127,蓝山县,4311 +431128,新田县,4311 +431129,江华瑶族自治县,4311 +4312,怀化市,43 +431202,鹤城区,4312 +431221,中方县,4312 +431222,沅陵县,4312 +431223,辰溪县,4312 +431224,溆浦县,4312 +431225,会同县,4312 +431226,麻阳苗族自治县,4312 +431227,新晃侗族自治县,4312 +431228,芷江侗族自治县,4312 +431229,靖州苗族侗族自治县,4312 +431230,通道侗族自治县,4312 +431281,洪江市,4312 +4313,娄底市,43 +431302,娄星区,4313 +431321,双峰县,4313 +431322,新化县,4313 +431381,冷水江市,4313 +431382,涟源市,4313 +4331,湘西土家族苗族自治州,43 +433101,吉首市,4331 +433122,泸溪县,4331 +433123,凤凰县,4331 +433124,花垣县,4331 +433125,保靖县,4331 +433126,古丈县,4331 +433127,永顺县,4331 +433130,龙山县,4331 +44,广东省, +4401,广州市,44 +440103,荔湾区,4401 +440104,越秀区,4401 +440105,海珠区,4401 +440106,天河区,4401 +440111,白云区,4401 +440112,黄埔区,4401 +440113,番禺区,4401 +440114,花都区,4401 +440115,南沙区,4401 +440117,从化区,4401 +440118,增城区,4401 +4402,韶关市,44 +440203,武江区,4402 +440204,浈江区,4402 +440205,曲江区,4402 +440222,始兴县,4402 +440224,仁化县,4402 +440229,翁源县,4402 +440232,乳源瑶族自治县,4402 +440233,新丰县,4402 +440281,乐昌市,4402 +440282,南雄市,4402 +4403,深圳市,44 +440303,罗湖区,4403 +440304,福田区,4403 +440305,南山区,4403 +440306,宝安区,4403 +440307,龙岗区,4403 +440308,盐田区,4403 +440309,龙华区,4403 +440310,坪山区,4403 +440311,光明区,4403 +4404,珠海市,44 +440402,香洲区,4404 +440403,斗门区,4404 +440404,金湾区,4404 +4405,汕头市,44 +440507,龙湖区,4405 +440511,金平区,4405 +440512,濠江区,4405 +440513,潮阳区,4405 +440514,潮南区,4405 +440515,澄海区,4405 +440523,南澳县,4405 +4406,佛山市,44 +440604,禅城区,4406 +440605,南海区,4406 +440606,顺德区,4406 +440607,三水区,4406 +440608,高明区,4406 +4407,江门市,44 +440703,蓬江区,4407 +440704,江海区,4407 +440705,新会区,4407 +440781,台山市,4407 +440783,开平市,4407 +440784,鹤山市,4407 +440785,恩平市,4407 +4408,湛江市,44 +440802,赤坎区,4408 +440803,霞山区,4408 +440804,坡头区,4408 +440811,麻章区,4408 +440823,遂溪县,4408 +440825,徐闻县,4408 +440881,廉江市,4408 +440882,雷州市,4408 +440883,吴川市,4408 +4409,茂名市,44 +440902,茂南区,4409 +440904,电白区,4409 +440981,高州市,4409 +440982,化州市,4409 +440983,信宜市,4409 +4412,肇庆市,44 +441202,端州区,4412 +441203,鼎湖区,4412 +441204,高要区,4412 +441223,广宁县,4412 +441224,怀集县,4412 +441225,封开县,4412 +441226,德庆县,4412 +441284,四会市,4412 +4413,惠州市,44 +441302,惠城区,4413 +441303,惠阳区,4413 +441322,博罗县,4413 +441323,惠东县,4413 +441324,龙门县,4413 +4414,梅州市,44 +441402,梅江区,4414 +441403,梅县区,4414 +441422,大埔县,4414 +441423,丰顺县,4414 +441424,五华县,4414 +441426,平远县,4414 +441427,蕉岭县,4414 +441481,兴宁市,4414 +4415,汕尾市,44 +441502,城区,4415 +441521,海丰县,4415 +441523,陆河县,4415 +441581,陆丰市,4415 +4416,河源市,44 +441602,源城区,4416 +441621,紫金县,4416 +441622,龙川县,4416 +441623,连平县,4416 +441624,和平县,4416 +441625,东源县,4416 +4417,阳江市,44 +441702,江城区,4417 +441704,阳东区,4417 +441721,阳西县,4417 +441781,阳春市,4417 +4418,清远市,44 +441802,清城区,4418 +441803,清新区,4418 +441821,佛冈县,4418 +441823,阳山县,4418 +441825,连山壮族瑶族自治县,4418 +441826,连南瑶族自治县,4418 +441881,英德市,4418 +441882,连州市,4418 +4419,东莞市,44 +4420,中山市,44 +4451,潮州市,44 +445102,湘桥区,4451 +445103,潮安区,4451 +445122,饶平县,4451 +4452,揭阳市,44 +445202,榕城区,4452 +445203,揭东区,4452 +445222,揭西县,4452 +445224,惠来县,4452 +445281,普宁市,4452 +4453,云浮市,44 +445302,云城区,4453 +445303,云安区,4453 +445321,新兴县,4453 +445322,郁南县,4453 +445381,罗定市,4453 +45,广西壮族自治区, +4501,南宁市,45 +450102,兴宁区,4501 +450103,青秀区,4501 +450105,江南区,4501 +450107,西乡塘区,4501 +450108,良庆区,4501 +450109,邕宁区,4501 +450110,武鸣区,4501 +450123,隆安县,4501 +450124,马山县,4501 +450125,上林县,4501 +450126,宾阳县,4501 +450127,横县,4501 +4502,柳州市,45 +450202,城中区,4502 +450203,鱼峰区,4502 +450204,柳南区,4502 +450205,柳北区,4502 +450206,柳江区,4502 +450222,柳城县,4502 +450223,鹿寨县,4502 +450224,融安县,4502 +450225,融水苗族自治县,4502 +450226,三江侗族自治县,4502 +4503,桂林市,45 +450302,秀峰区,4503 +450303,叠彩区,4503 +450304,象山区,4503 +450305,七星区,4503 +450311,雁山区,4503 +450312,临桂区,4503 +450321,阳朔县,4503 +450323,灵川县,4503 +450324,全州县,4503 +450325,兴安县,4503 +450326,永福县,4503 +450327,灌阳县,4503 +450328,龙胜各族自治县,4503 +450329,资源县,4503 +450330,平乐县,4503 +450332,恭城瑶族自治县,4503 +450381,荔浦市,4503 +4504,梧州市,45 +450403,万秀区,4504 +450405,长洲区,4504 +450406,龙圩区,4504 +450421,苍梧县,4504 +450422,藤县,4504 +450423,蒙山县,4504 +450481,岑溪市,4504 +4505,北海市,45 +450502,海城区,4505 +450503,银海区,4505 +450512,铁山港区,4505 +450521,合浦县,4505 +4506,防城港市,45 +450602,港口区,4506 +450603,防城区,4506 +450621,上思县,4506 +450681,东兴市,4506 +4507,钦州市,45 +450702,钦南区,4507 +450703,钦北区,4507 +450721,灵山县,4507 +450722,浦北县,4507 +4508,贵港市,45 +450802,港北区,4508 +450803,港南区,4508 +450804,覃塘区,4508 +450821,平南县,4508 +450881,桂平市,4508 +4509,玉林市,45 +450902,玉州区,4509 +450903,福绵区,4509 +450921,容县,4509 +450922,陆川县,4509 +450923,博白县,4509 +450924,兴业县,4509 +450981,北流市,4509 +4510,百色市,45 +451002,右江区,4510 +451021,田阳县,4510 +451022,田东县,4510 +451023,平果县,4510 +451024,德保县,4510 +451026,那坡县,4510 +451027,凌云县,4510 +451028,乐业县,4510 +451029,田林县,4510 +451030,西林县,4510 +451031,隆林各族自治县,4510 +451081,靖西市,4510 +4511,贺州市,45 +451102,八步区,4511 +451103,平桂区,4511 +451121,昭平县,4511 +451122,钟山县,4511 +451123,富川瑶族自治县,4511 +4512,河池市,45 +451202,金城江区,4512 +451203,宜州区,4512 +451221,南丹县,4512 +451222,天峨县,4512 +451223,凤山县,4512 +451224,东兰县,4512 +451225,罗城仫佬族自治县,4512 +451226,环江毛南族自治县,4512 +451227,巴马瑶族自治县,4512 +451228,都安瑶族自治县,4512 +451229,大化瑶族自治县,4512 +4513,来宾市,45 +451302,兴宾区,4513 +451321,忻城县,4513 +451322,象州县,4513 +451323,武宣县,4513 +451324,金秀瑶族自治县,4513 +451381,合山市,4513 +4514,崇左市,45 +451402,江州区,4514 +451421,扶绥县,4514 +451422,宁明县,4514 +451423,龙州县,4514 +451424,大新县,4514 +451425,天等县,4514 +451481,凭祥市,4514 +46,海南省, +4601,海口市,46 +460105,秀英区,4601 +460106,龙华区,4601 +460107,琼山区,4601 +460108,美兰区,4601 +4602,三亚市,46 +460202,海棠区,4602 +460203,吉阳区,4602 +460204,天涯区,4602 +460205,崖州区,4602 +4603,三沙市,46 +4604,儋州市,46 +469001,五指山市,46 +469002,琼海市,46 +469005,文昌市,46 +469006,万宁市,46 +469007,东方市,46 +469021,定安县,46 +469022,屯昌县,46 +469023,澄迈县,46 +469024,临高县,46 +469025,白沙黎族自治县,46 +469026,昌江黎族自治县,46 +469027,乐东黎族自治县,46 +469028,陵水黎族自治县,46 +469029,保亭黎族苗族自治县,46 +469030,琼中黎族苗族自治县,46 +50,重庆市, +500101,万州区,50 +500102,涪陵区,50 +500103,渝中区,50 +500104,大渡口区,50 +500105,江北区,50 +500106,沙坪坝区,50 +500107,九龙坡区,50 +500108,南岸区,50 +500109,北碚区,50 +500110,綦江区,50 +500111,大足区,50 +500112,渝北区,50 +500113,巴南区,50 +500114,黔江区,50 +500115,长寿区,50 +500116,江津区,50 +500117,合川区,50 +500118,永川区,50 +500119,南川区,50 +500120,璧山区,50 +500151,铜梁区,50 +500152,潼南区,50 +500153,荣昌区,50 +500154,开州区,50 +500155,梁平区,50 +500156,武隆区,50 +500229,城口县,50 +500230,丰都县,50 +500231,垫江县,50 +500233,忠县,50 +500235,云阳县,50 +500236,奉节县,50 +500237,巫山县,50 +500238,巫溪县,50 +500240,石柱土家族自治县,50 +500241,秀山土家族苗族自治县,50 +500242,酉阳土家族苗族自治县,50 +500243,彭水苗族土家族自治县,50 +51,四川省, +5101,成都市,51 +510104,锦江区,5101 +510105,青羊区,5101 +510106,金牛区,5101 +510107,武侯区,5101 +510108,成华区,5101 +510112,龙泉驿区,5101 +510113,青白江区,5101 +510114,新都区,5101 +510115,温江区,5101 +510116,双流区,5101 +510117,郫都区,5101 +510121,金堂县,5101 +510129,大邑县,5101 +510131,蒲江县,5101 +510132,新津县,5101 +510181,都江堰市,5101 +510182,彭州市,5101 +510183,邛崃市,5101 +510184,崇州市,5101 +510185,简阳市,5101 +5103,自贡市,51 +510302,自流井区,5103 +510303,贡井区,5103 +510304,大安区,5103 +510311,沿滩区,5103 +510321,荣县,5103 +510322,富顺县,5103 +5104,攀枝花市,51 +510402,东区,5104 +510403,西区,5104 +510411,仁和区,5104 +510421,米易县,5104 +510422,盐边县,5104 +5105,泸州市,51 +510502,江阳区,5105 +510503,纳溪区,5105 +510504,龙马潭区,5105 +510521,泸县,5105 +510522,合江县,5105 +510524,叙永县,5105 +510525,古蔺县,5105 +5106,德阳市,51 +510603,旌阳区,5106 +510604,罗江区,5106 +510623,中江县,5106 +510681,广汉市,5106 +510682,什邡市,5106 +510683,绵竹市,5106 +5107,绵阳市,51 +510703,涪城区,5107 +510704,游仙区,5107 +510705,安州区,5107 +510722,三台县,5107 +510723,盐亭县,5107 +510725,梓潼县,5107 +510726,北川羌族自治县,5107 +510727,平武县,5107 +510781,江油市,5107 +5108,广元市,51 +510802,利州区,5108 +510811,昭化区,5108 +510812,朝天区,5108 +510821,旺苍县,5108 +510822,青川县,5108 +510823,剑阁县,5108 +510824,苍溪县,5108 +5109,遂宁市,51 +510903,船山区,5109 +510904,安居区,5109 +510921,蓬溪县,5109 +510922,射洪县,5109 +510923,大英县,5109 +5110,内江市,51 +511002,市中区,5110 +511011,东兴区,5110 +511024,威远县,5110 +511025,资中县,5110 +511083,隆昌市,5110 +5111,乐山市,51 +511102,市中区,5111 +511111,沙湾区,5111 +511112,五通桥区,5111 +511113,金口河区,5111 +511123,犍为县,5111 +511124,井研县,5111 +511126,夹江县,5111 +511129,沐川县,5111 +511132,峨边彝族自治县,5111 +511133,马边彝族自治县,5111 +511181,峨眉山市,5111 +5113,南充市,51 +511302,顺庆区,5113 +511303,高坪区,5113 +511304,嘉陵区,5113 +511321,南部县,5113 +511322,营山县,5113 +511323,蓬安县,5113 +511324,仪陇县,5113 +511325,西充县,5113 +511381,阆中市,5113 +5114,眉山市,51 +511402,东坡区,5114 +511403,彭山区,5114 +511421,仁寿县,5114 +511423,洪雅县,5114 +511424,丹棱县,5114 +511425,青神县,5114 +5115,宜宾市,51 +511502,翠屏区,5115 +511503,南溪区,5115 +511504,叙州区,5115 +511523,江安县,5115 +511524,长宁县,5115 +511525,高县,5115 +511526,珙县,5115 +511527,筠连县,5115 +511528,兴文县,5115 +511529,屏山县,5115 +5116,广安市,51 +511602,广安区,5116 +511603,前锋区,5116 +511621,岳池县,5116 +511622,武胜县,5116 +511623,邻水县,5116 +511681,华蓥市,5116 +5117,达州市,51 +511702,通川区,5117 +511703,达川区,5117 +511722,宣汉县,5117 +511723,开江县,5117 +511724,大竹县,5117 +511725,渠县,5117 +511781,万源市,5117 +5118,雅安市,51 +511802,雨城区,5118 +511803,名山区,5118 +511822,荥经县,5118 +511823,汉源县,5118 +511824,石棉县,5118 +511825,天全县,5118 +511826,芦山县,5118 +511827,宝兴县,5118 +5119,巴中市,51 +511902,巴州区,5119 +511903,恩阳区,5119 +511921,通江县,5119 +511922,南江县,5119 +511923,平昌县,5119 +5120,资阳市,51 +512002,雁江区,5120 +512021,安岳县,5120 +512022,乐至县,5120 +5132,阿坝藏族羌族自治州,51 +513201,马尔康市,5132 +513221,汶川县,5132 +513222,理县,5132 +513223,茂县,5132 +513224,松潘县,5132 +513225,九寨沟县,5132 +513226,金川县,5132 +513227,小金县,5132 +513228,黑水县,5132 +513230,壤塘县,5132 +513231,阿坝县,5132 +513232,若尔盖县,5132 +513233,红原县,5132 +5133,甘孜藏族自治州,51 +513301,康定市,5133 +513322,泸定县,5133 +513323,丹巴县,5133 +513324,九龙县,5133 +513325,雅江县,5133 +513326,道孚县,5133 +513327,炉霍县,5133 +513328,甘孜县,5133 +513329,新龙县,5133 +513330,德格县,5133 +513331,白玉县,5133 +513332,石渠县,5133 +513333,色达县,5133 +513334,理塘县,5133 +513335,巴塘县,5133 +513336,乡城县,5133 +513337,稻城县,5133 +513338,得荣县,5133 +5134,凉山彝族自治州,51 +513401,西昌市,5134 +513422,木里藏族自治县,5134 +513423,盐源县,5134 +513424,德昌县,5134 +513425,会理县,5134 +513426,会东县,5134 +513427,宁南县,5134 +513428,普格县,5134 +513429,布拖县,5134 +513430,金阳县,5134 +513431,昭觉县,5134 +513432,喜德县,5134 +513433,冕宁县,5134 +513434,越西县,5134 +513435,甘洛县,5134 +513436,美姑县,5134 +513437,雷波县,5134 +52,贵州省, +5201,贵阳市,52 +520102,南明区,5201 +520103,云岩区,5201 +520111,花溪区,5201 +520112,乌当区,5201 +520113,白云区,5201 +520115,观山湖区,5201 +520121,开阳县,5201 +520122,息烽县,5201 +520123,修文县,5201 +520181,清镇市,5201 +5202,六盘水市,52 +520201,钟山区,5202 +520203,六枝特区,5202 +520221,水城县,5202 +520281,盘州市,5202 +5203,遵义市,52 +520302,红花岗区,5203 +520303,汇川区,5203 +520304,播州区,5203 +520322,桐梓县,5203 +520323,绥阳县,5203 +520324,正安县,5203 +520325,道真仡佬族苗族自治县,5203 +520326,务川仡佬族苗族自治县,5203 +520327,凤冈县,5203 +520328,湄潭县,5203 +520329,余庆县,5203 +520330,习水县,5203 +520381,赤水市,5203 +520382,仁怀市,5203 +5204,安顺市,52 +520402,西秀区,5204 +520403,平坝区,5204 +520422,普定县,5204 +520423,镇宁布依族苗族自治县,5204 +520424,关岭布依族苗族自治县,5204 +520425,紫云苗族布依族自治县,5204 +5205,毕节市,52 +520502,七星关区,5205 +520521,大方县,5205 +520522,黔西县,5205 +520523,金沙县,5205 +520524,织金县,5205 +520525,纳雍县,5205 +520526,威宁彝族回族苗族自治县,5205 +520527,赫章县,5205 +5206,铜仁市,52 +520602,碧江区,5206 +520603,万山区,5206 +520621,江口县,5206 +520622,玉屏侗族自治县,5206 +520623,石阡县,5206 +520624,思南县,5206 +520625,印江土家族苗族自治县,5206 +520626,德江县,5206 +520627,沿河土家族自治县,5206 +520628,松桃苗族自治县,5206 +5223,黔西南布依族苗族自治州,52 +522301,兴义市,5223 +522302,兴仁市,5223 +522323,普安县,5223 +522324,晴隆县,5223 +522325,贞丰县,5223 +522326,望谟县,5223 +522327,册亨县,5223 +522328,安龙县,5223 +5226,黔东南苗族侗族自治州,52 +522601,凯里市,5226 +522622,黄平县,5226 +522623,施秉县,5226 +522624,三穗县,5226 +522625,镇远县,5226 +522626,岑巩县,5226 +522627,天柱县,5226 +522628,锦屏县,5226 +522629,剑河县,5226 +522630,台江县,5226 +522631,黎平县,5226 +522632,榕江县,5226 +522633,从江县,5226 +522634,雷山县,5226 +522635,麻江县,5226 +522636,丹寨县,5226 +5227,黔南布依族苗族自治州,52 +522701,都匀市,5227 +522702,福泉市,5227 +522722,荔波县,5227 +522723,贵定县,5227 +522725,瓮安县,5227 +522726,独山县,5227 +522727,平塘县,5227 +522728,罗甸县,5227 +522729,长顺县,5227 +522730,龙里县,5227 +522731,惠水县,5227 +522732,三都水族自治县,5227 +53,云南省, +5301,昆明市,53 +530102,五华区,5301 +530103,盘龙区,5301 +530111,官渡区,5301 +530112,西山区,5301 +530113,东川区,5301 +530114,呈贡区,5301 +530115,晋宁区,5301 +530124,富民县,5301 +530125,宜良县,5301 +530126,石林彝族自治县,5301 +530127,嵩明县,5301 +530128,禄劝彝族苗族自治县,5301 +530129,寻甸回族彝族自治县,5301 +530181,安宁市,5301 +5303,曲靖市,53 +530302,麒麟区,5303 +530303,沾益区,5303 +530304,马龙区,5303 +530322,陆良县,5303 +530323,师宗县,5303 +530324,罗平县,5303 +530325,富源县,5303 +530326,会泽县,5303 +530381,宣威市,5303 +5304,玉溪市,53 +530402,红塔区,5304 +530403,江川区,5304 +530422,澄江县,5304 +530423,通海县,5304 +530424,华宁县,5304 +530425,易门县,5304 +530426,峨山彝族自治县,5304 +530427,新平彝族傣族自治县,5304 +530428,元江哈尼族彝族傣族自治县,5304 +5305,保山市,53 +530502,隆阳区,5305 +530521,施甸县,5305 +530523,龙陵县,5305 +530524,昌宁县,5305 +530581,腾冲市,5305 +5306,昭通市,53 +530602,昭阳区,5306 +530621,鲁甸县,5306 +530622,巧家县,5306 +530623,盐津县,5306 +530624,大关县,5306 +530625,永善县,5306 +530626,绥江县,5306 +530627,镇雄县,5306 +530628,彝良县,5306 +530629,威信县,5306 +530681,水富市,5306 +5307,丽江市,53 +530702,古城区,5307 +530721,玉龙纳西族自治县,5307 +530722,永胜县,5307 +530723,华坪县,5307 +530724,宁蒗彝族自治县,5307 +5308,普洱市,53 +530802,思茅区,5308 +530821,宁洱哈尼族彝族自治县,5308 +530822,墨江哈尼族自治县,5308 +530823,景东彝族自治县,5308 +530824,景谷傣族彝族自治县,5308 +530825,镇沅彝族哈尼族拉祜族自治县,5308 +530826,江城哈尼族彝族自治县,5308 +530827,孟连傣族拉祜族佤族自治县,5308 +530828,澜沧拉祜族自治县,5308 +530829,西盟佤族自治县,5308 +5309,临沧市,53 +530902,临翔区,5309 +530921,凤庆县,5309 +530922,云县,5309 +530923,永德县,5309 +530924,镇康县,5309 +530925,双江拉祜族佤族布朗族傣族自治县,5309 +530926,耿马傣族佤族自治县,5309 +530927,沧源佤族自治县,5309 +5323,楚雄彝族自治州,53 +532301,楚雄市,5323 +532322,双柏县,5323 +532323,牟定县,5323 +532324,南华县,5323 +532325,姚安县,5323 +532326,大姚县,5323 +532327,永仁县,5323 +532328,元谋县,5323 +532329,武定县,5323 +532331,禄丰县,5323 +5325,红河哈尼族彝族自治州,53 +532501,个旧市,5325 +532502,开远市,5325 +532503,蒙自市,5325 +532504,弥勒市,5325 +532523,屏边苗族自治县,5325 +532524,建水县,5325 +532525,石屏县,5325 +532527,泸西县,5325 +532528,元阳县,5325 +532529,红河县,5325 +532530,金平苗族瑶族傣族自治县,5325 +532531,绿春县,5325 +532532,河口瑶族自治县,5325 +5326,文山壮族苗族自治州,53 +532601,文山市,5326 +532622,砚山县,5326 +532623,西畴县,5326 +532624,麻栗坡县,5326 +532625,马关县,5326 +532626,丘北县,5326 +532627,广南县,5326 +532628,富宁县,5326 +5328,西双版纳傣族自治州,53 +532801,景洪市,5328 +532822,勐海县,5328 +532823,勐腊县,5328 +5329,大理白族自治州,53 +532901,大理市,5329 +532922,漾濞彝族自治县,5329 +532923,祥云县,5329 +532924,宾川县,5329 +532925,弥渡县,5329 +532926,南涧彝族自治县,5329 +532927,巍山彝族回族自治县,5329 +532928,永平县,5329 +532929,云龙县,5329 +532930,洱源县,5329 +532931,剑川县,5329 +532932,鹤庆县,5329 +5331,德宏傣族景颇族自治州,53 +533102,瑞丽市,5331 +533103,芒市,5331 +533122,梁河县,5331 +533123,盈江县,5331 +533124,陇川县,5331 +5333,怒江傈僳族自治州,53 +533301,泸水市,5333 +533323,福贡县,5333 +533324,贡山独龙族怒族自治县,5333 +533325,兰坪白族普米族自治县,5333 +5334,迪庆藏族自治州,53 +533401,香格里拉市,5334 +533422,德钦县,5334 +533423,维西傈僳族自治县,5334 +54,西藏自治区, +5401,拉萨市,54 +540102,城关区,5401 +540103,堆龙德庆区,5401 +540104,达孜区,5401 +540121,林周县,5401 +540122,当雄县,5401 +540123,尼木县,5401 +540124,曲水县,5401 +540127,墨竹工卡县,5401 +5402,日喀则市,54 +540202,桑珠孜区,5402 +540221,南木林县,5402 +540222,江孜县,5402 +540223,定日县,5402 +540224,萨迦县,5402 +540225,拉孜县,5402 +540226,昂仁县,5402 +540227,谢通门县,5402 +540228,白朗县,5402 +540229,仁布县,5402 +540230,康马县,5402 +540231,定结县,5402 +540232,仲巴县,5402 +540233,亚东县,5402 +540234,吉隆县,5402 +540235,聂拉木县,5402 +540236,萨嘎县,5402 +540237,岗巴县,5402 +5403,昌都市,54 +540302,卡若区,5403 +540321,江达县,5403 +540322,贡觉县,5403 +540323,类乌齐县,5403 +540324,丁青县,5403 +540325,察雅县,5403 +540326,八宿县,5403 +540327,左贡县,5403 +540328,芒康县,5403 +540329,洛隆县,5403 +540330,边坝县,5403 +5404,林芝市,54 +540402,巴宜区,5404 +540421,工布江达县,5404 +540422,米林县,5404 +540423,墨脱县,5404 +540424,波密县,5404 +540425,察隅县,5404 +540426,朗县,5404 +5405,山南市,54 +540502,乃东区,5405 +540521,扎囊县,5405 +540522,贡嘎县,5405 +540523,桑日县,5405 +540524,琼结县,5405 +540525,曲松县,5405 +540526,措美县,5405 +540527,洛扎县,5405 +540528,加查县,5405 +540529,隆子县,5405 +540530,错那县,5405 +540531,浪卡子县,5405 +5406,那曲市,54 +540602,色尼区,5406 +540621,嘉黎县,5406 +540622,比如县,5406 +540623,聂荣县,5406 +540624,安多县,5406 +540625,申扎县,5406 +540626,索县,5406 +540627,班戈县,5406 +540628,巴青县,5406 +540629,尼玛县,5406 +540630,双湖县,5406 +5425,阿里地区,54 +542521,普兰县,5425 +542522,札达县,5425 +542523,噶尔县,5425 +542524,日土县,5425 +542525,革吉县,5425 +542526,改则县,5425 +542527,措勤县,5425 +61,陕西省, +6101,西安市,61 +610102,新城区,6101 +610103,碑林区,6101 +610104,莲湖区,6101 +610111,灞桥区,6101 +610112,未央区,6101 +610113,雁塔区,6101 +610114,阎良区,6101 +610115,临潼区,6101 +610116,长安区,6101 +610117,高陵区,6101 +610118,鄠邑区,6101 +610122,蓝田县,6101 +610124,周至县,6101 +6102,铜川市,61 +610202,王益区,6102 +610203,印台区,6102 +610204,耀州区,6102 +610222,宜君县,6102 +6103,宝鸡市,61 +610302,渭滨区,6103 +610303,金台区,6103 +610304,陈仓区,6103 +610322,凤翔县,6103 +610323,岐山县,6103 +610324,扶风县,6103 +610326,眉县,6103 +610327,陇县,6103 +610328,千阳县,6103 +610329,麟游县,6103 +610330,凤县,6103 +610331,太白县,6103 +6104,咸阳市,61 +610402,秦都区,6104 +610403,杨陵区,6104 +610404,渭城区,6104 +610422,三原县,6104 +610423,泾阳县,6104 +610424,乾县,6104 +610425,礼泉县,6104 +610426,永寿县,6104 +610428,长武县,6104 +610429,旬邑县,6104 +610430,淳化县,6104 +610431,武功县,6104 +610481,兴平市,6104 +610482,彬州市,6104 +6105,渭南市,61 +610502,临渭区,6105 +610503,华州区,6105 +610522,潼关县,6105 +610523,大荔县,6105 +610524,合阳县,6105 +610525,澄城县,6105 +610526,蒲城县,6105 +610527,白水县,6105 +610528,富平县,6105 +610581,韩城市,6105 +610582,华阴市,6105 +6106,延安市,61 +610602,宝塔区,6106 +610603,安塞区,6106 +610621,延长县,6106 +610622,延川县,6106 +610623,子长县,6106 +610625,志丹县,6106 +610626,吴起县,6106 +610627,甘泉县,6106 +610628,富县,6106 +610629,洛川县,6106 +610630,宜川县,6106 +610631,黄龙县,6106 +610632,黄陵县,6106 +6107,汉中市,61 +610702,汉台区,6107 +610703,南郑区,6107 +610722,城固县,6107 +610723,洋县,6107 +610724,西乡县,6107 +610725,勉县,6107 +610726,宁强县,6107 +610727,略阳县,6107 +610728,镇巴县,6107 +610729,留坝县,6107 +610730,佛坪县,6107 +6108,榆林市,61 +610802,榆阳区,6108 +610803,横山区,6108 +610822,府谷县,6108 +610824,靖边县,6108 +610825,定边县,6108 +610826,绥德县,6108 +610827,米脂县,6108 +610828,佳县,6108 +610829,吴堡县,6108 +610830,清涧县,6108 +610831,子洲县,6108 +610881,神木市,6108 +6109,安康市,61 +610902,汉滨区,6109 +610921,汉阴县,6109 +610922,石泉县,6109 +610923,宁陕县,6109 +610924,紫阳县,6109 +610925,岚皋县,6109 +610926,平利县,6109 +610927,镇坪县,6109 +610928,旬阳县,6109 +610929,白河县,6109 +6110,商洛市,61 +611002,商州区,6110 +611021,洛南县,6110 +611022,丹凤县,6110 +611023,商南县,6110 +611024,山阳县,6110 +611025,镇安县,6110 +611026,柞水县,6110 +62,甘肃省, +6201,兰州市,62 +620102,城关区,6201 +620103,七里河区,6201 +620104,西固区,6201 +620105,安宁区,6201 +620111,红古区,6201 +620121,永登县,6201 +620122,皋兰县,6201 +620123,榆中县,6201 +6202,嘉峪关市,62 +6203,金昌市,62 +620302,金川区,6203 +620321,永昌县,6203 +6204,白银市,62 +620402,白银区,6204 +620403,平川区,6204 +620421,靖远县,6204 +620422,会宁县,6204 +620423,景泰县,6204 +6205,天水市,62 +620502,秦州区,6205 +620503,麦积区,6205 +620521,清水县,6205 +620522,秦安县,6205 +620523,甘谷县,6205 +620524,武山县,6205 +620525,张家川回族自治县,6205 +6206,武威市,62 +620602,凉州区,6206 +620621,民勤县,6206 +620622,古浪县,6206 +620623,天祝藏族自治县,6206 +6207,张掖市,62 +620702,甘州区,6207 +620721,肃南裕固族自治县,6207 +620722,民乐县,6207 +620723,临泽县,6207 +620724,高台县,6207 +620725,山丹县,6207 +6208,平凉市,62 +620802,崆峒区,6208 +620821,泾川县,6208 +620822,灵台县,6208 +620823,崇信县,6208 +620825,庄浪县,6208 +620826,静宁县,6208 +620881,华亭市,6208 +6209,酒泉市,62 +620902,肃州区,6209 +620921,金塔县,6209 +620922,瓜州县,6209 +620923,肃北蒙古族自治县,6209 +620924,阿克塞哈萨克族自治县,6209 +620981,玉门市,6209 +620982,敦煌市,6209 +6210,庆阳市,62 +621002,西峰区,6210 +621021,庆城县,6210 +621022,环县,6210 +621023,华池县,6210 +621024,合水县,6210 +621025,正宁县,6210 +621026,宁县,6210 +621027,镇原县,6210 +6211,定西市,62 +621102,安定区,6211 +621121,通渭县,6211 +621122,陇西县,6211 +621123,渭源县,6211 +621124,临洮县,6211 +621125,漳县,6211 +621126,岷县,6211 +6212,陇南市,62 +621202,武都区,6212 +621221,成县,6212 +621222,文县,6212 +621223,宕昌县,6212 +621224,康县,6212 +621225,西和县,6212 +621226,礼县,6212 +621227,徽县,6212 +621228,两当县,6212 +6229,临夏回族自治州,62 +622901,临夏市,6229 +622921,临夏县,6229 +622922,康乐县,6229 +622923,永靖县,6229 +622924,广河县,6229 +622925,和政县,6229 +622926,东乡族自治县,6229 +622927,积石山保安族东乡族撒拉族自治县,6229 +6230,甘南藏族自治州,62 +623001,合作市,6230 +623021,临潭县,6230 +623022,卓尼县,6230 +623023,舟曲县,6230 +623024,迭部县,6230 +623025,玛曲县,6230 +623026,碌曲县,6230 +623027,夏河县,6230 +63,青海省, +6301,西宁市,63 +630102,城东区,6301 +630103,城中区,6301 +630104,城西区,6301 +630105,城北区,6301 +630121,大通回族土族自治县,6301 +630122,湟中县,6301 +630123,湟源县,6301 +6302,海东市,63 +630202,乐都区,6302 +630203,平安区,6302 +630222,民和回族土族自治县,6302 +630223,互助土族自治县,6302 +630224,化隆回族自治县,6302 +630225,循化撒拉族自治县,6302 +6322,海北藏族自治州,63 +632221,门源回族自治县,6322 +632222,祁连县,6322 +632223,海晏县,6322 +632224,刚察县,6322 +6323,黄南藏族自治州,63 +632321,同仁县,6323 +632322,尖扎县,6323 +632323,泽库县,6323 +632324,河南蒙古族自治县,6323 +6325,海南藏族自治州,63 +632521,共和县,6325 +632522,同德县,6325 +632523,贵德县,6325 +632524,兴海县,6325 +632525,贵南县,6325 +6326,果洛藏族自治州,63 +632621,玛沁县,6326 +632622,班玛县,6326 +632623,甘德县,6326 +632624,达日县,6326 +632625,久治县,6326 +632626,玛多县,6326 +6327,玉树藏族自治州,63 +632701,玉树市,6327 +632722,杂多县,6327 +632723,称多县,6327 +632724,治多县,6327 +632725,囊谦县,6327 +632726,曲麻莱县,6327 +6328,海西蒙古族藏族自治州,63 +632801,格尔木市,6328 +632802,德令哈市,6328 +632803,茫崖市,6328 +632821,乌兰县,6328 +632822,都兰县,6328 +632823,天峻县,6328 +64,宁夏回族自治区, +6401,银川市,64 +640104,兴庆区,6401 +640105,西夏区,6401 +640106,金凤区,6401 +640121,永宁县,6401 +640122,贺兰县,6401 +640181,灵武市,6401 +6402,石嘴山市,64 +640202,大武口区,6402 +640205,惠农区,6402 +640221,平罗县,6402 +6403,吴忠市,64 +640302,利通区,6403 +640303,红寺堡区,6403 +640323,盐池县,6403 +640324,同心县,6403 +640381,青铜峡市,6403 +6404,固原市,64 +640402,原州区,6404 +640422,西吉县,6404 +640423,隆德县,6404 +640424,泾源县,6404 +640425,彭阳县,6404 +6405,中卫市,64 +640502,沙坡头区,6405 +640521,中宁县,6405 +640522,海原县,6405 +65,新疆维吾尔自治区, +6501,乌鲁木齐市,65 +650102,天山区,6501 +650103,沙依巴克区,6501 +650104,新市区,6501 +650105,水磨沟区,6501 +650106,头屯河区,6501 +650107,达坂城区,6501 +650109,米东区,6501 +650121,乌鲁木齐县,6501 +6502,克拉玛依市,65 +650202,独山子区,6502 +650203,克拉玛依区,6502 +650204,白碱滩区,6502 +650205,乌尔禾区,6502 +6504,吐鲁番市,65 +650402,高昌区,6504 +650421,鄯善县,6504 +650422,托克逊县,6504 +6505,哈密市,65 +650502,伊州区,6505 +650521,巴里坤哈萨克自治县,6505 +650522,伊吾县,6505 +6523,昌吉回族自治州,65 +652301,昌吉市,6523 +652302,阜康市,6523 +652323,呼图壁县,6523 +652324,玛纳斯县,6523 +652325,奇台县,6523 +652327,吉木萨尔县,6523 +652328,木垒哈萨克自治县,6523 +6527,博尔塔拉蒙古自治州,65 +652701,博乐市,6527 +652702,阿拉山口市,6527 +652722,精河县,6527 +652723,温泉县,6527 +6528,巴音郭楞蒙古自治州,65 +652801,库尔勒市,6528 +652822,轮台县,6528 +652823,尉犁县,6528 +652824,若羌县,6528 +652825,且末县,6528 +652826,焉耆回族自治县,6528 +652827,和静县,6528 +652828,和硕县,6528 +652829,博湖县,6528 +6529,阿克苏地区,65 +652901,阿克苏市,6529 +652922,温宿县,6529 +652923,库车县,6529 +652924,沙雅县,6529 +652925,新和县,6529 +652926,拜城县,6529 +652927,乌什县,6529 +652928,阿瓦提县,6529 +652929,柯坪县,6529 +6530,克孜勒苏柯尔克孜自治州,65 +653001,阿图什市,6530 +653022,阿克陶县,6530 +653023,阿合奇县,6530 +653024,乌恰县,6530 +6531,喀什地区,65 +653101,喀什市,6531 +653121,疏附县,6531 +653122,疏勒县,6531 +653123,英吉沙县,6531 +653124,泽普县,6531 +653125,莎车县,6531 +653126,叶城县,6531 +653127,麦盖提县,6531 +653128,岳普湖县,6531 +653129,伽师县,6531 +653130,巴楚县,6531 +653131,塔什库尔干塔吉克自治县,6531 +6532,和田地区,65 +653201,和田市,6532 +653221,和田县,6532 +653222,墨玉县,6532 +653223,皮山县,6532 +653224,洛浦县,6532 +653225,策勒县,6532 +653226,于田县,6532 +653227,民丰县,6532 +6540,伊犁哈萨克自治州,65 +654002,伊宁市,6540 +654003,奎屯市,6540 +654004,霍尔果斯市,6540 +654021,伊宁县,6540 +654022,察布查尔锡伯自治县,6540 +654023,霍城县,6540 +654024,巩留县,6540 +654025,新源县,6540 +654026,昭苏县,6540 +654027,特克斯县,6540 +654028,尼勒克县,6540 +6542,塔城地区,65 +654201,塔城市,6542 +654202,乌苏市,6542 +654221,额敏县,6542 +654223,沙湾县,6542 +654224,托里县,6542 +654225,裕民县,6542 +654226,和布克赛尔蒙古自治县,6542 +6543,阿勒泰地区,65 +654301,阿勒泰市,6543 +654321,布尔津县,6543 +654322,富蕴县,6543 +654323,福海县,6543 +654324,哈巴河县,6543 +654325,青河县,6543 +654326,吉木乃县,6543 +659001,石河子市,65 +659002,阿拉尔市,65 +659003,图木舒克市,65 +659004,五家渠市,65 +659005,北屯市,65 +659006,铁门关市,65 +659007,双河市,65 +659008,可克达拉市,65 +659009,昆玉市,65 +71,台湾省, +81,香港特别行政区, +82,澳门特别行政区, \ No newline at end of file diff --git a/web_src/src/components/ParentPlatformList.vue b/web_src/src/components/ParentPlatformList.vue index 61e93fc8..c3c9735f 100644 --- a/web_src/src/components/ParentPlatformList.vue +++ b/web_src/src/components/ParentPlatformList.vue @@ -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(); diff --git a/web_src/src/components/dialog/catalogEdit.vue b/web_src/src/components/dialog/catalogEdit.vue index e1cd8d26..e2fe59bc 100644 --- a/web_src/src/components/dialog/catalogEdit.vue +++ b/web_src/src/components/dialog/catalogEdit.vue @@ -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 () { diff --git a/web_src/src/components/dialog/chooseChannel.vue b/web_src/src/components/dialog/chooseChannel.vue index be7e969f..86bea831 100644 --- a/web_src/src/components/dialog/chooseChannel.vue +++ b/web_src/src/components/dialog/chooseChannel.vue @@ -8,7 +8,7 @@ - + @@ -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){ diff --git a/web_src/src/components/dialog/chooseChannelForCatalog.vue b/web_src/src/components/dialog/chooseChannelForCatalog.vue index c634b77d..ae79e644 100644 --- a/web_src/src/components/dialog/chooseChannelForCatalog.vue +++ b/web_src/src/components/dialog/chooseChannelForCatalog.vue @@ -28,7 +28,7 @@ - + @@ -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(); }); diff --git a/web_src/src/components/dialog/deviceEdit.vue b/web_src/src/components/dialog/deviceEdit.vue index dcef26ef..d833b132 100644 --- a/web_src/src/components/dialog/deviceEdit.vue +++ b/web_src/src/components/dialog/deviceEdit.vue @@ -49,12 +49,6 @@ - - - - - - diff --git a/web_src/src/components/dialog/platformEdit.vue b/web_src/src/components/dialog/platformEdit.vue index be7c5058..0158cf74 100644 --- a/web_src/src/components/dialog/platformEdit.vue +++ b/web_src/src/components/dialog/platformEdit.vue @@ -78,12 +78,6 @@ - - - - - -