上饶市公安局wvp平台
zhongrj
2023-03-04 642544f4f22fd75893b1cc917796b81ffde34903
手台,执法记录仪基础接口新增(新增,修改,查询接口)
集成lombok
6 files modified
11 files added
1509 ■■■■■ changed files
pom.xml 6 ●●●●● patch | view | raw | blame | history
src/main/java/com/genersoft/iot/vmp/netty/business/entity/TalkBackEquipment.java 148 ●●●●● patch | view | raw | blame | history
src/main/java/com/genersoft/iot/vmp/netty/business/entity/TalkBackEquipmentRecord.java 136 ●●●●● patch | view | raw | blame | history
src/main/java/com/genersoft/iot/vmp/netty/business/mapper/TalkBackEquipmentMapper.java 43 ●●●●● patch | view | raw | blame | history
src/main/java/com/genersoft/iot/vmp/netty/business/mapper/TalkBackEquipmentMapper.xml 80 ●●●●● patch | view | raw | blame | history
src/main/java/com/genersoft/iot/vmp/netty/business/service/TalkBackEquipmentService.java 19 ●●●●● patch | view | raw | blame | history
src/main/java/com/genersoft/iot/vmp/netty/business/service/impl/TalkBackEquipmentServiceImpl.java 64 ●●●●● patch | view | raw | blame | history
src/main/java/com/genersoft/iot/vmp/netty/handle/UdpServerHandler.java 64 ●●●●● patch | view | raw | blame | history
src/main/java/com/genersoft/iot/vmp/netty/server/UdpServer.java 15 ●●●●● patch | view | raw | blame | history
src/main/java/com/genersoft/iot/vmp/policeBodyCamera/entity/DeviceChannelPoliceCamera.java 452 ●●●●● patch | view | raw | blame | history
src/main/java/com/genersoft/iot/vmp/policeBodyCamera/mapper/DeviceChannelPoliceCameraMapper.java 350 ●●●●● patch | view | raw | blame | history
src/main/java/com/genersoft/iot/vmp/policeBodyCamera/service/DeviceChannelPoliceCameraService.java 19 ●●●●● patch | view | raw | blame | history
src/main/java/com/genersoft/iot/vmp/policeBodyCamera/service/impl/DeviceChannelPoliceCameraServiceImpl.java 65 ●●●●● patch | view | raw | blame | history
src/main/java/com/genersoft/iot/vmp/policeBodyCamera/vo/DeviceChannelPoliceCameraVO.java 14 ●●●●● patch | view | raw | blame | history
src/main/java/com/genersoft/iot/vmp/storager/impl/VideoManagerStoragerImpl.java 17 ●●●●● patch | view | raw | blame | history
src/main/resources/application-dev.yml 5 ●●●●● patch | view | raw | blame | history
src/main/resources/application-test.yml 12 ●●●●● patch | view | raw | blame | history
pom.xml
@@ -246,6 +246,12 @@
            <artifactId>spring-boot-starter-test</artifactId>
<!--            <scope>test</scope>-->
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.24</version>
        </dependency>
    </dependencies>
src/main/java/com/genersoft/iot/vmp/netty/business/entity/TalkBackEquipment.java
New file
@@ -0,0 +1,148 @@
package com.genersoft.iot.vmp.netty.business.entity;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.io.Serializable;
import java.util.Date;
/**
 * 对接设备信息表 实体类
 *
 * @author zhongrj
 * @since 2023-02-23
 */
@Data
@ApiModel(value = "TalkBackEquipment对象", description = "对接设备信息表")
public class TalkBackEquipment implements Serializable {
    private static final long serialVersionUID = 1L;
    /**
     * 主键id
     */
    @ApiModelProperty(value = "主键id")
    private Long id;
    /**
     * 设备名称
     */
    @ApiModelProperty(value = "设备名称")
    private String name;
    /**
     * 设备编号
     */
    @ApiModelProperty(value = "设备编号")
    private String code;
    /**
     * 设备状态 0:离线  1:在线
     */
    @ApiModelProperty(value = "设备状态")
    private Integer status;
    /**
     * 单位名称
     */
    @ApiModelProperty(value = "单位名称")
    private String unitName;
    /**
     * 单位编号
     */
    @ApiModelProperty(value = "单位编号")
    private String unitCode;
    /**
     * 民警姓名
     */
    @ApiModelProperty(value = "民警姓名")
    private String policeName;
    /**
     * 民警编号
     */
    @ApiModelProperty(value = "民警编号")
    private String policeCode;
    /**
     * 终端编号
     */
    @ApiModelProperty(value = "终端编号")
    private String terminalNumber;
    /**
     * 经度
     */
    @ApiModelProperty(value = "经度")
    private String longitude;
    /**
     * 纬度
     */
    @ApiModelProperty(value = "纬度")
    private String latitude;
    /**
     * 类型 1:手台  2:执法记录仪
     */
    @ApiModelProperty(value = "类型 1:手台  2:执法记录仪")
    private Integer type;
    /**
     * 速度,单位 米/秒
     */
    @ApiModelProperty(value = "速度,单位 米/秒")
    private String speed;
    /**
     * 方向,以正北方向为 0 角度,顺时针方向偏转
     */
    @ApiModelProperty(value = "方向,以正北方向为 0 角度,顺时针方向偏转")
    private String direction;
    /**
     * 高程,单位:米
     */
    @ApiModelProperty(value = "高程,单位:米")
    private String elevation;
    /**
     * 精度
     */
    @ApiModelProperty(value = "精度")
    private String precisions;
    /**
     * 日期
     */
    @ApiModelProperty(value = "日期")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date receiveTime;
    /**
     * 创建时间
     */
    @ApiModelProperty(value = "创建时间")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date createTime;
    /**
     * 更新时间
     */
    @ApiModelProperty(value = "更新时间")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date updateTime;
    /**
     * 说明
     */
//    @ApiModelProperty(value = "说明")
//    private String remark;
}
src/main/java/com/genersoft/iot/vmp/netty/business/entity/TalkBackEquipmentRecord.java
New file
@@ -0,0 +1,136 @@
package com.genersoft.iot.vmp.netty.business.entity;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.io.Serializable;
import java.util.Date;
/**
 * 对接设备信息记录表 实体类
 *
 * @author zhongrj
 * @since 2023-02-23
 */
