zxl
2025-05-29 71f61d13531b3e2a0099ba5afe3f268c99c5bacf
修改大屏录像可用率指标,点位在线指标,数据中心录像可用率,
7个文件已修改
282 ■■■■ 已修改文件
ycl-server/src/main/java/com/ycl/factory/IndexCalculationFactory.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ycl-server/src/main/java/com/ycl/platform/mapper/TMonitorMapper.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ycl-server/src/main/java/com/ycl/platform/service/DataCenterService.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ycl-server/src/main/java/com/ycl/platform/service/impl/CheckIndexVideoServiceImpl.java 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ycl-server/src/main/java/com/ycl/platform/service/impl/DataCenterServiceImpl.java 219 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ycl-server/src/main/java/com/ycl/task/UYTask.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ycl-server/src/main/resources/mapper/zgyw/TMonitorMapper.xml 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ycl-server/src/main/java/com/ycl/factory/IndexCalculationFactory.java
@@ -50,7 +50,7 @@
        //人脸目录一致
        calculatorClasses.put(CalculationStrategyConstants.Face_DirectConsistent, FaceConsistentCalculation.class);
        //一机一档注册率、档案考核比
        //注册率、档案考核比
        calculatorClasses.put(CalculationStrategyConstants.Video_MonitorRegis_ArchiveRate,MonitorRegistrationCalculation.class);
        //一机一档合格率
        calculatorClasses.put(CalculationStrategyConstants.Video_MonitorQualify, MonitorQualifyCalculation.class);
ycl-server/src/main/java/com/ycl/platform/mapper/TMonitorMapper.java
@@ -137,6 +137,8 @@
    void deleteAll();
    Long getAllVideo();
    List<String> getIdListVideo();
    /**
     * 批量修改设备厂商类型
ycl-server/src/main/java/com/ycl/platform/service/DataCenterService.java
@@ -12,6 +12,7 @@
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.List;
/**
@@ -30,6 +31,9 @@
    void pointOnlineCarExport(HttpServletResponse response, DataCenterQuery query) throws IOException;
    Result updateDynamicValue(UpdateDynamicValueForm form);
    //zxl
    BigDecimal videoPointOnlineRateCount(DataCenterQuery params);
    /**
     * 视频:点位在线率
@@ -72,6 +76,9 @@
     */
    Result videoAssessmentFileRatio(DataCenterQuery query);
    //zxl
    BigDecimal videoAvailabilityRateCount(DataCenterQuery params);
    /**
     * 视频:录像可用率
     *
ycl-server/src/main/java/com/ycl/platform/service/impl/CheckIndexVideoServiceImpl.java
@@ -3,12 +3,16 @@
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ycl.platform.domain.entity.CheckIndexVideo;
import com.ycl.platform.domain.query.DashboardQuery;
import com.ycl.platform.domain.query.DataCenterQuery;
import com.ycl.platform.mapper.CheckIndexVideoMapper;
import com.ycl.platform.service.DataCenterService;
import com.ycl.platform.service.ICheckIndexVideoService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import utils.DateUtils;
import java.util.Date;
import java.util.List;
/**
@@ -18,6 +22,7 @@
 * @date 2024-04-29
 */
@Service
@RequiredArgsConstructor
public class CheckIndexVideoServiceImpl extends ServiceImpl<CheckIndexVideoMapper, CheckIndexVideo> implements ICheckIndexVideoService
{
    @Autowired
@@ -96,8 +101,31 @@
        return checkIndexVideoMapper.deleteCheckIndexVideoById(id);
    }
    public final DataCenterService dataCenterService;
    @Override
    public CheckIndexVideo dashboard(DashboardQuery dashboardQuery) {
        //修改 录像可用率 和 点位在线率在今天
        if(dashboardQuery.getDeptId() == null){
            DataCenterQuery dataCenterQuery = new DataCenterQuery();
            dataCenterQuery.setDate(new Date());
            dataCenterQuery.setTime();
            //区县 2  省厅 1  公安部3
            if(dashboardQuery.getDataScope() == 2){
                dataCenterQuery.setDataType(0);
            }else if(dashboardQuery.getDataScope() == 1){
                dataCenterQuery.setDataType(1);
            }else if(dashboardQuery.getDataScope() == 3){
                dataCenterQuery.setDataType(2);
            }
            //全部0 省厅1 公安部2
            CheckIndexVideo checkIndexVideo = checkIndexVideoMapper.dashboard(dashboardQuery);
            checkIndexVideo.setSiteOnline(dataCenterService.videoPointOnlineRateCount(dataCenterQuery));
            checkIndexVideo.setVideoAvailable(dataCenterService.videoAvailabilityRateCount(dataCenterQuery));
            return  checkIndexVideo;
        }
        return checkIndexVideoMapper.dashboard(dashboardQuery);
    }
}
ycl-server/src/main/java/com/ycl/platform/service/impl/DataCenterServiceImpl.java
@@ -20,6 +20,7 @@
import com.ycl.platform.domain.vo.DynamicColumnVO;
import com.ycl.platform.mapper.DynamicColumnMapper;
import com.ycl.platform.mapper.ImageResourceSecurityDetailMapper;
import com.ycl.platform.mapper.TMonitorMapper;
import com.ycl.platform.mapper.YwPointMapper;
import com.ycl.platform.service.*;
import com.ycl.system.Result;
@@ -66,7 +67,6 @@
    private final MongoTemplate mongoTemplate;
    private final ImageResourceSecurityDetailMapper securityDetailMapper;
    private final YwPointMapper pointMapper;
    private final ICheckIndexVideoService checkIndexVideoService;
    private final ICheckIndexCarService checkIndexCarService;
    private final ICheckIndexFaceService checkIndexFaceService;
    private final DynamicColumnMapper dynamicColumnMapper;
