zhubaomin
2025-06-10 e88d34fd4cbe3a0cc57ecfdc1710d66bc88e26b5
Merge branch 'master' of http://8.140.179.55:20000/r/pipIrr-SV
24个文件已修改
25个文件已添加
1834 ■■■■■ 已修改文件
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol4Mqtt/pSdV1/MqttPubMsgSdV1.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol4Mqtt/pSdV1/MqttSubMsgSdV1.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/schedulerTask/SchedulerTaskSupport.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/webUtil/QueryResultVo.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/daoVi/ViCameraMapper.java 64 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/daoVi/ViYsAppMapper.java 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/pojoVi/ViCamera.java 94 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/pojoVi/ViYsApp.java 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/util/CameraTypeEnum.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/util/OrgListenerSupport.java 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/voVi/VoCamera.java 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-global/src/main/resources/application-global.yml 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-global/src/main/resources/mapper/ViCameraMapper.xml 235 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-global/src/main/resources/mapper/ViYsAppMapper.xml 101 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-mw/pipIrr-mw-rtu/src/main/resources/RtuDataDealTree.xml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-mw/pipIrr-mw-rtu/src/main/resources/config.properties 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-base/src/main/java/com/dy/pipIrrBase/util/InitListener.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-file/src/main/java/com/dy/pipIrrWebFile/fm/DyFmListener.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-project/src/main/java/com/dy/pipIrrProject/PipIrrProjectApplication.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-project/src/main/java/com/dy/pipIrrProject/video/CameraCtrl.java 239 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-project/src/main/java/com/dy/pipIrrProject/video/CameraDto.java 83 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-project/src/main/java/com/dy/pipIrrProject/video/CameraQo.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-project/src/main/java/com/dy/pipIrrProject/video/CameraSv.java 84 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-project/src/main/java/com/dy/pipIrrProject/video/CameraTypesConfig.java 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-project/src/main/java/com/dy/pipIrrProject/video/TypesVo.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/PipIrrRemoteApplication.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/monitor/p202404V201/cd15/CdCtrl.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/msCenter/Register2MwMsCenterListener.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/valve/ValveCtrl.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/video/VideoCtrl.java 120 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/video/VideoQo.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/video/VideoSv.java 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/video/VoVideo.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/video/YsAppCtrl.java 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/video/YsAppListener.java 120 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/video/YsAppSv.java 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/video/ys/YsAccessTokenData.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/video/ys/YsAccessTokenQuartzJob.java 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/video/ys/YsAccessTokenResponse.java 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/video/ys/YsAppClient.java 135 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-sso/src/main/java/com/dy/sso/util/SsoListener.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-statistics/src/main/java/com/dy/pipIrrStatistics/card/IcCardSv.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-statistics/src/main/java/com/dy/pipIrrStatistics/statistics/StChargeByClientSv.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-statistics/src/main/java/com/dy/pipIrrStatistics/statistics/StChargeByIcSv.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-statistics/src/main/java/com/dy/pipIrrStatistics/statistics/StatisticsJob.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-statistics/src/main/java/com/dy/pipIrrStatistics/statistics/StatisticsListener.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-wechat/src/main/java/com/dy/pipIrrWechat/client/ClientCardSv.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-wechat/src/main/java/com/dy/pipIrrWechat/command/CommandSv.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-wechat/src/main/java/com/dy/pipIrrWechat/command/ValveCtrl.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol4Mqtt/pSdV1/MqttPubMsgSdV1.java
@@ -2,6 +2,7 @@
import com.dy.common.mw.protocol4Mqtt.MqttPubMsg;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
 * @Author: liurunyu
@@ -9,6 +10,7 @@
 * @Description 下发的发布消息(即下行命令)
 */
