xiangpei
2024-08-01 66544379029bdc7ecce13e6b3a32b59be1527495
Merge remote-tracking branch 'origin/master'

# Conflicts:
# ycl-server/src/main/java/com/ycl/platform/service/impl/WorkOrderServiceImpl.java
23个文件已修改
7个文件已添加
1 文件已重命名
1个文件已删除
1305 ■■■■ 已修改文件
ycl-common/src/main/java/constant/ApiConstants.java 28 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ycl-common/src/main/java/constant/CalculationStrategyConstants.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ycl-common/src/main/java/constant/RedisConstant.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ycl-pojo/src/main/java/com/ycl/platform/domain/entity/TMonitor.java 49 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ycl-pojo/src/main/java/com/ycl/platform/domain/entity/YwPoint.java 15 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ycl-pojo/src/main/java/com/ycl/platform/domain/result/UY/OneMachineFileResult.java 89 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ycl-server/src/main/java/com/ycl/calculate/CarInFoAccuracyCalculation.java 136 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ycl-server/src/main/java/com/ycl/calculate/CarSiteOnlineCalculation.java 15 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ycl-server/src/main/java/com/ycl/calculate/CarSnapshotDelayCalculation.java 141 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ycl-server/src/main/java/com/ycl/calculate/FaceInFoAccuracyCalculation.java 132 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ycl-server/src/main/java/com/ycl/calculate/FaceSiteOnlineCalculation.java 33 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ycl-server/src/main/java/com/ycl/calculate/FaceSnapshotDelayCalculation.java 136 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ycl-server/src/main/java/com/ycl/calculate/IndexCalculationServe.java 69 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ycl-server/src/main/java/com/ycl/calculate/IndexCalculationUtils.java 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ycl-server/src/main/java/com/ycl/factory/IndexCalculationFactory.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ycl-server/src/main/java/com/ycl/feign/UYClient.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ycl-server/src/main/java/com/ycl/feign/UYFeignConfig.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ycl-server/src/main/java/com/ycl/platform/mapper/TMonitorMapper.java 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ycl-server/src/main/java/com/ycl/platform/service/ITMonitorService.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ycl-server/src/main/java/com/ycl/platform/service/YwPointService.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ycl-server/src/main/java/com/ycl/platform/service/impl/CalculateReportServiceImpl.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ycl-server/src/main/java/com/ycl/platform/service/impl/CheckIndexCarServiceImpl.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ycl-server/src/main/java/com/ycl/platform/service/impl/TMonitorServiceImpl.java 19 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ycl-server/src/main/java/com/ycl/platform/service/impl/WorkOrderServiceImpl.java 51 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ycl-server/src/main/java/com/ycl/platform/service/impl/YwPointServiceImpl.java 41 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ycl-server/src/main/java/com/ycl/task/CarTask.java 31 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ycl-server/src/main/java/com/ycl/task/FaceTask.java 33 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ycl-server/src/main/java/com/ycl/task/HKTask.java 30 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ycl-server/src/main/java/com/ycl/task/MonitorTask.java 88 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ycl-server/src/main/java/com/ycl/task/UYTask.java 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ycl-server/src/main/resources/mapper/zgyw/CheckScoreMapper.xml 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ycl-server/src/main/resources/mapper/zgyw/TMonitorMapper.xml 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ycl-common/src/main/java/constant/ApiConstants.java
@@ -10,19 +10,37 @@
    public final static Integer pageNo = 1;
    public final static Integer pageSize = 5000;
    //请求参数dataType-卡口过车
    public final static Integer HK_DATATYPE_CAR = 1;
    public final static Integer HK_DataType_CAR = 1;
    //请求参数dataType-人脸数据
    public final static Integer HK_DATATYPE_FACE = 2;
    public final static Integer HK_DataType_FACE = 2;
    //抓拍数据量监测结果 正常
    public final static Integer HK_SnapCount_ResultType_Normal = 1;
    //抓拍数据量监测结果 无数据
    public final static Integer HK_SnapCount_ResultType_Null = 2;
    //抓拍数据量监测结果 数据突降
    public final static Integer HK_SnapCount_ResultType_Descent = 3;
    //请求参数dataType 数据量少
    public final static Integer HK_DATATYPE_ResultType_Low = 4;
    public final static Integer HK_DataType_ResultType_Low = 4;
    //经纬度检测结果 正常
    public final static Integer HK_Info_LayType_Normal = 1;
    //经纬度检测结果 经纬度缺失
    public final static Integer HK_Info_LayType_Absent = 2;
    //经纬度检测结果 不在辖区
    public final static Integer HK_Info_LayType_NotIn = 3;
    //经纬度检测结果 精度低
    public final static Integer HK_Info_LayType_Low = 4;
    //国际编码监测结果 正常
    public final static Integer HK_Info_GbCodeType_Normal = 1;
    //国际编码监测结果 编码长度不等于20位
    public final static Integer HK_Info_GbCodeType_NotEq = 2;
    //国际编码监测结果 前6位不合标准
    public final static Integer HK_Info_GbCodeType_6NotStandard = 3;
    //国际编码监测结果 11-13位不合标准
    public final static Integer HK_Info_GbCodeType_11NotStandard = 4;
}
ycl-common/src/main/java/constant/CalculationStrategyConstants.java
@@ -8,9 +8,25 @@
    /**
     * 车辆点位在线率和视图库对接稳定性
     */
    public static final String CAR_SiteOnline_ViewStability = "carSiteOnlineViewStability";
    public static final String Car_SiteOnline_ViewStability = "carSiteOnlineViewStability";
    /**
     * 人脸点位在线率和视图库对接稳定性
     */
    public static final String Face_SiteOnline_ViewStability = "faceSiteOnlineViewStability";
    /**
     * 车辆卡口属性监测结果
     */
    public static final String Car_InfoAccuracy = "carInfoAccuracy";
    /**
     * 人脸属性监测结果
     */
    public static final String Face_InfoAccuracy = "faceInfoAccuracy";
    /**
     * 车辆数据上传及时性
     */
    public static final String Car_SnapshotDelay = "carSnapshotDelay";
    /**
     * 人脸数据上传及时性
     */
    public static final String Face_SnapshotDelay = "faceSnapshotDelay";
}
ycl-common/src/main/java/constant/RedisConstant.java
New file
@@ -0,0 +1,6 @@
package constant;
public class RedisConstant {
    /** 一机一档目录一致率 多出来的设备 Set集合 */
    public static final String New_Monitor_Set="New_Monitor_Set";
}
ycl-pojo/src/main/java/com/ycl/platform/domain/entity/TMonitor.java
@@ -1,6 +1,7 @@
package com.ycl.platform.domain.entity;
import annotation.Excel;
import com.baomidou.mybatisplus.annotation.TableField;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.ycl.system.entity.BaseEntity;
@@ -141,18 +142,8 @@
    @Excel(name = "类型编码 : [131.摄像机编码;132.网络摄像机编码;]")
    private Long lxbm;
    @Excel(name = "异常原因")
    private String reason;
    @Excel(name = "是否生成异常工单")
    private Long defaultOrder;
    @Excel(name ="异常恢复标识")
    private Long recovery;
    @Excel(name = "异常恢复时间")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date recoveryTime;
    @TableField(exist = false)
    private Integer recovery;
    private Long deptId;
@@ -164,14 +155,6 @@
        this.deptId = deptId;
    }
    public Long getDefaultOrder() {
        return defaultOrder;
    }
    public void setDefaultOrder(Long defaultOrder) {
        this.defaultOrder = defaultOrder;
    }
    public void setInstalledTime(Date installedTime) {
        this.installedTime = installedTime;
    }
