hotcoffie
2022-05-07 ec8ab540f8af6dca862d3ec9967e9042fa7dd8eb
Merge branch '648540858:wvp-28181-2.0' into wvp-28181-2.0
10个文件已修改
4个文件已添加
399 ■■■■ 已修改文件
README.md 44 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pom.xml 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/VManageBootstrap.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/common/ApiSaveConstant.java 46 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/conf/security/AnonymousAuthenticationEntryPoint.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/domain/req/PresetQuerySipReq.java 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/gb28181/bean/DeviceAlarmMethod.java 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderPlarformProvider.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/AlarmNotifyMessageHandler.java 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/PresetQueryResponseMessageHandler.java 124 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
web_src/index.html 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
web_src/src/components/devicePosition.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
web_src/static/js/mapConfig.js 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
README.md
@@ -109,21 +109,45 @@
- [X] 支持使用mysql作为数据库,默认sqlite3,开箱即用。
- [X] WEB端支持播放H264与H265,音频支持G.711A/G.711U/AAC,覆盖国标常用编码格式。
# docker快速体验
目前作者的docker-compose因为时间有限维护不及时,这里提供第三方提供的供大家使用,维护不易,大家记得给这位小伙伴点个star。
https://github.com/SaltFish001/wvp_pro_compose
[https://github.com/SaltFish001/wvp_pro_compose](https://github.com/SaltFish001/wvp_pro_compose)
这是作者维护的一个镜像,可能存在不及时的问题。
```shell
docker pull 648540858/wvp_pro
[//]: # (# docker快速体验)
docker run  --env WVP_IP="你的IP" -it -p 18080:18080 -p 30000-30500:30000-30500/udp -p 30000-30500:30000-30500/tcp -p 80:80 -p 5060:5060 -p 5060:5060/udp 648540858/wvp_pro
```
docker使用详情查看:[https://hub.docker.com/r/648540858/wvp_pro](https://hub.docker.com/r/648540858/wvp_pro)
[//]: # (目前作者的docker-compose因为时间有限维护不及时,这里提供第三方提供的供大家使用,维护不易,大家记得给这位小伙伴点个star。  )
[//]: # (https://github.com/SaltFish001/wvp_pro_compose)
[//]: # ([https://github.com/SaltFish001/wvp_pro_compose](https://github.com/SaltFish001/wvp_pro_compose))
[//]: # (这是作者维护的一个镜像,可能存在不及时的问题。)
[//]: # (```shell)
[//]: # (docker pull 648540858/wvp_pro)
[//]: # ()
[//]: # (docker run  --env WVP_IP="你的IP" -it -p 18080:18080 -p 30000-30500:30000-30500/udp -p 30000-30500:30000-30500/tcp -p 80:80 -p 5060:5060 -p 5060:5060/udp 648540858/wvp_pro)
[//]: # (```)
[//]: # (docker使用详情查看:[https://hub.docker.com/r/648540858/wvp_pro](https://hub.docker.com/r/648540858/wvp_pro))
# gitee同步仓库
https://gitee.com/pan648540858/wvp-GB28181-pro.git  
# 遇到问题
国标最麻烦的地方在于设备的兼容性,所以需要大量的设备来测试,目前作者手里的设备有限,再加上作者水平有限,所以遇到问题在所难免;
1. 查看wiki,仔细的阅读可以帮你避免几乎所有的问题
2. 搜索issues,这里有大部分的答案
3. 加QQ群,这里有大量热心的小伙伴,但是前提新希望你已经仔细阅读了wiki和搜索了issues。
4. 你可以请作者为你解答,但是我不是免费的。
5. 你可以把遇到问题的设备寄给我,可以更容易的复现问题。
# 合作
目前很多打着合作的幌子来私聊的,其实大家大可不必,目前作者没有精力,你有问题可以付费找我解答,也可以提PR
,如果对代码有建议可以提ISSUE;也可以加群一起聊聊。我们欢迎所有有兴趣但遇到项目中来的人。
# 使用帮助
QQ群: 901799015, ZLM使用文档[https://github.com/ZLMediaKit/ZLMediaKit](https://github.com/ZLMediaKit/ZLMediaKit)  
QQ私信一般不回, 精力有限.欢迎大家在群里讨论.觉得项目对你有帮助,欢迎star和提交pr。
pom.xml
@@ -256,6 +256,7 @@
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>2.3.5.RELEASE</version>
                <configuration>
                    <includeSystemScope>true</includeSystemScope>
                </configuration>
@@ -263,6 +264,7 @@
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
@@ -272,6 +274,7 @@
            <plugin>
                <groupId>pl.project13.maven</groupId>
                <artifactId>git-commit-id-plugin</artifactId>
                <version>3.0.1</version>
                <configuration>
                    <offline>true</offline>
                </configuration>
@@ -280,6 +283,7 @@
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.22.2</version>
                <configuration>
                    <skipTests>true</skipTests>
                </configuration>
src/main/java/com/genersoft/iot/vmp/VManageBootstrap.java
@@ -7,7 +7,6 @@
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
import springfox.documentation.oas.annotations.EnableOpenApi;
src/main/java/com/genersoft/iot/vmp/common/ApiSaveConstant.java
@@ -1,5 +1,9 @@
package com.genersoft.iot.vmp.common;
/**
 * 为API重命名, 方便向数据库记录数据的时候展示
 * @author lin
 */
public class ApiSaveConstant {
    public static String getVal(String key) {
@@ -35,8 +39,9 @@
                                    return "[设备控制] 强制关键帧";
                                case "home_position":
                                    return "[设备控制] 看守位控制";
                                default:
                                    return "";
                            }
                            break;
                            case "query":
                                if (keyItemArray.length <= 5) {
                                    return null;
@@ -51,23 +56,30 @@
                                                return "[设备查询] 同步设备通道";
                                            case "delete":
                                                return "[设备查询] 移除设备";
                                            default:
                                                return "";
                                        }
                                        break;
                                    case "channel":
                                        return "[设备查询] 更新通道信息";
                                    case "transport":
                                        return "[设备查询] 修改数据流传输模式";
                                    default:
                                        return "";
                                }
                        default:
                            return "";
                            }
                                break;
                            }
                case "gbStream":
                    switch (keyItemArray[3]) {
                        case "del":
                            return "移除通道与国标的关联";
                        case "add":
                            return "添加通道与国标的关联";
                        default:
                            return "";
                    }
                    break;
                case "media":
                    break;
                case "position":
@@ -85,8 +97,9 @@
                            return "向上级平台添加国标通道";
                        case "del_channel_for_gb":
                            return "从上级平台移除国标通道";
                        default:
                            return "";
                    }
                    break;
                case "platform_gb_stream":
                    break;
                case "play":
@@ -101,32 +114,36 @@
                            return "结束转码";
                        case "broadcast":
                            return "语音广播";
                        default:
                            return "";
                    }
                    break;
                case "download":
                    switch (keyItemArray[3]) {
                        case "start":
                            return "开始历史媒体下载";
                        case "stop":
                            return "停止历史媒体下载";
                        default:
                            return "";
                    }
                    break;
                case "playback":
                    switch (keyItemArray[3]) {
                        case "start":
                            return "开始视频回放";
                        case "stop":
                            return "停止视频回放";
                        default:
                            return "";
                    }
                    break;
                case "ptz":
                    switch (keyItemArray[3]) {
                        case "control":
                            return "云台控制";
                        case "front_end_command":
                            return "通用前端控制命令";
                        default:
                            return "";
                    }
                    break;
                case "gb_record":
                    break;
                case "onvif":
@@ -146,16 +163,18 @@
                            return "启用代理";
                        case "stop":
                            return "停用代理";
                        default:
                            return "";
                    }
                    break;
                case "push":
                    switch (keyItemArray[3]) {
                        case "save_to_gb":
                            return "将推流添加到国标";
                        case "remove_form_gb":
                            return "将推流移出到国标";
                        default:
                            return "";
                    }
                    break;
                case "user":
                    switch (keyItemArray[3]) {
                        case "login":
@@ -166,8 +185,11 @@
                            return "添加用户";
                        case "delete":
                            return "删除用户";
                        default:
                            return "";
                    }
                    break;
                default:
                    return "";
            }
        }
        return null;
src/main/java/com/genersoft/iot/vmp/conf/security/AnonymousAuthenticationEntryPoint.java
@@ -13,6 +13,7 @@
/**
 * 处理匿名用户访问逻辑
 * @author lin
 */
@Component
public class AnonymousAuthenticationEntryPoint implements AuthenticationEntryPoint {
@@ -21,7 +22,6 @@
    @Override
    public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException e) {
//        logger.debug("用户需要登录,访问[{}]失败,AuthenticationException=[{}]", request.getRequestURI(), e.getMessage());
        // 允许跨域
        response.setHeader("Access-Control-Allow-Origin", "*");
        // 允许自定义请求头token(允许head跨域)
@@ -30,7 +30,8 @@
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("code", "-1");
        jsonObject.put("msg", "请登录后重新请求");
        if (request.getRequestURI().contains("api/user/login")){
        String logUri = "api/user/login";
        if (request.getRequestURI().contains(logUri)){
            jsonObject.put("msg", e.getMessage());
        }
        response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
src/main/java/com/genersoft/iot/vmp/domain/req/PresetQuerySipReq.java
New file
@@ -0,0 +1,28 @@
package com.genersoft.iot.vmp.domain.req;
/**
 * @author chenjialing
 */
public class PresetQuerySipReq {
    private String presetId;
    private String presetName;
    public String getPresetId() {
        return presetId;
    }
    public void setPresetId(String presetId) {
        this.presetId = presetId;
    }
    public String getPresetName() {
        return presetName;
    }
    public void setPresetName(String presetName) {
        this.presetName = presetName;
    }
}
src/main/java/com/genersoft/iot/vmp/gb28181/bean/DeviceAlarmMethod.java
New file
@@ -0,0 +1,40 @@
package com.genersoft.iot.vmp.gb28181.bean;
/**
 * 报警方式
 * @author lin
 * 1为电话报警, 2为设备报警, 3为短信报警, 4为 GPS报警, 5为视频报警, 6为设备故障报警,
 * 7其他报警;可以为直接组合如12为电话报警或 设备报警-
 */
public enum DeviceAlarmMethod {
    // 1为电话报警
    Telephone(1),
    // 2为设备报警
    Device(2),
    // 3为短信报警
    SMS(3),
    // 4为 GPS报警
    GPS(4),
    // 5为视频报警
    Video(5),
    // 6为设备故障报警
    DeviceFailure(6),
    // 7其他报警
    Other(7);
    private final int val;
    DeviceAlarmMethod(int val) {
        this.val=val;
    }
    public int getVal() {
        return val;
    }
}
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderPlarformProvider.java
@@ -68,9 +68,6 @@
                toHeader, viaHeaders, maxForwards);
        List<String> agentParam = new ArrayList<>();
        agentParam.add("wvp-pro");
        UserAgentHeader userAgentHeader = sipFactory.createHeaderFactory().createUserAgentHeader(agentParam);
        request.addHeader(userAgentHeader);
        ContentTypeHeader contentTypeHeader = sipFactory.createHeaderFactory().createContentTypeHeader("Application", "MANSCDP+xml");
        request.setContent(content, contentTypeHeader);
@@ -115,10 +112,6 @@
        ExpiresHeader expires = sipFactory.createHeaderFactory().createExpiresHeader(Integer.parseInt(platform.getExpires()));
        request.addHeader(expires);
        List<String> agentParam = new ArrayList<>();
        agentParam.add("wvp-pro");
        UserAgentHeader userAgentHeader = sipFactory.createHeaderFactory().createUserAgentHeader(agentParam);
        request.addHeader(userAgentHeader);
        return request;
    }
@@ -226,10 +219,6 @@
        messageFactory.setDefaultContentEncodingCharset(parentPlatform.getCharacterSet());
        request = messageFactory.createRequest(requestURI, Request.MESSAGE, callIdHeader, cSeqHeader, fromHeader,
                toHeader, viaHeaders, maxForwards);
        List<String> agentParam = new ArrayList<>();
        agentParam.add("wvp-pro");
        UserAgentHeader userAgentHeader = sipFactory.createHeaderFactory().createUserAgentHeader(agentParam);
        request.addHeader(userAgentHeader);
        ContentTypeHeader contentTypeHeader = sipFactory.createHeaderFactory().createContentTypeHeader("Application", "MANSCDP+xml");
        request.setContent(content, contentTypeHeader);
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java
@@ -27,6 +27,7 @@
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.SpringBootVersion;
import org.springframework.context.annotation.DependsOn;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
@@ -37,7 +38,9 @@
import javax.sip.message.Request;
import java.lang.reflect.Field;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
/**    
 * @description:设备能力接口,用于定义设备的控制、查询能力   
@@ -1643,7 +1646,18 @@
        } else if("UDP".equals(device.getTransport())) {
            clientTransaction = udpSipProvider.getNewClientTransaction(request);
        }
        if (request.getHeader(UserAgentHeader.NAME) == null) {
            List<String> agentParam = new ArrayList<>();
            agentParam.add("wvp-pro");
            // TODO 添加版本信息以及日期
            UserAgentHeader userAgentHeader = null;
            try {
                userAgentHeader = sipFactory.createHeaderFactory().createUserAgentHeader(agentParam);
            } catch (ParseException e) {
                throw new RuntimeException(e);
            }
            request.addHeader(userAgentHeader);
        }
        CallIdHeader callIdHeader = (CallIdHeader)request.getHeader(CallIdHeader.NAME);
        // 添加错误订阅
        if (errorEvent != null) {
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/AlarmNotifyMessageHandler.java
@@ -32,7 +32,7 @@
@Component
public class AlarmNotifyMessageHandler extends SIPRequestProcessorParent implements InitializingBean, IMessageHandler {
    private Logger logger = LoggerFactory.getLogger(AlarmNotifyMessageHandler.class);
    private final Logger logger = LoggerFactory.getLogger(AlarmNotifyMessageHandler.class);
    private final String cmdType = "Alarm";
    @Autowired
@@ -85,24 +85,27 @@
        deviceAlarm.setAlarmPriority(getText(rootElement, "AlarmPriority"));
        deviceAlarm.setAlarmMethod(getText(rootElement, "AlarmMethod"));
        deviceAlarm.setAlarmTime(getText(rootElement, "AlarmTime"));
        if (getText(rootElement, "AlarmDescription") == null) {
        String alarmDescription = getText(rootElement, "AlarmDescription");
        if (alarmDescription == null) {
            deviceAlarm.setAlarmDescription("");
        } else {
            deviceAlarm.setAlarmDescription(getText(rootElement, "AlarmDescription"));
            deviceAlarm.setAlarmDescription(alarmDescription);
        }
        if (NumericUtil.isDouble(getText(rootElement, "Longitude"))) {
            deviceAlarm.setLongitude(Double.parseDouble(getText(rootElement, "Longitude")));
        String longitude = getText(rootElement, "Longitude");
        if (longitude != null && NumericUtil.isDouble(longitude)) {
            deviceAlarm.setLongitude(Double.parseDouble(longitude));
        } else {
            deviceAlarm.setLongitude(0.00);
        }
        if (NumericUtil.isDouble(getText(rootElement, "Latitude"))) {
            deviceAlarm.setLatitude(Double.parseDouble(getText(rootElement, "Latitude")));
        String latitude = getText(rootElement, "Latitude");
        if (latitude != null && NumericUtil.isDouble(latitude)) {
            deviceAlarm.setLatitude(Double.parseDouble(latitude));
        } else {
            deviceAlarm.setLatitude(0.00);
        }
        if (!StringUtils.isEmpty(deviceAlarm.getAlarmMethod())) {
            if ( deviceAlarm.getAlarmMethod().equals("4")) {
            if ( deviceAlarm.getAlarmMethod().contains(DeviceAlarmMethod.GPS.getVal() + "")) {
                MobilePosition mobilePosition = new MobilePosition();
                mobilePosition.setDeviceId(deviceAlarm.getDeviceId());
                mobilePosition.setTime(deviceAlarm.getAlarmTime());
@@ -122,7 +125,7 @@
            }
        }
        if (!StringUtils.isEmpty(deviceAlarm.getDeviceId())) {
            if (deviceAlarm.getAlarmMethod().equals("5")) {
            if (deviceAlarm.getAlarmMethod().contains(DeviceAlarmMethod.Video.getVal() + "")) {
                deviceAlarm.setAlarmType(getText(rootElement.element("Info"), "AlarmType"));
            }
        }
@@ -173,25 +176,28 @@
        deviceAlarm.setAlarmPriority(getText(rootElement, "AlarmPriority"));
        deviceAlarm.setAlarmMethod(getText(rootElement, "AlarmMethod"));
        deviceAlarm.setAlarmTime(getText(rootElement, "AlarmTime"));
        if (getText(rootElement, "AlarmDescription") == null) {
        String alarmDescription = getText(rootElement, "AlarmDescription");
        if (alarmDescription == null) {
            deviceAlarm.setAlarmDescription("");
        } else {
            deviceAlarm.setAlarmDescription(getText(rootElement, "AlarmDescription"));
            deviceAlarm.setAlarmDescription(alarmDescription);
        }
        if (NumericUtil.isDouble(getText(rootElement, "Longitude"))) {
            deviceAlarm.setLongitude(Double.parseDouble(getText(rootElement, "Longitude")));
        String longitude = getText(rootElement, "Longitude");
        if (longitude != null && NumericUtil.isDouble(longitude)) {
            deviceAlarm.setLongitude(Double.parseDouble(longitude));
        } else {
            deviceAlarm.setLongitude(0.00);
        }
        if (NumericUtil.isDouble(getText(rootElement, "Latitude"))) {
            deviceAlarm.setLatitude(Double.parseDouble(getText(rootElement, "Latitude")));
        String latitude = getText(rootElement, "Latitude");
        if (latitude != null && NumericUtil.isDouble(latitude)) {
            deviceAlarm.setLatitude(Double.parseDouble(latitude));
        } else {
            deviceAlarm.setLatitude(0.00);
        }
        if (!StringUtils.isEmpty(deviceAlarm.getAlarmMethod())) {
            if (deviceAlarm.getAlarmMethod().equals("5")) {
            if (deviceAlarm.getAlarmMethod().contains(DeviceAlarmMethod.Video.getVal() + "")) {
                deviceAlarm.setAlarmType(getText(rootElement.element("Info"), "AlarmType"));
            }
        }
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/PresetQueryResponseMessageHandler.java
New file
@@ -0,0 +1,124 @@
package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.response.cmd;
import com.genersoft.iot.vmp.conf.SipConfig;
import com.genersoft.iot.vmp.conf.UserSetting;
import com.genersoft.iot.vmp.domain.req.PresetQuerySipReq;
import com.genersoft.iot.vmp.gb28181.bean.*;
import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
import com.genersoft.iot.vmp.gb28181.session.CatalogDataCatch;
import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder;
import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage;
import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent;
import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.IMessageHandler;
import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.response.ResponseMessageHandler;
import com.genersoft.iot.vmp.gb28181.utils.Coordtransform;
import com.genersoft.iot.vmp.gb28181.utils.NumericUtil;
import com.genersoft.iot.vmp.gb28181.utils.XmlUtil;
import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import javax.sip.InvalidArgumentException;
import javax.sip.RequestEvent;
import javax.sip.SipException;
import javax.sip.message.Response;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.UUID;
import static com.genersoft.iot.vmp.gb28181.utils.XmlUtil.getText;
@Component
public class PresetQueryResponseMessageHandler extends SIPRequestProcessorParent implements InitializingBean, IMessageHandler {
    private Logger logger = LoggerFactory.getLogger(PresetQueryResponseMessageHandler.class);
    private final String cmdType = "PresetQuery";
    private SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    @Autowired
    private ResponseMessageHandler responseMessageHandler;
    @Autowired
    private DeferredResultHolder deferredResultHolder;
    @Override
    public void afterPropertiesSet() throws Exception {
        responseMessageHandler.addHandler(cmdType, this);
    }
    @Override
    public void handForDevice(RequestEvent evt, Device device, Element element) {
        Element rootElement = null;
        try {
            rootElement = getRootElement(evt, device.getCharset());
            Element presetListNumElement = rootElement.element("PresetList");
            Element snElement = rootElement.element("SN");
            //该字段可能为通道或则设备的id
            String deviceId = getText(rootElement, "DeviceID");
            String key = DeferredResultHolder.CALLBACK_CMD_PRESETQUERY + deviceId;
            if (snElement == null ||  presetListNumElement == null) {
                responseAck(evt, Response.BAD_REQUEST, "xml error");
                return;
            }
            int sumNum = Integer.parseInt(presetListNumElement.attributeValue("Num"));
            List<PresetQuerySipReq> presetQuerySipReqList = new ArrayList<>();
            if (sumNum == 0) {
                // 数据无预置位信息
            }else {
                for (Iterator<Element> presetIterator =  presetListNumElement.elementIterator();presetIterator.hasNext();){
                    Element itemListElement = presetIterator.next();
                    PresetQuerySipReq presetQuerySipReq = new PresetQuerySipReq();
                    for (Iterator<Element> itemListIterator =  itemListElement.elementIterator();itemListIterator.hasNext();){
                                // 遍历item
                                Element itemOne = itemListIterator.next();
                                String name = itemOne.getName();
                                String textTrim = itemOne.getTextTrim();
                                if("PresetID".equals(name)){
                                    presetQuerySipReq.setPresetId(textTrim);
                                }else {
                                    presetQuerySipReq.setPresetName(textTrim);
                                }
                    }
                    presetQuerySipReqList.add(presetQuerySipReq);
                }
            }
            RequestMessage requestMessage = new RequestMessage();
            requestMessage.setKey(key);
            requestMessage.setData(presetQuerySipReqList);
            deferredResultHolder.invokeAllResult(requestMessage);
            responseAck(evt, Response.OK);
        } catch (DocumentException e) {
            e.printStackTrace();
        } catch (InvalidArgumentException e) {
            e.printStackTrace();
        } catch (ParseException e) {
            e.printStackTrace();
        } catch (SipException e) {
            e.printStackTrace();
        }
    }
    @Override
    public void handForPlatform(RequestEvent evt, ParentPlatform parentPlatform, Element rootElement) {
    }
}
web_src/index.html
@@ -12,26 +12,7 @@
    <script type="text/javascript" src="./static/js/jessibuca/jessibuca.js"></script>
    <script type="text/javascript" src="./static/js/EasyWasmPlayer.js"></script>
    <script type="text/javascript" src="./static/js/ZLMRTCClient.js"></script>
    <script type="text/javascript" src="./static/js/mapConfig.js"></script>
    <div id="app"></div>
    <!-- built files will be auto injected -->
    <script>
      // map组件全局参数, 注释此内容可以关闭地图功能
      window.mapParam = {
        // 坐标系 GCJ-02 WGS-84,
        coordinateSystem: "GCJ-02",
        // 地图瓦片地址
        tilesUrl: "http://webrd0{1-4}.is.autonavi.com/appmaptile?x={x}&y={y}&z={z}&lang=zh_cn&size=1&scale=1&style=8",
        // 瓦片大小
        tileSize: 256,
        // 默认层级
        zoom:10,
        // 默认地图中心点
        center:[116.41020, 39.915119],
        // 地图最大层级
        maxZoom:18,
        // 地图最小层级
        minZoom: 3
      }
    </script>
  </body>
</html>
web_src/src/components/devicePosition.vue
@@ -59,7 +59,7 @@
  },
  data() {
    return {
      onOff: typeof window.mapParam !== "undefined",
      onOff: typeof window.mapParam !== "undefined" && window.mapParam.enable,
      deviceService: new DeviceService(),
      layer: null,
      lineLayer: null,
web_src/static/js/mapConfig.js
New file
@@ -0,0 +1,19 @@
// map组件全局参数, 注释此内容可以关闭地图功能
window.mapParam = {
  // 开启/关闭地图功能
  enable: true,
  // 坐标系 GCJ-02 WGS-84,
  coordinateSystem: "GCJ-02",
  // 地图瓦片地址
  tilesUrl: "http://webrd0{1-4}.is.autonavi.com/appmaptile?x={x}&y={y}&z={z}&lang=zh_cn&size=1&scale=1&style=8",
  // 瓦片大小
  tileSize: 256,
  // 默认层级
  zoom:10,
  // 默认地图中心点
  center:[116.41020, 39.915119],
  // 地图最大层级
  maxZoom:18,
  // 地图最小层级
  minZoom: 3
}