@@ -630,6 +630,50 @@
    }
    //zxl
    @Override
    public BigDecimal videoPointOnlineRateCount(DataCenterQuery params){
        //卡片统计
        int totalCount = 0;
        int onlineCount = 0;
        int offlineCount = 0;
        int unknownCount = 0;
        //构建条件
        List<Criteria> criteriaList = new ArrayList<>();
        // 添加固定条件
        criteriaList.add(Criteria.where("monitorType").regex(".*" + CheckConstants.Rule_Category_Video + ".*"));
        criteriaList.add(Criteria.where("mongoCreateTime").gte(params.getStartTime()).lte(params.getEndTime()));
        // 根据dataType动态添加条件
        if (params.getDataType() == 1) {
            criteriaList.add(Criteria.where("provinceTag").is(Boolean.TRUE));
        } else if (params.getDataType() == 2) {
            criteriaList.add(Criteria.where("deptTag").is(Boolean.TRUE));
        }
        // 构建match操作
        MatchOperation match = Aggregation.match(
                new Criteria().andOperator(criteriaList.toArray(new Criteria[0]))
        );
        GroupOperation group = Aggregation.group()
                .sum(ConditionalOperators.when(Criteria.where("online").is(ApiConstants.UY_OnlineSite_Online)).then(1).otherwise(0)).as("onlineCount")
                .sum(ConditionalOperators.when(Criteria.where("online").is(ApiConstants.UY_OnlineSite_Offline)).then(1).otherwise(0)).as("offlineCount")
                .sum(ConditionalOperators.when(Criteria.where("online").is(ApiConstants.UY_OnlineSite_Unknown)).then(1).otherwise(0)).as("unknownCount");
        // 将匹配阶段和分组阶段组合起来
        Aggregation aggregation = Aggregation.newAggregation(match, group);
        // 执行聚合查询
        AggregationResults<Map> results = mongoTemplate.aggregate(aggregation, "t_monitor_online", Map.class); // 替换为你的集合名称
        for (Map<String, Object> result : results.getMappedResults()) {
            offlineCount = (Integer) result.getOrDefault("offlineCount", 0L);
            unknownCount = (Integer) result.getOrDefault("unknownCount", 0L);
            onlineCount = (Integer) result.getOrDefault("onlineCount", 0L);
            totalCount = offlineCount + unknownCount + onlineCount;
        }
        BigDecimal onlineRate = BigDecimal.ZERO;
        if (totalCount!=0) {
            onlineRate = new BigDecimal(onlineCount).divide(new BigDecimal(totalCount), 3,RoundingMode.DOWN).multiply(new BigDecimal("100"));
        }
        return onlineRate;
    }
    /**
@@ -1370,45 +1414,23 @@
        return recordingMinTime;
    }
    private final TMonitorMapper tMonitorMapper;
    /**
     * 视频:录像可用率
     *
     * @param params
     * @return
     */
    //zxl
    @Override
    public Result videoAvailabilityRate(DataCenterQuery params) {
        List<String> likeFileds = Arrays.asList("deviceId", "deviceName");
        Query query = MongoUtil.getQuery(params, "createTime", likeFileds, null);
        //下拉框录像情况查询条件
        if (params.getOption() != null) {
            query.addCriteria(Criteria.where("recordStatus").is(params.getOption()));
        }
        long total = mongoTemplate.count(query, RecordMetaDSumResult.class);
        MongoUtil.setPage(query, params, "createTime");
        List<RecordMetaDSumResult> resultList = mongoTemplate.find(query, RecordMetaDSumResult.class);
        //查询动态列数据
        //查询动态列数据更具id查询
//        List<DynamicColumnVO> dynamicColumnNames = dynamicColumnMapper.getDynamicColumnByTableName("uy_record_meta_d_sum");
        //翻译行政区域
        resultList.forEach(item -> {
            String areaCode = item.getArealayername().substring(0, 6);
            AreaDeptEnum areaDeptEnum = AreaDeptEnum.fromCode(areaCode);
            if (areaDeptEnum != null) item.setArealayername(areaDeptEnum.getName());
            List<DynamicColumnVO> list = dynamicColumnMapper.getDynamicColumnByTable(TableNameConstants.COLUMN_NAME_VIDEO,item.getId());
            item.setDynamicColumnList(list);
        });
    public BigDecimal videoAvailabilityRateCount(DataCenterQuery params){
        System.out.println("------------------------------------------------------------------------------------");
        System.out.println(params);
        // 统计数量
        List<String> noString = tMonitorMapper.getIdListVideo();
        MongoDatabase database = mongoTemplate.getDb();
        MongoCollection<Document> collection = database.getCollection("uy_record_meta_d_sum");
        List<Integer> status = Arrays.asList(1, 0, -1);
        List<String> resultCount = status.stream().map(item -> {
            List<Document> dList = new ArrayList<>(2);
            dList.add(new Document("recordStatus", new Document("$eq", item)));
            dList.add(new Document("no", new Document("$in", noString)));
            setTag(params, dList);
            Document filter = new Document("$and", dList);
            // 构建聚合管道
@@ -1435,8 +1457,9 @@
        double finalRecordingMinTime = getSySMinTime();
        List<Document> documentList = new ArrayList<>(2);
        documentList.add(new Document("no", new Document("$in", noString)));
        setTag(params, documentList);
        Document recording = new Document("recordDuration",new Document("$gte", finalRecordingMinTime));
        Document recording = new Document("missDuration",new Document("$lte", finalRecordingMinTime));
        documentList.add(recording);
        Document filter = new Document("$and", documentList);
@@ -1448,25 +1471,13 @@
                new Document("$count", "uniqueDeviceIds")
        );
        AggregateIterable<Document> result = collection2.aggregate(pipeline);
        Integer uniqueDeviceIdCount = 0;
        for (Document doc : result) {
            uniqueDeviceIdCount = doc.getInteger("uniqueDeviceIds");
            break; // 不需要继续遍历,因为 $count 只会产生一个结果
        }
        log.error("录像可用率打印:{}",uniqueDeviceIdCount);
//        List<CheckIndexVideo> videoList = new LambdaQueryChainWrapper<>(checkIndexVideoService.getBaseMapper())
//                .select(CheckIndexVideo::getVideoAvailable)
//                .eq(params.getDataType().equals(1), CheckIndexVideo::getExamineTag, CheckConstants.Examine_Tag_Province)
//                .eq(params.getDataType().equals(2), CheckIndexVideo::getExamineTag, CheckConstants.Examine_Tag_Dept)
//                .between(CheckIndexVideo::getCreateTime, DateUtils.getDayStart(params.getStartTime()), DateUtils.getDayEnd(params.getEndTime()))
//                .list();
//        BigDecimal onlineRate = BigDecimal.ZERO;
//        if (CollectionUtils.isNotEmpty(videoList)) {
//            BigDecimal sum = videoList.stream().map(CheckIndexVideo::getVideoAvailable).reduce(BigDecimal.ZERO, BigDecimal::add);
//            BigDecimal count = BigDecimal.valueOf(videoList.size());
//            onlineRate = sum.divide(count, 4, RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(100));
//        }
        //加一个总数
        int totalCount = 0;
        for (String s : resultCount) {
            totalCount += Integer.parseInt(s);
@@ -1474,8 +1485,120 @@
        resultCount.add(0, totalCount + "");
        BigDecimal onlineRate = BigDecimal.ZERO;
//        1:完整 0:间歇 -1:异常 |
        if (!StringUtils.isEmpty(resultCount.get(0)) && !"0".equals(resultCount.get(0))) {
            //resultCount.get(0)是总数 uniqueDeviceIdCount是更具系统参数查询到mongodb中大于等于 recordDuration字段的总数
            onlineRate = new BigDecimal(uniqueDeviceIdCount).divide(new BigDecimal(resultCount.get(0)), 3,RoundingMode.DOWN).multiply(new BigDecimal("100"));
        }
        System.out.println(resultCount);
        System.out.println(onlineRate);
        return onlineRate;
    }
    /**
     * 视频:录像可用率
     *
     * @param params
     * @return
     */
    @Override
    public Result videoAvailabilityRate(DataCenterQuery params) {
        List<String> noString = tMonitorMapper.getIdListVideo();
        List<String> likeFileds = Arrays.asList("deviceId", "deviceName");
        Query query = MongoUtil.getQuery(params, "createTime", likeFileds, null);
        if (CollectionUtils.isNotEmpty(noString)) { // 防止空集合异常
            query.addCriteria(Criteria.where("no").in(noString));
        }
        //下拉框录像情况查询条件
        if (params.getOption() != null) {
            query.addCriteria(Criteria.where("recordStatus").is(params.getOption()));
        }
        long total = mongoTemplate.count(query, RecordMetaDSumResult.class);
        MongoUtil.setPage(query, params, "createTime");
        List<RecordMetaDSumResult> resultList = mongoTemplate.find(query, RecordMetaDSumResult.class);
        //查询动态列数据
        //查询动态列数据更具id查询
//        List<DynamicColumnVO> dynamicColumnNames = dynamicColumnMapper.getDynamicColumnByTableName("uy_record_meta_d_sum");
        //翻译行政区域
        resultList.forEach(item -> {
            String areaCode = item.getArealayername().substring(0, 6);
            AreaDeptEnum areaDeptEnum = AreaDeptEnum.fromCode(areaCode);
            if (areaDeptEnum != null) item.setArealayername(areaDeptEnum.getName());
            List<DynamicColumnVO> list = dynamicColumnMapper.getDynamicColumnByTable(TableNameConstants.COLUMN_NAME_VIDEO,item.getId());
            item.setDynamicColumnList(list);
        });
        // 统计数量
        MongoDatabase database = mongoTemplate.getDb();
        MongoCollection<Document> collection = database.getCollection("uy_record_meta_d_sum");
        List<Integer> status = Arrays.asList(1, 0, -1);
        List<String> resultCount = status.stream().map(item -> {
            List<Document> dList = new ArrayList<>(2);
            dList.add(new Document("recordStatus", new Document("$eq", item)));
            dList.add(new Document("no", new Document("$in", noString)));
            setTag(params, dList);
            Document filter = new Document("$and", dList);
            // 构建聚合管道
            List<Document> pipeline = Arrays.asList(
                    new Document("$match", filter),
                    // $group 去重
                    new Document("$group", new Document("_id", "$deviceId")),
                    new Document("$count", "uniqueDeviceIds")
            );
            // 执行聚合查询并获取结果
            AggregateIterable<Document> result = collection.aggregate(pipeline);
            Integer uniqueDeviceIdCount = 0;
            for (Document doc : result) {
                uniqueDeviceIdCount = doc.getInteger("uniqueDeviceIds");
                break; // 不需要继续遍历,因为 $count 只会产生一个结果
            }
            return uniqueDeviceIdCount + "";
        }).collect(Collectors.toList());
        //计算录像可用率
        MongoDatabase databaes2 = mongoTemplate.getDb();
        MongoCollection<Document> collection2 = databaes2.getCollection("uy_record_meta_d_sum");
        double finalRecordingMinTime = getSySMinTime();
        List<Document> documentList = new ArrayList<>(2);
        documentList.add(new Document("no", new Document("$in", noString)));
        setTag(params, documentList);
        Document recording = new Document("missDuration",new Document("$lte", finalRecordingMinTime));
        documentList.add(recording);
        Document filter = new Document("$and", documentList);
        // 构建聚合管道
        List<Document> pipeline = Arrays.asList(
                new Document("$match", filter),
                // $group 去重
                new Document("$group", new Document("_id", "$deviceId")),
                new Document("$count", "uniqueDeviceIds")
        );
        AggregateIterable<Document> result = collection2.aggregate(pipeline);
        Integer uniqueDeviceIdCount = 0;
        for (Document doc : result) {
            uniqueDeviceIdCount = doc.getInteger("uniqueDeviceIds");
            break; // 不需要继续遍历,因为 $count 只会产生一个结果
        }
        log.error("录像可用率打印:{}",uniqueDeviceIdCount);
        int totalCount = 0;
        for (String s : resultCount) {
            totalCount += Integer.parseInt(s);
        }
        resultCount.add(0, totalCount + "");
        BigDecimal onlineRate = BigDecimal.ZERO;
//        1:完整 0:间歇 -1:异常 |
        if (!StringUtils.isEmpty(resultCount.get(0)) && !"0".equals(resultCount.get(0))) {
            //resultCount.get(0)是总数 uniqueDeviceIdCount是更具系统参数查询到mongodb中大于等于 recordDuration字段的总数
@@ -1548,7 +1671,7 @@
        List<Document> documentList = new ArrayList<>(4);
        documentList.add(new Document("deptTag", new Document("$eq", Boolean.TRUE)));
        setTag(params, documentList);
        Document recording = new Document("recordDuration",new Document("$gte", finalRecordingMinTime));
        Document recording = new Document("missDuration",new Document("$lte", finalRecordingMinTime));
        documentList.add(recording);
        Document filter = new Document("$and", documentList);
        // 构建聚合管道
@@ -1655,7 +1778,7 @@
        List<Document> documentList = new ArrayList<>(4);
        documentList.add(new Document("importantTag", new Document("$eq", Boolean.TRUE)));
        setTag(params, documentList);
        Document recording = new Document("recordDuration",new Document("$gte", finalRecordingMinTime));
        Document recording = new Document("missDuration",new Document("$lte", finalRecordingMinTime));
        documentList.add(recording);
        Document filter = new Document("$and", documentList);
        // 构建聚合管道
ycl-server/src/main/java/com/ycl/task/UYTask.java
@@ -3,7 +3,6 @@
import com.alibaba.fastjson2.JSONObject;
import com.mongodb.client.result.DeleteResult;
import com.ycl.feign.UYClient;
import com.ycl.platform.domain.entity.TMonitor;
import com.ycl.platform.domain.entity.WorkOrder;
import com.ycl.platform.domain.param.UY.ImageDetectionParam;
import com.ycl.platform.domain.param.UY.MonitorQualifyParam;
@@ -28,9 +27,6 @@
import com.ycl.utils.DateUtils;
import constant.ApiConstants;
import constant.CheckConstants;
import constant.RedisConstant;
import enumeration.ErrorType;
import enumeration.general.WorkOrderStatusEnum;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
@@ -46,6 +42,7 @@
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Function;
import java.util.stream.Collectors;
@@ -422,6 +419,7 @@
        param.setStatTime(yesterday);
        JSONObject jsonObject = uyClient.recordMetaDSumList(param);
        double minTime = getSySMinTime();
        AtomicReference<Integer> count = new AtomicReference<>(0);
        if (jsonObject != null) {
            if (ApiConstants.UYSuccessCodeStr.equals(jsonObject.getString("code"))) {
                List<RecordMetaDSumResult> records = jsonObject.getList("data", RecordMetaDSumResult.class);
@@ -434,9 +432,13 @@
                        if (Objects.nonNull(item.getDeviceId())) {
                            item.setNo(item.getDeviceId());
                        }
                        //判断 并修改录像缺少状态
                        if (item.getRecordStatus() != -1){
                            count.getAndSet(count.get() + 1);
                            if (item.getMissDuration() > minTime){
                                log.error("改变数据status{}:",item.getRecordStatus());
                                item.setRecordStatus(0);
                            }else if (item.getMissDuration() < minTime){
                                item.setRecordStatus(1);
@@ -445,7 +447,9 @@
                    });
                    //打标签
                    pointService.setDeviceTagByGB(records,CheckConstants.Rule_Category_Video);
                    log.error("发生状态改变数量:{}",count);
                    //存放在mongo中
                    log.error("新增mongodb数据大小:{}",records.size());
                    mongoTemplate.insertAll(records);
//                    // 工单生成
//                    uyErrorTypeCheckService.recordMetaDSumCheck(records);
ycl-server/src/main/resources/mapper/zgyw/TMonitorMapper.xml
@@ -417,6 +417,18 @@
            ${params.dataScope}
        </where>
    </select>
    <select id="getAllVideo" resultType="java.lang.Long">
        SELECT
               IFNULL(SUM(IF((m.camera_fun_type like '%1%'), 1, 0)), 0) AS video
        FROM t_monitor m
                 left join t_yw_point p on m.serial_number = p.serial_number
    </select>
    <select id="getIdListVideo" resultType="java.lang.String">
        select m.serial_number
        FROM t_monitor m where m.camera_fun_type like '%1%'
    </select>
    <select id="assetManagementCount" resultType="java.util.Map">
        SELECT count(*) AS total,
        IFNULL(SUM(IF((m.camera_fun_type like '%1%'), 1, 0)), 0) AS video,