@@ -180,31 +163,13 @@
        return installedTime;
    }
    public Date getRecoveryTime() {
        return recoveryTime;
    }
    public void setRecoveryTime(Date recoveryTime) {
        this.recoveryTime = recoveryTime;
    }
    public Long getRecovery() {
    public Integer getRecovery() {
        return recovery;
    }
    public void setRecovery(Long recovery) {
    public void setRecovery(Integer recovery) {
        this.recovery = recovery;
    }
    public String getReason() {
        return reason;
    }
    public void setReason(String reason) {
        this.reason = reason;
    }
    public void setId(Long id)
    {
@@ -512,10 +477,6 @@
                ", cameraDept='" + cameraDept + '\'' +
                ", hybm='" + hybm + '\'' +
                ", lxbm=" + lxbm +
                ", reason='" + reason + '\'' +
                ", defaultOrder=" + defaultOrder +
                ", recovery=" + recovery +
                ", recoveryTime=" + recoveryTime +
                ", deptId=" + deptId +
                '}';
    }
ycl-pojo/src/main/java/com/ycl/platform/domain/entity/YwPoint.java
@@ -3,13 +3,15 @@
import com.baomidou.mybatisplus.annotation.FieldStrategy;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import java.time.LocalDateTime;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.ycl.platform.base.AbsEntity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;
import java.time.LocalDateTime;
import java.util.Date;
/**
 * 运维点位
@@ -60,5 +62,14 @@
    @TableField("point_tag")
    private String pointTag;
    @TableField("reason")
    private String reason;
    @TableField("recovery")
    private Integer recovery;
    @TableField("recovery_time")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date recoveryTime;
}
ycl-pojo/src/main/java/com/ycl/platform/domain/result/UY/OneMachineFileResult.java
@@ -27,6 +27,54 @@
    private String SBMC;
    /**
     * 摄像机采集区域(参考文档解析)
     */
    private String SXJCJQY;
    /**
     * 监控点位类型,1-一类视频监控点;2-二类视频监控点;3-三类视频监控点;4-公安内部视频监控点;9-其他点位。
     * 参照公安部《关于进一步加强公安机关视频图像信息应用工作的意见》(公通字﹝2015﹞4号)定义。
     */
    private String JKDWLX;
    /**
     * IPV4地址,摄像机IP地址。
     */
    private String IP;
    /**
     * IPV6地址,摄像机扩展IP地址。
     */
//    private String IPV6;
    /**
     * 经度。
     */
    private Double JD;
    /**
     * 纬度。
     */
    private Double WD;
    /**
     * 摄像机功能类型,取值范围(多选) : [1.视频监控;2.车辆识别;3.人员识别;] 数据格式[填入多个值并以/隔开。例如  1/2]
     */
    private String SXJGNLX;
    /**
     * MAC地址,摄像机MAC地址。
     */
    private String MACDZ;
    /**
     * 设备状态,1-在用;2-维修;3-拆除。
     */
    private String SBZT;
    //---------------------------------------------------------------------
    /**
     * 设备厂商,编码1-海康威视;2-大华;3-天地伟业;4-科达;5-安讯士;6-博世;7-亚安;8-英飞拓;9-宇视;10-海信;11-中星电子;12-明景;13-联想;14-中兴;99-其他。
     */
    private String SBCS;
@@ -35,12 +83,6 @@
     * 行政区域,行政区划、籍贯省市县代码。参照《GB/T 2260 中华人民共和国行政区划代码》。
     */
    private String XZQY;
    /**
     * 监控点位类型,1-一类视频监控点;2-二类视频监控点;3-三类视频监控点;4-公安内部视频监控点;9-其他点位。
     * 参照公安部《关于进一步加强公安机关视频图像信息应用工作的意见》(公通字﹝2015﹞4号)定义。
     */
    private String JKDWLX;
    /**
     * 设备型号,描述设备的具体型号。
@@ -53,29 +95,9 @@
    private String DWSC;
    /**
     * IPV4地址,摄像机IP地址。
     */
    private String IPV4;
    /**
     * IPV6地址,摄像机扩展IP地址。
     */
    private String IPV6;
    /**
     * MAC地址,摄像机MAC地址。
     */
    private String MACDZ;
    /**
     * 摄像机类型,1-球机;2-半球;3-固定枪机;4-遥控枪机;5-卡口枪机;99-未知。
     */
    private String SXJLX;
    /**
     * 摄像机功能类型,1-车辆卡口;2-人员卡口;3-微卡口;4-特征摄像机;5-普通监控;99-其他,多选各参数以“/”分隔。
     */
    private String SXJGNLX;
    /**
     * 补光属性,1-无补光、2-红外补光、3-白光补光、9-其他补光。
@@ -92,16 +114,6 @@
     * 参考范式:街道+门牌号码+单位名称。高速公路、国道等点位可参照“公路名称+公里数”范式。
     */
    private String AZDZ;
    /**
     * 经度。
     */
    private Double JD;
    /**
     * 纬度。
     */
    private Double WD;
    /**
     * 摄像机位置类型,1-省际检查站、2-党政机关、3-车站码头、4-中心广场、5-体育场馆、6-商业中心、7-宗教场所、8-校园周边、9-治安复杂区域、10-交通干线、11-医院周边、12-金融机构周边、13-危险物品场所周边、14-博物馆展览馆、15-重点水域、航道、96-市际公安检查站;97-涉外场所;98-边境沿线;99-旅游景区,多选各参数以“/”分隔。
@@ -147,11 +159,6 @@
     * 录像保存天数。
     */
    private Integer LXBCTS;
    /**
     * 设备状态,1-在用;2-维修;3-拆除。
     */
    private String SBZT;
    /**
     * 所属部门/行业,1-公安机关;2-环保部门;3-文博部门;4-医疗部门;5-旅游管理;6-新闻广电;7-食品医药监督管理部门;8-教育管理部门;9-检察院;10-法院;11-金融部门;12-交通部门;13-住房和城乡建设部门;14-水利部门;15-林业部门;16-安全生产监督部门;17-市政市容委;18-国土局,可扩展,多选各参数以“/”分隔。
ycl-server/src/main/java/com/ycl/calculate/CarInFoAccuracyCalculation.java
New file
@@ -0,0 +1,136 @@
package com.ycl.calculate;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ycl.platform.domain.entity.CheckIndexCar;
import com.ycl.platform.domain.entity.TMonitor;
import com.ycl.platform.domain.result.HK.CrossDetailResult;
import com.ycl.platform.domain.result.HK.SnapshotDataMonitorResult;
import com.ycl.platform.mapper.CheckIndexCarMapper;
import com.ycl.platform.mapper.TMonitorMapper;
import com.ycl.platform.service.ICheckIndexCarService;
import com.ycl.platform.service.ITMonitorService;
import com.ycl.system.mapper.SysConfigMapper;
import constant.ApiConstants;
import constant.CheckConstants;
import constant.CheckSnapCountConstants;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import utils.DateUtils;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
 * 计算车辆卡口信息采集准确率  设备编码、行政区划代码、安装位置、坐标经纬度信息完整准确
 * 获取分省厅、区域的map<k,v> k为deptId或者Province_deptId
 * 更新或新增
 */
@Component
public class CarInFoAccuracyCalculation extends IndexCalculationServe implements CalculationStrategy<CrossDetailResult> {
    @Autowired
    private CheckIndexCarMapper checkIndexCarMapper;
    @Autowired
    private SysConfigMapper sysConfigMapper;
    @Autowired
    private ITMonitorService monitorService;
    @Autowired
    private TMonitorMapper monitorMapper;
    @Autowired
    private ICheckIndexCarService checkIndexCarService;
    //区域车辆信息采集准确率的内部类
    private static class AreaStats {
        int totalSites = 0;
        int qualifySite = 0;
    }
    @Override
    public void calculate(List<CrossDetailResult> list) {
        if (CollectionUtils.isEmpty(list)) {
            return;
        }
        //返回以国标码为key的设备map
        //TODO:monitor去掉了deptId
        Map<String, TMonitor> monitorMap = monitorService.list(new QueryWrapper<TMonitor>()
                        .in("serial_number", list.stream().map(CrossDetailResult::getExternalIndexCode).collect(Collectors.toList())))
                .stream().collect(Collectors.toMap(TMonitor::getSerialNumber, Function.identity()));
        //获取省厅国标码集合
        List<String> provinceIds = getProvince();
        Map<String, AreaStats> areaStatsMap = new HashMap<>();
        for (CrossDetailResult result : list) {
            TMonitor monitor = monitorMap.get(result.getExternalIndexCode());
            if (monitor == null) continue;
            String deptId = monitor.getDeptId().toString();
            updateAreaStats(areaStatsMap, deptId, result);
            // 处理省厅数据
            if (!CollectionUtils.isEmpty(provinceIds) && provinceIds.contains(monitor.getSerialNumber())) {
                String provinceKey = "Province_" + deptId;
                updateAreaStats(areaStatsMap, provinceKey, result);
            }
        }
        // 查询是否index表已经存在今日数据
        List<CheckIndexCar> checkIndexCarList = checkIndexCarMapper.selectToday(DateUtils.getDate());
        List<CheckIndexCar> checkIndexCars = new ArrayList<>();
        areaStatsMap.forEach((deptId, stats) -> {
            if (stats.totalSites > 0) {
                CheckIndexCar checkIndexCar = createOrUpdateCheckIndexCar(deptId, stats, checkIndexCarList);
                checkIndexCars.add(checkIndexCar);
            }
        });
        checkIndexCarService.saveOrUpdateBatch(checkIndexCars);
    }
    /**
     * 累计总点位数、标注异常点位数
     */
    private void updateAreaStats(Map<String, AreaStats> areaStatsMap, String key, CrossDetailResult result) {
        //返回对象的引用,如果不存在会放入新的key,value
        AreaStats stats = areaStatsMap.computeIfAbsent(key, k -> new AreaStats());
        stats.totalSites++;
        if (ApiConstants.HK_Info_LayType_Normal.equals(result.getLalType()) && ApiConstants.HK_Info_GbCodeType_Normal.equals(result.getGbCodeType())) {
            stats.qualifySite++;
        }
    }
    /**
     * 车辆信息采集正确率
     */
    private CheckIndexCar createOrUpdateCheckIndexCar(String key, AreaStats stats, List<CheckIndexCar> checkIndexCarList) {
        CheckIndexCar checkIndexCar;
        // 检查是否已存在今日数据
        Optional<CheckIndexCar> existingCar = checkIndexCarList.stream()
                .filter(car -> key.equals(car.getDeptId().toString()) &&
                        (key.startsWith("Province_") ? CheckConstants.Examine_Tag_City.equals(car.getExamineTag())
                                : CheckConstants.Examine_Tag_County.equals(car.getExamineTag())))
                .findFirst();
        if (existingCar.isPresent()) {
            checkIndexCar = existingCar.get();
        } else {
            checkIndexCar = new CheckIndexCar();
            checkIndexCar.setDeptId(key.startsWith("Province_") ? Long.parseLong(key.split("_")[1]) : Long.parseLong(key));
            checkIndexCar.setExamineTag(key.startsWith("Province_") ? CheckConstants.Examine_Tag_City : CheckConstants.Examine_Tag_County);
            checkIndexCar.setCreateTime(new Date());
        }
        //调用计算方法
        Map<String, Object> siteOnlineParam = new HashMap<>();
        siteOnlineParam.put("totalSites", stats.totalSites);
        siteOnlineParam.put("qualifySite", stats.qualifySite);
        BigDecimal infoAccuracy = infoAccuracy(siteOnlineParam);
        checkIndexCar.setVehicleInformationCollectionAccuracy(infoAccuracy);
        return checkIndexCar;
    }
}
ycl-server/src/main/java/com/ycl/calculate/CarSiteOnlineCalculation.java
@@ -30,7 +30,7 @@
 * 更新或新增
 */
@Component
public class CarSiteOnlineCalculation implements CalculationStrategy<SnapshotDataMonitorResult> {
public class CarSiteOnlineCalculation extends IndexCalculationServe implements CalculationStrategy<SnapshotDataMonitorResult> {
    @Autowired
    private CheckIndexCarMapper checkIndexCarMapper;
    @Autowired
@@ -52,14 +52,15 @@
        if (CollectionUtils.isEmpty(list)) {
            return;
        }
        Map<String, AreaStats> areaStatsMap = new HashMap<>();
        //获得国标码为key的设备map
        Map<String, TMonitor> monitorMap = monitorService.list(new QueryWrapper<TMonitor>()
                        .in("serial_number", list.stream().map(SnapshotDataMonitorResult::getExternalIndexCode).collect(Collectors.toList())))
                .stream().collect(Collectors.toMap(TMonitor::getSerialNumber, Function.identity()));
        //获取省厅国标码集合
        List<String> provinceIds = getProvince();
        // TODO: 分省厅市局 需要补充集合数据
        List<String> provinceIds = new ArrayList<>(); // 这里需要根据点位补充
        Map<String, AreaStats> areaStatsMap = new HashMap<>();
        for (SnapshotDataMonitorResult result : list) {
            TMonitor monitor = monitorMap.get(result.getExternalIndexCode());
            if (monitor == null) continue;
@@ -135,14 +136,14 @@
        Map<String, Object> siteOnlineParam = new HashMap<>();
        siteOnlineParam.put("totalSites", stats.totalSites);
        siteOnlineParam.put("offlineSites", stats.offlineSites);
        BigDecimal siteOnline = IndexCalculationUtils.siteOnline(siteOnlineParam);
        BigDecimal siteOnline = siteOnline(siteOnlineParam);
        checkIndexCar.setSiteOnline(siteOnline);
        //视图库对接稳定性
        BigDecimal avgCount = key.startsWith("Province_") ? cityCountAvg : countyCountAvg;
        Map<String, Object> viewConnectParam = new HashMap<>();
        viewConnectParam.put("totalDataSum", stats.totalDataSum);
        viewConnectParam.put("avgCount", avgCount);
        BigDecimal viewConnectStability = IndexCalculationUtils.viewConnectStability(viewConnectParam);
        BigDecimal viewConnectStability = viewConnectStability(viewConnectParam);
        checkIndexCar.setViewConnectStability(viewConnectStability);
        return checkIndexCar;
    }
ycl-server/src/main/java/com/ycl/calculate/CarSnapshotDelayCalculation.java
New file
@@ -0,0 +1,141 @@
package com.ycl.calculate;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ycl.platform.domain.entity.CheckIndexCar;
import com.ycl.platform.domain.entity.TMonitor;
import com.ycl.platform.domain.result.HK.SnapshotDataMonitorResult;
import com.ycl.platform.domain.result.HK.SnapshotDelayMonitorResult;
import com.ycl.platform.mapper.CheckIndexCarMapper;
import com.ycl.platform.service.ICheckIndexCarService;
import com.ycl.platform.service.ITMonitorService;
import com.ycl.system.mapper.SysConfigMapper;
import constant.ApiConstants;
import constant.CheckConstants;
import constant.CheckSnapCountConstants;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import utils.DateUtils;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
 * 计算车辆备抓拍数据上传及时性
 * 获取分省厅、区域的map<k,v> k为deptId或者Province_deptId
 * 循环map计算数据上传及时性
 * 更新或新增
 */
@Component
public class CarSnapshotDelayCalculation extends IndexCalculationServe implements CalculationStrategy<SnapshotDelayMonitorResult> {
    @Autowired
    private CheckIndexCarMapper checkIndexCarMapper;
    @Autowired
    private SysConfigMapper sysConfigMapper;
    @Autowired
    private ITMonitorService monitorService;
    @Autowired
    private ICheckIndexCarService checkIndexCarService;
    //区域车辆点位在线指标的内部类
    private static class AreaStats {
        int totalCount = 0;
        //0-180s
        int delayCount1 = 0;
        //180-300s
        int delayCount2 = 0;
        //300-600s
        int delayCount3 = 0;
    }
    @Override
    public void calculate(List<SnapshotDelayMonitorResult> list) {
        if (CollectionUtils.isEmpty(list)) {
            return;
        }
        //获得国标码为key的设备map
        Map<String, TMonitor> monitorMap = monitorService.list(new QueryWrapper<TMonitor>()
                        .in("serial_number", list.stream().map(SnapshotDelayMonitorResult::getExternalIndexCode).collect(Collectors.toList())))
                .stream().collect(Collectors.toMap(TMonitor::getSerialNumber, Function.identity()));
        //获取省厅国标码集合
        List<String> provinceIds = getProvince();
        Map<String, AreaStats> areaStatsMap = new HashMap<>();
        for (SnapshotDelayMonitorResult result : list) {
            TMonitor monitor = monitorMap.get(result.getExternalIndexCode());
            if (monitor == null) continue;
            String deptId = monitor.getDeptId().toString();
            updateAreaStats(areaStatsMap, deptId, result);
            // 处理省厅数据
            if (!CollectionUtils.isEmpty(provinceIds) && provinceIds.contains(monitor.getSerialNumber())) {
                String provinceKey = "Province_" + deptId;
                updateAreaStats(areaStatsMap, provinceKey, result);
            }
        }
        // 查询是否index表已经存在今日数据
        List<CheckIndexCar> checkIndexCarList = checkIndexCarMapper.selectToday(DateUtils.getDate());
        List<CheckIndexCar> checkIndexCars = new ArrayList<>();
        areaStatsMap.forEach((deptId, stats) -> {
            if (stats.totalCount > 0) {
                CheckIndexCar checkIndexCar = createOrUpdateCheckIndexCar(deptId, stats, checkIndexCarList);
                checkIndexCars.add(checkIndexCar);
            }
        });
        checkIndexCarService.saveOrUpdateBatch(checkIndexCars);
    }
    /**
     * 累计总点位数、离线数、总抓拍量
     */
    private void updateAreaStats(Map<String, AreaStats> areaStatsMap, String key, SnapshotDelayMonitorResult result) {
        //返回对象的引用,如果不存在会放入新的key,value
        AreaStats stats = areaStatsMap.computeIfAbsent(key, k -> new AreaStats());
        stats.totalCount += result.getDataCount();
        stats.delayCount1 += result.getDataDelayCount1();
        stats.delayCount2 += result.getDataDelayCount2();
        stats.delayCount3 += result.getDataDelayCount3();
    }
    /**
     * 车辆点位在线率和视图库对接稳定性
     */
    private CheckIndexCar createOrUpdateCheckIndexCar(String key, AreaStats stats, List<CheckIndexCar> checkIndexCarList) {
        CheckIndexCar checkIndexCar;
        // 检查是否已存在今日数据
        Optional<CheckIndexCar> existingCar = checkIndexCarList.stream()
                .filter(car -> key.equals(car.getDeptId().toString()) &&
                        (key.startsWith("Province_") ? CheckConstants.Examine_Tag_City.equals(car.getExamineTag())
                                : CheckConstants.Examine_Tag_County.equals(car.getExamineTag())))
                .findFirst();
        if (existingCar.isPresent()) {
            checkIndexCar = existingCar.get();
        } else {
            checkIndexCar = new CheckIndexCar();
            checkIndexCar.setDeptId(key.startsWith("Province_") ? Long.parseLong(key.split("_")[1]) : Long.parseLong(key));
            checkIndexCar.setExamineTag(key.startsWith("Province_") ? CheckConstants.Examine_Tag_City : CheckConstants.Examine_Tag_County);
            checkIndexCar.setCreateTime(new Date());
        }
        //调用抓拍上传及时性计算方法
        Map<String, Object> param = new HashMap<>();
        param.put("totalCount", stats.totalCount);
        param.put("delayCount1", stats.delayCount1);
        param.put("delayCount2", stats.delayCount2);
        param.put("delayCount3", stats.delayCount3);
        BigDecimal index = snapshopDelay(param);
        checkIndexCar.setSiteOnline(index);
        return checkIndexCar;
    }
}
ycl-server/src/main/java/com/ycl/calculate/FaceInFoAccuracyCalculation.java
New file
@@ -0,0 +1,132 @@
package com.ycl.calculate;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ycl.platform.domain.entity.CheckIndexFace;
import com.ycl.platform.domain.entity.TMonitor;
import com.ycl.platform.domain.result.HK.MonitoringDetailResult;
import com.ycl.platform.mapper.CheckIndexFaceMapper;
import com.ycl.platform.mapper.TMonitorMapper;
import com.ycl.platform.service.ICheckIndexFaceService;
import com.ycl.platform.service.ITMonitorService;
import com.ycl.system.mapper.SysConfigMapper;
import constant.ApiConstants;
import constant.CheckConstants;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import utils.DateUtils;
import java.math.BigDecimal;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
 * 人脸卡口信息采集准确率  设备编码、行政区划代码、安装位置、坐标经纬度信息完整准确
 * 获取分省厅、区域的map<k,v> k为deptId或者Province_deptId
 * 更新或新增
 */
@Component
public class FaceInFoAccuracyCalculation extends IndexCalculationServe implements CalculationStrategy<MonitoringDetailResult> {
    @Autowired
    private CheckIndexFaceMapper checkIndexFaceMapper;
    @Autowired
    private ICheckIndexFaceService checkIndexFaceService;
    @Autowired
    private SysConfigMapper sysConfigMapper;
    @Autowired
    private ITMonitorService monitorService;
    @Autowired
    private TMonitorMapper monitorMapper;
    //区域车辆信息采集准确率的内部类
    private static class AreaStats {
        int totalSites = 0;
        int qualifySite = 0;
    }
    @Override
    public void calculate(List<MonitoringDetailResult> list) {
        if (CollectionUtils.isEmpty(list)) {
            return;
        }
        //返回以国标码为key的设备map
        //TODO:monitor去掉了deptId
        Map<String, TMonitor> monitorMap = monitorService.list(new QueryWrapper<TMonitor>()
                        .in("serial_number", list.stream().map(MonitoringDetailResult::getExternalIndexCode).collect(Collectors.toList())))
                .stream().collect(Collectors.toMap(TMonitor::getSerialNumber, Function.identity()));
        //获取省厅国标码集合
        List<String> provinceIds = getProvince();
        Map<String, AreaStats> areaStatsMap = new HashMap<>();
        for (MonitoringDetailResult result : list) {
            TMonitor monitor = monitorMap.get(result.getExternalIndexCode());
            if (monitor == null) continue;
            String deptId = monitor.getDeptId().toString();
            updateAreaStats(areaStatsMap, deptId, result);
            // 处理省厅数据
            if (!CollectionUtils.isEmpty(provinceIds) && provinceIds.contains(monitor.getSerialNumber())) {
                String provinceKey = "Province_" + deptId;
                updateAreaStats(areaStatsMap, provinceKey, result);
            }
        }
        // 查询是否index表已经存在今日数据
        List<CheckIndexFace> checkIndexFaceList = checkIndexFaceMapper.selectToday(DateUtils.getDate());
        List<CheckIndexFace> checkIndexFaces = new ArrayList<>();
        areaStatsMap.forEach((deptId, stats) -> {
            if (stats.totalSites > 0) {
                CheckIndexFace checkIndexFace = createOrUpdateCheckIndexFace(deptId, stats, checkIndexFaceList);
                checkIndexFaces.add(checkIndexFace);
            }
        });
        checkIndexFaceService.saveOrUpdateBatch(checkIndexFaces);
    }
    /**
     * 累计总点位数、标注异常点位数
     */
    private void updateAreaStats(Map<String, AreaStats> areaStatsMap, String key, MonitoringDetailResult result) {
        //返回对象的引用,如果不存在会放入新的key,value
        AreaStats stats = areaStatsMap.computeIfAbsent(key, k -> new AreaStats());
        stats.totalSites++;
        if (ApiConstants.HK_Info_LayType_Normal.equals(result.getLalType()) && ApiConstants.HK_Info_GbCodeType_Normal.equals(result.getGbCodeType())) {
            stats.qualifySite++;
        }
    }
    /**
     * 车辆信息采集正确率
     */
    private CheckIndexFace createOrUpdateCheckIndexFace(String key, AreaStats stats, List<CheckIndexFace> checkIndexFaceList) {
        CheckIndexFace checkIndexFace;
        // 检查是否已存在今日数据
        Optional<CheckIndexFace> existingFace = checkIndexFaceList.stream()
                .filter(car -> key.equals(car.getDeptId().toString()) &&
                        (key.startsWith("Province_") ? CheckConstants.Examine_Tag_City.equals(car.getExamineTag())
                                : CheckConstants.Examine_Tag_County.equals(car.getExamineTag())))
                .findFirst();
        if (existingFace.isPresent()) {
            checkIndexFace = existingFace.get();
        } else {
            checkIndexFace = new CheckIndexFace();
            checkIndexFace.setDeptId(key.startsWith("Province_") ? Long.parseLong(key.split("_")[1]) : Long.parseLong(key));
            checkIndexFace.setExamineTag(key.startsWith("Province_") ? CheckConstants.Examine_Tag_City : CheckConstants.Examine_Tag_County);
            checkIndexFace.setCreateTime(new Date());
        }
        //调用计算方法
        Map<String, Object> siteOnlineParam = new HashMap<>();
        siteOnlineParam.put("totalSites", stats.totalSites);
        siteOnlineParam.put("qualifySite", stats.qualifySite);
        BigDecimal infoAccuracy = infoAccuracy(siteOnlineParam);
        checkIndexFace.setFaceInformationCollectionAccuracy(infoAccuracy);
        return checkIndexFace;
    }
}
ycl-server/src/main/java/com/ycl/calculate/FaceSiteOnlineCalculation.java
@@ -1,18 +1,13 @@
package com.ycl.calculate;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ycl.platform.domain.entity.CheckIndexCar;
import com.ycl.platform.domain.entity.CheckIndexFace;
import com.ycl.platform.domain.entity.TMonitor;
import com.ycl.platform.domain.result.HK.SnapshotDataMonitorResult;
import com.ycl.platform.mapper.CheckIndexCarMapper;
import com.ycl.platform.mapper.CheckIndexFaceMapper;
import com.ycl.platform.service.ICheckIndexCarService;
import com.ycl.platform.service.ICheckIndexFaceService;
import com.ycl.platform.service.ITMonitorService;
import com.ycl.platform.service.impl.CheckIndexFaceServiceImpl;
import com.ycl.system.mapper.SysConfigMapper;
import com.ycl.system.mapper.SysDeptMapper;
import constant.ApiConstants;
import constant.CheckConstants;
import constant.CheckSnapCountConstants;
@@ -35,7 +30,7 @@
 * 更新或新增
 */
@Component
public class FaceSiteOnlineCalculation implements CalculationStrategy<SnapshotDataMonitorResult> {
public class FaceSiteOnlineCalculation extends IndexCalculationServe implements CalculationStrategy<SnapshotDataMonitorResult> {
    @Autowired
    private CheckIndexFaceMapper checkIndexFaceMapper;
    @Autowired
@@ -57,14 +52,14 @@
        if (CollectionUtils.isEmpty(list)) {
            return;
        }
        Map<String, AreaStats> areaStatsMap = new HashMap<>();
        //返回以国标码为key的设备map
        Map<String, TMonitor> monitorMap = monitorService.list(new QueryWrapper<TMonitor>()
                        .in("serial_number", list.stream().map(SnapshotDataMonitorResult::getExternalIndexCode).collect(Collectors.toList())))
                .stream().collect(Collectors.toMap(TMonitor::getSerialNumber, Function.identity()));
        //获取省厅国标码集合
        List<String> provinceIds = getProvince();
        // TODO: 分省厅市局 需要补充集合数据
        List<String> provinceIds = new ArrayList<>(); // 这里需要根据点位补充
        Map<String, AreaStats> areaStatsMap = new HashMap<>();
        for (SnapshotDataMonitorResult result : list) {
            TMonitor monitor = monitorMap.get(result.getExternalIndexCode());
@@ -138,15 +133,19 @@
            checkIndexFace.setCreateTime(new Date());
        }
        // 点位在线率
        BigDecimal totalSitesBd = new BigDecimal(stats.totalSites);
        BigDecimal offlineSitesBd = new BigDecimal(stats.offlineSites);
        BigDecimal onlineSitesBd = totalSitesBd.subtract(offlineSitesBd);
        checkIndexFace.setSiteOnline(onlineSitesBd.divide(totalSitesBd, 4, RoundingMode.HALF_UP));
        //调用点位在线计算方法
        Map<String, Object> siteOnlineParam = new HashMap<>();
        siteOnlineParam.put("totalSites", stats.totalSites);
        siteOnlineParam.put("offlineSites", stats.offlineSites);
        BigDecimal siteOnline = siteOnline(siteOnlineParam);
        checkIndexFace.setSiteOnline(siteOnline);
        //视图库对接稳定性
        BigDecimal avgCount = key.startsWith("Province_") ? cityCountAvg : countyCountAvg;
        checkIndexFace.setViewConnectStability(new BigDecimal(stats.totalDataSum).divide(avgCount, 4, RoundingMode.HALF_UP));
        Map<String, Object> viewConnectParam = new HashMap<>();
        viewConnectParam.put("totalDataSum", stats.totalDataSum);
        viewConnectParam.put("avgCount", avgCount);
        BigDecimal viewConnectStability = viewConnectStability(viewConnectParam);
        checkIndexFace.setViewConnectStability(viewConnectStability);
        return checkIndexFace;
    }
}
ycl-server/src/main/java/com/ycl/calculate/FaceSnapshotDelayCalculation.java
New file
@@ -0,0 +1,136 @@
package com.ycl.calculate;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ycl.platform.domain.entity.CheckIndexFace;
import com.ycl.platform.domain.entity.TMonitor;
import com.ycl.platform.domain.result.HK.SnapshotDelayMonitorResult;
import com.ycl.platform.mapper.CheckIndexFaceMapper;
import com.ycl.platform.service.ICheckIndexFaceService;
import com.ycl.platform.service.ITMonitorService;
import com.ycl.system.mapper.SysConfigMapper;
import constant.CheckConstants;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import utils.DateUtils;
import java.math.BigDecimal;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
 * 计算人脸设备抓拍数据上传及时性
 * 获取分省厅、区域的map<k,v> k为deptId或者Province_deptId
 * 循环map计算数据上传及时性
 * 更新或新增
 */
@Component
public class FaceSnapshotDelayCalculation extends IndexCalculationServe implements CalculationStrategy<SnapshotDelayMonitorResult> {
    @Autowired
    private CheckIndexFaceMapper checkIndexFaceMapper;
    @Autowired
    private SysConfigMapper sysConfigMapper;
    @Autowired
    private ITMonitorService monitorService;
    @Autowired
    private ICheckIndexFaceService checkIndexFaceService;
    //区域车辆点位在线指标的内部类
    private static class AreaStats {
        int totalCount = 0;
        //0-180s
        int delayCount1 = 0;
        //180-300s
        int delayCount2 = 0;
        //300-600s
        int delayCount3 = 0;
    }
    @Override
    public void calculate(List<SnapshotDelayMonitorResult> list) {
        if (CollectionUtils.isEmpty(list)) {
            return;
        }
        //获得国标码为key的设备map
        Map<String, TMonitor> monitorMap = monitorService.list(new QueryWrapper<TMonitor>()
                        .in("serial_number", list.stream().map(SnapshotDelayMonitorResult::getExternalIndexCode).collect(Collectors.toList())))
                .stream().collect(Collectors.toMap(TMonitor::getSerialNumber, Function.identity()));
        //获取省厅国标码集合
        List<String> provinceIds = getProvince();
        Map<String, AreaStats> areaStatsMap = new HashMap<>();
        for (SnapshotDelayMonitorResult result : list) {
            TMonitor monitor = monitorMap.get(result.getExternalIndexCode());
            if (monitor == null) continue;
            String deptId = monitor.getDeptId().toString();
            updateAreaStats(areaStatsMap, deptId, result);
            // 处理省厅数据
            if (!CollectionUtils.isEmpty(provinceIds) && provinceIds.contains(monitor.getSerialNumber())) {
                String provinceKey = "Province_" + deptId;
                updateAreaStats(areaStatsMap, provinceKey, result);
            }
        }
        // 查询是否index表已经存在今日数据
        List<CheckIndexFace> checkIndexFaceList = checkIndexFaceMapper.selectToday(DateUtils.getDate());
        List<CheckIndexFace> checkIndexFaces = new ArrayList<>();
        areaStatsMap.forEach((deptId, stats) -> {
            if (stats.totalCount > 0) {
                CheckIndexFace checkIndexFace = createOrUpdateCheckIndexFace(deptId, stats, checkIndexFaceList);
                checkIndexFaces.add(checkIndexFace);
            }
        });
        checkIndexFaceService.saveOrUpdateBatch(checkIndexFaces);
    }
    /**
     * 累计总点位数、离线数、总抓拍量
     */
    private void updateAreaStats(Map<String, AreaStats> areaStatsMap, String key, SnapshotDelayMonitorResult result) {
        //返回对象的引用,如果不存在会放入新的key,value
        AreaStats stats = areaStatsMap.computeIfAbsent(key, k -> new AreaStats());
        stats.totalCount += result.getDataCount();
        stats.delayCount1 += result.getDataDelayCount1();
        stats.delayCount2 += result.getDataDelayCount2();
        stats.delayCount3 += result.getDataDelayCount3();
    }
    /**
     * 车辆点位在线率和视图库对接稳定性
     */
    private CheckIndexFace createOrUpdateCheckIndexFace(String key, AreaStats stats, List<CheckIndexFace> checkIndexFaceList) {
        CheckIndexFace checkIndexFace;
        // 检查是否已存在今日数据
        Optional<CheckIndexFace> existingFace = checkIndexFaceList.stream()
                .filter(face -> key.equals(face.getDeptId().toString()) &&
                        (key.startsWith("Province_") ? CheckConstants.Examine_Tag_City.equals(face.getExamineTag())
                                : CheckConstants.Examine_Tag_County.equals(face.getExamineTag())))
                .findFirst();
        if (existingFace.isPresent()) {
            checkIndexFace = existingFace.get();
        } else {
            checkIndexFace = new CheckIndexFace();
            checkIndexFace.setDeptId(key.startsWith("Province_") ? Long.parseLong(key.split("_")[1]) : Long.parseLong(key));
            checkIndexFace.setExamineTag(key.startsWith("Province_") ? CheckConstants.Examine_Tag_City : CheckConstants.Examine_Tag_County);
            checkIndexFace.setCreateTime(new Date());
        }
        //调用抓拍上传及时性计算方法
        Map<String, Object> param = new HashMap<>();
        param.put("totalCount", stats.totalCount);
        param.put("delayCount1", stats.delayCount1);
        param.put("delayCount2", stats.delayCount2);
        param.put("delayCount3", stats.delayCount3);
        BigDecimal index = snapshopDelay(param);
        checkIndexFace.setSiteOnline(index);
        return checkIndexFace;
    }
}
ycl-server/src/main/java/com/ycl/calculate/IndexCalculationServe.java
New file
@@ -0,0 +1,69 @@
package com.ycl.calculate;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ycl.platform.domain.entity.TMonitor;
import com.ycl.platform.domain.result.HK.SnapshotDataMonitorResult;
import com.ycl.platform.service.ITMonitorService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
 * 计算公式
 */
@Component
public class IndexCalculationServe {
    @Autowired
    private ITMonitorService monitorService;
    //点位在线率
    public BigDecimal siteOnline(Map<String, Object> param) {
        BigDecimal totalSites = new BigDecimal((Integer) param.get("totalSites"));
        BigDecimal offlineSites = new BigDecimal((Integer) param.get("offlineSites"));
        BigDecimal onlineSites = totalSites.subtract(offlineSites);
        return onlineSites.divide(totalSites, 4, RoundingMode.HALF_UP);
    }
    //视图库对接稳定性
    public BigDecimal viewConnectStability(Map<String, Object> param) {
        BigDecimal totalDataSum = new BigDecimal((Integer) param.get("totalDataSum"));
        BigDecimal avgCount = new BigDecimal((Integer) param.get("avgCount"));
        return avgCount.divide(totalDataSum, 4, RoundingMode.HALF_UP);
    }
    //标注正确率
    public BigDecimal infoAccuracy(Map<String, Object> param) {
        BigDecimal totalSitesCount = new BigDecimal((Integer) param.get("totalSites"));
        BigDecimal qualifySiteCount = new BigDecimal((Integer) param.get("qualifySite"));
        return qualifySiteCount.divide(totalSitesCount, 4, RoundingMode.HALF_UP);
    }
    //数据上传及时性
    public BigDecimal snapshopDelay(Map<String, Object> param) {
        BigDecimal totalCount = new BigDecimal((Integer) param.get("totalCount"));
        BigDecimal delayCount1 = new BigDecimal((Integer) param.get("delayCount1"));
        BigDecimal delayCount2 = new BigDecimal((Integer) param.get("delayCount2"));
        BigDecimal delayCount3 = new BigDecimal((Integer) param.get("delayCount3"));
        BigDecimal result = delayCount1.divide(totalCount, 10, RoundingMode.HALF_UP).multiply(BigDecimal.ONE)
                .add(delayCount2.divide(totalCount, 10, RoundingMode.HALF_UP).multiply(new BigDecimal("0.8")))
                .add(delayCount3.divide(totalCount, 10, RoundingMode.HALF_UP).multiply(new BigDecimal("0.6")));
        return result.setScale(4, RoundingMode.HALF_UP);
    }
    //返回省厅国标码集合
    public List<String> getProvince() {
        // TODO: 分省厅市局 需要补充集合数据
        List<String> list = new ArrayList<>();
        return list;
    }
}
ycl-server/src/main/java/com/ycl/calculate/IndexCalculationUtils.java
File was deleted
ycl-server/src/main/java/com/ycl/factory/IndexCalculationFactory.java
@@ -1,8 +1,6 @@
package com.ycl.factory;
import com.ycl.calculate.CalculationStrategy;
import com.ycl.calculate.CarSiteOnlineCalculation;
import com.ycl.calculate.FaceSiteOnlineCalculation;
import com.ycl.calculate.*;
import constant.CalculationStrategyConstants;
import java.util.HashMap;
@@ -12,8 +10,12 @@
    private static final Map<String, CalculationStrategy> calculators = new HashMap<>();
    static {
        calculators.put(CalculationStrategyConstants.CAR_SiteOnline_ViewStability, new CarSiteOnlineCalculation());
        calculators.put(CalculationStrategyConstants.Car_SiteOnline_ViewStability, new CarSiteOnlineCalculation());
        calculators.put(CalculationStrategyConstants.Face_SiteOnline_ViewStability, new FaceSiteOnlineCalculation());
        calculators.put(CalculationStrategyConstants.Car_InfoAccuracy, new CarInFoAccuracyCalculation());
        calculators.put(CalculationStrategyConstants.Face_InfoAccuracy, new FaceInFoAccuracyCalculation());
        calculators.put(CalculationStrategyConstants.Car_SnapshotDelay, new CarSnapshotDelayCalculation());
        calculators.put(CalculationStrategyConstants.Face_SnapshotDelay, new FaceSnapshotDelayCalculation());
    }
    public static CalculationStrategy getCalculator(String indexName) {
ycl-server/src/main/java/com/ycl/feign/UYClient.java
@@ -15,7 +15,7 @@
 */
@Component
@FeignClient(name = "UYClient", url = "${request.youYunDomain}", configuration = YYFeignConfig.class)
@FeignClient(name = "UYClient", url = "${request.youYunDomain}", configuration = UYFeignConfig.class)
public interface UYClient {
    /**
ycl-server/src/main/java/com/ycl/feign/UYFeignConfig.java
File was renamed from ycl-server/src/main/java/com/ycl/feign/YYFeignConfig.java
@@ -11,7 +11,7 @@
 * 优云接口配置
 */
@Configuration
public class YYFeignConfig {
public class UYFeignConfig {
    /**
     * 注入拦截器
     */
ycl-server/src/main/java/com/ycl/platform/mapper/TMonitorMapper.java
@@ -65,10 +65,16 @@
    /**
     * 获取视频统计
     * @param cameraFunType 类型
     * @param tMonitor 条件
     * @return 统计数
     */
    Map<String, String> getVideoCount(TMonitor tMonitor);
    Map<String, String> recoveryException();
    Map<String, String> recoveryException(String time);
    /**
     * 获取恢复异常持续关注设备
     * @return 设备
     */
    List<TMonitorVO> selectRecoveryMonitor(String time);
}
ycl-server/src/main/java/com/ycl/platform/service/ITMonitorService.java
@@ -66,7 +66,7 @@
    /**
     * 获取指定摄像头功能类型下的视频数量。
     *
     * @param cameraFunType 摄像头功能类型,用于筛选视频。
     * @param tMonitor 条件
     * @return 返回一个包含视频数量的Map对象,其中key为统计指标,value为对应功能类型下的统计数量。
     */
    Map<String, String> getVideoCount(TMonitor tMonitor);
ycl-server/src/main/java/com/ycl/platform/service/YwPointService.java
@@ -85,4 +85,13 @@
     * @return
     */
    Result select(String keyword);
    /**
     * 批量同步状态
     *
     * @param pointIds 点位id
     * @param recovery  状态
     * @return 数量
     */
    boolean updateRecovery(List<Integer> pointIds, int recovery);
}
ycl-server/src/main/java/com/ycl/platform/service/impl/CalculateReportServiceImpl.java
@@ -204,7 +204,7 @@
        CalculateExport calculateExport = new CalculateExport();
        calculateExport.setRuleName("合计");
        calculateExport.setNum(list.stream().mapToInt(CalculateExport::getNum).sum());
        calculateExport.setScore(list.stream().mapToInt(CalculateExport::getScore).sum());
        calculateExport.setScore(100 + list.stream().mapToInt(CalculateExport::getScore).sum());
        list.add(calculateExport);
        // 输出文件
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
ycl-server/src/main/java/com/ycl/platform/service/impl/CheckIndexCarServiceImpl.java
@@ -1,7 +1,6 @@
package com.ycl.platform.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ycl.calculate.IndexCalculationUtils;
import com.ycl.platform.domain.entity.CheckIndexCar;
import com.ycl.platform.mapper.CheckIndexCarMapper;
import com.ycl.platform.service.ICheckIndexCarService;
ycl-server/src/main/java/com/ycl/platform/service/impl/TMonitorServiceImpl.java
@@ -6,11 +6,14 @@
import com.ycl.platform.domain.vo.TMonitorVO;
import com.ycl.platform.mapper.TMonitorMapper;
import com.ycl.platform.service.ITMonitorService;
import com.ycl.system.service.ISysConfigService;
import com.ycl.utils.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map;
import java.util.Objects;
/**
 * 设备资产Service业务层处理
@@ -23,6 +26,8 @@
{
    @Autowired
    private TMonitorMapper tMonitorMapper;
    @Autowired
    private ISysConfigService configService;
    /**
     * 查询设备资产
@@ -46,7 +51,16 @@
    @DataScope(deptAlias = "d",userAlias = "u")
    public List<TMonitorVO> selectTMonitorList(TMonitor tMonitor)
    {
        return tMonitorMapper.selectTMonitorList(tMonitor);
        List<TMonitorVO> monitors = tMonitorMapper.selectTMonitorList(tMonitor);
        if (Objects.equals(tMonitor.getRecovery(), 1)) {
            String time = configService.selectConfigByKey("abnormal.equipment.continuous.attention.time");
            if (StringUtils.isBlank(time)) {
                throw new RuntimeException("请配置异常设备连续关注时间");
            }
            List<TMonitorVO> recoveryMonitors = tMonitorMapper.selectRecoveryMonitor(time);
            monitors.addAll(recoveryMonitors);
        }
        return monitors;
    }
    /**
@@ -105,6 +119,7 @@
    @Override
    public Map<String, String> recoveryException() {
        return tMonitorMapper.recoveryException();
        String time = configService.selectConfigByKey("abnormal.equipment.continuous.attention.time");
        return tMonitorMapper.recoveryException(time);
    }
}
ycl-server/src/main/java/com/ycl/platform/service/impl/WorkOrderServiceImpl.java
@@ -19,6 +19,7 @@
import com.ycl.platform.service.NotifyService;
import com.ycl.platform.service.WorkOrderAuditingRecordService;
import com.ycl.platform.service.WorkOrderService;
import com.ycl.platform.service.YwPointService;
import com.ycl.system.Result;
import com.ycl.system.model.LoginUser;
import com.ycl.system.page.PageUtil;
@@ -26,6 +27,10 @@
import com.ycl.utils.SecurityUtils;
import com.ycl.utils.redis.RedisCache;
import com.ycl.utils.uuid.IdUtils;
import enumeration.general.NotifyTypeEnum;
import enumeration.general.UrgentLevelEnum;
import enumeration.general.WorkOrderDistributeWayEnum;
import enumeration.general.WorkOrderStatusEnum;
import enumeration.general.*;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
@@ -40,6 +45,7 @@
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.*;
import java.util.stream.Collectors;
/**
@@ -53,8 +59,7 @@
public class WorkOrderServiceImpl extends ServiceImpl<WorkOrderMapper, WorkOrder> implements WorkOrderService {
    private final WorkOrderMapper workOrderMapper;
    private final YwUnitMapper ywUnitMapper;
    private final YwPeopleMapper ywPeopleMapper;
    private final YwPointService ywPointService;
    private final WorkOrderAuditingRecordMapper workOrderAuditingRecordMapper;
    private final WorkOrderAuditingRecordService workOrderAuditingRecordService;
    private final WorkOrderYwConditionRecordMapper workOrderYwConditionRecordMapper;
@@ -124,6 +129,10 @@
                UrgentLevelEnum.WARNING,
                workOrder.getWorkOrderNo());
        notifyService.save(notify);
        // 同步点位状态
        if (form.getAuditingResult() == WorkOrderStatusEnum.AUDITING_SUCCESS) {
            ywPointService.updateRecovery(Collections.singletonList(workOrder.getPointId()), 0);
        }
        return Result.ok("操作成功");
    }
@@ -267,53 +276,49 @@
    }
    @Override
    @Transactional
    public Result distributeFast(DistributeWorkOrderVO data) {
        // 获取当前时间
        LocalDateTime now = LocalDateTime.now(ZoneId.systemDefault());
        data.setEnd(now);
        switch (data.getFastWay()) {
            case LAST_HALF_HOUR:
                data.setStart(now.minusMinutes(30));
                data.setEnd(now);
                break;
            case LAST_HOUR:
                data.setStart(now.minusHours(1));
                data.setEnd(now);
                break;
            case LAST_TWO_HOUR:
               data.setStart(now.minusHours(2));
               data.setEnd(now);
               break;
            case LAST_DAY:
                data.setStart(now.minusDays(1));
                data.setEnd(now);
                break;
           }
        // 查询符合条件的工单
        List<Integer> ids = new LambdaQueryChainWrapper<>(baseMapper)
        List<WorkOrder> list = new LambdaQueryChainWrapper<>(baseMapper)
                .select(WorkOrder::getId, WorkOrder::getPointId)
                .eq(WorkOrder::getStatus, WorkOrderStatusEnum.WAIT_DISTRIBUTE)
                .eq(Objects.nonNull(data.getUnitId()), WorkOrder::getUnitId, data.getUnitId())
                .eq(WorkOrder::getErrorType, data.getErrorType())
                .between(WorkOrder::getCreateTime, data.getStart(), data.getEnd())
                .orderByDesc(WorkOrder::getCreateTime)
                .last("limit " + data.getFastNumLimit())
                .list()
                .stream()
                .map(WorkOrder::getId)
                .toList();
                .list();
        List<Integer> ids = list.stream().map(WorkOrder::getId).toList();
        List<Integer> pointIds = list.stream().map(WorkOrder::getPointId).toList();
        if (ids.isEmpty()) {
            return Result.error("没有符合条件的工单");
        }
        if (!getDistributeLock()) {
            return Result.error("此刻有人下发中,为避免冲突,请稍后重试");
        }
        if (ids.isEmpty()) { return Result.error("没有符合条件的工单"); }
        if (!getDistributeLock()) { return Result.error("此刻有人下发中,为避免冲突,请稍后重试"); }
        try {
            new LambdaUpdateChainWrapper<>(baseMapper)
                    .set(WorkOrder::getStatus, WorkOrderStatusEnum.DISTRIBUTED)
                    .in(WorkOrder::getId, ids)
                    .update();
            addDistributeRecord(ids, WorkOrderDistributeWayEnum.FAST_DISTRIBUTE);
            // 同步点位状态
            ywPointService.updateRecovery(pointIds, 1);
            return Result.ok("成功下发" + ids.size() + "条工单");
        } catch (Exception e) {
            return Result.error("操作失败");
@@ -323,11 +328,10 @@
    }
    @Override
    @Transactional
    public Result selectedIdsDistribute(DistributeWorkOrderQuery query) {
        WorkOrderDistributeWayEnum distributeWayEnum = WorkOrderDistributeWayEnum.SELECTED_DISTRIBUTE;
        if (!getDistributeLock()) {
            return Result.error("此刻有人下发中,为避免冲突,请稍后重试");
        }
        if (!getDistributeLock()) { return Result.error("此刻有人下发中,为避免冲突,请稍后重试"); }
        try {
            if (query.getIds().isEmpty()) {
                query.setIds(new LambdaQueryChainWrapper<>(baseMapper)
@@ -340,14 +344,15 @@
                        .collect(Collectors.toList()));
                distributeWayEnum = WorkOrderDistributeWayEnum.ALL_DISTRIBUTE;
            }
            if (query.getIds().isEmpty()) {
                return Result.error("没有工单待下发");
            }
            if (query.getIds().isEmpty()) { return Result.error("没有工单待下发"); }
            new LambdaUpdateChainWrapper<>(baseMapper)
                    .set(WorkOrder::getStatus, WorkOrderStatusEnum.DISTRIBUTED)
                    .in(WorkOrder::getId, query.getIds())
                    .update();
            addDistributeRecord(query.getIds(), distributeWayEnum);
            // 同步点位状态
            List<Integer> pointIds = new LambdaQueryChainWrapper<>(baseMapper).select(WorkOrder::getPointId).in(WorkOrder::getId, query.getIds()).list().stream().map(WorkOrder::getPointId).toList();
            ywPointService.updateRecovery(pointIds, 1);
            return Result.ok("成功下发" + query.getIds().size() + "条工单");
        } catch (Exception e) {
            return Result.error("操作失败");
ycl-server/src/main/java/com/ycl/platform/service/impl/YwPointServiceImpl.java
@@ -1,43 +1,35 @@
package com.ycl.platform.service.impl;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ycl.platform.base.BaseSelect;
import com.ycl.platform.domain.entity.Region;
import com.ycl.platform.domain.entity.YwPeople;
import com.ycl.platform.domain.entity.YwPoint;
import com.ycl.platform.domain.entity.YwUnit;
import com.ycl.platform.domain.form.BatchEditPointForm;
import com.ycl.platform.mapper.RegionMapper;
import com.ycl.platform.domain.form.YwPointForm;
import com.ycl.platform.domain.query.YwPointQuery;
import com.ycl.platform.domain.vo.YwPointVO;
import com.ycl.platform.mapper.YwPeopleMapper;
import com.ycl.platform.mapper.YwPointMapper;
import com.ycl.platform.mapper.YwUnitMapper;
import com.ycl.platform.service.YwPointService;
import com.ycl.platform.service.YwUnitService;
import com.ycl.system.Result;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ycl.platform.domain.form.YwPointForm;
import com.ycl.platform.domain.vo.YwPointVO;
import com.ycl.platform.domain.query.YwPointQuery;
import java.util.List;
import com.ycl.system.entity.SysUser;
import com.ycl.system.mapper.SysDeptMapper;
import com.ycl.system.service.ISysDeptService;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.ycl.system.page.PageUtil;
import com.ycl.utils.DateUtils;
import com.ycl.utils.SecurityUtils;
import enumeration.general.RegionLevelEnum;
import org.springframework.stereotype.Service;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import java.util.ArrayList;
import org.springframework.util.StringUtils;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import lombok.RequiredArgsConstructor;
import org.springframework.util.StringUtils;
/**
 * 运维点位 服务实现类
@@ -214,4 +206,13 @@
        }).collect(Collectors.toList());
        return Result.ok().data(data);
    }
    @Override
    public boolean updateRecovery(List<Integer> pointIds, int recovery) {
        return new LambdaUpdateChainWrapper<>(baseMapper)
                .in(YwPoint::getId, pointIds)
                .set(YwPoint::getRecovery, recovery)
                .set(recovery == 0, YwPoint::getRecoveryTime, DateUtils.getNowDate())
                .update();
    }
}
ycl-server/src/main/java/com/ycl/task/CarTask.java
@@ -3,7 +3,9 @@
import com.ycl.calculate.CalculationStrategy;
import com.ycl.factory.IndexCalculationFactory;
import com.ycl.platform.domain.result.HK.CrossDetailResult;
import com.ycl.platform.domain.result.HK.SnapshotDataMonitorResult;
import com.ycl.platform.domain.result.HK.SnapshotDelayMonitorResult;
import com.ycl.utils.DateUtils;
import constant.ApiConstants;
import constant.CalculationStrategyConstants;
@@ -33,10 +35,31 @@
        Query query = new Query();
        query.addCriteria(Criteria
                .where("mongoCreateTime").gte(DateUtils.getDayStart(yesterday)).lt(DateUtils.getDayEnd(yesterday))
                .and("dataType").is(ApiConstants.HK_DATATYPE_CAR));
        List<SnapshotDataMonitorResult> snapshotDataMonitorResults = mongoTemplate.find(query, SnapshotDataMonitorResult.class);
        CalculationStrategy<SnapshotDataMonitorResult> siteOnlineCalculator = IndexCalculationFactory.getCalculator(CalculationStrategyConstants.CAR_SiteOnline_ViewStability);
        siteOnlineCalculator.calculate(snapshotDataMonitorResults);
                .and("dataType").is(ApiConstants.HK_DataType_CAR));
        List<SnapshotDataMonitorResult> results = mongoTemplate.find(query, SnapshotDataMonitorResult.class);
        CalculationStrategy<SnapshotDataMonitorResult> calculator = IndexCalculationFactory.getCalculator(CalculationStrategyConstants.Car_SiteOnline_ViewStability);
        calculator.calculate(results);
    }
    public void infoAccuracyTask(){
        Date yesterday = DateUtils.addDays(new Date(), -1);
        //计算车辆卡口信息采集准确率
        Query query = new Query();
        query.addCriteria(Criteria
                .where("mongoCreateTime").gte(DateUtils.getDayStart(yesterday)).lt(DateUtils.getDayEnd(yesterday)));
        List<CrossDetailResult> results = mongoTemplate.find(query, CrossDetailResult.class);
        CalculationStrategy calculator = IndexCalculationFactory.getCalculator(CalculationStrategyConstants.Car_InfoAccuracy);
        calculator.calculate(results);
    }
    public void snapShopDelay(){
        Date yesterday = DateUtils.addDays(new Date(), -1);
        //计算车辆卡口信息采集准确率
        Query query = new Query();
        query.addCriteria(Criteria
                .where("mongoCreateTime").gte(DateUtils.getDayStart(yesterday)).lt(DateUtils.getDayEnd(yesterday))
                .and("dataType").is(ApiConstants.HK_DataType_CAR));
        List<SnapshotDelayMonitorResult> results = mongoTemplate.find(query, SnapshotDelayMonitorResult.class);
        CalculationStrategy calculator = IndexCalculationFactory.getCalculator(CalculationStrategyConstants.Car_SnapshotDelay);
        calculator.calculate(results);
    }
ycl-server/src/main/java/com/ycl/task/FaceTask.java
@@ -3,7 +3,10 @@
import com.ycl.calculate.CalculationStrategy;
import com.ycl.factory.IndexCalculationFactory;
import com.ycl.platform.domain.result.HK.CrossDetailResult;
import com.ycl.platform.domain.result.HK.MonitoringDetailResult;
import com.ycl.platform.domain.result.HK.SnapshotDataMonitorResult;
import com.ycl.platform.domain.result.HK.SnapshotDelayMonitorResult;
import com.ycl.utils.DateUtils;
import constant.ApiConstants;
import constant.CalculationStrategyConstants;
@@ -33,10 +36,30 @@
        Query query = new Query();
        query.addCriteria(Criteria
                .where("mongoCreateTime").gte(DateUtils.getDayStart(yesterday)).lt(DateUtils.getDayEnd(yesterday))
                .and("dataType").is(ApiConstants.HK_DATATYPE_FACE));
        List<SnapshotDataMonitorResult> snapshotDataMonitorResults = mongoTemplate.find(query, SnapshotDataMonitorResult.class);
        CalculationStrategy<SnapshotDataMonitorResult> siteOnlineCalculator = IndexCalculationFactory.getCalculator(CalculationStrategyConstants.Face_SiteOnline_ViewStability);
        siteOnlineCalculator.calculate(snapshotDataMonitorResults);
                .and("dataType").is(ApiConstants.HK_DataType_FACE));
        List<SnapshotDataMonitorResult> results = mongoTemplate.find(query, SnapshotDataMonitorResult.class);
        CalculationStrategy calculator = IndexCalculationFactory.getCalculator(CalculationStrategyConstants.Face_SiteOnline_ViewStability);
        calculator.calculate(results);
    }
    public void InfoAccuracyTask(){
        Date yesterday = DateUtils.addDays(new Date(), -1);
        //计算车辆卡口信息采集准确率
        Query query = new Query();
        query.addCriteria(Criteria
                .where("mongoCreateTime").gte(DateUtils.getDayStart(yesterday)).lt(DateUtils.getDayEnd(yesterday)));
        List<MonitoringDetailResult> results = mongoTemplate.find(query, MonitoringDetailResult.class);
        CalculationStrategy calculator = IndexCalculationFactory.getCalculator(CalculationStrategyConstants.Face_InfoAccuracy);
        calculator.calculate(results);
    }
    public void snapShopDelay(){
        Date yesterday = DateUtils.addDays(new Date(), -1);
        //计算车辆卡口信息采集准确率
        Query query = new Query();
        query.addCriteria(Criteria
                .where("mongoCreateTime").gte(DateUtils.getDayStart(yesterday)).lt(DateUtils.getDayEnd(yesterday))
                .and("dataType").is(ApiConstants.HK_DataType_FACE));
        List<SnapshotDelayMonitorResult> results = mongoTemplate.find(query, SnapshotDelayMonitorResult.class);
        CalculationStrategy calculator = IndexCalculationFactory.getCalculator(CalculationStrategyConstants.Face_SnapshotDelay);
        calculator.calculate(results);
    }
}
ycl-server/src/main/java/com/ycl/task/HKTask.java
@@ -86,33 +86,33 @@
        log.info("开始执行抓拍数据量检测结果数据同步");
        /** 车辆数据 */
        SnapshotDataMonitorParam carParam = new SnapshotDataMonitorParam();
        carParam.setPageNO(ApiConstants.pageNo).setPageSize(ApiConstants.pageSize).setDate(DateUtils.getDate()).setDataType(ApiConstants.HK_DATATYPE_CAR);
        carParam.setPageNO(ApiConstants.pageNo).setPageSize(ApiConstants.pageSize).setDate(DateUtils.getDate()).setDataType(ApiConstants.HK_DataType_CAR);
        JSONObject carJsonObject = hkClient.SnapshotDataMonitor(carParam);
        List<SnapshotDataMonitorResult> carList = getDataList(carJsonObject, SnapshotDataMonitorResult.class, "车辆抓拍数据量检测结果数据");
        if (!CollectionUtils.isEmpty(carList)) {
            //如果今天存在之前的数据先删除
            Query query = new Query(Criteria
                    .where("mongoCreateTime").gte(DateUtils.getDayStart(new Date())).lt(DateUtils.getDayEnd(new Date()))
                    .and("dataType").is(ApiConstants.HK_DATATYPE_CAR));
                    .and("dataType").is(ApiConstants.HK_DataType_CAR));
            DeleteResult result = mongoTemplate.remove(query, SnapshotDataMonitorResult.class);
            //存放在mongo中
            carList.forEach(item -> item.setDataType(ApiConstants.HK_DATATYPE_CAR));
            carList.forEach(item -> item.setDataType(ApiConstants.HK_DataType_CAR));
            mongoTemplate.insert(carList);
        }
        /** 人脸数据 */
        SnapshotDataMonitorParam faceParam = new SnapshotDataMonitorParam();
        faceParam.setPageNO(ApiConstants.pageNo).setPageSize(ApiConstants.pageSize).setDate(DateUtils.getDate()).setDataType(ApiConstants.HK_DATATYPE_FACE);
        faceParam.setPageNO(ApiConstants.pageNo).setPageSize(ApiConstants.pageSize).setDate(DateUtils.getDate()).setDataType(ApiConstants.HK_DataType_FACE);
        JSONObject faceJsonObject = hkClient.SnapshotDataMonitor(carParam);
        List<SnapshotDataMonitorResult> faceList = getDataList(faceJsonObject, SnapshotDataMonitorResult.class, "人脸抓拍数据量检测结果数据为空");
        if (!CollectionUtils.isEmpty(faceList)) {
            //如果今天存在之前的数据先删除
            Query query = new Query(Criteria
                    .where("mongoCreateTime").gte(DateUtils.getDayStart(new Date())).lt(DateUtils.getDayEnd(new Date()))
                    .and("dataType").is(ApiConstants.HK_DATATYPE_FACE));
                    .and("dataType").is(ApiConstants.HK_DataType_FACE));
            DeleteResult result = mongoTemplate.remove(query, SnapshotDataMonitorResult.class);
            //存放在mongo中
            carList.forEach(item -> item.setDataType(ApiConstants.HK_DATATYPE_FACE));
            carList.forEach(item -> item.setDataType(ApiConstants.HK_DataType_FACE));
            mongoTemplate.insert(faceList);
        }
        //TODO:工单
@@ -164,7 +164,7 @@
        log.info("开始执行数据完整性监测结果数据同步");
        //车辆卡口设备抓拍数据完整性
        DataIntegrityMonitoringParam param = new DataIntegrityMonitoringParam();
        param.setPageNO(ApiConstants.pageNo).setPageSize(ApiConstants.pageSize).setDate(DateUtils.getDate()).setDataType(ApiConstants.HK_DATATYPE_CAR);
        param.setPageNO(ApiConstants.pageNo).setPageSize(ApiConstants.pageSize).setDate(DateUtils.getDate()).setDataType(ApiConstants.HK_DataType_CAR);
        JSONObject jsonObject = hkClient.DataIntegrityMonitoring(param);
        List<DataIntegrityMonitoringResult> faceList = getDataList(jsonObject, DataIntegrityMonitoringResult.class, "数据完整性监测结果数据为空");
        if (!CollectionUtils.isEmpty(faceList)) {
@@ -184,7 +184,7 @@
        log.info("开始执行属性识别准确监测结果数据同步");
        //车辆卡口设备抓拍数据准确性
        AttrRecognitionParam param = new AttrRecognitionParam();
        param.setPageNO(ApiConstants.pageNo).setPageSize(ApiConstants.pageSize).setDate(DateUtils.getDate()).setDataType(ApiConstants.HK_DATATYPE_CAR);
        param.setPageNO(ApiConstants.pageNo).setPageSize(ApiConstants.pageSize).setDate(DateUtils.getDate()).setDataType(ApiConstants.HK_DataType_CAR);
        JSONObject jsonObject = hkClient.AttrRecognitionMonitor(param);
        List<AttrRecognitionMonitorResult> faceList = getDataList(jsonObject, AttrRecognitionMonitorResult.class, "属性识别准确监测结果数据为空");
        if (!CollectionUtils.isEmpty(faceList)) {
@@ -206,33 +206,33 @@
        //车辆卡口设备抓拍数据上传及时性
        /** 车辆数据 */
        SnapshotDelayMonitorParam carParam = new SnapshotDelayMonitorParam();
        carParam.setPageNO(ApiConstants.pageNo).setPageSize(ApiConstants.pageSize).setDate(DateUtils.getDate()).setDataType(ApiConstants.HK_DATATYPE_CAR);
        carParam.setPageNO(ApiConstants.pageNo).setPageSize(ApiConstants.pageSize).setDate(DateUtils.getDate()).setDataType(ApiConstants.HK_DataType_CAR);
        JSONObject carJsonObject = hkClient.SnapshotDelayMonitor(carParam);
        List<SnapshotDelayMonitorResult> carList = getDataList(carJsonObject, SnapshotDelayMonitorResult.class, "车辆抓拍数据量检测结果数据");
        if (!CollectionUtils.isEmpty(carList)) {
            //如果今天存在之前的数据先删除
            Query query = new Query(Criteria
                    .where("mongoCreateTime").gte(DateUtils.getDayStart(new Date())).lt(DateUtils.getDayEnd(new Date()))
                    .and("dataType").is(ApiConstants.HK_DATATYPE_CAR));
                    .and("dataType").is(ApiConstants.HK_DataType_CAR));
            DeleteResult result = mongoTemplate.remove(query, SnapshotDelayMonitorParam.class);
            //存放在mongo中
            carList.forEach(item -> item.setDataType(ApiConstants.HK_DATATYPE_CAR));
            carList.forEach(item -> item.setDataType(ApiConstants.HK_DataType_CAR));
            mongoTemplate.insert(carList);
        }
        /** 人脸数据 */
        SnapshotDelayMonitorParam faceParam = new SnapshotDelayMonitorParam();
        faceParam.setPageNO(ApiConstants.pageNo).setPageSize(ApiConstants.pageSize).setDate(DateUtils.getDate()).setDataType(ApiConstants.HK_DATATYPE_FACE);
        faceParam.setPageNO(ApiConstants.pageNo).setPageSize(ApiConstants.pageSize).setDate(DateUtils.getDate()).setDataType(ApiConstants.HK_DataType_FACE);
        JSONObject faceJsonObject = hkClient.SnapshotDelayMonitor(faceParam);
        List<SnapshotDelayMonitorParam> faceList = getDataList(faceJsonObject, SnapshotDelayMonitorParam.class, "人脸抓拍数据量检测结果数据为空");
        if (!CollectionUtils.isEmpty(faceList)) {
            //如果今天存在之前的数据先删除
            Query query = new Query(Criteria
                    .where("mongoCreateTime").gte(DateUtils.getDayStart(new Date())).lt(DateUtils.getDayEnd(new Date()))
                    .and("dataType").is(ApiConstants.HK_DATATYPE_FACE));
                    .and("dataType").is(ApiConstants.HK_DataType_FACE));
            DeleteResult result = mongoTemplate.remove(query, SnapshotDelayMonitorParam.class);
            //存放在mongo中
            carList.forEach(item -> item.setDataType(ApiConstants.HK_DATATYPE_FACE));
            carList.forEach(item -> item.setDataType(ApiConstants.HK_DataType_FACE));
            mongoTemplate.insert(faceList);
        }
        //TODO:工单
@@ -244,7 +244,7 @@
        log.info("开始执行图片访问监测结果数据同步");
        //车辆卡口信息采集准确率、车辆卡口设备url可用性
        PicAccessParam param = new PicAccessParam();
        param.setPageNO(ApiConstants.pageNo).setPageSize(ApiConstants.pageSize).setDate(DateUtils.getDate()).setDataType(ApiConstants.HK_DATATYPE_CAR);
        param.setPageNO(ApiConstants.pageNo).setPageSize(ApiConstants.pageSize).setDate(DateUtils.getDate()).setDataType(ApiConstants.HK_DataType_CAR);
        JSONObject jsonObject = hkClient.PicAccessMonitor(param);
        List<PicAccessResult> faceList = getDataList(jsonObject, PicAccessResult.class, "图片访问监测结果数据为空");
        if (!CollectionUtils.isEmpty(faceList)) {
ycl-server/src/main/java/com/ycl/task/MonitorTask.java
New file
@@ -0,0 +1,88 @@
package com.ycl.task;
import com.alibaba.druid.support.json.JSONUtils;
import com.alibaba.fastjson2.JSONArray;
import com.ycl.platform.domain.entity.TMonitor;
import com.ycl.platform.domain.result.UY.OneMachineFileResult;
import com.ycl.platform.domain.vo.TMonitorVO;
import com.ycl.platform.service.ITMonitorService;
import com.ycl.system.entity.SysDictData;
import com.ycl.system.service.ISysDictDataService;
import com.ycl.utils.DateUtils;
import constant.RedisConstant;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
 * 当天晚上 同步mongodb一机一档到数据库
 */
@Slf4j
@Component("monitorTask")
public class MonitorTask {
    @Autowired
    private MongoTemplate mongoTemplate;
    @Autowired
    private ITMonitorService monitorService;
    @Autowired
    private ISysDictDataService dictDataService;
    @Autowired
    private RedisTemplate redisTemplate;
    //同步mongodb一机一档到数据库
    public void synchronize() {
        Query query = new Query(Criteria.where("mongoCreateTime").gte(DateUtils.getDayStart(new Date())).lt(DateUtils.getDayEnd(new Date())));
        List<OneMachineFileResult> oneMachineFileResults = mongoTemplate.find(query, OneMachineFileResult.class);
        List<String> serialNumberInBase = monitorService.selectTMonitorList(null).stream().map(TMonitorVO::getSerialNumber).collect(Collectors.toList());
        //准备插入数据库的数据
        List<TMonitor> monitorList = new ArrayList<>();
        //新的数据,原数据库中不存在的数据
        Set<TMonitor> newMonitorList = new HashSet<>();
        for (OneMachineFileResult result : oneMachineFileResults) {
            TMonitor monitor = setMonitor(result);
            monitorList.add(monitor);
            //比对筛选出新的数据
            if(!CollectionUtils.isEmpty(serialNumberInBase) && !serialNumberInBase.contains(result.getSBBM())){
                newMonitorList.add(monitor);
            }
        }
        //新的数据放入Redis中等待考核指标任务使用
        redisTemplate.opsForValue().set(RedisConstant.New_Monitor_Set, JSONArray.toJSONString(newMonitorList));
        //TODO:解析区域
        //TODO:解析重点点位
        //重点点位集合字典
        SysDictData sysDictData = new SysDictData();
        sysDictData.setDictType("platform_important_site");
        List<SysDictData> DictDataList = dictDataService.selectDictDataList(sysDictData);
        List<String> importantSite = DictDataList.stream().map(SysDictData::getDictValue).collect(Collectors.toList());
    }
    private TMonitor setMonitor(OneMachineFileResult result) {
        TMonitor monitor = new TMonitor();
        monitor.setSerialNumber(result.getSBBM());
        monitor.setName(result.getSBMC());
        monitor.setSiteType(Long.valueOf(result.getJKDWLX()));
        monitor.setMacAddr(result.getMACDZ());
        monitor.setIp(result.getIP());
        monitor.setCameraFunType(result.getSXJGNLX());
        monitor.setLongitude(result.getJD() + "");
        monitor.setLatitude(result.getWD() + "");
        monitor.setCameraCaptureArea(result.getSXJCJQY());
        monitor.setOnState(Long.valueOf(result.getSBZT()));
        //国标码前八位为行政编码
        monitor.setCivilCode(result.getSBBM().substring(0, 8));
        return monitor;
    }
}
ycl-server/src/main/java/com/ycl/task/UYTask.java
@@ -9,6 +9,7 @@
import com.ycl.platform.domain.result.UY.OneMachineFileResult;
import com.ycl.platform.domain.result.UY.QueryVqdResult;
import com.ycl.platform.domain.result.UY.RecordMetaDSumResult;
import com.ycl.platform.service.ITMonitorService;
import com.ycl.platform.service.IYwThresholdService;
import com.ycl.utils.DateUtils;
import constant.ApiConstants;
@@ -23,6 +24,7 @@
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
//优云对接数据任务
@Slf4j
@@ -35,7 +37,8 @@
    private UYClient uyClient;
    @Autowired
    private IYwThresholdService ywThresholdService;
    @Autowired
    private ITMonitorService monitorService;
    @Value("${youYun.tenantId}")
    private String tenantId;
ycl-server/src/main/resources/mapper/zgyw/CheckScoreMapper.xml
@@ -123,21 +123,17 @@
    <select id="selectCheckScoreMap" resultType="com.ycl.platform.domain.entity.CheckScore">
        SELECT
            id,
            tcs.dept_id,
            examine_category,
            ROUND(AVG(score), 2) AS score,
            #{startDate} AS startDate,
            #{endDate} AS endDate,
            ANY_VALUE(tcs.create_time) AS createTime
            ROUND(AVG(score) OVER(PARTITION BY tcs.dept_id, examine_category), 2) AS score,
            tcs.create_time AS createTime
        FROM
            t_check_score tcs
                LEFT JOIN sys_dept d ON tcs.dept_id = d.dept_id
        WHERE
            examine_tag = #{examineTag}
          AND tcs.create_time BETWEEN #{startDate} AND #{endDate}
        GROUP BY
            tcs.dept_id,
            examine_category
          AND DATE_FORMAT(tcs.create_time, '%Y-%m') BETWEEN DATE_FORMAT(#{startDate}, '%Y-%m') AND DATE_FORMAT(#{endDate}, '%Y-%m')
    </select>
</mapper>
ycl-server/src/main/resources/mapper/zgyw/TMonitorMapper.xml
@@ -37,22 +37,22 @@
        <result property="hybm"    column="hybm"    />
        <result property="lxbm"    column="lxbm"    />
        <result property="reason"    column="reason"    />
        <result property="defaultOrder"    column="default_order"    />
        <result property="recovery"    column="recovery"    />
        <result property="recoveryTime"    column="recovery_time"    />
        <result property="deptId"    column="dept_id"    />
    </resultMap>
    <sql id="selectTMonitorVo">
        select id, serial_number, name, site_type, mac_addr, ip, camera_fun_type, longitude, latitude, camera_capture_area, on_state, civil_code, integrated_device, camera_brand, address, net_working, public_security, installed_time, management_unit, mu_contact_info, storage_days, monitor_azimuth, scene_photo_addr, model, site_vulgo, camera_type, camera_light_type, encoded_format, camera_dept, hybm, lxbm, reason, default_order,recovery,recovery_time,dept_id from t_monitor
        select id, serial_number, name, site_type, mac_addr, ip, camera_fun_type, longitude, latitude, camera_capture_area, on_state, civil_code, integrated_device, camera_brand, address, net_working, public_security, installed_time, management_unit, mu_contact_info, storage_days, monitor_azimuth, scene_photo_addr, model, site_vulgo, camera_type, camera_light_type, encoded_format, camera_dept, hybm, lxbm from t_monitor
    </sql>
    <select id="selectTMonitorList" resultType="com.ycl.platform.domain.vo.TMonitorVO">
        select id, serial_number, name, site_type, mac_addr, ip, camera_fun_type, longitude, latitude, camera_capture_area, on_state, civil_code, integrated_device, camera_brand, address, net_working, public_security, installed_time, management_unit, mu_contact_info, storage_days
        , monitor_azimuth, scene_photo_addr, model, site_vulgo, camera_type, camera_light_type, encoded_format, camera_dept, hybm, lxbm, reason, default_order,recovery,recovery_time,d.dept_name from t_monitor m
        left join sys_dept d on m.dept_id = d.dept_id
        select m.id, m.serial_number, name, site_type, mac_addr, ip, camera_fun_type, longitude, latitude, camera_capture_area, on_state, civil_code, integrated_device, camera_brand, address, net_working, public_security, installed_time, management_unit, mu_contact_info, storage_days
        , monitor_azimuth, scene_photo_addr, model, site_vulgo, camera_type, camera_light_type, encoded_format, camera_dept, hybm, lxbm, d.dept_name from t_monitor m
        left join t_yw_point p on m.serial_number = p.serial_number
        left join sys_dept d on p.dept_id = d.dept_id
        <where>
            <if test="serialNumber != null  and serialNumber != ''"> and serial_number = #{serialNumber}</if>
            <if test="serialNumber != null  and serialNumber != ''"> and m.serial_number = #{serialNumber}</if>
            <if test="name != null  and name != ''"> and name like concat('%', #{name}, '%')</if>
            <if test="siteType != null "> and site_type = #{siteType}</if>
            <if test="macAddr != null  and macAddr != ''"> and mac_addr = #{macAddr}</if>
@@ -82,11 +82,7 @@
            <if test="cameraDept != null  and cameraDept != ''"> and camera_dept = #{cameraDept}</if>
            <if test="hybm != null  and hybm != ''"> and hybm = #{hybm}</if>
            <if test="lxbm != null "> and lxbm = #{lxbm}</if>
            <if test="reason != null  and reason != ''"> and reason = #{reason}</if>
            <if test="defaultOrder != null "> and default_order = #{defaultOrder}</if>
            <if test="recovery != null "> and recovery = #{recovery}</if>
            <if test="recoveryTime != null "> and recovery_time = #{recoveryTime}</if>
            <if test="deptId != null "> and m.dept_id = #{deptId}</if>
            <if test="recovery != null "> and p.recovery = #{recovery}</if>
        </where>
        ${params.dataScope}
    </select>
@@ -129,11 +125,6 @@
            <if test="cameraDept != null">camera_dept,</if>
            <if test="hybm != null">hybm,</if>
            <if test="lxbm != null">lxbm,</if>
            <if test="reason != null">reason,</if>
            <if test="defaultOrder != null">default_order,</if>
            <if test="recovery != null">recovery,</if>
            <if test="recoveryTime != null">recovery_time,</if>
            <if test="deptId != null">dept_id,</if>
         </trim>
        <trim prefix="values (" suffix=")" suffixOverrides=",">
            <if test="serialNumber != null and serialNumber != ''">#{serialNumber},</if>
@@ -166,11 +157,6 @@
            <if test="cameraDept != null">#{cameraDept},</if>
            <if test="hybm != null">#{hybm},</if>
            <if test="lxbm != null">#{lxbm},</if>
            <if test="reason != null">#{reason},</if>
            <if test="defaultOrder != null">#{defaultOrder},</if>
            <if test="recovery != null">#{recovery},</if>
            <if test="recoveryTime != null">#{recoveryTime},</if>
            <if test="deptId != null">#{deptId},</if>
         </trim>
    </insert>
@@ -207,11 +193,6 @@
            <if test="cameraDept != null">camera_dept = #{cameraDept},</if>
            <if test="hybm != null">hybm = #{hybm},</if>
            <if test="lxbm != null">lxbm = #{lxbm},</if>
            <if test="reason != null">reason = #{reason},</if>
            <if test="defaultOrder != null">default_order = #{defaultOrder},</if>
            <if test="recovery != null">recovery = #{defaultOrder},</if>
            <if test="recoveryTime != null">recovery_time = #{recoveryTime},</if>
            <if test="deptId != null">dept_id = #{deptId},</if>
        </trim>
        where id = #{id}
    </update>
@@ -231,14 +212,10 @@
        SELECT count(*)                                                          AS totalPosts,
               IFNULL(SUM(IF(on_state = 1, 1, 0)), 0)                            AS totalMembers,
               IFNULL(SUM(IF(on_state = 2, 1, 0)), 0)                            AS postsPercentage,
               IFNULL(SUM(IF(default_order = 1, 1, 0)), 0)                       AS totalViews,
               -1                                                                as noStore,
               -1                                                                as partStore,
               IFNULL(ROUND(SUM(IF(on_state = 1, 1, 0)) / count(*) * 100, 2), 0) as viewsPercentage,
               -1                                                                as totalFace,
               -1                                                                as totalCar
               IFNULL(ROUND(SUM(IF(on_state = 1, 1, 0)) / count(*) * 100, 2), 0) as viewsPercentage
        FROM t_monitor m
         left join sys_dept d on m.dept_id = d.dept_id
            left join t_yw_point p on m.serial_number = p.serial_number
            left join sys_dept d on p.dept_id = d.dept_id
        <where>
            camera_fun_type like concat('%', #{cameraFunType}, '%')
        </where>
@@ -246,13 +223,24 @@
    </select>
    <select id="recoveryException" resultType="java.util.Map">
        <![CDATA[
        SELECT count(*)                                                          AS totalPosts,
               IFNULL(SUM(IF(on_state = 1, 1, 0)), 0)                            AS totalMembers,
               IFNULL(SUM(IF(on_state = 2, 1, 0)), 0)                            AS postsPercentage,
               IFNULL(SUM(IF(default_order = 1, 1, 0)), 0)                       AS totalViews,
               IFNULL(ROUND(SUM(IF(on_state = 1, 1, 0)) / count(*) * 100, 2), 0) as viewsPercentage
        FROM t_monitor
        WHERE recovery = 1
        FROM t_monitor t
        LEFT JOIN t_yw_point p ON t.serial_number = p.serial_number
        WHERE p.recovery = 1 OR TIMESTAMPDIFF(DAY, p.recovery_time, NOW()) <= #{time}
        ]]>
    </select>
    <select id="selectRecoveryMonitor" resultType="com.ycl.platform.domain.vo.TMonitorVO">
        <![CDATA[
        SELECT t.id, p.serial_number, name, site_type, mac_addr, ip, camera_fun_type, longitude, latitude, camera_capture_area, on_state, civil_code, integrated_device, camera_brand, address, net_working, public_security, installed_time, management_unit, mu_contact_info, storage_days, monitor_azimuth, scene_photo_addr, model, site_vulgo, camera_type, camera_light_type, encoded_format, camera_dept, hybm, lxbm
        FROM t_monitor t
        LEFT JOIN t_yw_point p ON t.serial_number = p.serial_number
        WHERE TIMESTAMPDIFF(DAY, p.recovery_time, NOW()) <= #{time}
        ]]>
    </select>
</mapper>