648540858
2021-09-13 5e8a7ce21e35b2c4d7faeede04e60b3537db2f3c
添加utf-8解析设备信息
10个文件已修改
1个文件已添加
252 ■■■■■ 已修改文件
sql/mysql.sql 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/gb28181/auth/RegisterLogicHandler.java 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/gb28181/bean/Device.java 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/MessageRequestProcessor.java 29 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/NotifyRequestProcessor.java 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/RegisterRequestProcessor.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/storager/dao/DeviceMapper.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/device/DeviceQuery.java 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/wvp.sqlite 补丁 | 查看 | 原始文档 | blame | 历史
web_src/src/components/DeviceList.vue 21 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
web_src/src/components/dialog/deviceEdit.vue 117 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
sql/mysql.sql
@@ -23,7 +23,8 @@
    updateTime    varchar(50)  not null,
    port          int          not null,
    expires       int          not null,
    hostAddress   varchar(50)  not null
    hostAddress   varchar(50)  not null,
    charset       varchar(50)  not null
);
create table device_channel
src/main/java/com/genersoft/iot/vmp/gb28181/auth/RegisterLogicHandler.java
@@ -1,5 +1,7 @@
package com.genersoft.iot.vmp.gb28181.auth;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@@ -14,13 +16,17 @@
@Component
public class RegisterLogicHandler {
    private Logger logger = LoggerFactory.getLogger(RegisterLogicHandler.class);
    @Autowired
    private SIPCommander cmder;
    
    public void onRegister(Device device) {
        // TODO 后续处理,只有第一次注册时调用查询设备信息,如需更新调用更新API接口
        // 只有第一次注册时调用查询设备信息,如需更新调用更新API接口
        if (device.isFirsRegister()) {
            logger.info("[{}] 首次注册,查询设备信息以及通道信息", device.getDeviceId());
        cmder.deviceInfoQuery(device);
        cmder.catalogQuery(device, null);
    }
}
}
src/main/java/com/genersoft/iot/vmp/gb28181/bean/Device.java
@@ -99,6 +99,18 @@
     */
    private String mediaServerId;
    /**
     * 首次注册
     */
    private boolean firsRegister;
    /**
     * 字符集, 支持 utf-8 与 gb2312
     */
    private String charset ;
    public String getDeviceId() {
        return deviceId;
    }