@Data
@EqualsAndHashCode(callSuper=false)
public class MqttPubMsgSdV1 extends MqttPubMsg {
    public Integer address ;//寄存器地址
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol4Mqtt/pSdV1/MqttSubMsgSdV1.java
@@ -4,6 +4,7 @@
import com.dy.common.mw.protocol4Mqtt.MqttSubMsg;
import com.dy.common.util.Callback;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
 * @Author: liurunyu
@@ -11,6 +12,7 @@
 * @Description 收到的订阅消息
 */
@Data
@EqualsAndHashCode(callSuper=false)
public class MqttSubMsgSdV1 extends MqttSubMsg {
    public Integer address ;//寄存器地址
    public String value ;//寄存器值
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/schedulerTask/SchedulerTaskSupport.java
@@ -19,6 +19,17 @@
            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秒钟重复工作一次的工作任务,
@@ -61,7 +72,6 @@
                    .withIntervalInSeconds(intervalInSeconds)
                    .withRepeatCount(repeatCount))
            .build();
        sched.scheduleJob(job, trigger);
        sched.start();
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/webUtil/QueryResultVo.java
@@ -53,6 +53,16 @@
    @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 ;
pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/daoVi/ViCameraMapper.java
New file
@@ -0,0 +1,64 @@
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);
}
pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/daoVi/ViYsAppMapper.java
New file
@@ -0,0 +1,31 @@
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);
}
pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/pojoVi/ViCamera.java
New file
@@ -0,0 +1,94 @@
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;
}
pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/pojoVi/ViYsApp.java
New file
@@ -0,0 +1,60 @@
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;
}
pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/util/CameraTypeEnum.java
New file
@@ -0,0 +1,24 @@
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 ;
    }
}
pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/util/OrgListenerSupport.java
@@ -15,14 +15,14 @@
public abstract class OrgListenerSupport {
    /**
     * 实始化
     * 初始化
     */
    @SuppressWarnings("unused ")
    protected void init(ResourceLoader resourceLoader) {
        this.doInit(resourceLoader);
    }
    /**
     * 实始化
     * 初始化
     */
    @SuppressWarnings("unused ")
    protected void doInit(ResourceLoader resourceLoader) {
@@ -61,7 +61,7 @@
    // 得到
    ////////////////////////////////
    /**
     * 实始化
     * 初始化
     */
    @SuppressWarnings("unused ")
    protected List<Org.OrgVo> get(ResourceLoader resourceLoader) {
@@ -69,7 +69,7 @@
    }
    /**
     * 实始化
     * 初始化
     */
    @SuppressWarnings("unused ")
    protected List<Org.OrgVo> doGet(ResourceLoader resourceLoader) {
pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/voVi/VoCamera.java
New file
@@ -0,0 +1,59 @@
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;
}
pipIrr-platform/pipIrr-global/src/main/resources/application-global.yml
@@ -472,6 +472,24 @@
        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:
pipIrr-platform/pipIrr-global/src/main/resources/mapper/ViCameraMapper.xml
New file
@@ -0,0 +1,235 @@
<?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>
pipIrr-platform/pipIrr-global/src/main/resources/mapper/ViYsAppMapper.xml
New file
@@ -0,0 +1,101 @@
<?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>
pipIrr-platform/pipIrr-mw/pipIrr-mw-rtu/src/main/resources/RtuDataDealTree.xml
@@ -94,7 +94,7 @@
        </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>
pipIrr-platform/pipIrr-mw/pipIrr-mw-rtu/src/main/resources/config.properties
@@ -42,6 +42,7 @@
#   甘州: 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
pipIrr-platform/pipIrr-web/pipIrr-web-base/src/main/java/com/dy/pipIrrBase/util/InitListener.java
@@ -120,7 +120,7 @@
    @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();
@@ -130,7 +130,7 @@
    }
    /**
     * 实始化
     * 初始化
     */
    @SuppressWarnings("unused ")
    private void init(ApplicationReadyEvent event){
pipIrr-platform/pipIrr-web/pipIrr-web-file/src/main/java/com/dy/pipIrrWebFile/fm/DyFmListener.java
@@ -23,7 +23,7 @@
    @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();
pipIrr-platform/pipIrr-web/pipIrr-web-project/src/main/java/com/dy/pipIrrProject/PipIrrProjectApplication.java
@@ -25,7 +25,7 @@
                })
        }
)
@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) {
pipIrr-platform/pipIrr-web/pipIrr-web-project/src/main/java/com/dy/pipIrrProject/video/CameraCtrl.java
New file
@@ -0,0 +1,239 @@
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) ;
        }
    }
}
pipIrr-platform/pipIrr-web/pipIrr-web-project/src/main/java/com/dy/pipIrrProject/video/CameraDto.java
New file
@@ -0,0 +1,83 @@
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;
    }
}
pipIrr-platform/pipIrr-web/pipIrr-web-project/src/main/java/com/dy/pipIrrProject/video/CameraQo.java
New file
@@ -0,0 +1,22 @@
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;
}
pipIrr-platform/pipIrr-web/pipIrr-web-project/src/main/java/com/dy/pipIrrProject/video/CameraSv.java
New file
@@ -0,0 +1,84 @@
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) ;
    }
}
pipIrr-platform/pipIrr-web/pipIrr-web-project/src/main/java/com/dy/pipIrrProject/video/CameraTypesConfig.java
New file
@@ -0,0 +1,27 @@
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 ;
    }
}
pipIrr-platform/pipIrr-web/pipIrr-web-project/src/main/java/com/dy/pipIrrProject/video/TypesVo.java
New file
@@ -0,0 +1,14 @@
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 ;
}
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/PipIrrRemoteApplication.java
@@ -30,7 +30,8 @@
        "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 {
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/monitor/p202404V201/cd15/CdCtrl.java
@@ -9,6 +9,7 @@
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;
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/msCenter/Register2MwMsCenterListener.java
@@ -51,7 +51,7 @@
    @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();
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/valve/ValveCtrl.java
@@ -19,6 +19,7 @@
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;
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/video/VideoCtrl.java
New file
@@ -0,0 +1,120 @@
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()) ;
        }
    }
}
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/video/VideoQo.java
New file
@@ -0,0 +1,18 @@
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 {
}
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/video/VideoSv.java
New file
@@ -0,0 +1,44 @@
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;
    }
}
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/video/VoVideo.java
New file
@@ -0,0 +1,20 @@
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 ;
}
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/video/YsAppCtrl.java
New file
@@ -0,0 +1,48 @@
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 ;
    }
}
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/video/YsAppListener.java
New file
@@ -0,0 +1,120 @@
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);
            }
        }
    }
}
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/video/YsAppSv.java
New file
@@ -0,0 +1,47 @@
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() ;
    }
}
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/video/ys/YsAccessTokenData.java
New file
@@ -0,0 +1,18 @@
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 ;
}
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/video/ys/YsAccessTokenQuartzJob.java
New file
@@ -0,0 +1,25 @@
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);
    }
}
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/video/ys/YsAccessTokenResponse.java
New file
@@ -0,0 +1,19 @@
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 ;
}
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/video/ys/YsAppClient.java
New file
@@ -0,0 +1,135 @@
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 ;
    }
}
pipIrr-platform/pipIrr-web/pipIrr-web-sso/src/main/java/com/dy/sso/util/SsoListener.java
@@ -17,7 +17,7 @@
    @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();