@Data
@ApiModel(value = "TalkBackEquipment对象", description = "对接设备信息记录表")
public class TalkBackEquipmentRecord implements Serializable {
    private static final long serialVersionUID = 1L;
    /**
     * 主键id
     */
    @ApiModelProperty(value = "主键id")
    private Long id;
    /**
     * 设备id
     */
    @ApiModelProperty(value = "设备id")
    private Long talkBackEquipmentId;
    /**
     * 设备状态 0:离线  1:在线
     */
    @ApiModelProperty(value = "设备状态")
    private Integer status;
    /**
     * 单位名称
     */
    @ApiModelProperty(value = "单位名称")
    private String unitName;
    /**
     * 单位编号
     */
    @ApiModelProperty(value = "单位编号")
    private String unitCode;
    /**
     * 民警姓名
     */
    @ApiModelProperty(value = "民警姓名")
    private String policeName;
    /**
     * 民警编号
     */
    @ApiModelProperty(value = "民警编号")
    private String policeCode;
    /**
     * 终端编号
     */
    @ApiModelProperty(value = "终端编号")
    private String terminalNumber;
    /**
     * 经度
     */
    @ApiModelProperty(value = "经度")
    private String longitude;
    /**
     * 纬度
     */
    @ApiModelProperty(value = "纬度")
    private String latitude;
    /**
     * 类型 1:手台  2:执法记录仪
     */
    @ApiModelProperty(value = "类型 1:手台  2:执法记录仪")
    private Integer type;
    /**
     * 速度,单位 米/秒
     */
    @ApiModelProperty(value = "速度,单位 米/秒")
    private String speed;
    /**
     * 方向,以正北方向为 0 角度,顺时针方向偏转
     */
    @ApiModelProperty(value = "方向,以正北方向为 0 角度,顺时针方向偏转")
    private String direction;
    /**
     * 高程,单位:米
     */
    @ApiModelProperty(value = "高程,单位:米")
    private String elevation;
    /**
     * 精度
     */
    @ApiModelProperty(value = "精度")
    private String precisions;
    /**
     * 日期
     */
    @ApiModelProperty(value = "日期")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date receiveTime;
    /**
     * 创建时间
     */
    @ApiModelProperty(value = "创建时间")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date createTime;
//    /**
//     * 说明
//     */
//    @ApiModelProperty(value = "说明")
//    private String remark;
}
src/main/java/com/genersoft/iot/vmp/netty/business/mapper/TalkBackEquipmentMapper.java
New file
@@ -0,0 +1,43 @@
package com.genersoft.iot.vmp.netty.business.mapper;
import com.genersoft.iot.vmp.netty.business.entity.TalkBackEquipment;
import com.genersoft.iot.vmp.netty.business.entity.TalkBackEquipmentRecord;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.SelectKey;
/**
 * 对讲设备mapper映射层
 * @author zhongrj
 * @date 2023-03-02
 */
@Mapper
public interface TalkBackEquipmentMapper {
    /**
     * 新增对讲设备数据
     * @param talkBackEquipment
     */
    void saveTalkBackEquipment(TalkBackEquipment talkBackEquipment);
    /**
     * 新增对讲设备历史数据
     * @param talkBackEquipmentRecord
     */
    void saveTalkBackEquipmentRecord(TalkBackEquipmentRecord talkBackEquipmentRecord);
    /**
     * 查询设备信息
     * @param code
     * @return
     */
    @Select("select * from sys_talk_back_equipment where code = #{code}")
    TalkBackEquipment getTalkBackEquipment(String code);
    /**
     * 修改对讲设备信息
     * @param talkBackEquipment
     */
    void updateTalkBackEquipment(TalkBackEquipment talkBackEquipment);
}
src/main/java/com/genersoft/iot/vmp/netty/business/mapper/TalkBackEquipmentMapper.xml
New file
@@ -0,0 +1,80 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.genersoft.iot.vmp.netty.business.mapper.TalkBackEquipmentMapper">
    <!--新增对讲设备信息-->
    <insert id="saveTalkBackEquipment" useGeneratedKeys="true" keyProperty="id">
        insert into sys_talk_back_equipment
        (
        name,code,status,unit_name,unit_code,police_name,police_code,terminal_number,longitude,latitude,
        type,speed,direction,elevation,precisions,receive_time,create_time,update_time
        )
        values
        (
        #{name},#{code},#{status},#{unitName},#{unitCode},#{policeName},#{policeCode},#{terminalNumber},#{longitude},#{latitude},
        #{type},#{speed},#{direction},#{elevation},#{precisions},#{receiveTime},#{createTime},#{updateTime}
        )
    </insert>
    <!--新增对接设备历史记录信息-->
    <insert id="saveTalkBackEquipmentRecord">
        insert into sys_talk_back_equipment_record
        (
        talk_back_equipment_id,status,unit_name,unit_code,police_name,police_code,terminal_number,
        longitude,latitude,type,speed,direction,elevation,precisions,receive_time,create_time
        )
        values
        (
        #{talkBackEquipmentId},#{status},#{unitName},#{unitCode},#{policeName},#{policeCode},#{terminalNumber},
        #{longitude},#{latitude}, #{type},#{speed},#{direction},#{elevation},#{precisions},#{receiveTime},#{createTime}
        )
    </insert>
    <!--修改对讲设备信息-->
    <update id="updateTalkBackEquipment">
        update sys_talk_back_equipment
        set
        code = #{code},
        name = #{name},
        status = #{status},
        <if test="null!=unitName and unitName!=''">
            unit_name = #{unitName},
        </if>
        <if test="null!=unitCode and unitCode!=''">
            unit_code = #{unitCode},
        </if>
        <if test="null!=policeName and policeName!=''">
            police_name = #{policeName},
        </if>
        <if test="null!=policeCode and policeCode!=''">
            police_code = #{policeCode},
        </if>
        <if test="null!=terminalNumber and terminalNumber!=''">
            terminal_number = #{terminalNumber},
        </if>
        <if test="null!=longitude and longitude!=''">
            longitude = #{longitude},
        </if>
        <if test="null!=latitude and latitude!=''">
            latitude = #{latitude},
        </if>
        <if test="null!=speed and speed!=''">
            speed = #{speed},
        </if>
        <if test="null!=direction and direction!=''">
            direction = #{direction},
        </if>
        <if test="null!=elevation and elevation!=''">
            elevation = #{elevation},
        </if>
        <if test="null!=precisions and precisions!=''">
            precisions = #{precisions},
        </if>
        <if test="null!=receiveTime">
            receive_time = #{receiveTime},
        </if>
        update_time = #{updateTime}
        where id = #{id}
    </update>
</mapper>
src/main/java/com/genersoft/iot/vmp/netty/business/service/TalkBackEquipmentService.java
New file
@@ -0,0 +1,19 @@
package com.genersoft.iot.vmp.netty.business.service;
import com.genersoft.iot.vmp.netty.business.entity.TalkBackEquipment;
/**
 * 对讲设备信息表 服务类
 *
 * @author zhongrj
 * @date 2023-03-02
 */
public interface TalkBackEquipmentService{
    /**
     * 保存对讲设备数据
     * @param talkBackEquipment
     */
    void save(TalkBackEquipment talkBackEquipment);
}
src/main/java/com/genersoft/iot/vmp/netty/business/service/impl/TalkBackEquipmentServiceImpl.java
New file
@@ -0,0 +1,64 @@
package com.genersoft.iot.vmp.netty.business.service.impl;
import com.genersoft.iot.vmp.netty.business.entity.TalkBackEquipment;
import com.genersoft.iot.vmp.netty.business.entity.TalkBackEquipmentRecord;
import com.genersoft.iot.vmp.netty.business.mapper.TalkBackEquipmentMapper;
import com.genersoft.iot.vmp.netty.business.service.TalkBackEquipmentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Date;
/**
 * 对讲设备服务实现层
 * @author zhongrj
 * @date 2023-03-02
 */