@@ -242,4 +254,20 @@
    public void setMediaServerId(String mediaServerId) {
        this.mediaServerId = mediaServerId;
    }
    public boolean isFirsRegister() {
        return firsRegister;
    }
    public void setFirsRegister(boolean firsRegister) {
        this.firsRegister = firsRegister;
    }
    public String getCharset() {
        return charset;
    }
    public void setCharset(String charset) {
        this.charset = charset;
    }
}
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/MessageRequestProcessor.java
@@ -172,6 +172,7 @@
            String deviceId = deviceIdElement.getTextTrim().toString();
            Device device = storager.queryVideoDevice(deviceId);
            if (device != null) {
                rootElement = getRootElement(evt, device.getCharset());
                if (!StringUtils.isEmpty(device.getName())) {
                    mobilePosition.setDeviceName(device.getName());
                }
@@ -449,8 +450,11 @@
            Element rootElement = getRootElement(evt);
            String requestName = rootElement.getName();
            Element deviceIdElement = rootElement.element("DeviceID");
            String deviceId = deviceIdElement.getTextTrim().toString();
            String deviceId = deviceIdElement.getTextTrim();
            Device device = storager.queryVideoDevice(deviceId);
            if (device != null ) {
                rootElement = getRootElement(evt, device.getCharset());
            }
            if (requestName.equals("Query")) {
                logger.info("接收到DeviceInfo查询消息");
                FromHeader fromHeader = (FromHeader) evt.getRequest().getHeader(FromHeader.NAME);
@@ -470,7 +474,9 @@
                if (device == null) {
                    return;
                }
                device.setName(XmlUtil.getText(rootElement, "DeviceName"));
                device.setManufacturer(XmlUtil.getText(rootElement, "Manufacturer"));
                device.setModel(XmlUtil.getText(rootElement, "Model"));
                device.setFirmware(XmlUtil.getText(rootElement, "Firmware"));
@@ -569,12 +575,14 @@
            } else {
                Iterator<Element> deviceListIterator = deviceListElement.elementIterator();
                if (deviceListIterator != null) {
                    Device device = storager.queryVideoDevice(deviceId);
                    if (device == null) {
                        return;
                    }
                deviceListElement = getRootElement(evt, device.getCharset()).element("DeviceList");
                Iterator<Element> deviceListIterator = deviceListElement.elementIterator();
                if (deviceListIterator != null) {
                    // 遍历DeviceList
                    while (deviceListIterator.hasNext()) {
                        Element itemDevice = deviceListIterator.next();
@@ -692,6 +700,9 @@
            Device device = storager.queryVideoDevice(deviceId);
            if (device == null) {
                return;
            }
            if (device.getCharset() != null) {
                rootElement = getRootElement(evt, device.getCharset());
            }
            if (rootElement.getName().equals("Notify")) {    // 处理报警通知
@@ -816,6 +827,10 @@
            Element rootElement = getRootElement(evt);
            Element deviceIdElement = rootElement.element("DeviceID");
            String deviceId = deviceIdElement.getText().toString();
            Device device = storager.queryVideoDevice(deviceId);
            if (device != null ) {
                rootElement = getRootElement(evt, device.getCharset());
            }
            recordInfo.setDeviceId(deviceId);
            recordInfo.setName(XmlUtil.getText(rootElement, "Name"));
            if (XmlUtil.getText(rootElement, "SumNum")== null || XmlUtil.getText(rootElement, "SumNum") =="") {
@@ -1009,9 +1024,15 @@
    }
    private Element getRootElement(RequestEvent evt) throws DocumentException {
        return getRootElement(evt, "gb2312");
    }
    private Element getRootElement(RequestEvent evt, String charset) throws DocumentException {
        if (charset == null) charset = "gb2312";
        Request request = evt.getRequest();
        SAXReader reader = new SAXReader();
        reader.setEncoding("gbk");
        reader.setEncoding(charset);
        Document xml = reader.read(new ByteArrayInputStream(request.getRawContent()));
        return xml.getRootElement();
    }
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/NotifyRequestProcessor.java
@@ -156,6 +156,7 @@
            if (device == null) {
                return;
            }
            rootElement = getRootElement(evt, device.getCharset());
            DeviceAlarm deviceAlarm = new DeviceAlarm();
            deviceAlarm.setDeviceId(deviceId);
            deviceAlarm.setAlarmPriority(XmlUtil.getText(rootElement, "AlarmPriority"));
@@ -218,6 +219,9 @@
            Element deviceIdElement = rootElement.element("DeviceID");
            String deviceId = deviceIdElement.getText();
            Device device = storager.queryVideoDevice(deviceId);
            if (device != null ) {
                rootElement = getRootElement(evt, device.getCharset());
            }
            Element deviceListElement = rootElement.element("DeviceList");
            if (deviceListElement == null) {
                return;
@@ -347,11 +351,14 @@
        serverTransaction.sendResponse(response);
        if (serverTransaction.getDialog() != null) serverTransaction.getDialog().delete();
    }
    private Element getRootElement(RequestEvent evt) throws DocumentException {
        return getRootElement(evt, "gb2312");
    }
    private Element getRootElement(RequestEvent evt, String charset) throws DocumentException {
        if (charset == null) charset = "gb2312";
        Request request = evt.getRequest();
        SAXReader reader = new SAXReader();
        reader.setEncoding("gbk");
        reader.setEncoding(charset);
        Document xml = reader.read(new ByteArrayInputStream(request.getRawContent()));
        return xml.getRootElement();
    }
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/RegisterRequestProcessor.java
@@ -134,7 +134,9 @@
                    if (device == null) {
                        device = new Device();
                        device.setStreamMode("UDP");
                        device.setCharset("gb2312");
                        device.setDeviceId(deviceId);
                        device.setFirsRegister(true);
                    }
                    device.setIp(received);
                    device.setPort(rPort);
src/main/java/com/genersoft/iot/vmp/storager/dao/DeviceMapper.java
@@ -32,6 +32,7 @@
                "keepaliveTime," +
                "createTime," +
                "updateTime," +
                "charset," +
                "online" +
            ") VALUES (" +
                "#{deviceId}," +
@@ -49,6 +50,7 @@
                "#{keepaliveTime}," +
                "#{createTime}," +
                "#{updateTime}," +
                "#{charset}," +
                "#{online}" +
            ")")
    int add(Device device);
@@ -69,6 +71,7 @@
                "<if test=\"registerTime != null\">, registerTime='${registerTime}'</if>" +
                "<if test=\"keepaliveTime != null\">, keepaliveTime='${keepaliveTime}'</if>" +
                "<if test=\"expires != null\">, expires=${expires}</if>" +
                "<if test=\"charset != null\">, charset='${charset}'</if>" +
                "WHERE deviceId='${deviceId}'"+
            " </script>"})
    int update(Device device);
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/device/DeviceQuery.java
@@ -3,6 +3,7 @@
import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage;
import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
import com.genersoft.iot.vmp.vmanager.bean.WVPResult;
import com.github.pagehelper.PageInfo;
import io.swagger.annotations.*;
import org.slf4j.Logger;
@@ -22,6 +23,7 @@
import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
import javax.sip.message.Response;
import java.io.UnsupportedEncodingException;
@Api(tags = "国标设备查询", value = "国标设备查询")
@SuppressWarnings("rawtypes")
@@ -274,6 +276,32 @@
    }
    /**
     * 更新设备信息
     * @param device 设备信息
     * @return
     */
    @ApiOperation("更新设备信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "device", value = "设备信息", required = true, dataTypeClass = Device.class)
    })
    @PostMapping("/device/update/")
    public ResponseEntity<WVPResult<String>> updateDevice(Device device){
        if (device != null && device.getDeviceId() != null) {
            Device deviceInStore = storager.queryVideoDevice(device.getDeviceId());
            if (!StringUtils.isEmpty(device.getName())) deviceInStore.setName(device.getName());
            if (!StringUtils.isEmpty(device.getCharset())) deviceInStore.setCharset(device.getCharset());
            if (!StringUtils.isEmpty(device.getMediaServerId())) deviceInStore.setMediaServerId(device.getMediaServerId());
            storager.updateDevice(deviceInStore);
            cmder.deviceInfoQuery(deviceInStore);
        }
        WVPResult<String> result = new WVPResult<>();
        result.setCode(0);
        result.setMsg("success");
        return new ResponseEntity<>(result,HttpStatus.OK);
    }
    /**
     * 设备状态查询请求API接口
     * 
     * @param deviceId 设备id
src/main/resources/wvp.sqlite
Binary files differ
web_src/src/components/DeviceList.vue
@@ -60,7 +60,7 @@
                            <el-button-group>
                <el-button size="mini" icon="el-icon-video-camera-solid" v-bind:disabled="scope.row.online==0"  type="primary" @click="showChannelList(scope.row)">通道</el-button>
                <el-button size="mini" icon="el-icon-location" v-bind:disabled="scope.row.online==0"  type="primary" @click="showDevicePosition(scope.row)">定位</el-button>
                <el-button size="mini" icon="el-icon-s-tools" v-bind:disabled="scope.row.online==0"  type="primary">控制</el-button>
                <el-button size="mini" icon="el-icon-delete" type="primary" @click="edit(scope.row)">编辑</el-button>
                <el-button size="mini" icon="el-icon-delete" type="danger" v-if="scope.row.online==0"  @click="deleteDevice(scope.row)">删除</el-button>
                            </el-button-group>
                            </template>
@@ -76,7 +76,7 @@
                    layout="total, sizes, prev, pager, next"
                    :total="total">
                </el-pagination>
        <deviceEdit ref="deviceEdit" ></deviceEdit>
            </el-main>
        </el-container>
    </div>
@@ -84,10 +84,12 @@
<script>
    import uiHeader from './UiHeader.vue'
    import deviceEdit from './dialog/deviceEdit.vue'
    export default {
        name: 'app',
        components: {
            uiHeader
            uiHeader,
      deviceEdit
        },
        data() {
            return {
@@ -239,6 +241,19 @@
        }).catch(function(e) {
        });
      },
      edit: function (row) {
        console.log(row);
        this.$refs.deviceEdit.openDialog(row, ()=>{
          this.$refs.deviceEdit.close();
          this.$message({
            showClose: true,
            message: "设备修改成功,通道字符集将在下次更新生效",
            type: "success",
          });
          setTimeout(this.getDeviceList, 200)
        })
      }
        }
web_src/src/components/dialog/deviceEdit.vue
New file
@@ -0,0 +1,117 @@
<template>
  <div id="deviceEdit" v-loading="isLoging">
    <el-dialog
      title="设备编辑"
      width="40%"
      top="2rem"
      :close-on-click-modal="false"
      :visible.sync="showDialog"
      :destroy-on-close="true"
      @close="close()"
    >
      <div id="shared" style="margin-top: 1rem;margin-right: 100px;">
        <el-form ref="form" :rules="rules" :model="form" label-width="140px" >
          <el-form-item label="设备编号" >
            <el-input v-model="form.deviceId" disabled></el-input>
          </el-form-item>
          <el-form-item label="设备名称" prop="name">
            <el-input v-model="form.name" clearable></el-input>
          </el-form-item>
<!--          <el-form-item label="流媒体ID" prop="mediaServerId">-->
<!--            <el-select v-model="form.mediaServerId" style="float: left; width: 100%" >-->
<!--              <el-option key="auto" label="自动负载最小" value="null"></el-option>-->
<!--              <el-option-->
<!--                v-for="item in mediaServerList"-->
<!--                :key="item.id"-->
<!--                :label="item.id"-->
<!--                :value="item.id">-->
<!--              </el-option>-->
<!--            </el-select>-->
<!--          </el-form-item>-->
          <el-form-item label="字符集" prop="charset" >
            <el-select v-model="form.charset" style="float: left; width: 100%" >
                <el-option key="GB2312" label="GB2312" value="gb2312"></el-option>
              <el-option key="UTF-8" label="UTF-8" value="utf-8"></el-option>
            </el-select>
          </el-form-item>
          <el-form-item>
            <div style="float: right;">
              <el-button type="primary" @click="onSubmit" >确认</el-button>
              <el-button @click="close">取消</el-button>
            </div>
          </el-form-item>
        </el-form>
      </div>
    </el-dialog>
  </div>
</template>
<script>
import MediaServer from '../service/MediaServer'
export default {
  name: "deviceEdit",
  props: {},
  computed: {},
  created() {},
  data() {
    return {
      listChangeCallback: null,
      showDialog: false,
      isLoging: false,
      hostNames:[],
      mediaServerList: [], // 滅体节点列表
      mediaServerObj : new MediaServer(),
      form: {},
      rules: {
        name: [{ required: true, message: "请输入名称", trigger: "blur" }]
      },
    };
  },
  methods: {
    openDialog: function (row, callback) {
      console.log(row)
      this.showDialog = true;
      this.listChangeCallback = callback;
      if (row != null) {
        this.form = row;
      }
      this.getMediaServerList();
    },
    getMediaServerList: function (){
      let that = this;
      that.mediaServerObj.getMediaServerList((data)=>{
        that.mediaServerList = data.data;
      })
    },
    onSubmit: function () {
      console.log("onSubmit");
      console.log(this.form);
      this.$axios({
        method: 'post',
        url:`/api/device/query/device/update/`,
        params: this.form
      }).then((res) => {
        console.log(res.data)
        if (res.data.code == 0) {
          this.listChangeCallback()
        }else {
          this.$message({
            showClose: true,
            message: res.data.msg,
            type: "error",
          });
        }
      }).catch(function (error) {
        console.log(error);
      });
    },
    close: function () {
      this.showDialog = false;
      this.$refs.form.resetFields();
    },
  },
};
</script>