pipIrr-platform/pipIrr-web/pipIrr-web-statistics/src/main/java/com/dy/pipIrrStatistics/card/IcCardSv.java
@@ -2,6 +2,7 @@
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;
pipIrr-platform/pipIrr-web/pipIrr-web-statistics/src/main/java/com/dy/pipIrrStatistics/statistics/StChargeByClientSv.java
@@ -1,5 +1,6 @@
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;
pipIrr-platform/pipIrr-web/pipIrr-web-statistics/src/main/java/com/dy/pipIrrStatistics/statistics/StChargeByIcSv.java
@@ -1,5 +1,6 @@
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;
pipIrr-platform/pipIrr-web/pipIrr-web-statistics/src/main/java/com/dy/pipIrrStatistics/statistics/StatisticsJob.java
@@ -21,7 +21,7 @@
 */
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 ;
pipIrr-platform/pipIrr-web/pipIrr-web-statistics/src/main/java/com/dy/pipIrrStatistics/statistics/StatisticsListener.java
@@ -53,7 +53,7 @@
    @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();
pipIrr-platform/pipIrr-web/pipIrr-web-wechat/src/main/java/com/dy/pipIrrWechat/client/ClientCardSv.java
@@ -1,5 +1,6 @@
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;
pipIrr-platform/pipIrr-web/pipIrr-web-wechat/src/main/java/com/dy/pipIrrWechat/command/CommandSv.java
@@ -28,9 +28,11 @@
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;
pipIrr-platform/pipIrr-web/pipIrr-web-wechat/src/main/java/com/dy/pipIrrWechat/command/ValveCtrl.java
@@ -16,6 +16,7 @@
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;