Merge branch 'master' of http://8.140.179.55:20000/r/pipIrr-SV
 
	
	
	
	
	
	
	
	
	
	
	
	
	
 |  |  | 
 |  |  |  | 
 |  |  | import com.dy.common.mw.protocol4Mqtt.MqttPubMsg; | 
 |  |  | import lombok.Data; | 
 |  |  | import lombok.EqualsAndHashCode; | 
 |  |  |  | 
 |  |  | /** | 
 |  |  |  * @Author: liurunyu | 
 |  |  | 
 |  |  |  * @Description 下发的发布消息(即下行命令) | 
 |  |  |  */ | 
 |  |  | @Data | 
 |  |  | @EqualsAndHashCode(callSuper=false) | 
 |  |  | public class MqttPubMsgSdV1 extends MqttPubMsg { | 
 |  |  |  | 
 |  |  |     public Integer address ;//寄存器地址 | 
 
 |  |  | 
 |  |  | import com.dy.common.mw.protocol4Mqtt.MqttSubMsg; | 
 |  |  | import com.dy.common.util.Callback; | 
 |  |  | import lombok.Data; | 
 |  |  | import lombok.EqualsAndHashCode; | 
 |  |  |  | 
 |  |  | /** | 
 |  |  |  * @Author: liurunyu | 
 |  |  | 
 |  |  |  * @Description 收到的订阅消息 | 
 |  |  |  */ | 
 |  |  | @Data | 
 |  |  | @EqualsAndHashCode(callSuper=false) | 
 |  |  | public class MqttSubMsgSdV1 extends MqttSubMsg { | 
 |  |  |     public Integer address ;//寄存器地址 | 
 |  |  |     public String value ;//寄存器值 | 
 
 |  |  | 
 |  |  |             SchedulerTaskSupport.threadPoolPriority = threadPoolPriority; | 
 |  |  |         } | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 删除工作任务 | 
 |  |  |      * @param jobName | 
 |  |  |      * @param jobGroupName | 
 |  |  |      * @throws SchedulerException | 
 |  |  |      */ | 
 |  |  |     public static void deleteJob(String jobName, String jobGroupName) throws SchedulerException{ | 
 |  |  |         Scheduler sched = SchedulerTaskFactory.getSingleScheduler() ; | 
 |  |  |         sched.deleteJob(new JobKey(jobName, jobGroupName)); | 
 |  |  |     } | 
 |  |  |      | 
 |  |  |     /** | 
 |  |  |      * 添加每X秒钟重复工作一次的工作任务, | 
 |  |  | 
 |  |  |                     .withIntervalInSeconds(intervalInSeconds) | 
 |  |  |                     .withRepeatCount(repeatCount)) | 
 |  |  |             .build(); | 
 |  |  |          | 
 |  |  |         sched.scheduleJob(job, trigger); | 
 |  |  |         sched.start(); | 
 |  |  |  | 
 
 |  |  | 
 |  |  |     @JSONField(serialize = false) | 
 |  |  |     public Integer queryCount ; | 
 |  |  |  | 
 |  |  |     public void copyTo(QueryResultVo to){ | 
 |  |  |         to.pageSize = this.pageSize ; | 
 |  |  |         to.itemTotal = this.itemTotal  ; | 
 |  |  |         to.pageCurr = this.pageCurr  ; | 
 |  |  |         to.pageTotal = this.pageTotal  ; | 
 |  |  |         to.obj = this.obj ; | 
 |  |  |         to.queryStart = this.queryStart  ; | 
 |  |  |         to.queryCount = this.queryCount  ; | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |  | 
 |  |  |     public void calculateAndSet(Long itemTotal, Map<String, Object> params) { | 
 |  |  |         this.itemTotal = itemTotal ; | 
 
| New file | 
 |  |  | 
 |  |  | package com.dy.pipIrrGlobal.daoVi; | 
 |  |  |  | 
 |  |  | import com.baomidou.mybatisplus.core.mapper.BaseMapper; | 
 |  |  | import com.dy.pipIrrGlobal.pojoVi.ViCamera; | 
 |  |  | import com.dy.pipIrrGlobal.voVi.VoCamera; | 
 |  |  | import org.apache.ibatis.annotations.Mapper; | 
 |  |  |  | 
 |  |  | import java.util.List; | 
 |  |  | import java.util.Map; | 
 |  |  |  | 
 |  |  | /** | 
 |  |  |  * @Author: liurunyu | 
 |  |  |  * @Date: 2025/6/9 9:15 | 
 |  |  |  * @Description | 
 |  |  |  */ | 
 |  |  | @Mapper | 
 |  |  | public interface ViCameraMapper extends BaseMapper<ViCamera> { | 
 |  |  |     int deleteByPrimaryKey(Long id); | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 逻辑删除 | 
 |  |  |      * @param id primaryKey | 
 |  |  |      * @return update count | 
 |  |  |      */ | 
 |  |  |     int deleteLogicById(Long id); | 
 |  |  |  | 
 |  |  |  | 
 |  |  |     int insert(ViCamera record); | 
 |  |  |  | 
 |  |  |     int insertSelective(ViCamera record); | 
 |  |  |  | 
 |  |  |     ViCamera selectByPrimaryKey(Long id); | 
 |  |  |     /** | 
 |  |  |      * 查询总数 | 
 |  |  |      * @param params 查询条件 | 
 |  |  |      * @return 总数 | 
 |  |  |      */ | 
 |  |  |     Long selectTotal(Map<?, ?> params) ; | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 分页查询一些 | 
 |  |  |      * @param params 查询条件 | 
 |  |  |      * @return 实体集合 | 
 |  |  |      */ | 
 |  |  |     List<VoCamera> selectSome(Map<?, ?> params) ; | 
 |  |  |    /** | 
 |  |  |      * 查询总数 | 
 |  |  |      * @param params 查询条件 | 
 |  |  |      * @return 总数 | 
 |  |  |      */ | 
 |  |  |     Long selectTotal4Monitor(Map<?, ?> params) ; | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 分页查询一些 | 
 |  |  |      * @param params 查询条件 | 
 |  |  |      * @return 实体集合 | 
 |  |  |      */ | 
 |  |  |     List<VoCamera> selectSome4Monitor(Map<?, ?> params) ; | 
 |  |  |  | 
 |  |  | // Update the record in the ViCamera table based on the primary key, but only update the fields that are not null | 
 |  |  |     int updateByPrimaryKeySelective(ViCamera record); | 
 |  |  |  | 
 |  |  |     int updateByPrimaryKey(ViCamera record); | 
 |  |  | } | 
 
| New file | 
 |  |  | 
 |  |  | package com.dy.pipIrrGlobal.daoVi; | 
 |  |  |  | 
 |  |  | import com.baomidou.mybatisplus.core.mapper.BaseMapper; | 
 |  |  | import com.dy.pipIrrGlobal.pojoVi.ViYsApp; | 
 |  |  | import org.apache.ibatis.annotations.Mapper; | 
 |  |  |  | 
 |  |  | import java.util.List; | 
 |  |  |  | 
 |  |  | /** | 
 |  |  |  * @Author: liurunyu | 
 |  |  |  * @Date: 2025/6/7 10:44 | 
 |  |  |  * @Description | 
 |  |  |  */ | 
 |  |  | @Mapper | 
 |  |  | public interface ViYsAppMapper extends BaseMapper<ViYsApp> { | 
 |  |  |     int deleteByPrimaryKey(Long id); | 
 |  |  |  | 
 |  |  |     int deleteAll(); | 
 |  |  |  | 
 |  |  |     int insert(ViYsApp record); | 
 |  |  |  | 
 |  |  |     int insertSelective(ViYsApp record); | 
 |  |  |  | 
 |  |  |     ViYsApp selectByPrimaryKey(Long id); | 
 |  |  |  | 
 |  |  |     List<ViYsApp> selectAll(); | 
 |  |  |  | 
 |  |  |     int updateByPrimaryKeySelective(ViYsApp record); | 
 |  |  |  | 
 |  |  |     int updateByPrimaryKey(ViYsApp record); | 
 |  |  | } | 
 
| New file | 
 |  |  | 
 |  |  | package com.dy.pipIrrGlobal.pojoVi; | 
 |  |  |  | 
 |  |  | import com.alibaba.fastjson2.annotation.JSONField; | 
 |  |  | import com.alibaba.fastjson2.writer.ObjectWriterImplToString; | 
 |  |  | import com.baomidou.mybatisplus.annotation.IdType; | 
 |  |  | import com.baomidou.mybatisplus.annotation.TableId; | 
 |  |  | import com.baomidou.mybatisplus.annotation.TableName; | 
 |  |  | import com.dy.common.po.BaseEntity; | 
 |  |  | import io.swagger.v3.oas.annotations.media.Schema; | 
 |  |  | import lombok.*; | 
 |  |  |  | 
 |  |  | /** | 
 |  |  |  * @Author: liurunyu | 
 |  |  |  * @Date: 2025/6/9 9:15 | 
 |  |  |  * @Description | 
 |  |  |  */ | 
 |  |  |  | 
 |  |  | /** | 
 |  |  |  * 萤石摄像机(视频站) | 
 |  |  |  */ | 
 |  |  | @TableName(value="vi_camera", autoResultMap = true) | 
 |  |  | @Data | 
 |  |  | @Builder | 
 |  |  | @ToString | 
 |  |  | @NoArgsConstructor | 
 |  |  | @AllArgsConstructor | 
 |  |  | @Schema(name = "视频监控摄像机") | 
 |  |  | public class ViCamera implements BaseEntity { | 
 |  |  |  | 
 |  |  |     public static final long serialVersionUID = 202506071604001L; | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 主键 | 
 |  |  |      */ | 
 |  |  |     @Schema(description = "主键", requiredMode = Schema.RequiredMode.REQUIRED) | 
 |  |  |     @JSONField(serializeUsing= ObjectWriterImplToString.class) | 
 |  |  |     @TableId(type = IdType.INPUT) | 
 |  |  |     public Long id; | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 类型(1萤石) | 
 |  |  |      */ | 
 |  |  |     @Schema(description = "摄像机类型", requiredMode = Schema.RequiredMode.NOT_REQUIRED) | 
 |  |  |     public Byte type; | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 摄像机序列号 | 
 |  |  |      */ | 
 |  |  |     @Schema(description = "摄像机序列号", requiredMode = Schema.RequiredMode.NOT_REQUIRED) | 
 |  |  |     public String devNo; | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 视频站名称 | 
 |  |  |      */ | 
 |  |  |     @Schema(description = "视频站名称", requiredMode = Schema.RequiredMode.NOT_REQUIRED) | 
 |  |  |     public String name; | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 经度 | 
 |  |  |      */ | 
 |  |  |     @Schema(description = "视频站经度", requiredMode = Schema.RequiredMode.NOT_REQUIRED) | 
 |  |  |     public Double lng; | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 纬度 | 
 |  |  |      */ | 
 |  |  |     @Schema(description = "视频站纬度", requiredMode = Schema.RequiredMode.NOT_REQUIRED) | 
 |  |  |     public Double lat; | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 是否大屏展示(1是,0或null否) | 
 |  |  |      */ | 
 |  |  |     @Schema(description = "是否大展集中显示", requiredMode = Schema.RequiredMode.NOT_REQUIRED) | 
 |  |  |     public Byte onScreen; | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 大屏展示排序(大于等于1,数字越小排序越前) | 
 |  |  |      */ | 
 |  |  |     @Schema(description = "大屏展示排序", requiredMode = Schema.RequiredMode.NOT_REQUIRED) | 
 |  |  |     public Integer onSort; | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 备注 | 
 |  |  |      */ | 
 |  |  |     @Schema(description = "备注信息", requiredMode = Schema.RequiredMode.NOT_REQUIRED) | 
 |  |  |     public String remark; | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 是否删除(1是,0否) | 
 |  |  |      */ | 
 |  |  |     @Schema(description = "是否删除", requiredMode = Schema.RequiredMode.NOT_REQUIRED) | 
 |  |  |     public Byte deleted; | 
 |  |  |  | 
 |  |  | } | 
 
| New file | 
 |  |  | 
 |  |  | package com.dy.pipIrrGlobal.pojoVi; | 
 |  |  |  | 
 |  |  | import com.alibaba.fastjson2.annotation.JSONField; | 
 |  |  | import com.alibaba.fastjson2.writer.ObjectWriterImplToString; | 
 |  |  | import com.baomidou.mybatisplus.annotation.IdType; | 
 |  |  | import com.baomidou.mybatisplus.annotation.TableId; | 
 |  |  | import com.baomidou.mybatisplus.annotation.TableName; | 
 |  |  | import com.dy.common.po.BaseEntity; | 
 |  |  | import io.swagger.v3.oas.annotations.media.Schema; | 
 |  |  | import lombok.*; | 
 |  |  |  | 
 |  |  | import java.util.Date; | 
 |  |  |  | 
 |  |  | /** | 
 |  |  |  * @Author: liurunyu | 
 |  |  |  * @Date: 2025/6/7 10:44 | 
 |  |  |  * @Description | 
 |  |  |  */ | 
 |  |  |  | 
 |  |  | /** | 
 |  |  |  * 萤石云应用App相关 | 
 |  |  |  */ | 
 |  |  | @TableName(value="vi_ys_app", autoResultMap = true) | 
 |  |  | @Data | 
 |  |  | @Builder | 
 |  |  | @ToString | 
 |  |  | @NoArgsConstructor | 
 |  |  | @AllArgsConstructor | 
 |  |  | @Schema(name = "萤石云应用App") | 
 |  |  | public class ViYsApp implements BaseEntity { | 
 |  |  |  | 
 |  |  |     public static final long serialVersionUID = 202506071603001L; | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 主键 | 
 |  |  |      */ | 
 |  |  |     @Schema(description = "主键", requiredMode = Schema.RequiredMode.REQUIRED) | 
 |  |  |     @JSONField(serializeUsing= ObjectWriterImplToString.class) | 
 |  |  |     @TableId(type = IdType.INPUT) | 
 |  |  |     public Long id; | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 萤石云的AccessToken | 
 |  |  |      */ | 
 |  |  |     @Schema(description = "萤石云开放平台应用AccessToken", requiredMode = Schema.RequiredMode.NOT_REQUIRED) | 
 |  |  |     public String accessToken; | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * AccessToken过期时间 | 
 |  |  |      */ | 
 |  |  |     @Schema(description = "AccessToken过期时间(毫秒)", requiredMode = Schema.RequiredMode.NOT_REQUIRED) | 
 |  |  |     public Long expireTime; | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * AccessToken过期时间 | 
 |  |  |      */ | 
 |  |  |     @Schema(description = "AccessToken过期时间(年月日时分秒)", requiredMode = Schema.RequiredMode.NOT_REQUIRED) | 
 |  |  |     public Date expireDt; | 
 |  |  |  | 
 |  |  | } | 
 
| New file | 
 |  |  | 
 |  |  | package com.dy.pipIrrGlobal.util; | 
 |  |  |  | 
 |  |  | /** | 
 |  |  |  * @Author: liurunyu | 
 |  |  |  * @Date: 2025/6/9 11:31 | 
 |  |  |  * @Description | 
 |  |  |  */ | 
 |  |  | public enum CameraTypeEnum { | 
 |  |  |     YINGSHI((byte)1, "萤石"); | 
 |  |  |  | 
 |  |  |     private Byte type ; //1萤石 2海康 | 
 |  |  |     private String name ;//萤石 海康 | 
 |  |  |  | 
 |  |  |     CameraTypeEnum(Byte type, String name){ | 
 |  |  |         this.type = type ; | 
 |  |  |         this.name = name ; | 
 |  |  |     } | 
 |  |  |     public Byte getType() { | 
 |  |  |         return this.type ; | 
 |  |  |     } | 
 |  |  |     public String getName() { | 
 |  |  |         return this.name ; | 
 |  |  |     } | 
 |  |  | } | 
 
 |  |  | 
 |  |  | public abstract class OrgListenerSupport { | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 实始化 | 
 |  |  |      * 初始化 | 
 |  |  |      */ | 
 |  |  |     @SuppressWarnings("unused ") | 
 |  |  |     protected void init(ResourceLoader resourceLoader) { | 
 |  |  |         this.doInit(resourceLoader); | 
 |  |  |     } | 
 |  |  |     /** | 
 |  |  |      * 实始化 | 
 |  |  |      * 初始化 | 
 |  |  |      */ | 
 |  |  |     @SuppressWarnings("unused ") | 
 |  |  |     protected void doInit(ResourceLoader resourceLoader) { | 
 |  |  | 
 |  |  |     // 得到 | 
 |  |  |     //////////////////////////////// | 
 |  |  |     /** | 
 |  |  |      * 实始化 | 
 |  |  |      * 初始化 | 
 |  |  |      */ | 
 |  |  |     @SuppressWarnings("unused ") | 
 |  |  |     protected List<Org.OrgVo> get(ResourceLoader resourceLoader) { | 
 |  |  | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 实始化 | 
 |  |  |      * 初始化 | 
 |  |  |      */ | 
 |  |  |     @SuppressWarnings("unused ") | 
 |  |  |     protected List<Org.OrgVo> doGet(ResourceLoader resourceLoader) { | 
 
| New file | 
 |  |  | 
 |  |  | package com.dy.pipIrrGlobal.voVi; | 
 |  |  |  | 
 |  |  | import com.alibaba.fastjson2.annotation.JSONField; | 
 |  |  | import com.alibaba.fastjson2.writer.ObjectWriterImplToString; | 
 |  |  | import io.swagger.v3.oas.annotations.media.Schema; | 
 |  |  | import lombok.Data; | 
 |  |  |  | 
 |  |  | /** | 
 |  |  |  * @Author: liurunyu | 
 |  |  |  * @Date: 2025/6/9 9:12 | 
 |  |  |  * @Description | 
 |  |  |  */ | 
 |  |  | @Data | 
 |  |  | public class VoCamera { | 
 |  |  |     private static final long serialVersionUID = 202506090918001L; | 
 |  |  |     @JSONField(serializeUsing= ObjectWriterImplToString.class) | 
 |  |  |     public Long id; | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 类型(1萤石) | 
 |  |  |      */ | 
 |  |  |     public Byte type; | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 摄像机序列号 | 
 |  |  |      */ | 
 |  |  |     public String devNo; | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 视频站名称 | 
 |  |  |      */ | 
 |  |  |     public String name; | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 经度 | 
 |  |  |      */ | 
 |  |  |     public Double lng; | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 纬度 | 
 |  |  |      */ | 
 |  |  |     public Double lat; | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 是否大屏展示(1是,0或null否) | 
 |  |  |      */ | 
 |  |  |     public Byte onScreen; | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 大屏展示排序(大于等于1,数字越小排序越前) | 
 |  |  |      */ | 
 |  |  |     public Integer onSort; | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 备注 | 
 |  |  |      */ | 
 |  |  |     public String remark; | 
 |  |  |  | 
 |  |  | } | 
 
 |  |  | 
 |  |  |         at-all: true | 
 |  |  |         mobile: 18602657034 | 
 |  |  |  | 
 |  |  | #视频监控相关 | 
 |  |  | video: | 
 |  |  |     #萤石云开放平台 | 
 |  |  |     ys: | 
 |  |  |         accessTokenExpireDay: 7 #AccessToken过期时间,单位天 | 
 |  |  |         appKey: 93987fd687444c23b427181a108f5253 | 
 |  |  |         secret: d73a08e4fb3c3d9d0b696630eea8bd4e | 
 |  |  |         requestAccessTokenUrl: https://open.ys7.com/api/lapp/token/get | 
 |  |  |         requestVideoCommonUrl: https://open.ys7.com/console/jssdk/pc.html | 
 |  |  |         requestVideoCameraPreUrl: ezopen://open.ys7.com/ | 
 |  |  |         requestVideoCameraTailUrl: /1.live&themeId= | 
 |  |  |     types: | 
 |  |  |         - 1,萤石 #1:萤石 | 
 |  |  |         #- 2,海康 #2:海康 | 
 |  |  |         #- 3,大华 #3:大华 | 
 |  |  |         #- 4,天地伟业 #4:天地伟业 | 
 |  |  |     screen: | 
 |  |  |         count: 4 #默认显示4个视频 | 
 |  |  | #阀控器参数 | 
 |  |  | rtu: | 
 |  |  |     signalIntensity: | 
 
| New file | 
 |  |  | 
 |  |  | <?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.dy.pipIrrGlobal.daoVi.ViCameraMapper"> | 
 |  |  |   <resultMap id="BaseResultMap" type="com.dy.pipIrrGlobal.pojoVi.ViCamera"> | 
 |  |  |     <!--@mbg.generated--> | 
 |  |  |     <!--@Table vi_camera--> | 
 |  |  |     <id column="id" jdbcType="BIGINT" property="id" /> | 
 |  |  |     <result column="type" jdbcType="TINYINT" property="type" /> | 
 |  |  |     <result column="dev_no" jdbcType="VARCHAR" property="devNo" /> | 
 |  |  |     <result column="name" jdbcType="VARCHAR" property="name" /> | 
 |  |  |     <result column="lng" jdbcType="DOUBLE" property="lng" /> | 
 |  |  |     <result column="lat" jdbcType="DOUBLE" property="lat" /> | 
 |  |  |     <result column="on_screen" jdbcType="TINYINT" property="onScreen" /> | 
 |  |  |     <result column="on_sort" jdbcType="INTEGER" property="onSort" /> | 
 |  |  |     <result column="remark" jdbcType="VARCHAR" property="remark" /> | 
 |  |  |     <result column="deleted" jdbcType="TINYINT" property="deleted" /> | 
 |  |  |   </resultMap> | 
 |  |  |   <sql id="Base_Column_List"> | 
 |  |  |     <!--@mbg.generated--> | 
 |  |  |     id, `type`, dev_no, `name`, lng, lat, on_screen, on_sort, remark, deleted | 
 |  |  |   </sql> | 
 |  |  |   <sql id="part_Column_List"> | 
 |  |  |     <!--@mbg.generated--> | 
 |  |  |     id, `type`, dev_no, `name`, lng, lat, on_screen, on_sort, remark | 
 |  |  |   </sql> | 
 |  |  |   <select id="selectByPrimaryKey" parameterType="java.lang.Long" resultMap="BaseResultMap"> | 
 |  |  |     <!--@mbg.generated--> | 
 |  |  |     select  | 
 |  |  |     <include refid="Base_Column_List" /> | 
 |  |  |     from vi_camera | 
 |  |  |     where id = #{id,jdbcType=BIGINT} | 
 |  |  |   </select> | 
 |  |  |  | 
 |  |  |   <select id="selectTotal" parameterType="java.util.Map" resultType="java.lang.Long"> | 
 |  |  |     select | 
 |  |  |     count(*) | 
 |  |  |     from vi_camera tb | 
 |  |  |     where tb.deleted != 1 | 
 |  |  |     <trim prefix="and" suffixOverrides="and"> | 
 |  |  |       <if test="name != null and name != ''"> | 
 |  |  |         tb.`name` like concat('%', #{name}, '%') and | 
 |  |  |       </if> | 
 |  |  |     </trim> | 
 |  |  |   </select> | 
 |  |  |   <select id="selectSome" parameterType="java.util.Map" resultType="com.dy.pipIrrGlobal.voVi.VoCamera"> | 
 |  |  |     <!--@mbg.generated--> | 
 |  |  |     select | 
 |  |  |     <include refid="part_Column_List" > | 
 |  |  |       <property name="alias" value="tb"/> | 
 |  |  |     </include> | 
 |  |  |     from vi_camera tb | 
 |  |  |     where tb.deleted != 1 | 
 |  |  |     <trim prefix="and" suffixOverrides="and"> | 
 |  |  |       <if test="name != null"> | 
 |  |  |         tb.`name` like concat('%', #{name}, '%') and | 
 |  |  |       </if> | 
 |  |  |     </trim> | 
 |  |  |     order by tb.on_sort ASC, tb.id DESC | 
 |  |  |     <trim prefix="limit " > | 
 |  |  |       <if test="start != null and count != null"> | 
 |  |  |         #{start,javaType=Integer,jdbcType=INTEGER}, #{count,javaType=Integer,jdbcType=INTEGER} | 
 |  |  |       </if> | 
 |  |  |     </trim> | 
 |  |  |   </select> | 
 |  |  |  | 
 |  |  |   <select id="selectTotal4Monitor" parameterType="java.util.Map" resultType="java.lang.Long"> | 
 |  |  |     select | 
 |  |  |     count(*) | 
 |  |  |     from vi_camera tb | 
 |  |  |     where tb.deleted != 1 and tb.on_screen = 1 | 
 |  |  |     <trim prefix="and" suffixOverrides="and"> | 
 |  |  |       <if test="name != null and name != ''"> | 
 |  |  |         tb.`name` like concat('%', #{name}, '%') and | 
 |  |  |       </if> | 
 |  |  |     </trim> | 
 |  |  |   </select> | 
 |  |  |   <select id="selectSome4Monitor" parameterType="java.util.Map" resultType="com.dy.pipIrrGlobal.voVi.VoCamera"> | 
 |  |  |     <!--@mbg.generated--> | 
 |  |  |     select | 
 |  |  |     <include refid="part_Column_List" > | 
 |  |  |       <property name="alias" value="tb"/> | 
 |  |  |     </include> | 
 |  |  |     from vi_camera tb | 
 |  |  |     where tb.deleted != 1 and tb.on_screen = 1 | 
 |  |  |     <trim prefix="and" suffixOverrides="and"> | 
 |  |  |       <if test="name != null"> | 
 |  |  |         tb.`name` like concat('%', #{name}, '%') and | 
 |  |  |       </if> | 
 |  |  |     </trim> | 
 |  |  |     order by tb.on_sort ASC, tb.id DESC | 
 |  |  |     <trim prefix="limit " > | 
 |  |  |       <if test="start != null and count != null"> | 
 |  |  |         #{start,javaType=Integer,jdbcType=INTEGER}, #{count,javaType=Integer,jdbcType=INTEGER} | 
 |  |  |       </if> | 
 |  |  |     </trim> | 
 |  |  |   </select> | 
 |  |  |   <delete id="deleteByPrimaryKey" parameterType="java.lang.Long"> | 
 |  |  |     <!--@mbg.generated--> | 
 |  |  |     delete from vi_camera | 
 |  |  |     where id = #{id,jdbcType=BIGINT} | 
 |  |  |   </delete> | 
 |  |  |   <delete id="deleteLogicById" parameterType="java.lang.Long"> | 
 |  |  |     <!--@mbg.generated--> | 
 |  |  |     update vi_camera set deleted = 1 | 
 |  |  |     where id = #{id,jdbcType=BIGINT} | 
 |  |  |   </delete> | 
 |  |  |  | 
 |  |  |   <insert id="insert" parameterType="com.dy.pipIrrGlobal.pojoVi.ViCamera"> | 
 |  |  |     <!--@mbg.generated--> | 
 |  |  |     insert into vi_camera (id, `type`, dev_no,  | 
 |  |  |       `name`, lng, lat, on_screen,  | 
 |  |  |       on_sort, remark, deleted | 
 |  |  |       ) | 
 |  |  |     values (#{id,jdbcType=BIGINT}, #{type,jdbcType=TINYINT}, #{devNo,jdbcType=VARCHAR},  | 
 |  |  |       #{name,jdbcType=VARCHAR}, #{lng,jdbcType=DOUBLE}, #{lat,jdbcType=DOUBLE}, #{onScreen,jdbcType=TINYINT},  | 
 |  |  |       #{onSort,jdbcType=INTEGER}, #{remark,jdbcType=VARCHAR}, #{deleted,jdbcType=TINYINT} | 
 |  |  |       ) | 
 |  |  |   </insert> | 
 |  |  |   <insert id="insertSelective" parameterType="com.dy.pipIrrGlobal.pojoVi.ViCamera"> | 
 |  |  |     <!--@mbg.generated--> | 
 |  |  |     insert into vi_camera | 
 |  |  |     <trim prefix="(" suffix=")" suffixOverrides=","> | 
 |  |  |       <if test="id != null"> | 
 |  |  |         id, | 
 |  |  |       </if> | 
 |  |  |       <if test="type != null"> | 
 |  |  |         `type`, | 
 |  |  |       </if> | 
 |  |  |       <if test="devNo != null"> | 
 |  |  |         dev_no, | 
 |  |  |       </if> | 
 |  |  |       <if test="name != null"> | 
 |  |  |         `name`, | 
 |  |  |       </if> | 
 |  |  |       <if test="lng != null"> | 
 |  |  |         lng, | 
 |  |  |       </if> | 
 |  |  |       <if test="lat != null"> | 
 |  |  |         lat, | 
 |  |  |       </if> | 
 |  |  |       <if test="onScreen != null"> | 
 |  |  |         on_screen, | 
 |  |  |       </if> | 
 |  |  |       <if test="onSort != null"> | 
 |  |  |         on_sort, | 
 |  |  |       </if> | 
 |  |  |       <if test="remark != null"> | 
 |  |  |         remark, | 
 |  |  |       </if> | 
 |  |  |       <if test="deleted != null"> | 
 |  |  |         deleted, | 
 |  |  |       </if> | 
 |  |  |     </trim> | 
 |  |  |     <trim prefix="values (" suffix=")" suffixOverrides=","> | 
 |  |  |       <if test="id != null"> | 
 |  |  |         #{id,jdbcType=BIGINT}, | 
 |  |  |       </if> | 
 |  |  |       <if test="type != null"> | 
 |  |  |         #{type,jdbcType=TINYINT}, | 
 |  |  |       </if> | 
 |  |  |       <if test="devNo != null"> | 
 |  |  |         #{devNo,jdbcType=VARCHAR}, | 
 |  |  |       </if> | 
 |  |  |       <if test="name != null"> | 
 |  |  |         #{name,jdbcType=VARCHAR}, | 
 |  |  |       </if> | 
 |  |  |       <if test="lng != null"> | 
 |  |  |         #{lng,jdbcType=DOUBLE}, | 
 |  |  |       </if> | 
 |  |  |       <if test="lat != null"> | 
 |  |  |         #{lat,jdbcType=DOUBLE}, | 
 |  |  |       </if> | 
 |  |  |       <if test="onScreen != null"> | 
 |  |  |         #{onScreen,jdbcType=TINYINT}, | 
 |  |  |       </if> | 
 |  |  |       <if test="onSort != null"> | 
 |  |  |         #{onSort,jdbcType=INTEGER}, | 
 |  |  |       </if> | 
 |  |  |       <if test="remark != null"> | 
 |  |  |         #{remark,jdbcType=VARCHAR}, | 
 |  |  |       </if> | 
 |  |  |       <if test="deleted != null"> | 
 |  |  |         #{deleted,jdbcType=TINYINT}, | 
 |  |  |       </if> | 
 |  |  |     </trim> | 
 |  |  |   </insert> | 
 |  |  |   <update id="updateByPrimaryKeySelective" parameterType="com.dy.pipIrrGlobal.pojoVi.ViCamera"> | 
 |  |  |     <!--@mbg.generated--> | 
 |  |  |     update vi_camera | 
 |  |  |     <set> | 
 |  |  |       <if test="type != null"> | 
 |  |  |         `type` = #{type,jdbcType=TINYINT}, | 
 |  |  |       </if> | 
 |  |  |       <if test="devNo != null"> | 
 |  |  |         dev_no = #{devNo,jdbcType=VARCHAR}, | 
 |  |  |       </if> | 
 |  |  |       <if test="name != null"> | 
 |  |  |         `name` = #{name,jdbcType=VARCHAR}, | 
 |  |  |       </if> | 
 |  |  |       <if test="lng != null"> | 
 |  |  |         lng = #{lng,jdbcType=DOUBLE}, | 
 |  |  |       </if> | 
 |  |  |       <if test="lat != null"> | 
 |  |  |         lat = #{lat,jdbcType=DOUBLE}, | 
 |  |  |       </if> | 
 |  |  |       <if test="onScreen != null"> | 
 |  |  |         on_screen = #{onScreen,jdbcType=TINYINT}, | 
 |  |  |       </if> | 
 |  |  |       <if test="onSort != null"> | 
 |  |  |         on_sort = #{onSort,jdbcType=INTEGER}, | 
 |  |  |       </if> | 
 |  |  |       <if test="remark != null"> | 
 |  |  |         remark = #{remark,jdbcType=VARCHAR}, | 
 |  |  |       </if> | 
 |  |  |       <if test="deleted != null"> | 
 |  |  |         deleted = #{deleted,jdbcType=TINYINT}, | 
 |  |  |       </if> | 
 |  |  |     </set> | 
 |  |  |     where id = #{id,jdbcType=BIGINT} | 
 |  |  |   </update> | 
 |  |  |   <update id="updateByPrimaryKey" parameterType="com.dy.pipIrrGlobal.pojoVi.ViCamera"> | 
 |  |  |     <!--@mbg.generated--> | 
 |  |  |     update vi_camera | 
 |  |  |     set `type` = #{type,jdbcType=TINYINT}, | 
 |  |  |       dev_no = #{devNo,jdbcType=VARCHAR}, | 
 |  |  |       `name` = #{name,jdbcType=VARCHAR}, | 
 |  |  |       lng = #{lng,jdbcType=DOUBLE}, | 
 |  |  |       lat = #{lat,jdbcType=DOUBLE}, | 
 |  |  |       on_screen = #{onScreen,jdbcType=TINYINT}, | 
 |  |  |       on_sort = #{onSort,jdbcType=INTEGER}, | 
 |  |  |       remark = #{remark,jdbcType=VARCHAR}, | 
 |  |  |       deleted = #{deleted,jdbcType=TINYINT} | 
 |  |  |     where id = #{id,jdbcType=BIGINT} | 
 |  |  |   </update> | 
 |  |  | </mapper> | 
 
| New file | 
 |  |  | 
 |  |  | <?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.dy.pipIrrGlobal.daoVi.ViYsAppMapper"> | 
 |  |  |   <resultMap id="BaseResultMap" type="com.dy.pipIrrGlobal.pojoVi.ViYsApp"> | 
 |  |  |     <!--@mbg.generated--> | 
 |  |  |     <!--@Table vi_ys_app--> | 
 |  |  |     <id column="id" jdbcType="BIGINT" property="id" /> | 
 |  |  |     <result column="access_token" jdbcType="VARCHAR" property="accessToken" /> | 
 |  |  |     <result column="expire_time" jdbcType="BIGINT" property="expireTime" /> | 
 |  |  |     <result column="expire_dt" jdbcType="TIMESTAMP" property="expireDt" /> | 
 |  |  |   </resultMap> | 
 |  |  |   <sql id="Base_Column_List"> | 
 |  |  |     <!--@mbg.generated--> | 
 |  |  |     id, access_token, expire_time, expire_dt | 
 |  |  |   </sql> | 
 |  |  |   <select id="selectByPrimaryKey" parameterType="java.lang.Long" resultMap="BaseResultMap"> | 
 |  |  |     <!--@mbg.generated--> | 
 |  |  |     select  | 
 |  |  |     <include refid="Base_Column_List" /> | 
 |  |  |     from vi_ys_app | 
 |  |  |     where id = #{id,jdbcType=BIGINT} | 
 |  |  |   </select> | 
 |  |  |   <select id="selectAll" resultMap="BaseResultMap"> | 
 |  |  |     <!--@mbg.generated--> | 
 |  |  |     select | 
 |  |  |     <include refid="Base_Column_List" /> | 
 |  |  |     from vi_ys_app | 
 |  |  |   </select> | 
 |  |  |   <delete id="deleteByPrimaryKey" parameterType="java.lang.Long"> | 
 |  |  |     <!--@mbg.generated--> | 
 |  |  |     delete from vi_ys_app | 
 |  |  |     where id = #{id,jdbcType=BIGINT} | 
 |  |  |   </delete> | 
 |  |  |   <delete id="deleteAll" > | 
 |  |  |     <!--@mbg.generated--> | 
 |  |  |     delete from vi_ys_app | 
 |  |  |   </delete> | 
 |  |  |   <insert id="insert" parameterType="com.dy.pipIrrGlobal.pojoVi.ViYsApp"> | 
 |  |  |     <!--@mbg.generated--> | 
 |  |  |     insert into vi_ys_app (id, access_token, expire_time,  | 
 |  |  |       expire_dt) | 
 |  |  |     values (#{id,jdbcType=BIGINT}, #{accessToken,jdbcType=VARCHAR}, #{expireTime,jdbcType=BIGINT},  | 
 |  |  |       #{expireDt,jdbcType=TIMESTAMP}) | 
 |  |  |   </insert> | 
 |  |  |   <insert id="insertSelective" parameterType="com.dy.pipIrrGlobal.pojoVi.ViYsApp"> | 
 |  |  |     <!--@mbg.generated--> | 
 |  |  |     insert into vi_ys_app | 
 |  |  |     <trim prefix="(" suffix=")" suffixOverrides=","> | 
 |  |  |       <if test="id != null"> | 
 |  |  |         id, | 
 |  |  |       </if> | 
 |  |  |       <if test="accessToken != null"> | 
 |  |  |         access_token, | 
 |  |  |       </if> | 
 |  |  |       <if test="expireTime != null"> | 
 |  |  |         expire_time, | 
 |  |  |       </if> | 
 |  |  |       <if test="expireDt != null"> | 
 |  |  |         expire_dt, | 
 |  |  |       </if> | 
 |  |  |     </trim> | 
 |  |  |     <trim prefix="values (" suffix=")" suffixOverrides=","> | 
 |  |  |       <if test="id != null"> | 
 |  |  |         #{id,jdbcType=BIGINT}, | 
 |  |  |       </if> | 
 |  |  |       <if test="accessToken != null"> | 
 |  |  |         #{accessToken,jdbcType=VARCHAR}, | 
 |  |  |       </if> | 
 |  |  |       <if test="expireTime != null"> | 
 |  |  |         #{expireTime,jdbcType=BIGINT}, | 
 |  |  |       </if> | 
 |  |  |       <if test="expireDt != null"> | 
 |  |  |         #{expireDt,jdbcType=TIMESTAMP}, | 
 |  |  |       </if> | 
 |  |  |     </trim> | 
 |  |  |   </insert> | 
 |  |  |   <update id="updateByPrimaryKeySelective" parameterType="com.dy.pipIrrGlobal.pojoVi.ViYsApp"> | 
 |  |  |     <!--@mbg.generated--> | 
 |  |  |     update vi_ys_app | 
 |  |  |     <set> | 
 |  |  |       <if test="accessToken != null"> | 
 |  |  |         access_token = #{accessToken,jdbcType=VARCHAR}, | 
 |  |  |       </if> | 
 |  |  |       <if test="expireTime != null"> | 
 |  |  |         expire_time = #{expireTime,jdbcType=BIGINT}, | 
 |  |  |       </if> | 
 |  |  |       <if test="expireDt != null"> | 
 |  |  |         expire_dt = #{expireDt,jdbcType=TIMESTAMP}, | 
 |  |  |       </if> | 
 |  |  |     </set> | 
 |  |  |     where id = #{id,jdbcType=BIGINT} | 
 |  |  |   </update> | 
 |  |  |   <update id="updateByPrimaryKey" parameterType="com.dy.pipIrrGlobal.pojoVi.ViYsApp"> | 
 |  |  |     <!--@mbg.generated--> | 
 |  |  |     update vi_ys_app | 
 |  |  |     set access_token = #{accessToken,jdbcType=VARCHAR}, | 
 |  |  |       expire_time = #{expireTime,jdbcType=BIGINT}, | 
 |  |  |       expire_dt = #{expireDt,jdbcType=TIMESTAMP} | 
 |  |  |     where id = #{id,jdbcType=BIGINT} | 
 |  |  |   </update> | 
 |  |  | </mapper> | 
 
 |  |  | 
 |  |  |         </task> | 
 |  |  |         <!-- Mqtt消息中间件订阅的消息 --> | 
 |  |  |         <task id="TkMqttData" name="接收Mqtt消息" enable="true" class="com.dy.rtuMw.server.rtuData.TkMqttData"> | 
 |  |  |             <task id="TkFindPSdV1" name="识别山东V1数据" enable="true" class="com.dy.rtuMw.server.rtuData.pSdV1.TkFindPSdV1"> | 
 |  |  |             <task id="TkFindPSdV1" name="识别山东V1数据" enable="true" class="com.dy.rtuMw.server.rtuData.pSdV1.TkFindPSdV1"></task> | 
 |  |  |         </task> | 
 |  |  |     </task> | 
 |  |  | </project> | 
 
 |  |  | 
 |  |  | #   甘州: mqtt.enable=false | 
 |  |  | #   凉州: mqtt.enable=false | 
 |  |  | #   金川: mqtt.enable=true | 
 |  |  | # mq/sd1/338220031439/weather | 
 |  |  | mqtt.enable=true | 
 |  |  | mqtt.topicAndQos=ym/sd1/10000/control/m1,1;ym/sd1/10000/control/m2,1;ym/sd1/control/m4,1;ym/sd1/10000/control/m80,1 | 
 |  |  |  | 
 
 |  |  | 
 |  |  |     @Override | 
 |  |  |     public void onApplicationEvent(@NonNull ApplicationReadyEvent event) { | 
 |  |  |         try { | 
 |  |  |             //等1秒,等待com.alibaba.druid.pool.DruidDataSource实始化完成 | 
 |  |  |             //等1秒,等待com.alibaba.druid.pool.DruidDataSource初始化完成 | 
 |  |  |             Thread.sleep(1000L); | 
 |  |  |         } catch (InterruptedException e) { | 
 |  |  |             e.printStackTrace(); | 
 |  |  | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 实始化 | 
 |  |  |      * 初始化 | 
 |  |  |      */ | 
 |  |  |     @SuppressWarnings("unused ") | 
 |  |  |     private void init(ApplicationReadyEvent event){ | 
 
 |  |  | 
 |  |  |     @Override | 
 |  |  |     public void onApplicationEvent(@NonNull ApplicationReadyEvent event) { | 
 |  |  |         try { | 
 |  |  |             //等1秒,等待com.alibaba.druid.pool.DruidDataSource实始化完成 | 
 |  |  |             //等1秒,等待com.alibaba.druid.pool.DruidDataSource初始化完成 | 
 |  |  |             Thread.sleep(1000L); | 
 |  |  |         } catch (InterruptedException e) { | 
 |  |  |             e.printStackTrace(); | 
 
 |  |  | 
 |  |  |                 }) | 
 |  |  |         } | 
 |  |  | ) | 
 |  |  | @MapperScan({"com.dy.pipIrrGlobal.daoPr", "com.dy.pipIrrGlobal.daoBa","com.dy.pipIrrGlobal.daoFi"}) | 
 |  |  | @MapperScan({"com.dy.pipIrrGlobal.daoPr", "com.dy.pipIrrGlobal.daoBa","com.dy.pipIrrGlobal.daoFi","com.dy.pipIrrGlobal.daoVi"}) | 
 |  |  | public class PipIrrProjectApplication { | 
 |  |  |  | 
 |  |  |     public static void main(String[] args) { | 
 
| New file | 
 |  |  | 
 |  |  | package com.dy.pipIrrProject.video; | 
 |  |  |  | 
 |  |  | import com.dy.common.aop.SsoAop; | 
 |  |  | import com.dy.common.webUtil.BaseResponse; | 
 |  |  | import com.dy.common.webUtil.BaseResponseUtils; | 
 |  |  | import com.dy.common.webUtil.QueryResultVo; | 
 |  |  | import com.dy.common.webUtil.ResultCodeMsg; | 
 |  |  | import com.dy.pipIrrGlobal.pojoVi.ViCamera; | 
 |  |  | import com.dy.pipIrrGlobal.voVi.VoCamera; | 
 |  |  | import io.swagger.v3.oas.annotations.Operation; | 
 |  |  | import io.swagger.v3.oas.annotations.media.Content; | 
 |  |  | import io.swagger.v3.oas.annotations.media.Schema; | 
 |  |  | import io.swagger.v3.oas.annotations.responses.ApiResponse; | 
 |  |  | import io.swagger.v3.oas.annotations.responses.ApiResponses; | 
 |  |  | import io.swagger.v3.oas.annotations.tags.Tag; | 
 |  |  | import jakarta.validation.Valid; | 
 |  |  | import lombok.RequiredArgsConstructor; | 
 |  |  | import lombok.extern.slf4j.Slf4j; | 
 |  |  | import org.springframework.beans.factory.annotation.Autowired; | 
 |  |  | import org.springframework.http.MediaType; | 
 |  |  | import org.springframework.validation.BindingResult; | 
 |  |  | import org.springframework.web.bind.annotation.*; | 
 |  |  |  | 
 |  |  | import java.util.ArrayList; | 
 |  |  | import java.util.List; | 
 |  |  | import java.util.Objects; | 
 |  |  |  | 
 |  |  | /** | 
 |  |  |  * @Author: liurunyu | 
 |  |  |  * @Date: 2025/6/9 9:01 | 
 |  |  |  * @Description | 
 |  |  |  */ | 
 |  |  | @Slf4j | 
 |  |  | @Tag(name = "视频站管理", description = "视频站管理") | 
 |  |  | @RestController | 
 |  |  | @RequestMapping(path = "camera") | 
 |  |  | @RequiredArgsConstructor | 
 |  |  | public class CameraCtrl { | 
 |  |  |     private CameraSv sv; | 
 |  |  |  | 
 |  |  |     @Autowired | 
 |  |  |     private void setSv(CameraSv sv){ | 
 |  |  |         this.sv = sv ; | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 客户端请求得到所有摄像机类型 | 
 |  |  |      * @return 所有摄像机类型 | 
 |  |  |      */ | 
 |  |  |     @Operation(summary = "获得全部摄像机类型", description = "返回全部摄像机类型") | 
 |  |  |     @ApiResponses(value = { | 
 |  |  |             @ApiResponse( | 
 |  |  |                     responseCode = ResultCodeMsg.RsCode.SUCCESS_CODE, | 
 |  |  |                     description = "返回全部摄像机类型数据(BaseResponse.content:TypesVo[{}])", | 
 |  |  |                     content = {@Content(mediaType = MediaType.APPLICATION_JSON_VALUE, | 
 |  |  |                             schema = @Schema(implementation = TypesVo.class))} | 
 |  |  |             ) | 
 |  |  |     }) | 
 |  |  |     @GetMapping(path = "types") | 
 |  |  |     @SsoAop() | 
 |  |  |     public BaseResponse<QueryResultVo<List<TypesVo>>> types() { | 
 |  |  |         try { | 
 |  |  |             List<TypesVo> list = new ArrayList<>() ; | 
 |  |  |             if(CameraTypesConfig.types != null && CameraTypesConfig.types.size() > 0){ | 
 |  |  |                 for (String type : CameraTypesConfig.types) { | 
 |  |  |                     String[] typeGrp = type.split(","); | 
 |  |  |                     if(typeGrp.length == 2){ | 
 |  |  |                         TypesVo vo = new TypesVo() ; | 
 |  |  |                         vo.type = Integer.parseInt(typeGrp[0].trim()) ; | 
 |  |  |                         vo.name = typeGrp[1].trim() ; | 
 |  |  |                         list.add(vo) ; | 
 |  |  |                     } | 
 |  |  |                 } | 
 |  |  |             } | 
 |  |  |             QueryResultVo<List<TypesVo>> res = new QueryResultVo() ; | 
 |  |  |             res.obj = list ; | 
 |  |  |             return BaseResponseUtils.buildSuccess(res); | 
 |  |  |         } catch (Exception e) { | 
 |  |  |             log.error("查询取水口异常", e); | 
 |  |  |             return BaseResponseUtils.buildException(e.getMessage()); | 
 |  |  |         } | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 客户端请求得到一些摄像机数据 | 
 |  |  |      * @return 所有摄像机数据 | 
 |  |  |      */ | 
 |  |  |     @Operation(summary = "获得一页摄像机数据", description = "返回一页摄像机数据数据") | 
 |  |  |     @ApiResponses(value = { | 
 |  |  |             @ApiResponse( | 
 |  |  |                     responseCode = ResultCodeMsg.RsCode.SUCCESS_CODE, | 
 |  |  |                     description = "返回一页摄像机数据(BaseResponse.content:QueryResultVo[{}])", | 
 |  |  |                     content = {@Content(mediaType = MediaType.APPLICATION_JSON_VALUE, | 
 |  |  |                             schema = @Schema(implementation = VoCamera.class))} | 
 |  |  |             ) | 
 |  |  |     }) | 
 |  |  |     @GetMapping(path = "some") | 
 |  |  |     @SsoAop() | 
 |  |  |     public BaseResponse<QueryResultVo<List<VoCamera>>> some(CameraQo vo){ | 
 |  |  |         try { | 
 |  |  |             QueryResultVo<List<VoCamera>> res = this.sv.some(vo) ; | 
 |  |  |             return BaseResponseUtils.buildSuccess(res); | 
 |  |  |         } catch (Exception e) { | 
 |  |  |             log.error("查询摄像机异常", e); | 
 |  |  |             return BaseResponseUtils.buildException(e.getMessage()) ; | 
 |  |  |         } | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 得到一个摄像机数据 | 
 |  |  |      * @return 一个摄像机数据 | 
 |  |  |      */ | 
 |  |  |     @Operation(summary = "一个摄像机", description = "得到一个摄像机数据") | 
 |  |  |     @ApiResponses(value = { | 
 |  |  |             @ApiResponse( | 
 |  |  |                     responseCode = ResultCodeMsg.RsCode.SUCCESS_CODE, | 
 |  |  |                     description = "返回一个摄像机数据(BaseResponse.content:{})", | 
 |  |  |                     content = {@Content(mediaType = MediaType.APPLICATION_JSON_VALUE, | 
 |  |  |                             schema = @Schema(implementation = ViCamera.class))} | 
 |  |  |             ) | 
 |  |  |     }) | 
 |  |  |     @GetMapping(path = "one") | 
 |  |  |     @SsoAop() | 
 |  |  |     public BaseResponse<ViCamera> one(Long id){ | 
 |  |  |         return BaseResponseUtils.buildSuccess(this.sv.selectById(id)); | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 保存摄像机 | 
 |  |  |      * @param dto 保存摄像机form表单对象 | 
 |  |  |      * @return 是否成功 | 
 |  |  |      */ | 
 |  |  |     @Operation(summary = "保存摄像机", description = "提交摄像机数据(form表单),进行保存") | 
 |  |  |     @ApiResponses(value = { | 
 |  |  |             @ApiResponse( | 
 |  |  |                     responseCode = ResultCodeMsg.RsCode.SUCCESS_CODE, | 
 |  |  |                     description = "操作结果:true:成功,false:失败(BaseResponse.content)", | 
 |  |  |                     content = {@Content(mediaType = MediaType.APPLICATION_JSON_VALUE, | 
 |  |  |                             schema = @Schema(implementation = Boolean.class))} | 
 |  |  |             ) | 
 |  |  |     }) | 
 |  |  |     @PostMapping(path = "save", consumes = MediaType.APPLICATION_JSON_VALUE) | 
 |  |  |     @SsoAop() | 
 |  |  |     public BaseResponse<Boolean> save(@RequestBody @Valid CameraDto dto, BindingResult bindingResult){ | 
 |  |  |         if(bindingResult != null && bindingResult.hasErrors()){ | 
 |  |  |             return BaseResponseUtils.buildFail(Objects.requireNonNull(bindingResult.getFieldError()).getDefaultMessage()); | 
 |  |  |         } | 
 |  |  |         ViCamera po = dto.toNewPo() ; | 
 |  |  |         po.deleted = 0 ; | 
 |  |  |         int count; | 
 |  |  |         try { | 
 |  |  |             count = this.sv.save(po); | 
 |  |  |         } catch (Exception e) { | 
 |  |  |             log.error("保存摄像机异常", e); | 
 |  |  |             return BaseResponseUtils.buildException(e.getMessage()) ; | 
 |  |  |         } | 
 |  |  |         if(count <= 0){ | 
 |  |  |             return BaseResponseUtils.buildFail("数据库存储失败") ; | 
 |  |  |         }else{ | 
 |  |  |             return BaseResponseUtils.buildSuccess(true) ; | 
 |  |  |         } | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 编辑修改摄像机 | 
 |  |  |      * @param dto 保存摄像机form表单对象 | 
 |  |  |      * @return 是否成功 | 
 |  |  |      */ | 
 |  |  |     @Operation(summary = "编辑修改摄像机", description = "提交摄像机数据(form表单),进行修改") | 
 |  |  |     @ApiResponses(value = { | 
 |  |  |             @ApiResponse( | 
 |  |  |                     responseCode = ResultCodeMsg.RsCode.SUCCESS_CODE, | 
 |  |  |                     description = "操作结果:true:成功,false:失败(BaseResponse.content)", | 
 |  |  |                     content = {@Content(mediaType = MediaType.APPLICATION_JSON_VALUE, | 
 |  |  |                             schema = @Schema(implementation = Boolean.class))} | 
 |  |  |             ) | 
 |  |  |     }) | 
 |  |  |     @PostMapping(path = "update", consumes = MediaType.APPLICATION_JSON_VALUE) | 
 |  |  |     @SsoAop() | 
 |  |  |     public BaseResponse<Boolean> update(@RequestBody @Valid CameraDto dto, BindingResult bindingResult){ | 
 |  |  |         if(bindingResult != null && bindingResult.hasErrors()){ | 
 |  |  |             return BaseResponseUtils.buildFail(Objects.requireNonNull(bindingResult.getFieldError()).getDefaultMessage()); | 
 |  |  |         } | 
 |  |  |         ViCamera po = dto.toPo() ; | 
 |  |  |         if(po.id == null){ | 
 |  |  |             return BaseResponseUtils.buildFail("无数据实体ID") ; | 
 |  |  |         } | 
 |  |  |         int count; | 
 |  |  |         try { | 
 |  |  |             count = this.sv.update(po); | 
 |  |  |         } catch (Exception e) { | 
 |  |  |             log.error("保存摄像机异常", e); | 
 |  |  |             return BaseResponseUtils.buildException(e.getMessage()) ; | 
 |  |  |         } | 
 |  |  |         if(count <= 0){ | 
 |  |  |             return BaseResponseUtils.buildFail("数据库存储失败") ; | 
 |  |  |         }else{ | 
 |  |  |             return BaseResponseUtils.buildSuccess(true) ; | 
 |  |  |         } | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 删除摄像机 | 
 |  |  |      * @param id 摄像机ID | 
 |  |  |      * @return 是否成功 | 
 |  |  |      */ | 
 |  |  |     @Operation(summary = "删除摄像机", description = "提交摄像机ID,进行逻辑删除") | 
 |  |  |     @ApiResponses(value = { | 
 |  |  |             @ApiResponse( | 
 |  |  |                     responseCode = ResultCodeMsg.RsCode.SUCCESS_CODE, | 
 |  |  |                     description = "操作结果:true:成功,false:失败(BaseResponse.content)", | 
 |  |  |                     content = {@Content(mediaType = MediaType.APPLICATION_JSON_VALUE, | 
 |  |  |                             schema = @Schema(implementation = Boolean.class))} | 
 |  |  |             ) | 
 |  |  |     }) | 
 |  |  |     @GetMapping(path = "delete") | 
 |  |  |     @SsoAop() | 
 |  |  |     public BaseResponse<Boolean> delete(Long id){ | 
 |  |  |         if(id == null){ | 
 |  |  |             return BaseResponseUtils.buildFail("id不能为空") ; | 
 |  |  |         } | 
 |  |  |         int count; | 
 |  |  |         try { | 
 |  |  |             count = this.sv.delete(id); | 
 |  |  |         } catch (Exception e) { | 
 |  |  |             log.error("保存摄像机异常", e); | 
 |  |  |             return BaseResponseUtils.buildException(e.getMessage()) ; | 
 |  |  |         } | 
 |  |  |         if(count <= 0){ | 
 |  |  |             return BaseResponseUtils.buildFail("数据库存储失败") ; | 
 |  |  |         }else{ | 
 |  |  |             return BaseResponseUtils.buildSuccess(true) ; | 
 |  |  |         } | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |  | 
 |  |  | } | 
 
| New file | 
 |  |  | 
 |  |  | package com.dy.pipIrrProject.video; | 
 |  |  |  | 
 |  |  | import com.dy.pipIrrGlobal.pojoVi.ViCamera; | 
 |  |  | import io.swagger.v3.oas.annotations.media.Schema; | 
 |  |  | import jakarta.validation.constraints.NotEmpty; | 
 |  |  | import jakarta.validation.constraints.NotNull; | 
 |  |  | import lombok.Data; | 
 |  |  |  | 
 |  |  | /** | 
 |  |  |  * @Author: liurunyu | 
 |  |  |  * @Date: 2025/6/9 10:18 | 
 |  |  |  * @Description | 
 |  |  |  */ | 
 |  |  | @Data | 
 |  |  | @Schema(name = "摄像机(视频站)") | 
 |  |  | public class CameraDto { | 
 |  |  |     public static final long serialVersionUID = 202506091020001L; | 
 |  |  |     /** | 
 |  |  |      * 主键 | 
 |  |  |      */ | 
 |  |  |     public String id; | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 类型(1萤石) | 
 |  |  |      */ | 
 |  |  |     @NotNull(message = "摄像机类型不能为空") //不能为空也不能为null | 
 |  |  |     public Byte type; | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 摄像机序列号 | 
 |  |  |      */ | 
 |  |  |     @NotEmpty(message = "摄像机类型不能为空") //不能为空也不能为null | 
 |  |  |     public String devNo; | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 视频站名称 | 
 |  |  |      */ | 
 |  |  |     @NotEmpty(message = "视频站名称不能为空") //不能为空也不能为null | 
 |  |  |     public String name; | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 经度 | 
 |  |  |      */ | 
 |  |  |     public Double lng; | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 纬度 | 
 |  |  |      */ | 
 |  |  |     public Double lat; | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 是否大屏展示(1是,0或null否) | 
 |  |  |      */ | 
 |  |  |     public Byte onScreen; | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 大屏展示排序(大于等于1,数字越小排序越前) | 
 |  |  |      */ | 
 |  |  |     public Integer onSort; | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 备注 | 
 |  |  |      */ | 
 |  |  |     public String remark; | 
 |  |  |  | 
 |  |  |     public ViCamera toNewPo(){ | 
 |  |  |         ViCamera po = new ViCamera(); | 
 |  |  |         po.type = this.type; | 
 |  |  |         po.devNo = this.devNo; | 
 |  |  |         po.name = this.name; | 
 |  |  |         po.lng = this.lng; | 
 |  |  |         po.lat = this.lat; | 
 |  |  |         po.onScreen = this.onScreen; | 
 |  |  |         po.onSort = this.onSort; | 
 |  |  |         po.remark = this.remark; | 
 |  |  |         return po; | 
 |  |  |     } | 
 |  |  |     public ViCamera toPo(){ | 
 |  |  |         ViCamera po = this.toNewPo(); | 
 |  |  |         po.id = Long.parseLong(this.id) ; | 
 |  |  |         return po; | 
 |  |  |     } | 
 |  |  | } | 
 
| New file | 
 |  |  | 
 |  |  | package com.dy.pipIrrProject.video; | 
 |  |  |  | 
 |  |  | import com.dy.common.webUtil.QueryConditionVo; | 
 |  |  | import io.swagger.v3.oas.annotations.media.Schema; | 
 |  |  | import lombok.*; | 
 |  |  |  | 
 |  |  | /** | 
 |  |  |  * @Author: liurunyu | 
 |  |  |  * @Date: 2025/6/9 9:03 | 
 |  |  |  * @Description | 
 |  |  |  */ | 
 |  |  | @Data | 
 |  |  | @EqualsAndHashCode(callSuper = false) | 
 |  |  | @ToString(callSuper = true) | 
 |  |  | @NoArgsConstructor | 
 |  |  | @AllArgsConstructor | 
 |  |  | @Builder | 
 |  |  | @Schema(name = "视频监控查询条件") | 
 |  |  | public class CameraQo extends QueryConditionVo { | 
 |  |  |     @Schema(description = "名称(地址)") | 
 |  |  |     public String name; | 
 |  |  | } | 
 
| New file | 
 |  |  | 
 |  |  | package com.dy.pipIrrProject.video; | 
 |  |  |  | 
 |  |  | import com.dy.common.webUtil.QueryResultVo; | 
 |  |  | import com.dy.pipIrrGlobal.daoVi.ViCameraMapper; | 
 |  |  | import com.dy.pipIrrGlobal.pojoVi.ViCamera; | 
 |  |  | import com.dy.pipIrrGlobal.voVi.VoCamera; | 
 |  |  | import lombok.extern.slf4j.Slf4j; | 
 |  |  | import org.apache.dubbo.common.utils.PojoUtils; | 
 |  |  | import org.springframework.beans.factory.annotation.Autowired; | 
 |  |  | import org.springframework.stereotype.Service; | 
 |  |  | import org.springframework.transaction.annotation.Transactional; | 
 |  |  |  | 
 |  |  | import java.util.List; | 
 |  |  | import java.util.Map; | 
 |  |  |  | 
 |  |  | /** | 
 |  |  |  * @Author: liurunyu | 
 |  |  |  * @Date: 2025/6/9 9:01 | 
 |  |  |  * @Description | 
 |  |  |  */ | 
 |  |  | @Slf4j | 
 |  |  | @Service | 
 |  |  | public class CameraSv { | 
 |  |  |  | 
 |  |  |     @Autowired | 
 |  |  |     private ViCameraMapper dao; | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 根据指定条件获取实体记录 | 
 |  |  |      * @param queryQo 查询条件值对象 | 
 |  |  |      * @return 实体记录列表 | 
 |  |  |      */ | 
 |  |  |     public QueryResultVo<List<VoCamera>> some(CameraQo queryQo) { | 
 |  |  |         Map<String, Object> params = (Map<String, Object>) PojoUtils.generalize(queryQo); | 
 |  |  |         Long itemTotal = dao.selectTotal(params); | 
 |  |  |  | 
 |  |  |         QueryResultVo<List<VoCamera>> rsVo = new QueryResultVo<>(); | 
 |  |  |         rsVo.pageSize = queryQo.pageSize; | 
 |  |  |         rsVo.pageCurr = queryQo.pageCurr; | 
 |  |  |         rsVo.calculateAndSet(itemTotal, params); | 
 |  |  |         rsVo.obj = dao.selectSome(params); | 
 |  |  |         return rsVo; | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 得到一个实体 | 
 |  |  |      * @param id 实体ID | 
 |  |  |      * @return 实体 | 
 |  |  |      */ | 
 |  |  |     public ViCamera selectById(Long id){ | 
 |  |  |         return this.dao.selectById(id) ; | 
 |  |  |     } | 
 |  |  |     /** | 
 |  |  |      * 保存(添加)视频监控点 | 
 |  |  |      * @param po | 
 |  |  |      * @return | 
 |  |  |      */ | 
 |  |  |     @Transactional | 
 |  |  |     Integer save(ViCamera po) { | 
 |  |  |         return dao.insert(po); | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 修改实体 | 
 |  |  |      * @param po 实体 | 
 |  |  |      * @return 数量 | 
 |  |  |      */ | 
 |  |  |     @Transactional | 
 |  |  |     public int update(ViCamera po) { | 
 |  |  |         return this.dao.updateByPrimaryKeySelective(po); | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 保存修改实体 | 
 |  |  |      * @param id 实体ID | 
 |  |  |      * @return 影响记录数量 | 
 |  |  |      */ | 
 |  |  |     @Transactional | 
 |  |  |     public int delete(Long id){ | 
 |  |  |         return this.dao.deleteLogicById(id) ; | 
 |  |  |     } | 
 |  |  |  | 
 |  |  | } | 
 
| New file | 
 |  |  | 
 |  |  | package com.dy.pipIrrProject.video; | 
 |  |  |  | 
 |  |  | import org.springframework.boot.context.properties.ConfigurationProperties; | 
 |  |  | import org.springframework.context.annotation.Configuration; | 
 |  |  |  | 
 |  |  | import java.util.List; | 
 |  |  |  | 
 |  |  | /** | 
 |  |  |  * @Author: liurunyu | 
 |  |  |  * @Date: 2025/6/9 14:21 | 
 |  |  |  * @Description | 
 |  |  |  */ | 
 |  |  | @Configuration | 
 |  |  | @ConfigurationProperties(prefix = "video") | 
 |  |  | public class CameraTypesConfig { | 
 |  |  |  | 
 |  |  |     public static List<String> types; | 
 |  |  |  | 
 |  |  |     public List<String> getTypes(){ | 
 |  |  |         return types; | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     public void setTypes(List<String> types){ | 
 |  |  |         CameraTypesConfig.types = types ; | 
 |  |  |     } | 
 |  |  |  | 
 |  |  | } | 
 
| New file | 
 |  |  | 
 |  |  | package com.dy.pipIrrProject.video; | 
 |  |  |  | 
 |  |  | import lombok.Data; | 
 |  |  |  | 
 |  |  | /** | 
 |  |  |  * @Author: liurunyu | 
 |  |  |  * @Date: 2025/6/9 9:37 | 
 |  |  |  * @Description | 
 |  |  |  */ | 
 |  |  | @Data | 
 |  |  | public class TypesVo { | 
 |  |  |     public Integer type ; | 
 |  |  |     public String name ; | 
 |  |  | } | 
 
 |  |  | 
 |  |  |         "com.dy.pipIrrGlobal.daoFi", | 
 |  |  |         "com.dy.pipIrrGlobal.daoAllRound", | 
 |  |  |         "com.dy.pipIrrGlobal.daoLargeScreen", | 
 |  |  |         "com.dy.pipIrrGlobal.daoIr" | 
 |  |  |         "com.dy.pipIrrGlobal.daoIr", | 
 |  |  |         "com.dy.pipIrrGlobal.daoVi" | 
 |  |  | }) | 
 |  |  | public class PipIrrRemoteApplication { | 
 |  |  |  | 
 
 |  |  | 
 |  |  | import com.dy.common.util.NumUtil; | 
 |  |  | import com.dy.common.webUtil.BaseResponse; | 
 |  |  | import com.dy.common.webUtil.BaseResponseUtils; | 
 |  |  | import com.dy.pipIrrGlobal.pojoSe.SeClientCard; | 
 |  |  | import com.dy.pipIrrRemote.common.dto.DtoBase; | 
 |  |  | import com.dy.pipIrrRemote.monitor.common.ComCtrl; | 
 |  |  | import io.swagger.v3.oas.annotations.tags.Tag; | 
 
 |  |  | 
 |  |  |     @Override | 
 |  |  |     public void onApplicationEvent(@NonNull ApplicationReadyEvent event) { | 
 |  |  |         try { | 
 |  |  |             //等1秒,等待com.alibaba.druid.pool.DruidDataSource实始化完成 | 
 |  |  |             //等1秒,等待com.alibaba.druid.pool.DruidDataSource初始化完成 | 
 |  |  |             Thread.sleep(1000L); | 
 |  |  |         } catch (InterruptedException e) { | 
 |  |  |             e.printStackTrace(); | 
 
 |  |  | 
 |  |  | import com.dy.pipIrrGlobal.command.ComSupport; | 
 |  |  | import com.dy.pipIrrGlobal.command.dto.Param; | 
 |  |  | import com.dy.pipIrrGlobal.daoSe.SeVirtualCardMapper; | 
 |  |  | import com.dy.pipIrrGlobal.pojoSe.SeClientCard; | 
 |  |  | import com.dy.pipIrrGlobal.voRm.VoUnclosedParam; | 
 |  |  | import com.dy.pipIrrGlobal.voRm.VoUnclosedValve; | 
 |  |  | import com.dy.pipIrrGlobal.voSe.VoVirtualCard; | 
 
| New file | 
 |  |  | 
 |  |  | package com.dy.pipIrrRemote.video; | 
 |  |  |  | 
 |  |  | import com.dy.common.aop.SsoAop; | 
 |  |  | import com.dy.common.webUtil.BaseResponse; | 
 |  |  | import com.dy.common.webUtil.BaseResponseUtils; | 
 |  |  | import com.dy.common.webUtil.QueryResultVo; | 
 |  |  | import com.dy.common.webUtil.ResultCodeMsg; | 
 |  |  | import com.dy.pipIrrGlobal.pojoVi.ViYsApp; | 
 |  |  | import com.dy.pipIrrGlobal.util.CameraTypeEnum; | 
 |  |  | import com.dy.pipIrrGlobal.voVi.VoCamera; | 
 |  |  | import io.swagger.v3.oas.annotations.Operation; | 
 |  |  | import io.swagger.v3.oas.annotations.media.Content; | 
 |  |  | import io.swagger.v3.oas.annotations.media.Schema; | 
 |  |  | import io.swagger.v3.oas.annotations.responses.ApiResponse; | 
 |  |  | import io.swagger.v3.oas.annotations.responses.ApiResponses; | 
 |  |  | import io.swagger.v3.oas.annotations.tags.Tag; | 
 |  |  | import lombok.RequiredArgsConstructor; | 
 |  |  | import lombok.extern.slf4j.Slf4j; | 
 |  |  | import org.springframework.beans.factory.annotation.Autowired; | 
 |  |  | import org.springframework.beans.factory.annotation.Value; | 
 |  |  | import org.springframework.http.MediaType; | 
 |  |  | import org.springframework.web.bind.annotation.GetMapping; | 
 |  |  | import org.springframework.web.bind.annotation.PostMapping; | 
 |  |  | import org.springframework.web.bind.annotation.RequestMapping; | 
 |  |  | import org.springframework.web.bind.annotation.RestController; | 
 |  |  |  | 
 |  |  | import java.util.ArrayList; | 
 |  |  | import java.util.List; | 
 |  |  |  | 
 |  |  | /** | 
 |  |  |  * @Author: liurunyu | 
 |  |  |  * @Date: 2025/6/9 10:34 | 
 |  |  |  * @Description | 
 |  |  |  */ | 
 |  |  | @Slf4j | 
 |  |  | @Tag(name = "视频监控", description = "视频监控") | 
 |  |  | @RestController | 
 |  |  | @RequestMapping(path = "video") | 
 |  |  | @RequiredArgsConstructor | 
 |  |  | public class VideoCtrl { | 
 |  |  |     private VideoSv sv; | 
 |  |  |     private YsAppSv ysSv; | 
 |  |  |  | 
 |  |  |     @Value("${video.screen.count: 4}") | 
 |  |  |     private Integer pageSize;//每页显示条数 | 
 |  |  |  | 
 |  |  |     @Value("${video.ys.requestVideoCommonUrl: https://open.ys7.com/console/jssdk/pc.html}") | 
 |  |  |     private String requestVideoCommonUrl;// | 
 |  |  |     @Value("${video.ys.requestVideoCameraPreUrl: ezopen://open.ys7.com/}") | 
 |  |  |     private String requestVideoCameraPreUrl;// | 
 |  |  |     @Value("${video.ys.requestVideoCameraTailUrl: /1.live&themeId=}") | 
 |  |  |     private String requestVideoCameraTailUrl;// | 
 |  |  |  | 
 |  |  |     @Autowired | 
 |  |  |     private void setSv(VideoSv sv, YsAppSv ysSv){ | 
 |  |  |         this.sv = sv ; | 
 |  |  |         this.ysSv = ysSv ; | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 客户端请求得到一些摄像机数据 | 
 |  |  |      * @return 所有摄像机数据 | 
 |  |  |      */ | 
 |  |  |     @Operation(summary = "获得一页摄像机数据", description = "返回一页摄像机数据数据") | 
 |  |  |     @ApiResponses(value = { | 
 |  |  |             @ApiResponse( | 
 |  |  |                     responseCode = ResultCodeMsg.RsCode.SUCCESS_CODE, | 
 |  |  |                     description = "返回一页摄像机数据(BaseResponse.content:QueryResultVo[{}])", | 
 |  |  |                     content = {@Content(mediaType = MediaType.APPLICATION_JSON_VALUE, | 
 |  |  |                             schema = @Schema(implementation = VoCamera.class))} | 
 |  |  |             ) | 
 |  |  |     }) | 
 |  |  |     @GetMapping(path = "some") | 
 |  |  |     @SsoAop() | 
 |  |  |     public BaseResponse<QueryResultVo<List<VoVideo>>> some(VideoQo queryQo){ | 
 |  |  |         try { | 
 |  |  |             ViYsApp ysApp = this.ysSv.selectSingleton() ; | 
 |  |  |             if(ysApp == null){ | 
 |  |  |                 //remote模块的自动任务可能清空了,所以再查询一次 | 
 |  |  |                 ysApp = this.ysSv.selectSingleton() ; | 
 |  |  |             } | 
 |  |  |             List<VoVideo> list = new ArrayList<>() ; | 
 |  |  |             QueryResultVo<List<VoCamera>> resTmp = this.sv.some(queryQo, pageSize) ; | 
 |  |  |             if(resTmp != null && resTmp.obj != null){ | 
 |  |  |                 for(VoCamera vo : resTmp.obj){ | 
 |  |  |                     VoVideo vvo = new VoVideo() ; | 
 |  |  |                     vvo.id = vo.id ; | 
 |  |  |                     vvo.name = vo.name ; | 
 |  |  |                     if(ysApp != null && vo.type != null && vo.type.byteValue() == CameraTypeEnum.YINGSHI.getType().byteValue()){ | 
 |  |  |                         //萤石 | 
 |  |  |                         StringBuilder sb = new StringBuilder(); | 
 |  |  |                         sb.append(requestVideoCommonUrl); | 
 |  |  |                         sb.append("?accessToken="); | 
 |  |  |                         sb.append(ysApp.accessToken); | 
 |  |  |                         sb.append("&url="); | 
 |  |  |                         sb.append(requestVideoCameraPreUrl); | 
 |  |  |                         sb.append(vo.devNo); | 
 |  |  |                         sb.append(requestVideoCameraTailUrl); | 
 |  |  |                         vvo.videoUrl4Simple = sb.toString() + "simple"; | 
 |  |  |                         vvo.videoUrl4Standard = sb.toString() + "standard" ; | 
 |  |  |                         vvo.videoUrl4Security = sb.toString() + "security" ; | 
 |  |  |                     }else{ | 
 |  |  |                         vvo.videoUrl4Simple = "" ; | 
 |  |  |                         vvo.videoUrl4Standard = "" ; | 
 |  |  |                         vvo.videoUrl4Security = "" ; | 
 |  |  |                     } | 
 |  |  |                     list.add(vvo) ; | 
 |  |  |                 } | 
 |  |  |             } | 
 |  |  |             QueryResultVo<List<VoVideo>> res = new QueryResultVo<>() ; | 
 |  |  |             resTmp.copyTo(res); | 
 |  |  |             res.obj = list ; | 
 |  |  |             return BaseResponseUtils.buildSuccess(res); | 
 |  |  |         } catch (Exception e) { | 
 |  |  |             log.error("查询摄像机异常", e); | 
 |  |  |             return BaseResponseUtils.buildException(e.getMessage()) ; | 
 |  |  |         } | 
 |  |  |     } | 
 |  |  | } | 
 
| New file | 
 |  |  | 
 |  |  | package com.dy.pipIrrRemote.video; | 
 |  |  |  | 
 |  |  | import com.dy.common.webUtil.QueryConditionVo; | 
 |  |  | import io.swagger.v3.oas.annotations.media.Schema; | 
 |  |  | import lombok.*; | 
 |  |  |  | 
 |  |  | /** | 
 |  |  |  * @Author: liurunyu | 
 |  |  |  * @Date: 2025/6/9 9:03 | 
 |  |  |  * @Description | 
 |  |  |  */ | 
 |  |  | @Data | 
 |  |  | @EqualsAndHashCode(callSuper = false) | 
 |  |  | @ToString(callSuper = true) | 
 |  |  | @Builder | 
 |  |  | @Schema(name = "视频监控查询条件") | 
 |  |  | public class VideoQo extends QueryConditionVo { | 
 |  |  | } | 
 
| New file | 
 |  |  | 
 |  |  | package com.dy.pipIrrRemote.video; | 
 |  |  |  | 
 |  |  | import com.dy.common.webUtil.QueryResultVo; | 
 |  |  | import com.dy.pipIrrGlobal.daoVi.ViCameraMapper; | 
 |  |  | import com.dy.pipIrrGlobal.voVi.VoCamera; | 
 |  |  | import lombok.extern.slf4j.Slf4j; | 
 |  |  | import org.apache.dubbo.common.utils.PojoUtils; | 
 |  |  | import org.springframework.beans.factory.annotation.Autowired; | 
 |  |  | import org.springframework.stereotype.Service; | 
 |  |  |  | 
 |  |  | import java.util.List; | 
 |  |  | import java.util.Map; | 
 |  |  |  | 
 |  |  | /** | 
 |  |  |  * @Author: liurunyu | 
 |  |  |  * @Date: 2025/6/9 10:42 | 
 |  |  |  * @Description | 
 |  |  |  */ | 
 |  |  | @Slf4j | 
 |  |  | @Service | 
 |  |  | public class VideoSv { | 
 |  |  |  | 
 |  |  |     @Autowired | 
 |  |  |     private ViCameraMapper dao; | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 根据指定条件获取实体记录 | 
 |  |  |      * @param queryQo 查询条件值对象 | 
 |  |  |      * @return 实体记录列表 | 
 |  |  |      */ | 
 |  |  |     public QueryResultVo<List<VoCamera>> some(VideoQo queryQo, int pageSize) { | 
 |  |  |         Map<String, Object> params = (Map<String, Object>) PojoUtils.generalize(queryQo); | 
 |  |  |         Long itemTotal = dao.selectTotal4Monitor(params); | 
 |  |  |  | 
 |  |  |         QueryResultVo<List<VoCamera>> rsVo = new QueryResultVo<>(); | 
 |  |  |         rsVo.pageSize = pageSize; | 
 |  |  |         rsVo.pageCurr = queryQo.pageCurr; | 
 |  |  |         rsVo.calculateAndSet(itemTotal, params); | 
 |  |  |         rsVo.obj = dao.selectSome4Monitor((params)) ; | 
 |  |  |         return rsVo; | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |  | 
 |  |  | } | 
 
| New file | 
 |  |  | 
 |  |  | package com.dy.pipIrrRemote.video; | 
 |  |  |  | 
 |  |  | import com.alibaba.fastjson2.annotation.JSONField; | 
 |  |  | import com.alibaba.fastjson2.writer.ObjectWriterImplToString; | 
 |  |  | import lombok.Data; | 
 |  |  |  | 
 |  |  | /** | 
 |  |  |  * @Author: liurunyu | 
 |  |  |  * @Date: 2025/6/9 10:57 | 
 |  |  |  * @Description | 
 |  |  |  */ | 
 |  |  | @Data | 
 |  |  | public class VoVideo { | 
 |  |  |     @JSONField(serializeUsing= ObjectWriterImplToString.class) | 
 |  |  |     public Long id ; | 
 |  |  |     public String name ; | 
 |  |  |     public String videoUrl4Simple ; | 
 |  |  |     public String videoUrl4Standard ; | 
 |  |  |     public String videoUrl4Security ; | 
 |  |  | } | 
 
| New file | 
 |  |  | 
 |  |  | package com.dy.pipIrrRemote.video; | 
 |  |  |  | 
 |  |  | import com.dy.common.multiDataSource.DataSourceContext; | 
 |  |  | import com.dy.pipIrrGlobal.pojoVi.ViYsApp; | 
 |  |  | import com.dy.pipIrrGlobal.util.Org; | 
 |  |  | import com.dy.pipIrrGlobal.util.OrgListenerSupport; | 
 |  |  | import lombok.extern.slf4j.Slf4j; | 
 |  |  | import org.springframework.beans.factory.annotation.Autowired; | 
 |  |  | import org.springframework.core.io.ResourceLoader; | 
 |  |  | import org.springframework.web.bind.annotation.RestController; | 
 |  |  |  | 
 |  |  | import java.util.List; | 
 |  |  |  | 
 |  |  | /** | 
 |  |  |  * @Author: liurunyu | 
 |  |  |  * @Date: 2025/6/7 12:45 | 
 |  |  |  * @Description 类名中包含Inner,表示内部应用的Controller | 
 |  |  |  */ | 
 |  |  | @Slf4j | 
 |  |  | @RestController | 
 |  |  | public class YsAppCtrl extends OrgListenerSupport { | 
 |  |  |  | 
 |  |  |     @Autowired | 
 |  |  |     protected ResourceLoader resourceLoader ; | 
 |  |  |  | 
 |  |  |     @Autowired | 
 |  |  |     protected YsAppSv ysAppSv; | 
 |  |  |  | 
 |  |  |     public ViYsApp selectSingletonYsApp(){ | 
 |  |  |         return ysAppSv.selectSingleton() ; | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     public Long saveAccessTokenOfYs(String accessToken, Long expireTime){ | 
 |  |  |         if(Org.OrgList == null || Org.OrgList.size() == 0){ | 
 |  |  |             super.init(resourceLoader); | 
 |  |  |         } | 
 |  |  |         List<Org.OrgVo> orgList = Org.OrgList ; | 
 |  |  |         if(orgList != null || orgList.size() > 0){ | 
 |  |  |             for(Org.OrgVo vo : orgList){ | 
 |  |  |                 //遍历所有org,得到各自的萤石应用AccessToken | 
 |  |  |                 DataSourceContext.set(vo.tag);//设置数据源 | 
 |  |  |                 ysAppSv.deleteAll(); | 
 |  |  |                 ysAppSv.save(accessToken, expireTime) ; | 
 |  |  |             } | 
 |  |  |         } | 
 |  |  |         return null ; | 
 |  |  |     } | 
 |  |  | } | 
 
| New file | 
 |  |  | 
 |  |  | package com.dy.pipIrrRemote.video; | 
 |  |  |  | 
 |  |  |  | 
 |  |  | import com.dy.common.multiDataSource.DataSourceContext; | 
 |  |  | import com.dy.pipIrrGlobal.pojoVi.ViYsApp; | 
 |  |  | import com.dy.pipIrrGlobal.util.Org; | 
 |  |  | import com.dy.pipIrrGlobal.util.OrgListenerSupport; | 
 |  |  | import com.dy.pipIrrRemote.video.ys.YsAppClient; | 
 |  |  | import lombok.extern.slf4j.Slf4j; | 
 |  |  | import org.springframework.beans.factory.annotation.Autowired; | 
 |  |  | import org.springframework.boot.context.event.ApplicationReadyEvent; | 
 |  |  | import org.springframework.context.ApplicationListener; | 
 |  |  | import org.springframework.core.io.ResourceLoader; | 
 |  |  | import org.springframework.lang.NonNull; | 
 |  |  | import org.springframework.stereotype.Component; | 
 |  |  |  | 
 |  |  | import java.util.*; | 
 |  |  |  | 
 |  |  | /** | 
 |  |  |  * @Author: liurunyu | 
 |  |  |  * @Date: 2025/6/6 17:19 | 
 |  |  |  * @Description 视频监控 | 
 |  |  |  * 监听器,实现功能:启动日统计定时任务 | 
 |  |  |  * 本监听器不能采用ServletContextListener方式,因为Servlet上下文Context创建后 | 
 |  |  |  * Spring容器并没有创建完,而本类中用了Spring容器中的Bean,即*Dao 。 | 
 |  |  |  * 所以采用了Spring事件监听器来实现 | 
 |  |  |  */ | 
 |  |  | @Slf4j | 
 |  |  | @Component | 
 |  |  | public class YsAppListener extends OrgListenerSupport implements ApplicationListener<ApplicationReadyEvent> { | 
 |  |  |  | 
 |  |  |     @Autowired | 
 |  |  |     protected ResourceLoader resourceLoader ; | 
 |  |  |  | 
 |  |  |     @Autowired | 
 |  |  |     protected YsAppCtrl ysAppCtrl; | 
 |  |  |  | 
 |  |  |     @Autowired | 
 |  |  |     protected YsAppClient ysAppClient; | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * SpringBoot容器已经准备好了,执行下面方法 | 
 |  |  |      * @param event 事件 | 
 |  |  |      */ | 
 |  |  |     @Override | 
 |  |  |     public void onApplicationEvent(@NonNull ApplicationReadyEvent event) { | 
 |  |  |         try { | 
 |  |  |             //等1秒,等待com.alibaba.druid.pool.DruidDataSource初始化完成 | 
 |  |  |             Thread.sleep(1000L); | 
 |  |  |         } catch (InterruptedException e) { | 
 |  |  |             e.printStackTrace(); | 
 |  |  |         }finally { | 
 |  |  |             try{ | 
 |  |  |                 super.init(resourceLoader); | 
 |  |  |                 this.atSysStart(event); | 
 |  |  |             }catch (Exception e){ | 
 |  |  |                 log.error("注册萤石云定时任务出错", e); | 
 |  |  |             } | 
 |  |  |         } | 
 |  |  |     } | 
 |  |  |     /** | 
 |  |  |      * 初始化 | 
 |  |  |      */ | 
 |  |  |     private void atSysStart(ApplicationReadyEvent event) throws Exception{ | 
 |  |  |         //所有Org,共用一个萤石应用的AccessToken | 
 |  |  |         boolean isNowGetNewAccessToken = false ;//当下是否获得AccessToken | 
 |  |  |         List<Org.OrgVo> orgList = Org.OrgList ; | 
 |  |  |         Map<String, ViYsApp> viYsAppMap = new HashMap<>() ; | 
 |  |  |         if(orgList != null && orgList.size() >0){ | 
 |  |  |             for(Org.OrgVo vo : orgList){ | 
 |  |  |                 //遍历所有org,得到各自的萤石应用AccessToken | 
 |  |  |                 DataSourceContext.set(vo.tag);//设置数据源 | 
 |  |  |                 ViYsApp po = ysAppCtrl.selectSingletonYsApp() ; | 
 |  |  |                 if(po == null){ | 
 |  |  |                     isNowGetNewAccessToken = true ; | 
 |  |  |                 }else{ | 
 |  |  |                     viYsAppMap.put(vo.tag, po) ; | 
 |  |  |                 } | 
 |  |  |             } | 
 |  |  |             this.dealAtSysStart(viYsAppMap, isNowGetNewAccessToken); | 
 |  |  |         } | 
 |  |  |     } | 
 |  |  |     private void dealAtSysStart(Map<String, ViYsApp> viYsAppMap, boolean isNowGetNewAccessToken){ | 
 |  |  |         if(!isNowGetNewAccessToken){ | 
 |  |  |             if(viYsAppMap != null && viYsAppMap.size() >0){ | 
 |  |  |                 long nowMustAtMillis = System.currentTimeMillis()  ; | 
 |  |  |                 Collection<ViYsApp> col = viYsAppMap.values() ; | 
 |  |  |                 Iterator<ViYsApp> it = col.iterator() ; | 
 |  |  |                 ViYsApp po ; | 
 |  |  |                 while (it.hasNext()){ | 
 |  |  |                     po = it.next() ; | 
 |  |  |                     if(po.expireTime != null && nowMustAtMillis > po.expireTime){ | 
 |  |  |                         isNowGetNewAccessToken = true ; | 
 |  |  |                     } | 
 |  |  |                 } | 
 |  |  |             }else{ | 
 |  |  |                 isNowGetNewAccessToken = true ; | 
 |  |  |             } | 
 |  |  |         } | 
 |  |  |         if(isNowGetNewAccessToken){ | 
 |  |  |             this.ysAppClient.getAccessToken(); | 
 |  |  |             this.ysAppClient.reSetNextGetAccessToken(null) ; | 
 |  |  |         }else{ | 
 |  |  |             long nextGetTokenAtMillis = 0L ; | 
 |  |  |             Collection<ViYsApp> col = viYsAppMap.values() ; | 
 |  |  |             Iterator<ViYsApp> it = col.iterator() ; | 
 |  |  |             ViYsApp po ; | 
 |  |  |             while (it.hasNext()){ | 
 |  |  |                 po = it.next() ; | 
 |  |  |                 if(nextGetTokenAtMillis == 0 || nextGetTokenAtMillis > po.expireTime){ | 
 |  |  |                     nextGetTokenAtMillis = po.expireTime ; | 
 |  |  |                 } | 
 |  |  |             } | 
 |  |  |             if(nextGetTokenAtMillis > 0L){ | 
 |  |  |                 this.ysAppClient.reSetNextGetAccessToken(nextGetTokenAtMillis); | 
 |  |  |             } | 
 |  |  |         } | 
 |  |  |     } | 
 |  |  |  | 
 |  |  | } | 
 
| New file | 
 |  |  | 
 |  |  | package com.dy.pipIrrRemote.video; | 
 |  |  |  | 
 |  |  | import com.dy.common.util.DateTime; | 
 |  |  | import com.dy.pipIrrGlobal.daoVi.ViYsAppMapper; | 
 |  |  | import com.dy.pipIrrGlobal.pojoVi.ViYsApp; | 
 |  |  | import org.springframework.beans.factory.annotation.Autowired; | 
 |  |  | import org.springframework.stereotype.Component; | 
 |  |  | import org.springframework.transaction.annotation.Transactional; | 
 |  |  |  | 
 |  |  | import java.util.List; | 
 |  |  |  | 
 |  |  | /** | 
 |  |  |  * @Author: liurunyu | 
 |  |  |  * @Date: 2025/6/7 9:14 | 
 |  |  |  * @Description | 
 |  |  |  */ | 
 |  |  | @Component | 
 |  |  | public class YsAppSv { | 
 |  |  |  | 
 |  |  |     @Autowired | 
 |  |  |     protected ViYsAppMapper viYsAppDao ; | 
 |  |  |  | 
 |  |  |  | 
 |  |  |     public ViYsApp selectSingleton(){ | 
 |  |  |         List<ViYsApp> all = this.viYsAppDao.selectAll() ; | 
 |  |  |         if(all == null || all.size() == 0){ | 
 |  |  |             return null ; | 
 |  |  |         }else{ | 
 |  |  |             return all.get(0) ; | 
 |  |  |         } | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     @Transactional(rollbackFor = Exception.class) | 
 |  |  |     public Long save(String accessToken, Long expireTime){ | 
 |  |  |         ViYsApp po = new ViYsApp() ; | 
 |  |  |         po.accessToken = accessToken ; | 
 |  |  |         po.expireTime = expireTime ; | 
 |  |  |         po.expireDt = DateTime.getDate(expireTime) ; | 
 |  |  |         this.viYsAppDao.insert(po) ; | 
 |  |  |         return po.id ; | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     @Transactional(rollbackFor = Exception.class) | 
 |  |  |     public void deleteAll(){ | 
 |  |  |         viYsAppDao.deleteAll() ; | 
 |  |  |     } | 
 |  |  | } | 
 
| New file | 
 |  |  | 
 |  |  | package com.dy.pipIrrRemote.video.ys; | 
 |  |  |  | 
 |  |  | import lombok.AllArgsConstructor; | 
 |  |  | import lombok.Data; | 
 |  |  | import lombok.NoArgsConstructor; | 
 |  |  |  | 
 |  |  | /** | 
 |  |  |  * @Author: liurunyu | 
 |  |  |  * @Date: 2025/6/7 14:00 | 
 |  |  |  * @Description | 
 |  |  |  */ | 
 |  |  | @Data | 
 |  |  | @NoArgsConstructor | 
 |  |  | @AllArgsConstructor | 
 |  |  | public class YsAccessTokenData { | 
 |  |  |     public String accessToken ; | 
 |  |  |     public Long expireTime ; | 
 |  |  | } | 
 
| New file | 
 |  |  | 
 |  |  | package com.dy.pipIrrRemote.video.ys; | 
 |  |  |  | 
 |  |  | import com.dy.common.schedulerTask.TaskJob; | 
 |  |  | import com.dy.common.springUtil.SpringContextUtil; | 
 |  |  | import org.quartz.JobExecutionContext; | 
 |  |  | import org.quartz.JobExecutionException; | 
 |  |  |  | 
 |  |  | /** | 
 |  |  |  * @Author: liurunyu | 
 |  |  |  * @Date: 2025/6/7 15:39 | 
 |  |  |  * @Description | 
 |  |  |  */ | 
 |  |  | public class YsAccessTokenQuartzJob extends TaskJob { | 
 |  |  |     /** | 
 |  |  |      * Quartz定时任务,其不在Spring容器中 | 
 |  |  |      * @param ctx | 
 |  |  |      * @throws JobExecutionException | 
 |  |  |      */ | 
 |  |  |     @Override | 
 |  |  |     public void execute(JobExecutionContext ctx) throws JobExecutionException { | 
 |  |  |         YsAppClient ysCli = SpringContextUtil.getBean(YsAppClient.class); | 
 |  |  |         ysCli.getAccessToken(); | 
 |  |  |         ysCli.reSetNextGetAccessToken(null); | 
 |  |  |     } | 
 |  |  | } | 
 
| New file | 
 |  |  | 
 |  |  | package com.dy.pipIrrRemote.video.ys; | 
 |  |  |  | 
 |  |  | import lombok.AllArgsConstructor; | 
 |  |  | import lombok.Data; | 
 |  |  | import lombok.NoArgsConstructor; | 
 |  |  |  | 
 |  |  | /** | 
 |  |  |  * @Author: liurunyu | 
 |  |  |  * @Date: 2025/6/7 14:00 | 
 |  |  |  * @Description | 
 |  |  |  */ | 
 |  |  | @Data | 
 |  |  | @NoArgsConstructor | 
 |  |  | @AllArgsConstructor | 
 |  |  | public class YsAccessTokenResponse { | 
 |  |  |     public YsAccessTokenData data ; | 
 |  |  |     public String code ; | 
 |  |  |     public String msg ; | 
 |  |  | } | 
 
| New file | 
 |  |  | 
 |  |  | package com.dy.pipIrrRemote.video.ys; | 
 |  |  |  | 
 |  |  | import com.dy.common.schedulerTask.SchedulerTaskSupport; | 
 |  |  | import com.dy.pipIrrRemote.video.YsAppCtrl; | 
 |  |  | import lombok.extern.slf4j.Slf4j; | 
 |  |  | import org.springframework.beans.factory.annotation.Autowired; | 
 |  |  | import org.springframework.beans.factory.annotation.Value; | 
 |  |  | import org.springframework.http.*; | 
 |  |  | import org.springframework.stereotype.Component; | 
 |  |  | import org.springframework.util.LinkedMultiValueMap; | 
 |  |  | import org.springframework.util.MultiValueMap; | 
 |  |  | import org.springframework.web.client.RestTemplate; | 
 |  |  | import org.springframework.web.util.UriComponentsBuilder; | 
 |  |  |  | 
 |  |  | /** | 
 |  |  |  * @Author: liurunyu | 
 |  |  |  * @Date: 2025/6/7 11:40 | 
 |  |  |  * @Description | 
 |  |  |  */ | 
 |  |  | @Slf4j | 
 |  |  | @Component | 
 |  |  | public class YsAppClient { | 
 |  |  |  | 
 |  |  |     private static final String JobName = "VideoYsJob" ; | 
 |  |  |     private static final String JobGroupName = "VideoYsGroup" ; | 
 |  |  |     private static final Integer ThreadPoolMaxCount = 1 ;//线程池线程最大个数 | 
 |  |  |     private static final Integer ThreadPoolPriority = 5 ;//线程优先级 | 
 |  |  |     private static final boolean quartzJobRunOneTimes = true ;//定时任务只执行一次 | 
 |  |  |  | 
 |  |  |     @Value("${video.ys.accessTokenExpireDay: 7}") | 
 |  |  |     protected Integer accessTokenExpireDay;//AccessToken过期时间,单位天 | 
 |  |  |  | 
 |  |  |     @Value("${video.ys.appKey}") | 
 |  |  |     protected String appKey; | 
 |  |  |  | 
 |  |  |     @Value("${video.ys.secret}") | 
 |  |  |     protected String secret; | 
 |  |  |  | 
 |  |  |     @Value("${video.ys.requestAccessTokenUrl}") | 
 |  |  |     protected String requestAccessTokenUrl; | 
 |  |  |  | 
 |  |  |     @Autowired | 
 |  |  |     protected RestTemplate restTemplate ; | 
 |  |  |  | 
 |  |  |     @Autowired | 
 |  |  |     protected YsAppCtrl ysVideoCtrl; | 
 |  |  |  | 
 |  |  |     private Long computeNetGetAccessTokenAt(){ | 
 |  |  |         Long millis = (System.currentTimeMillis() + (accessTokenExpireDay * 24 * 60 * 60 * 1000) ) ; | 
 |  |  |         // millis = 10000L ; | 
 |  |  |         return millis ; | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 获得AccessToken | 
 |  |  |      */ | 
 |  |  |     public void getAccessToken(){ | 
 |  |  |         if((appKey != null && appKey.trim().length() > 0) | 
 |  |  |                 && (secret != null && secret.trim().length() > 0) | 
 |  |  |                 && (requestAccessTokenUrl != null && requestAccessTokenUrl.trim().length() > 0)){ | 
 |  |  |             MultiValueMap<String, String> formData = new LinkedMultiValueMap<>(); | 
 |  |  |             formData.add("appKey", appKey); | 
 |  |  |             formData.add("appSecret", secret); | 
 |  |  |             YsAccessTokenResponse response = this.postRequest2Ys(restTemplate, requestAccessTokenUrl, formData); | 
 |  |  |             if(response != null){ | 
 |  |  |                 switch (response.code){ | 
 |  |  |                     case "200" :{ | 
 |  |  |                         this.dealSuccessOfRequestAccessTokenFromYs(response) ; | 
 |  |  |                         break ; | 
 |  |  |                     } | 
 |  |  |                     default: { | 
 |  |  |                         this.dealErrorOfRequestAccessTokenFromYs(response) ; | 
 |  |  |                         break ; | 
 |  |  |                     } | 
 |  |  |                 } | 
 |  |  |             } | 
 |  |  |         } | 
 |  |  |     } | 
 |  |  |     private void dealSuccessOfRequestAccessTokenFromYs(YsAccessTokenResponse response){ | 
 |  |  |         if(response != null && response.data != null){ | 
 |  |  |             ysVideoCtrl.saveAccessTokenOfYs(response.data.accessToken, response.data.expireTime); | 
 |  |  |         } | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     private void dealErrorOfRequestAccessTokenFromYs(YsAccessTokenResponse response){ | 
 |  |  |         log.error("从萤石开放平台获得AccessToken失败,错误码:{},错误信息:{}", response.code, response.msg); | 
 |  |  |     } | 
 |  |  |     /** | 
 |  |  |      * 设置下次获得AccessToken | 
 |  |  |      */ | 
 |  |  |     public void reSetNextGetAccessToken(Long getAccessTokenAt){ | 
 |  |  |         if(getAccessTokenAt == null || getAccessTokenAt.longValue() == 0){ | 
 |  |  |             getAccessTokenAt = this.computeNetGetAccessTokenAt() ; | 
 |  |  |         } | 
 |  |  |         //毫秒变成秒 | 
 |  |  |         int futureSecond = (int)((getAccessTokenAt - System.currentTimeMillis()) / 1000) ; | 
 |  |  |         try { | 
 |  |  |             SchedulerTaskSupport.setThreadPoolPro(ThreadPoolMaxCount , ThreadPoolPriority); | 
 |  |  |             //因为要重复加工作任务,所以先把上次加的同组同名任务删除 | 
 |  |  |             SchedulerTaskSupport.deleteJob(JobName , JobGroupName) ; | 
 |  |  |             // 只执行一次的任务 | 
 |  |  |             SchedulerTaskSupport.addSecondlyJob(JobName , JobGroupName, YsAccessTokenQuartzJob.class, null, futureSecond, 1, 0) ; | 
 |  |  |         } catch (Exception e) { | 
 |  |  |             log.error("设置从萤石开放平台定时获得AccessToken任务时发生异常", e); | 
 |  |  |         } | 
 |  |  |     } | 
 |  |  |     /** | 
 |  |  |      * 向萤石开放平台发送Post请求 | 
 |  |  |      * @param restTemplate SpringBoot的RestTemplate | 
 |  |  |      * @param toMwUrl web请求Url | 
 |  |  |      * @param body 数据 | 
 |  |  |      * @return | 
 |  |  |      */ | 
 |  |  |     private YsAccessTokenResponse postRequest2Ys(RestTemplate restTemplate, String toMwUrl, Object body) { | 
 |  |  |         String url = UriComponentsBuilder.fromUriString(toMwUrl) | 
 |  |  |                 .build() | 
 |  |  |                 .toUriString(); | 
 |  |  |         HttpHeaders headers = new HttpHeaders(); | 
 |  |  |         headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); | 
 |  |  |  | 
 |  |  |         HttpEntity<?> httpEntity = new HttpEntity<>(body, headers); | 
 |  |  |         ResponseEntity<YsAccessTokenResponse> resEntity = null; | 
 |  |  |         try { | 
 |  |  |             // 通过Post方式调用接口 | 
 |  |  |             resEntity = restTemplate.exchange(url, HttpMethod.POST, httpEntity, YsAccessTokenResponse.class); | 
 |  |  |         } catch (Exception e) { | 
 |  |  |             log.error("从萤石开放平台定时获得AccessToken任务执行时发生异常", e); | 
 |  |  |         } | 
 |  |  |         if(resEntity != null){ | 
 |  |  |             return resEntity.getBody(); | 
 |  |  |         } | 
 |  |  |         return null ; | 
 |  |  |     } | 
 |  |  |  | 
 |  |  | } | 
 
 |  |  | 
 |  |  |     @Override | 
 |  |  |     public void onApplicationEvent(ApplicationReadyEvent event) { | 
 |  |  |         try { | 
 |  |  |             //等1秒,等待com.alibaba.druid.pool.DruidDataSource实始化完成 | 
 |  |  |             //等1秒,等待com.alibaba.druid.pool.DruidDataSource初始化完成 | 
 |  |  |             Thread.sleep(1000L); | 
 |  |  |         } catch (InterruptedException e) { | 
 |  |  |             e.printStackTrace(); | 
 
 |  |  | 
 |  |  |  | 
 |  |  | import com.dy.common.webUtil.QueryResultVo; | 
 |  |  | import com.dy.pipIrrGlobal.daoSe.SeCardOperateMapper; | 
 |  |  | import com.dy.pipIrrGlobal.daoSe.SeClientCardMapper; | 
 |  |  | import com.dy.pipIrrGlobal.voSt.VoCardUsage; | 
 |  |  | import com.dy.pipIrrGlobal.voSt.VoICCard; | 
 |  |  | import com.dy.pipIrrStatistics.card.IcCardqo.CommonQO; | 
 
 |  |  | 
 |  |  | package com.dy.pipIrrStatistics.statistics; | 
 |  |  |  | 
 |  |  | import com.dy.pipIrrGlobal.daoSe.SeRechargeHistoryMapper; | 
 |  |  | import com.dy.pipIrrGlobal.daoSt.StRechargeClientDayMapper; | 
 |  |  | import com.dy.pipIrrGlobal.daoSt.StRechargeClientMonthMapper; | 
 |  |  | import com.dy.pipIrrGlobal.daoSt.StRechargeClientYearMapper; | 
 
 |  |  | 
 |  |  | package com.dy.pipIrrStatistics.statistics; | 
 |  |  |  | 
 |  |  | import com.dy.pipIrrGlobal.daoSe.SeRechargeHistoryMapper; | 
 |  |  | import com.dy.pipIrrGlobal.daoSt.StRechargeIcDayMapper; | 
 |  |  | import com.dy.pipIrrGlobal.daoSt.StRechargeIcMonthMapper; | 
 |  |  | import com.dy.pipIrrGlobal.daoSt.StRechargeIcYearMapper; | 
 
 |  |  | 
 |  |  |  */ | 
 |  |  | public class StatisticsJob extends TaskJob { | 
 |  |  |  | 
 |  |  |     private static Logger log = LogManager.getLogger(Test.class.getName()) ; | 
 |  |  |     private static Logger log = LogManager.getLogger(StatisticsJob.class.getName()) ; | 
 |  |  |  | 
 |  |  |     private String orgTag ; | 
 |  |  |  | 
 
 |  |  | 
 |  |  |     @Override | 
 |  |  |     public void onApplicationEvent(@NonNull ApplicationReadyEvent event) { | 
 |  |  |         try { | 
 |  |  |             //等1秒,等待com.alibaba.druid.pool.DruidDataSource实始化完成 | 
 |  |  |             //等1秒,等待com.alibaba.druid.pool.DruidDataSource初始化完成 | 
 |  |  |             Thread.sleep(1000L); | 
 |  |  |         } catch (InterruptedException e) { | 
 |  |  |             e.printStackTrace(); | 
 
 |  |  | 
 |  |  | package com.dy.pipIrrWechat.client; | 
 |  |  |  | 
 |  |  | import com.dy.pipIrrGlobal.daoSe.SeClientCardMapper; | 
 |  |  | import com.dy.pipIrrGlobal.voWe.VoCards3; | 
 |  |  | import lombok.extern.slf4j.Slf4j; | 
 |  |  | import org.springframework.beans.factory.annotation.Autowired; | 
 
 |  |  | 
 |  |  | import com.dy.pipIrrGlobal.daoRm.RmCommandHistoryMapper; | 
 |  |  | import com.dy.pipIrrGlobal.daoRm.RmIrrigateProfileMapper; | 
 |  |  | import com.dy.pipIrrGlobal.daoRm.RmOpenCloseValveLastMapper; | 
 |  |  | import com.dy.pipIrrGlobal.daoSe.SeClientCardMapper; | 
 |  |  | import com.dy.pipIrrGlobal.daoSe.SeVirtualCardMapper; | 
 |  |  | import com.dy.pipIrrGlobal.pojoIr.IrIntakeOperate; | 
 |  |  | import com.dy.pipIrrGlobal.pojoRm.RmCommandHistory; | 
 |  |  | import com.dy.pipIrrGlobal.pojoSe.SeClientCard; | 
 |  |  | import com.dy.pipIrrGlobal.voRm.VoIrrigaterProfile; | 
 |  |  | import com.dy.pipIrrGlobal.voRm.VoRtuAndVc; | 
 |  |  | import com.dy.pipIrrGlobal.voRm.VoUnclosedValve; | 
 
 |  |  | 
 |  |  | import com.dy.pipIrrGlobal.command.ComSupport; | 
 |  |  | import com.dy.pipIrrGlobal.command.dto.Param; | 
 |  |  | import com.dy.pipIrrGlobal.daoSe.SeVirtualCardMapper; | 
 |  |  | import com.dy.pipIrrGlobal.pojoSe.SeClientCard; | 
 |  |  | import com.dy.pipIrrGlobal.voRm.VoIrrigaterProfile; | 
 |  |  | import com.dy.pipIrrGlobal.voRm.VoUnclosedValve; | 
 |  |  | import com.dy.pipIrrGlobal.voSe.VoVirtualCard; |