@Service
public class TalkBackEquipmentServiceImpl implements TalkBackEquipmentService {
    @Autowired
    private TalkBackEquipmentMapper talkBackEquipmentMapper;
    /**
     * 保存对讲设备数据
     * @param talkBackEquipment
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void save(TalkBackEquipment talkBackEquipment) {
        //判断设备是否已存在,如果存在则更新,不存在则新增
        TalkBackEquipment backEquipment = talkBackEquipmentMapper.getTalkBackEquipment(talkBackEquipment.getCode());
        if (null==backEquipment) {
            //新增对接设备数据
            talkBackEquipmentMapper.saveTalkBackEquipment(talkBackEquipment);
        }else {
            talkBackEquipment.setId(backEquipment.getId());
            //修改
            talkBackEquipmentMapper.updateTalkBackEquipment(talkBackEquipment);
        }
        //判断是否存在设备id
        if (null != talkBackEquipment.getId()) {
            TalkBackEquipmentRecord equipmentRecord = new TalkBackEquipmentRecord();
            equipmentRecord.setTalkBackEquipmentId(talkBackEquipment.getId());
            equipmentRecord.setStatus(talkBackEquipment.getStatus());
            equipmentRecord.setUnitName(talkBackEquipment.getUnitName());
            equipmentRecord.setUnitCode(talkBackEquipment.getUnitCode());
            equipmentRecord.setPoliceName(talkBackEquipment.getPoliceName());
            equipmentRecord.setPoliceCode(talkBackEquipment.getPoliceCode());
            equipmentRecord.setTerminalNumber(talkBackEquipment.getTerminalNumber());
            equipmentRecord.setType(talkBackEquipment.getType());
            equipmentRecord.setLongitude(talkBackEquipment.getLongitude());
            equipmentRecord.setLatitude(talkBackEquipment.getLatitude());
            equipmentRecord.setSpeed(talkBackEquipment.getSpeed());
            equipmentRecord.setDirection(talkBackEquipment.getDirection());
            equipmentRecord.setElevation(talkBackEquipment.getElevation());
            equipmentRecord.setPrecisions(talkBackEquipment.getPrecisions());
            equipmentRecord.setReceiveTime(talkBackEquipment.getReceiveTime());
            equipmentRecord.setCreateTime(new Date());
            //新增记录信息
            talkBackEquipmentMapper.saveTalkBackEquipmentRecord(equipmentRecord);
        }
    }
}
src/main/java/com/genersoft/iot/vmp/netty/handle/UdpServerHandler.java
@@ -1,5 +1,7 @@
package com.genersoft.iot.vmp.netty.handle;
import com.genersoft.iot.vmp.netty.business.entity.TalkBackEquipment;
import com.genersoft.iot.vmp.netty.business.service.TalkBackEquipmentService;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
@@ -7,7 +9,12 @@
import io.netty.util.CharsetUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.util.Date;
/**
 * updHandler udp 服务端数据接收处理
@@ -17,6 +24,18 @@
@Component
public class UdpServerHandler extends SimpleChannelInboundHandler<DatagramPacket> {
    private Logger logger = LoggerFactory.getLogger(this.getClass());
    private static UdpServerHandler udpServerHandler;
    @Autowired
    private TalkBackEquipmentService talkBackEquipmentService;
    @PostConstruct
    public void init() {
        udpServerHandler = this;
        udpServerHandler.talkBackEquipmentService = this.talkBackEquipmentService;
    }
    @Override
    protected void channelRead0(ChannelHandlerContext channelHandlerContext, DatagramPacket datagramPacket) throws Exception {
@@ -29,9 +48,46 @@
        //获取字符串的长度
        int length = body.length();
        System.out.println("数据长度>>>>>> = " + length);
        //保存数据
        saveTalkBackEquipmentInfo(body);
    }
    //捕获异常
    /**
     * 保存设备数据
     * @param body
     */
    @Async
    public void saveTalkBackEquipmentInfo(String body) {
        TalkBackEquipment equipmentRecord = new TalkBackEquipment();
        equipmentRecord.setName("ces");
        equipmentRecord.setCode("cs123456");
        equipmentRecord.setStatus(1);
        equipmentRecord.setUnitName("CSDW");
        equipmentRecord.setUnitCode("CSDW123456");
        equipmentRecord.setPoliceName("JINGYUAN");
        equipmentRecord.setPoliceCode("JINGYUAN123456");
        equipmentRecord.setTerminalNumber("788888888888");
        equipmentRecord.setType(1);
        equipmentRecord.setLongitude("128.124124412");
        equipmentRecord.setLatitude("27.1224521421");
        equipmentRecord.setSpeed("10");
        equipmentRecord.setDirection("10");
        equipmentRecord.setElevation("10");
        equipmentRecord.setPrecisions("10");
        equipmentRecord.setReceiveTime(new Date());
        equipmentRecord.setCreateTime(new Date());
        equipmentRecord.setUpdateTime(new Date());
        //保存数据
        udpServerHandler.talkBackEquipmentService.save(equipmentRecord);
    }
    /**
     * 捕获异常
     * @param ctx
     * @param cause
     * @throws Exception
     */
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)throws Exception {
        logger.error("UdpServerHandler exceptionCaught"+cause.getMessage());
@@ -40,7 +96,11 @@
        ctx.close();
    }
    //消息没有结束的时候触发
    /**
     * 消息没有结束的时候触发
     * @param ctx
     * @throws Exception
     */
    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        ctx.flush();
src/main/java/com/genersoft/iot/vmp/netty/server/UdpServer.java
@@ -31,15 +31,16 @@
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                //InetSocketAddress socketAddress = new InetSocketAddress("s16s652780.51mypc.cn", 21403);
                //启动服务
                EventLoopGroup workerGroup = new NioEventLoopGroup();
                //优化使用的线程
                final EventExecutorGroup group = new DefaultEventExecutorGroup(16);
                try {
                    Bootstrap b = new Bootstrap();//udp不能使用ServerBootstrap
                    b.group(workerGroup).channel(NioDatagramChannel.class)//设置UDP通道
                    //udp不能使用ServerBootstrap
                    Bootstrap b = new Bootstrap();
                    //设置UDP通道
                    b.group(workerGroup).channel(NioDatagramChannel.class)
                        //设置udp的管道工厂
                        .handler(new ChannelInitializer<NioDatagramChannel>() {
                            //NioDatagramChannel标志着是UDP格式的
@@ -57,9 +58,11 @@
                        })//初始化处理器
                        //true / false 多播模式(UDP适用),可以向多个主机发送消息
                        .option(ChannelOption.SO_BROADCAST, true)// 支持广播
                        .option(ChannelOption.SO_RCVBUF, 2048 * 1024)// 设置UDP读缓冲区为2M
                        .option(ChannelOption.SO_SNDBUF, 1024 * 1024);// 设置UDP写缓冲区为1M
                        .option(ChannelOption.SO_BROADCAST, true)
                        // 设置UDP读缓冲区为2M
                        .option(ChannelOption.SO_RCVBUF, 2048 * 1024)
                        // 设置UDP写缓冲区为1M
                        .option(ChannelOption.SO_SNDBUF, 1024 * 1024);
                    // 绑定端口,开始接收进来的连接
                    ChannelFuture f = b.bind(port).sync();
src/main/java/com/genersoft/iot/vmp/policeBodyCamera/entity/DeviceChannelPoliceCamera.java
New file
@@ -0,0 +1,452 @@
package com.genersoft.iot.vmp.policeBodyCamera.entity;
import lombok.Data;
/**
 * 执法记录仪 实体类
 * @author zhongrj
 * @date 2023-03-04
 */
@Data
public class DeviceChannelPoliceCamera {
    /**
     * 数据库自赠ID
     */
    private int id;
    /**
     * 通道id
     */
    private String channelId;
    /**
     * 设备id
     */
    private String deviceId;
    /**
     * 通道名
     */
    private String name;
    /**
     * 生产厂商
     */
    private String manufacture;
    /**
     * 型号
     */
    private String model;
    /**
     * 设备归属
     */
    private String owner;
    /**
     * 行政区域
     */
    private String civilCode;
    /**
     * 警区
     */
    private String block;
    /**
     * 安装地址
     */
    private String address;
    /**
     * 是否有子设备 1有, 0没有
     */
    private int parental;
    /**
     * 父级id
     */
    private String parentId;
    /**
     * 信令安全模式  缺省为0; 0:不采用; 2: S/MIME签名方式; 3: S/ MIME加密签名同时采用方式; 4:数字摘要方式
     */
    private int safetyWay;
    /**
     * 注册方式 缺省为1;1:符合IETFRFC3261标准的认证注册模 式; 2:基于口令的双向认证注册模式; 3:基于数字证书的双向认证注册模式
     */
    private int registerWay;
    /**
     * 证书序列号
     */
    private String certNum;
    /**
     * 证书有效标识 缺省为0;证书有效标识:0:无效1: 有效
     */
    private int certifiable;
    /**
     * 证书无效原因码
     */
    private int errCode;
    /**
     * 证书终止有效期
     */
    private String endTime;
    /**
     * 保密属性 缺省为0; 0:不涉密, 1:涉密
     */
    private String secrecy;
    /**
     * IP地址
     */
    private String ipAddress;
    /**
     * 端口号
     */
    private int port;
    /**
     * 密码
     */
    private String password;
    /**
     * 云台类型
     */
    private int PTZType;
    /**
     * 云台类型描述字符串
     */
    private String PTZTypeText;
    /**
     * 创建时间
     */
    private String createTime;
    /**
     * 更新时间
     */
    private String updateTime;
    /**
     * 在线/离线
     * 1在线,0离线
     * 默认在线
     * 信令:
     * <Status>ON</Status>
     * <Status>OFF</Status>
     * 遇到过NVR下的IPC下发信令可以推流, 但是 Status 响应 OFF
     */
    private int status;
    /**
     * 经度
     */
    private double longitude;
    /**
     * 纬度
     */
    private double latitude;
    /**
     * 子设备数
     */
    private int subCount;
    /**
     * 流唯一编号,存在表示正在直播
     */
    private String  streamId;
    /**
     *  是否含有音频
     */
    private boolean hasAudio;
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getDeviceId() {
        return deviceId;
    }
    public void setDeviceId(String deviceId) {
        this.deviceId = deviceId;
    }
    public void setPTZType(int PTZType) {
        this.PTZType = PTZType;
        switch (PTZType) {
            case 0:
                this.PTZTypeText = "未知";
                break;
            case 1:
                this.PTZTypeText = "球机";
                break;
            case 2:
                this.PTZTypeText = "半球";
                break;
            case 3:
                this.PTZTypeText = "固定枪机";
                break;
            case 4:
                this.PTZTypeText = "遥控枪机";
                break;
        }
    }
    public String getChannelId() {
        return channelId;
    }
    public void setChannelId(String channelId) {
        this.channelId = channelId;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getManufacture() {
        return manufacture;
    }
    public void setManufacture(String manufacture) {
        this.manufacture = manufacture;
    }
    public String getModel() {
        return model;
    }
    public void setModel(String model) {
        this.model = model;
    }
    public String getOwner() {
        return owner;
    }
    public void setOwner(String owner) {
        this.owner = owner;
    }
    public String getCivilCode() {
        return civilCode;
    }
    public void setCivilCode(String civilCode) {
        this.civilCode = civilCode;
    }
    public String getBlock() {
        return block;
    }
    public void setBlock(String block) {
        this.block = block;
    }
    public String getAddress() {
        return address;
    }
    public void setAddress(String address) {
        this.address = address;
    }
    public int getParental() {
        return parental;
    }
    public void setParental(int parental) {
        this.parental = parental;
    }
    public String getParentId() {
        return parentId;
    }
    public void setParentId(String parentId) {
        this.parentId = parentId;
    }
    public int getSafetyWay() {
        return safetyWay;
    }
    public void setSafetyWay(int safetyWay) {
        this.safetyWay = safetyWay;
    }
    public int getRegisterWay() {
        return registerWay;
    }
    public void setRegisterWay(int registerWay) {
        this.registerWay = registerWay;
    }
    public String getCertNum() {
        return certNum;
    }
    public void setCertNum(String certNum) {
        this.certNum = certNum;
    }
    public int getCertifiable() {
        return certifiable;
    }
    public void setCertifiable(int certifiable) {
        this.certifiable = certifiable;
    }
    public int getErrCode() {
        return errCode;
    }
    public void setErrCode(int errCode) {
        this.errCode = errCode;
    }
    public String getEndTime() {
        return endTime;
    }
    public void setEndTime(String endTime) {
        this.endTime = endTime;
    }
    public String getSecrecy() {
        return secrecy;
    }
    public void setSecrecy(String secrecy) {
        this.secrecy = secrecy;
    }
    public String getIpAddress() {
        return ipAddress;
    }
    public void setIpAddress(String ipAddress) {
        this.ipAddress = ipAddress;
    }
    public int getPort() {
        return port;
    }
    public void setPort(int port) {
        this.port = port;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    public int getPTZType() {
        return PTZType;
    }
    public String getPTZTypeText() {
        return PTZTypeText;
    }
    public void setPTZTypeText(String PTZTypeText) {
        this.PTZTypeText = PTZTypeText;
    }
    public int getStatus() {
        return status;
    }
    public void setStatus(int status) {
        this.status = status;
    }
    public double getLongitude() {
        return longitude;
    }
    public void setLongitude(double longitude) {
        this.longitude = longitude;
    }
    public double getLatitude() {
        return latitude;
    }
    public void setLatitude(double latitude) {
        this.latitude = latitude;
    }
    public int getSubCount() {
        return subCount;
    }
    public void setSubCount(int subCount) {
        this.subCount = subCount;
    }
    public boolean isHasAudio() {
        return hasAudio;
    }
    public void setHasAudio(boolean hasAudio) {
        this.hasAudio = hasAudio;
    }
    public String getStreamId() {
        return streamId;
    }
    public void setStreamId(String streamId) {
        this.streamId = streamId;
    }
    public String getCreateTime() {
        return createTime;
    }
    public void setCreateTime(String createTime) {
        this.createTime = createTime;
    }
    public String getUpdateTime() {
        return updateTime;
    }
    public void setUpdateTime(String updateTime) {
        this.updateTime = updateTime;
    }
}
src/main/java/com/genersoft/iot/vmp/policeBodyCamera/mapper/DeviceChannelPoliceCameraMapper.java
New file
@@ -0,0 +1,350 @@
package com.genersoft.iot.vmp.policeBodyCamera.mapper;
import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
import com.genersoft.iot.vmp.policeBodyCamera.entity.DeviceChannelPoliceCamera;
import com.genersoft.iot.vmp.vmanager.bean.DeviceChannelTree;
import com.genersoft.iot.vmp.vmanager.gb28181.platform.bean.ChannelReduce;
import org.apache.ibatis.annotations.*;
import org.springframework.stereotype.Repository;
import java.util.List;
/**
 * 用于存储设备通道信息
 * @author zhongrj
 * @date 2023-03-04
 */
@Mapper
@Repository
public interface DeviceChannelPoliceCameraMapper {
    /**
     * 新增执法记录仪信息
     * @param channel
     * @return
     */
    @Insert("INSERT INTO device_channel_police_camera (channelId, deviceId, name, manufacture, model, owner, civilCode, block, " +
            "address, parental, parentId, safetyWay, registerWay, certNum, certifiable, errCode, secrecy, " +
            "ipAddress, port, password, PTZType, status, streamId, longitude, latitude, createTime, updateTime) " +
            "VALUES ('${channelId}', '${deviceId}', '${name}', '${manufacture}', '${model}', '${owner}', '${civilCode}', '${block}'," +
            "'${address}', ${parental}, '${parentId}', ${safetyWay}, ${registerWay}, '${certNum}', ${certifiable}, ${errCode}, '${secrecy}', " +
            "'${ipAddress}', ${port}, '${password}', ${PTZType}, ${status}, '${streamId}', ${longitude}, ${latitude},'${createTime}', '${updateTime}')")
    int add(DeviceChannel channel);
    /**
     * 更新执法记录仪信息
     * @param channel
     * @return
     */
    @Update(value = {" <script>" +
            "UPDATE device_channel_police_camera " +
            "SET updateTime='${updateTime}'" +
            "<if test='name != null'>, name='${name}'</if>" +
            "<if test='manufacture != null'>, manufacture='${manufacture}'</if>" +
            "<if test='model != null'>, model='${model}'</if>" +
            "<if test='owner != null'>, owner='${owner}'</if>" +
            "<if test='civilCode != null'>, civilCode='${civilCode}'</if>" +
            "<if test='block != null'>, block='${block}'</if>" +
            "<if test='address != null'>, address='${address}'</if>" +
            "<if test='parental != null'>, parental=${parental}</if>" +
            "<if test='parentId != null'>, parentId='${parentId}'</if>" +
            "<if test='safetyWay != null'>, safetyWay=${safetyWay}</if>" +
            "<if test='registerWay != null'>, registerWay=${registerWay}</if>" +
            "<if test='certNum != null'>, certNum='${certNum}'</if>" +
            "<if test='certifiable != null'>, certifiable=${certifiable}</if>" +
            "<if test='errCode != null'>, errCode=${errCode}</if>" +
            "<if test='secrecy != null'>, secrecy='${secrecy}'</if>" +
            "<if test='ipAddress != null'>, ipAddress='${ipAddress}'</if>" +
            "<if test='port != null'>, port=${port}</if>" +
            "<if test='password != null'>, password='${password}'</if>" +
            "<if test='PTZType != null'>, PTZType=${PTZType}</if>" +
            "<if test='status != null'>, status='${status}'</if>" +
            "<if test='streamId != null'>, streamId='${streamId}'</if>" +
            "<if test='hasAudio != null'>, hasAudio=${hasAudio}</if>" +
            "<if test='longitude != null'>, longitude=${longitude}</if>" +
            "<if test='latitude != null'>, latitude=${latitude}</if>" +
            "WHERE deviceId='${deviceId}' AND channelId='${channelId}'"+
            " </script>"})
    int update(DeviceChannel channel);
    @Select(value = {" <script>" +
            "SELECT " +
            "dc.id,\n" +
            "dc.channelId,\n" +
            "dc.`name`,\n" +
            "dc.manufacture,\n" +
            "dc.model,\n" +
            "dc.`owner`,\n" +
            "dc.civilCode,\n" +
            "dc.block,\n" +
            "dc.address,\n" +
            "dc.parentId,\n" +
            "dc.safetyWay,\n" +
            "dc.registerWay,\n" +
            "dc.certNum,\n" +
            "dc.certifiable,\n" +
            "dc.errCode,\n" +
            "dc.endTime,\n" +
            "dc.secrecy,\n" +
            "dc.ipAddress,dc.`port`,dc.`password`,dc.PTZType,dc.`status`,dc.streamId,dc.deviceId,\n" +
            "dc.parental,dc.hasAudio,dc.createTime,dc.updateTime,dc.subCount," +
            "any_value ( CASE WHEN dc.latitude = 0 THEN dmp.latitude ELSE dc.latitude END ) AS latitude," +
            "any_value ( CASE WHEN dc.longitude = 0 THEN dmp.longitude ELSE dc.longitude END ) AS longitude " +
            "from " +
            "device_channel_police_camera dc " +
            "LEFT JOIN device_mobile_position dmp ON dc.channelId = dmp.deviceId " +
            "WHERE " +
            "dc.deviceId = #{deviceId} " +
            " <if test='query != null'> AND (dc.channelId LIKE '%${query}%' OR dc.name LIKE '%${query}%' OR dc.name LIKE '%${query}%')</if> " +
            " <if test='parentChannelId != null'> AND dc.parentId=#{parentChannelId} </if> " +
            " <if test='online == true' > AND dc.status=1</if>" +
            " <if test='online == false' > AND dc.status=0</if>" +
            " <if test='type == 0' > AND dc.name like '%赣E%'</if>" +
            " <if test='type == 1' > AND dc.name not like '%赣E%' and dc.ipAddress is not null and dc.ipAddress != '' </if>" +
            " <if test='hasSubChannel == true' >  AND dc.subCount > 0 </if>" +
            " <if test='hasSubChannel == false' >  AND dc.subCount = 0 </if>" +
            "GROUP BY dc.channelId " +
            " </script>"})
    List<DeviceChannel> queryChannelsCar(String deviceId, String parentChannelId, String query,String type, Boolean hasSubChannel, Boolean online);
    @Select(value = {" <script>" +
            "SELECT " +
            "dc.id,\n" +
            "dc.channelId,\n" +
            "dc.`name`,\n" +
            "dc.manufacture,\n" +
            "dc.model,\n" +
            "dc.`owner`,\n" +
            "dc.civilCode,\n" +
            "dc.block,\n" +
            "dc.address,\n" +
            "dc.parentId,\n" +
            "dc.safetyWay,\n" +
            "dc.registerWay,\n" +
            "dc.certNum,\n" +
            "dc.certifiable,\n" +
            "dc.errCode,\n" +
            "dc.endTime,\n" +
            "dc.secrecy,\n" +
            "dc.ipAddress,dc.`port`,dc.`password`,dc.PTZType,dc.`status`,dc.streamId,dc.deviceId,\n" +
            "dc.parental,dc.hasAudio,dc.createTime,dc.updateTime,dc.subCount," +
            "any_value ( CASE WHEN dc.latitude = 0 THEN dmp.latitude ELSE dc.latitude END ) AS latitude," +
            "any_value ( CASE WHEN dc.longitude = 0 THEN dmp.longitude ELSE dc.longitude END ) AS longitude " +
            "from " +
            "device_channel_police_camera dc " +
            "LEFT JOIN device_mobile_position dmp ON dc.channelId = dmp.deviceId " +
            "WHERE " +
            "dc.deviceId = #{deviceId} " +
            " <if test='query != null'> AND (dc.channelId LIKE '%${query}%' OR dc.name LIKE '%${query}%' OR dc.name LIKE '%${query}%')</if> " +
            " <if test='parentChannelId != null'> AND dc.parentId=#{parentChannelId} </if> " +
            " <if test='online == true' > AND dc.status=1</if>" +
            " <if test='online == false' > AND dc.status=0</if>" +
            " <if test='hasSubChannel == true' >  AND dc.subCount > 0 </if>" +
            " <if test='hasSubChannel == false' >  AND dc.subCount = 0 </if>" +
            "GROUP BY dc.channelId " +
            " </script>"})
    List<DeviceChannel> queryChannels(String deviceId, String parentChannelId, String query, Boolean hasSubChannel, Boolean online);
    /**
     * 查询执法记录仪信息
     * @param deviceId
     * @param channelId
     * @return
     */
    @Select("SELECT * FROM device_channel_police_camera_police_camera WHERE deviceId=#{deviceId} AND channelId=#{channelId}")
    DeviceChannelPoliceCamera queryChannel(String deviceId, String channelId);
    @Delete("DELETE FROM device_channel_police_camera WHERE deviceId=#{deviceId}")
    int cleanChannelsByDeviceId(String deviceId);
    /**
     * 删除执法记录仪信息
     * @param deviceId
     * @param channelId
     * @return
     */
    @Delete("DELETE FROM device_channel_police_camera WHERE deviceId=#{deviceId} AND channelId=#{channelId}")
    int del(String deviceId, String channelId);
    @Update(value = {"UPDATE device_channel_police_camera SET streamId=null WHERE deviceId=#{deviceId} AND channelId=#{channelId}"})
    void stopPlay(String deviceId, String channelId);
    @Update(value = {"UPDATE device_channel_police_camera SET streamId=#{streamId} WHERE deviceId=#{deviceId} AND channelId=#{channelId}"})
    void startPlay(String deviceId, String channelId, String streamId);
    @Select(value = {" <script>" +
            "SELECT " +
            "    dc.id,\n" +
            "    dc.channelId,\n" +
            "    dc.deviceId,\n" +
            "    dc.name,\n" +
            "    de.manufacturer,\n" +
            "    de.hostAddress,\n" +
            "    dc.subCount,\n" +
            "    pgc.platformId as platformId,\n" +
            "    pgc.catalogId as catalogId " +
            " FROM device_channel_police_camera dc " +
            " LEFT JOIN device de ON dc.deviceId = de.deviceId " +
            " LEFT JOIN platform_gb_channel pgc on pgc.deviceChannelId = dc.id " +
            " WHERE 1=1 " +
            " <if test='query != null'> AND (dc.channelId LIKE '%${query}%' OR dc.name LIKE '%${query}%' OR dc.name LIKE '%${query}%')</if> " +
            " <if test='online == true' > AND dc.status=1</if> " +
            " <if test='online == false' > AND dc.status=0</if> " +
            " <if test='hasSubChannel!= null and hasSubChannel == true' >  AND dc.subCount > 0</if> " +
            " <if test='hasSubChannel!= null and hasSubChannel == false' >  AND dc.subCount == 0</if> " +
            " <if test='catalogId == null ' >  AND dc.id not in (select deviceChannelId from platform_gb_channel where platformId=#{platformId} ) </if> " +
            " <if test='catalogId != null ' >  AND pgc.platformId = #{platformId} and pgc.catalogId=#{catalogId} </if> " +
            " ORDER BY dc.deviceId, dc.channelId ASC" +
            " </script>"})
    List<ChannelReduce> queryChannelListInAll(String query, Boolean online, Boolean hasSubChannel, String platformId, String catalogId);
    @Select("SELECT * FROM device_channel_police_camera WHERE channelId=#{channelId}")
    List<DeviceChannel> queryChannelByChannelId( String channelId);
    @Update(value = {"UPDATE device_channel_police_camera SET status=0 WHERE deviceId=#{deviceId} AND channelId=#{channelId}"})
    void offline(String deviceId,  String channelId);
    @Update(value = {"UPDATE device_channel_police_camera SET status=1 WHERE deviceId=#{deviceId} AND channelId=#{channelId}"})
    void online(String deviceId,  String channelId);
    @Insert("<script> " +
            "insert into device_channel_police_camera " +
            "(channelId, deviceId, name, manufacture, model, owner, civilCode, block, subCount, " +
            "  address, parental, parentId, safetyWay, registerWay, certNum, certifiable, errCode, secrecy, " +
            "  ipAddress, port, password, PTZType, status, streamId, longitude, latitude, createTime, updateTime) " +
            "values " +
            "<foreach collection='addChannels' index='index' item='item' separator=','> " +
            "('${item.channelId}', '${item.deviceId}', '${item.name}', '${item.manufacture}', '${item.model}', " +
            "'${item.owner}', '${item.civilCode}', '${item.block}',${item.subCount}," +
            "'${item.address}', ${item.parental}, '${item.parentId}', ${item.safetyWay}, ${item.registerWay}, " +
            "'${item.certNum}', ${item.certifiable}, ${item.errCode}, '${item.secrecy}', " +
            "'${item.ipAddress}', ${item.port}, '${item.password}', ${item.PTZType}, ${item.status}, " +
            "'${item.streamId}', ${item.longitude}, ${item.latitude},'${item.createTime}', '${item.updateTime}')" +
            "</foreach> " +
            "ON DUPLICATE KEY UPDATE " +
            "updateTime=VALUES(updateTime), " +
            "name=VALUES(name), " +
            "manufacture=VALUES(manufacture), " +
            "model=VALUES(model), " +
            "owner=VALUES(owner), " +
            "civilCode=VALUES(civilCode), " +
            "block=VALUES(block), " +
            "subCount=VALUES(subCount), " +
            "address=VALUES(address), " +
            "parental=VALUES(parental), " +
            "parentId=VALUES(parentId), " +
            "safetyWay=VALUES(safetyWay), " +
            "registerWay=VALUES(registerWay), " +
            "certNum=VALUES(certNum), " +
            "certifiable=VALUES(certifiable), " +
            "errCode=VALUES(errCode), " +
            "secrecy=VALUES(secrecy), " +
            "ipAddress=VALUES(ipAddress), " +
            "port=VALUES(port), " +
            "password=VALUES(password), " +
            "PTZType=VALUES(PTZType), " +
            "status=VALUES(status), " +
            "streamId=VALUES(streamId), " +
            "longitude=VALUES(longitude), " +
            "latitude=VALUES(latitude)" +
            "</script>")
    int batchAdd(List<DeviceChannel> addChannels);
    @Update({"<script>" +
            "<foreach collection='updateChannels' item='item' separator=';'>" +
            " UPDATE" +
            " device_channel_police_camera" +
            " SET updateTime='${item.updateTime}'" +
            "<if test='item.name != null'>, name='${item.name}'</if>" +
            "<if test='item.manufacture != null'>, manufacture='${item.manufacture}'</if>" +
            "<if test='item.model != null'>, model='${item.model}'</if>" +
            "<if test='item.owner != null'>, owner='${item.owner}'</if>" +
            "<if test='item.civilCode != null'>, civilCode='${item.civilCode}'</if>" +
            "<if test='item.block != null'>, block='${item.block}'</if>" +
            "<if test='item.subCount != null'>, block=${item.subCount}</if>" +
            "<if test='item.address != null'>, address='${item.address}'</if>" +
            "<if test='item.parental != null'>, parental=${item.parental}</if>" +
            "<if test='item.parentId != null'>, parentId='${item.parentId}'</if>" +
            "<if test='item.safetyWay != null'>, safetyWay=${item.safetyWay}</if>" +
            "<if test='item.registerWay != null'>, registerWay=${item.registerWay}</if>" +
            "<if test='item.certNum != null'>, certNum='${item.certNum}'</if>" +
            "<if test='item.certifiable != null'>, certifiable=${item.certifiable}</if>" +
            "<if test='item.errCode != null'>, errCode=${item.errCode}</if>" +
            "<if test='item.secrecy != null'>, secrecy='${item.secrecy}'</if>" +
            "<if test='item.ipAddress != null'>, ipAddress='${item.ipAddress}'</if>" +
            "<if test='item.port != null'>, port=${item.port}</if>" +
            "<if test='item.password != null'>, password='${item.password}'</if>" +
            "<if test='item.PTZType != null'>, PTZType=${item.PTZType}</if>" +
            "<if test='item.status != null'>, status='${item.status}'</if>" +
            "<if test='item.streamId != null'>, streamId='${item.streamId}'</if>" +
            "<if test='item.hasAudio != null'>, hasAudio=${item.hasAudio}</if>" +
            "<if test='item.longitude != null'>, longitude=${item.longitude}</if>" +
            "<if test='item.latitude != null'>, latitude=${item.latitude}</if>" +
            "WHERE deviceId=#{item.deviceId} AND channelId=#{item.channelId}"+
            "</foreach>" +
            "</script>"})
    int batchUpdate(List<DeviceChannel> updateChannels);
    @Select(value = {" <script>" +
            "SELECT " +
            "dc1.* " +
            "from " +
            "device_channel_police_camera dc1 " +
            "WHERE " +
            "dc1.deviceId = #{deviceId} " +
            " <if test='query != null'> AND (dc1.channelId LIKE '%${query}%' OR dc1.name LIKE '%${query}%' OR dc1.name LIKE '%${query}%')</if> " +
            " <if test='parentChannelId != null'> AND dc1.parentId=#{parentChannelId} </if> " +
            " <if test='online == true' > AND dc1.status=1</if>" +
            " <if test='online == false' > AND dc1.status=0</if>" +
            " <if test='hasSubChannel == true' >  AND dc1.subCount >0</if>" +
            " <if test='hasSubChannel == false' >  AND dc1.subCount=0</if>" +
            "ORDER BY dc1.channelId ASC " +
            "Limit #{limit} OFFSET #{start}" +
            " </script>"})
    List<DeviceChannelPoliceCamera> queryChannelsByDeviceIdWithStartAndLimit(String deviceId, String parentChannelId, String query,
                                                                             Boolean hasSubChannel, Boolean online, int start, int limit);
    @Select("SELECT * FROM device_channel_police_camera WHERE deviceId=#{deviceId} AND status=1")
    List<DeviceChannel> queryOnlineChannelsByDeviceId(String deviceId);
    @Select(" SELECT\n" +
            "        id,\n" +
            "        channelId,\n" +
            "        deviceId,\n" +
            "        parentId,\n" +
            "        status,\n" +
            "        name as title,\n" +
            "        channelId as \"value\",\n" +
            "        channelId as \"key\",\n" +
            "        longitude,\n" +
            "        latitude\n" +
            "        from device_channel_police_camera\n" +
            "        where deviceId = #{deviceId}")
    List<DeviceChannelTree> tree(String deviceId);
    @Delete(value = {" <script>" +
            "DELETE " +
            "from " +
            "device_channel_police_camera " +
            "WHERE " +
            "deviceId = #{deviceId} " +
            " AND channelId NOT IN " +
            "<foreach collection='channels'  item='item'  open='(' separator=',' close=')' > #{item.channelId}</foreach>" +
            " </script>"})
    int cleanChannelsNotInList(String deviceId, List<DeviceChannel> channels);
    /**
     * 更新是否有子节点
     * @param deviceId
     * @param channelId
     * @return
     */
    @Update(" update device_channel_police_camera" +
            " set subCount = (select *" +
            "                from (select count(0)" +
            "                      from device_channel_police_camera" +
            "                      where deviceId = #{deviceId} and parentId = #{channelId}) as temp)" +
            " where deviceId = #{deviceId} " +
            " and channelId = #{channelId}")
    int updateChannelSubCount(String deviceId, String channelId);
}
src/main/java/com/genersoft/iot/vmp/policeBodyCamera/service/DeviceChannelPoliceCameraService.java
New file
@@ -0,0 +1,19 @@
package com.genersoft.iot.vmp.policeBodyCamera.service;
import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
public interface DeviceChannelPoliceCameraService {
    /**
     * 更新执法记录仪信息
     * @param channel
     */
    void updateChannelPoliceCamera(DeviceChannel channel);
    /**
     * 删除执法记录仪信息
     * @param deviceId
     * @param channelId
     */
    void del(String deviceId, String channelId);
}
src/main/java/com/genersoft/iot/vmp/policeBodyCamera/service/impl/DeviceChannelPoliceCameraServiceImpl.java
New file
@@ -0,0 +1,65 @@
package com.genersoft.iot.vmp.policeBodyCamera.service.impl;
import com.genersoft.iot.vmp.common.StreamInfo;
import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
import com.genersoft.iot.vmp.policeBodyCamera.entity.DeviceChannelPoliceCamera;
import com.genersoft.iot.vmp.policeBodyCamera.mapper.DeviceChannelPoliceCameraMapper;
import com.genersoft.iot.vmp.policeBodyCamera.service.DeviceChannelPoliceCameraService;
import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.text.SimpleDateFormat;
/**
 * 执法记录仪服务实现层
 * @author zhongrj
 * @date 2023-03-04
 */
@Service
public class DeviceChannelPoliceCameraServiceImpl implements DeviceChannelPoliceCameraService {
    @Autowired
    private IRedisCatchStorage redisCatchStorage;
    @Autowired
    private DeviceChannelPoliceCameraMapper deviceChannelPoliceCameraMapper;
    private SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    /**
     * 更新执法记录仪信息
     * 注:DeviceChannel类和DeviceChannelPoliceCamera类字段完全相同
     * @param channel
     */
    @Override
    public void updateChannelPoliceCamera(DeviceChannel channel) {
        String channelId = channel.getChannelId();
        String deviceId = channel.getDeviceId();
        //日期格式化
        String now = this.format.format(System.currentTimeMillis());
        //查询执法记录仪信息
        DeviceChannelPoliceCamera deviceChannel = deviceChannelPoliceCameraMapper.queryChannel(deviceId, channelId);
        //如果为空,则新增
        if (deviceChannel == null) {
            channel.setCreateTime(now);
            //新增
            deviceChannelPoliceCameraMapper.add(channel);
        }else {
            channel.setId(deviceChannel.getId());
            //更新
            deviceChannelPoliceCameraMapper.update(channel);
        }
        deviceChannelPoliceCameraMapper.updateChannelSubCount(deviceId,channel.getParentId());
    }
    /**
     * 删除执法记录仪信息
     * @param deviceId
     * @param channelId
     */
    @Override
    public void del(String deviceId, String channelId) {
        deviceChannelPoliceCameraMapper.del(deviceId,channelId);
    }
}
src/main/java/com/genersoft/iot/vmp/policeBodyCamera/vo/DeviceChannelPoliceCameraVO.java
New file
@@ -0,0 +1,14 @@
package com.genersoft.iot.vmp.policeBodyCamera.vo;
import com.genersoft.iot.vmp.policeBodyCamera.entity.DeviceChannelPoliceCamera;
import lombok.Data;
/**
 * 执法记录仪vo
 * @author zhongrj
 * @date 2023-03-04
 */
@Data
public class DeviceChannelPoliceCameraVO extends DeviceChannelPoliceCamera {
}
src/main/java/com/genersoft/iot/vmp/storager/impl/VideoManagerStoragerImpl.java
@@ -9,6 +9,8 @@
import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem;
import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem;
import com.genersoft.iot.vmp.policeBodyCamera.entity.DeviceChannelPoliceCamera;
import com.genersoft.iot.vmp.policeBodyCamera.service.DeviceChannelPoliceCameraService;
import com.genersoft.iot.vmp.service.IGbStreamService;
import com.genersoft.iot.vmp.service.bean.GPSMsgInfo;
import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
@@ -102,6 +104,9 @@
    @Autowired
    private MediaServerMapper mediaServerMapper;
    @Autowired
    private DeviceChannelPoliceCameraService deviceChannelPoliceCameraService;
    private SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
@@ -159,6 +164,7 @@
    public synchronized void updateChannel(String deviceId, DeviceChannel channel) {
        String channelId = channel.getChannelId();
        channel.setDeviceId(deviceId);
        //更新通道数据
        StreamInfo streamInfo = redisCatchStorage.queryPlayByDevice(deviceId, channelId);
        if (streamInfo != null) {
            channel.setStreamId(streamInfo.getStream());
@@ -173,6 +179,11 @@
            deviceChannelMapper.update(channel);
        }
        deviceChannelMapper.updateChannelSubCount(deviceId,channel.getParentId());
        //如果是是执法记录仪
        if (null!=channel.getName() && channel.getName().contains("执法记录仪")){
            //更新执法记录仪信息
            deviceChannelPoliceCameraService.updateChannelPoliceCamera(channel);
        }
    }
    @Override
@@ -392,6 +403,12 @@
    @Override
    public int delChannel(String deviceId, String channelId) {
        //查询设备信息
        DeviceChannel deviceChannel = deviceChannelMapper.queryChannel(deviceId, channelId);
        if (deviceChannel.getName().equals("执法记录仪")){
            //同时删除执法记录仪信息
            deviceChannelPoliceCameraService.del(deviceId, channelId);
        }
        return deviceChannelMapper.del(deviceId, channelId);
    }
src/main/resources/application-dev.yml
@@ -101,3 +101,8 @@
# 手台,执法记录仪udp接收端口
syscfg:
  udpReceivePort: 7687
#mybatis 配置
mybatis:
  mapper-locations: classpath:**/mapper/*Mapper.xml
src/main/resources/application-test.yml
@@ -11,7 +11,7 @@
    # [必须修改] 端口号
    port: 6379
    # [可选] 数据库 DB
    database: 6
    database: 9
    # [可选] 访问密码,若你的redis服务器没有设置密码,就不需要用密码去连接
    password:
    # [可选] 超时时间
@@ -21,12 +21,12 @@
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://106.225.193.35:3306/wvp?useUnicode=true&characterEncoding=UTF8&rewriteBatchedStatements=true&serverTimezone=PRC&useSSL=false&allowPublicKeyRetrieval=true
    url: jdbc:mysql://106.225.193.35:3306/videos_test?useUnicode=true&characterEncoding=UTF8&rewriteBatchedStatements=true&serverTimezone=PRC&useSSL=false&allowPublicKeyRetrieval=true
    username: root
    password: HCyj@2022
    druid:
      initialSize: 10                       # 连接池初始化连接数
      maxActive: 200                        # 连接池最大连接数
      maxActive: 500                        # 连接池最大连接数
      minIdle: 5                            # 连接池最小空闲连接数
      maxWait: 60000                        # 获取连接时最大等待时间,单位毫秒。配置了maxWait之后,缺省启用公平锁,并发效率会有所\下降,如果需要可以通过配置useUnfairLock属性为true使用非公平锁。
      keepAlive: true                       # 连接池中的minIdle数量以内的连接,空闲时间超过minEvictableIdleTimeMillis,则会执行keepAlive操作。
@@ -53,7 +53,7 @@
  # [必须修改] 本机的IP
  ip: 192.168.0.126
  # [可选] 28181服务监听的端口
  port: 5060
  port: 5070
  # 根据国标6.1.2中规定,domain宜采用ID统一编码的前十位编码。国标附录D中定义前8位为中心编码(由省级、市级、区级、基层编号组成,参照GB/T 2260-2007)
  # 后两位为行业编码,定义参照附录D.3
  # 3701020049标识山东济南历下区 信息行业接入
@@ -101,3 +101,7 @@
# 手台,执法记录仪udp接收端口
syscfg:
  udpReceivePort: 7687
#mybatis 配置
mybatis:
  mapper-locations: classpath:**/mapper/*Mapper.xml