zxl
1 天以前 2e644445577d0773482753b7d08b3425afae7837
ycl-server/src/main/java/com/ycl/platform/service/impl/DataCenterServiceImpl.java
@@ -20,27 +20,36 @@
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;
import com.ycl.system.entity.SysDept;
import com.ycl.system.model.LoginUser;
import com.ycl.system.service.ISysConfigService;
import com.ycl.system.service.ISysDeptService;
import com.ycl.utils.DateUtils;
import com.ycl.utils.MongoUtil;
import com.ycl.utils.SecurityUtils;
import com.ycl.utils.StringUtils;
import com.ycl.utils.bean.BeanUtils;
import com.ycl.utils.poi.ExcelUtil;
import constant.*;
import enumeration.DataCenterMethodNameEnum;
import enumeration.general.AreaDeptEnum;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.bson.Document;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.*;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import java.io.IOException;
@@ -49,6 +58,9 @@
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionException;
import java.util.concurrent.ExecutionException;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
@@ -66,34 +78,79 @@
    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;
    @Qualifier("threadPoolTaskExecutor")
    @Autowired
    private ThreadPoolTaskExecutor taskExecutor;
    private final static String TIME_FIELD = "mongoCreateTime";
    private static DecimalFormat DF = new DecimalFormat("#.####");
    public Map<String,List<DynamicColumnVO>> getDynamicByConditions(DataCenterQuery params,List<DynamicColumnVO> list){
        //TODO 该位置没有过滤账号的部门对应的设备信息,而是更具条件查询的全部
        //获得到对应id,且包含传入字符串 动态列集合
        List<DynamicColumnVO> likeFieldDynamicColumnVOList = list.stream()
                .filter(dynamicColumnVO ->
                    dynamicColumnVO.getLabelId().equals(params.getDyId()) &&
                            dynamicColumnVO.getColumnValue().contains(params.getDyValue())
        ).collect(Collectors.toList());
        //获得满足条件的id集合
        List<String> ids = likeFieldDynamicColumnVOList.stream().map(DynamicColumnVO::getRefStringId).toList();
        Map<String,List<DynamicColumnVO>> groupByRefStringIdMap = list.stream().collect(Collectors.groupingBy(DynamicColumnVO::getRefStringId));
        Set<String> removeSet = new HashSet<>(ids);
        //移除掉不符合条件的key
        groupByRefStringIdMap.keySet().retainAll(removeSet);
        return groupByRefStringIdMap;
    }
    //录像可用
    @Override
    public void recordingAvailabilityExport(HttpServletResponse response,DataCenterQuery params) throws IOException {
        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()));
        }
        SysDept sysDept = getSysDeptByLoginUser();
        if (sysDept !=null){
            AreaDeptEnum areaDeptEnum = AreaDeptEnum.fromDept(Math.toIntExact(sysDept.getDeptId()));
            if (areaDeptEnum != null){
                query.addCriteria(Criteria.where("no").regex("^" +areaDeptEnum.getCode()));
            }
        }
        MongoUtil.setNoPage(query, params, TIME_FIELD);
        List<RecordMetaDSumResult> resultList = mongoTemplate.find(query, RecordMetaDSumResult.class);
        //翻译行政区域
        resultList.forEach(item -> {
            String areaCode = item.getArealayername().substring(0, 6);
            AreaDeptEnum areaDeptEnum = AreaDeptEnum.fromCode(areaCode);
            if (areaDeptEnum != null) item.setArealayername(areaDeptEnum.getName());
        });
        //获得动态列数据
        List<DynamicColumnVO> dynamicColumnVOList = dynamicColumnMapper.getDynamicColumnByTableName(TableNameConstants.COLUMN_NAME_VIDEO);
        Map<String,List<DynamicColumnVO>> groupByRefStringIdMap = dynamicColumnVOList.stream().collect(Collectors.groupingBy(DynamicColumnVO::getRefStringId));
        //判断是否有查询条件
        boolean conditions = false;
        Map<String,List<DynamicColumnVO>> groupByRefStringIdMap = new HashMap<>();
        if (params.getDyId() != null && StringUtils.isNotEmpty(params.getDyValue())){
            conditions = true;
            //获得动态列集合中包含了的字符串值的集合 区分大小写
            groupByRefStringIdMap = getDynamicByConditions(params,dynamicColumnVOList);
        }else{
            groupByRefStringIdMap = dynamicColumnVOList.stream().collect(Collectors.groupingBy(DynamicColumnVO::getRefStringId));
        }
        //固定表头
        LinkedHashSet<String> headers = new LinkedHashSet<>();
        headers.add(RecordingAvailabilityHeaders.arealayername);
@@ -115,21 +172,28 @@
            headersList.addAll(dynamicsHeaders);
            headers.addAll(headersList);
        }
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        SimpleDateFormat dateFormat2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        //查询到有动态列查询条件
        //获得对应动态列中ref的对象id 与 查询结果id过滤
        if (conditions){
            Map<String, List<DynamicColumnVO>> finalGroupByRefStringIdMap = groupByRefStringIdMap;
            resultList = resultList.stream()
                    .filter(obj -> finalGroupByRefStringIdMap.containsKey(obj.getId()))
                    .collect(Collectors.toList());
        }
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        List<List<Object>> data = new ArrayList<>();
        for (RecordMetaDSumResult result : resultList){
            List<Object> row = new ArrayList<>();
            row.add(result.getArealayername());
            row.add(result.getArealayerno());
            row.add(dateFormat2.format(result.getCreateTime()));
            row.add(dateFormat.format(result.getCreateTime()));
            row.add(result.getDeviceId());
            row.add(result.getMissDuration());
            row.add(result.getPlatId());
            row.add(result.getRecordDuration());
            row.add(result.getRecordStatusText());
            row.add(dateFormat2.format(result.getCreateTime()));
            row.add(dateFormat.format(result.getCreateTime()));
            //添加动态列数据
            for (String header : headersList){
                boolean flag = false;
@@ -158,10 +222,21 @@
                .doWrite(data); // 写入数据
    }
    //点位在线
    @Override
    public void pointOnlineFaceExport(HttpServletResponse response, DataCenterQuery params) throws IOException {
        List<String> likeFileds = Arrays.asList("name", "no", "ip");
        Query query = MongoUtil.getQuery(params, TIME_FIELD, likeFileds, null);
        Query query = null;
        SysDept sysDept = getSysDeptByLoginUser();
        if (sysDept !=null){
            AreaDeptEnum areaDeptEnum = AreaDeptEnum.fromDept(Math.toIntExact(sysDept.getDeptId()));
            if (areaDeptEnum != null){
                query = MongoUtil.getQueryDataCenter(areaDeptEnum.getCode(),params,TIME_FIELD,likeFileds,null,"no");
            }
        }else {
            query = MongoUtil.getQuery(params, TIME_FIELD, likeFileds, null);
        }
        //查人脸设备
        query.addCriteria(Criteria.where("monitorType").regex(".*" + CheckConstants.Rule_Category_Face + ".*"));
        //下拉框在线情况查询条件
@@ -201,8 +276,23 @@
                item.setOffLineTimeStr(offLineTime);
            }
        });
        List<DynamicColumnVO> dynamicColumnVOList = dynamicColumnMapper.getDynamicColumnByTableName(TableNameConstants.COLUMN_NAME_FACE_POINT);
        Map<String,List<DynamicColumnVO>> groupByRefStringIdMap = dynamicColumnVOList.stream().collect(Collectors.groupingBy(DynamicColumnVO::getRefStringId));
        //判断是否有查询条件
        boolean conditions = false;
        Map<String,List<DynamicColumnVO>> groupByRefStringIdMap = new HashMap<>();
        if (params.getDyId() != null && StringUtils.isNotEmpty(params.getDyValue())){
            conditions = true;
            //获得动态列集合中包含了的字符串值的集合 区分大小写
            groupByRefStringIdMap = getDynamicByConditions(params,dynamicColumnVOList);
        }else{
            groupByRefStringIdMap = dynamicColumnVOList.stream().collect(Collectors.groupingBy(DynamicColumnVO::getRefStringId));
        }
        //固定表头
        LinkedHashSet<String> headers = new LinkedHashSet<>();
        headers.add(PointOnlineHeaders.no);
@@ -223,6 +313,13 @@
            //使用链表保证后续补充数据时获取数据顺序一致
            headersList.addAll(dynamicsHeaders);
            headers.addAll(headersList);
        }
        if (conditions){
            Map<String, List<DynamicColumnVO>> finalGroupByRefStringIdMap = groupByRefStringIdMap;
            resultList = resultList.stream()
                    .filter(obj -> finalGroupByRefStringIdMap.containsKey(obj.getNo()))
                    .collect(Collectors.toList());
        }
        List<List<Object>> data = new ArrayList<>();
@@ -269,12 +366,34 @@
                .sheet("人脸点位在线率") // 设置sheet名称
                .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
                .doWrite(data); // 写入数据
    }
    } private final ISysDeptService deptService;
    public SysDept getSysDeptByLoginUser(){
        LoginUser loginUser = SecurityUtils.getLoginUser();
        SysDept sysDept = null;
        Long deptId =null;
        if (loginUser.getDeptId() != null){
            deptId = loginUser.getDeptId();
            sysDept = deptService.selectDeptById(deptId);
        }
        return sysDept;
    }
    //视频单位在线
    @Override
    public void pointOnlineVideoExport(HttpServletResponse response, DataCenterQuery params) throws IOException {
        List<String> likeFileds = Arrays.asList("name", "no", "ip");
        Query query = MongoUtil.getQuery(params, TIME_FIELD, likeFileds, null);
        Query query = null;
        SysDept sysDept = getSysDeptByLoginUser();
        if (sysDept !=null){
            AreaDeptEnum areaDeptEnum = AreaDeptEnum.fromDept(Math.toIntExact(sysDept.getDeptId()));
            if (areaDeptEnum != null){
                query = MongoUtil.getQueryDataCenter(areaDeptEnum.getCode(),params,TIME_FIELD,likeFileds,null,"no");
            }
        }else {
            query = MongoUtil.getQuery(params, TIME_FIELD, likeFileds, null);
        }
        //查视频设备
        query.addCriteria(Criteria.where("monitorType").regex(".*" + CheckConstants.Rule_Category_Video + ".*"));
        //下拉框在线情况查询条件
@@ -313,7 +432,16 @@
            }
        });
        List<DynamicColumnVO> dynamicColumnVOList = dynamicColumnMapper.getDynamicColumnByTableName(TableNameConstants.COLUMN_NAME_VIDEO_POINT);
        Map<String,List<DynamicColumnVO>> groupByRefStringIdMap = dynamicColumnVOList.stream().collect(Collectors.groupingBy(DynamicColumnVO::getRefStringId));
        //判断是否有查询条件
        boolean conditions = false;
        Map<String,List<DynamicColumnVO>> groupByRefStringIdMap = new HashMap<>();
        if (params.getDyId() != null && StringUtils.isNotEmpty(params.getDyValue())){
            conditions = true;
            //获得动态列集合中包含了的字符串值的集合 区分大小写
            groupByRefStringIdMap = getDynamicByConditions(params,dynamicColumnVOList);
        }else{
            groupByRefStringIdMap = dynamicColumnVOList.stream().collect(Collectors.groupingBy(DynamicColumnVO::getRefStringId));
        }
        //固定表头
        LinkedHashSet<String> headers = new LinkedHashSet<>();
        headers.add(PointOnlineHeaders.no);
@@ -334,6 +462,14 @@
            //使用链表保证后续补充数据时获取数据顺序一致
            headersList.addAll(dynamicsHeaders);
            headers.addAll(headersList);
        }
        if (conditions){
            Map<String, List<DynamicColumnVO>> finalGroupByRefStringIdMap = groupByRefStringIdMap;
            resultList = resultList.stream()
                    .filter(obj -> finalGroupByRefStringIdMap.containsKey(obj.getNo()))
                    .collect(Collectors.toList());
        }
        List<List<Object>> data = new ArrayList<>();
@@ -383,11 +519,20 @@
    }
    //车辆点位在线
    @Override
    public void pointOnlineCarExport(HttpServletResponse response, DataCenterQuery params) throws IOException {
        List<String> likeFileds = Arrays.asList("name", "no", "ip");
        Query query = MongoUtil.getQuery(params, TIME_FIELD, likeFileds, null);
        Query query = null;
        SysDept sysDept = getSysDeptByLoginUser();
        if (sysDept !=null){
            AreaDeptEnum areaDeptEnum = AreaDeptEnum.fromDept(Math.toIntExact(sysDept.getDeptId()));
            if (areaDeptEnum != null){
                query = MongoUtil.getQueryDataCenter(areaDeptEnum.getCode(),params,TIME_FIELD,likeFileds,null,"no");
            }
        }else {
            query = MongoUtil.getQuery(params, TIME_FIELD, likeFileds, null);
        }
        //查车辆设备
        query.addCriteria(Criteria.where("monitorType").regex(".*" + CheckConstants.Rule_Category_Car + ".*"));
        //下拉框在线情况查询条件
@@ -428,7 +573,16 @@
            }
        });
        List<DynamicColumnVO> dynamicColumnVOList = dynamicColumnMapper.getDynamicColumnByTableName(TableNameConstants.COLUMN_NAME_CAR_POINT);
        Map<String,List<DynamicColumnVO>> groupByRefStringIdMap = dynamicColumnVOList.stream().collect(Collectors.groupingBy(DynamicColumnVO::getRefStringId));
        //判断是否有查询条件
        boolean conditions = false;
        Map<String,List<DynamicColumnVO>> groupByRefStringIdMap = new HashMap<>();
        if (params.getDyId() != null && StringUtils.isNotEmpty(params.getDyValue())){
            conditions = true;
            //获得动态列集合中包含了的字符串值的集合 区分大小写
            groupByRefStringIdMap = getDynamicByConditions(params,dynamicColumnVOList);
        }else{
            groupByRefStringIdMap = dynamicColumnVOList.stream().collect(Collectors.groupingBy(DynamicColumnVO::getRefStringId));
        }
        //固定表头
        LinkedHashSet<String> headers = new LinkedHashSet<>();
        headers.add(PointOnlineHeaders.no);
@@ -449,6 +603,14 @@
            //使用链表保证后续补充数据时获取数据顺序一致
            headersList.addAll(dynamicsHeaders);
            headers.addAll(headersList);
        }
        if (conditions){
            Map<String, List<DynamicColumnVO>> finalGroupByRefStringIdMap = groupByRefStringIdMap;
            resultList = resultList.stream()
                    .filter(obj -> finalGroupByRefStringIdMap.containsKey(obj.getNo()))
                    .collect(Collectors.toList());
        }
        List<List<Object>> data = new ArrayList<>();
@@ -538,132 +700,450 @@
    }
    /**
     * 视频:点位在线率
     *
     * @param params
     * @return
     * 内部类:存储统计结果(避免零散变量传递)
     */
    @Override
    public Result videoPointOnlineRate(DataCenterQuery params) {
        List<String> likeFileds = Arrays.asList("name", "no", "ip");
        Query query = MongoUtil.getQuery(params, TIME_FIELD, likeFileds, null);
        //查视频设备
        query.addCriteria(Criteria.where("monitorType").regex(".*" + CheckConstants.Rule_Category_Video + ".*"));
        //下拉框在线情况查询条件
        if (params.getOption() != null) {
            query.addCriteria(Criteria.where("online").is(params.getOption()));
        }
        Sort sort = Sort.by(
                Sort.Order.asc("pingOnline"), // 首先按照 pingOnline 升序排序
                Sort.Order.desc("offLineCount") // 首先按照 pingOnline 升序排序
        );
        // 通过pingOnline字段排序,为false的排在前面
        query.with(sort);
        //分页数量
        long total = mongoTemplate.count(query, TMonitorResult.class);
        MongoUtil.setPage(query, params, TIME_FIELD);
        List<TMonitorResult> resultList = mongoTemplate.find(query, TMonitorResult.class);
    private static class StatisticsResult {
        int totalCount;
        int onlineCount;
        int offlineCount;
        int unknownCount;
        BigDecimal onlineRate;
        resultList.forEach(item -> {
            if (item.getPingOnline() == null) {
                item.setPingOnlineStr("未知");
            } else if (item.getPingOnline()) {
                item.setPingOnlineStr("在线");
            } else if (!item.getPingOnline()) {
                item.setPingOnlineStr("离线");
            }
            if (1 == item.getOnline()) {
                item.setOnlineStr("在线");
            } else if (-1 == item.getOnline()) {
                item.setOnlineStr("离线");
            } else {
                item.setOnlineStr("未知");
            }
            List<String> offLineTime = item.getOffLineTimeStr();
            if (!CollectionUtils.isEmpty(offLineTime)) {
                if (offLineTime.size() > 1) {
                    offLineTime = offLineTime.subList(offLineTime.size() - 2, offLineTime.size());
        public StatisticsResult(int totalCount, int onlineCount, int offlineCount, int unknownCount, BigDecimal onlineRate) {
            this.totalCount = totalCount;
            this.onlineCount = onlineCount;
            this.offlineCount = offlineCount;
            this.unknownCount = unknownCount;
            this.onlineRate = onlineRate;
        }
    }
    /**
     * 列表数据格式化
     */
    private void formatResultList(List<TMonitorResult> resultList,String tag) {
        if(DataCenterMethodNameEnum.VIDEO_POINT_ONLINE_RATE.name().equals(tag)){
            resultList.forEach(item -> {
                // pingOnline 状态转换
                if (item.getPingOnline() == null) {
                    item.setPingOnlineStr("未知");
                } else if (item.getPingOnline()) {
                    item.setPingOnlineStr("在线");
                } else {
                    item.setPingOnlineStr("离线");
                }
                item.setOffLineTimeStr(offLineTime);
            }
            //添加动态数据
            List<DynamicColumnVO> list = dynamicColumnMapper.getDynamicColumnByTable(TableNameConstants.COLUMN_NAME_VIDEO_POINT,item.getNo());
            item.setDynamicColumnList(list);
        });
                // online 状态转换
                if (1 == item.getOnline()) {
                    item.setOnlineStr("在线");
                } else if (-1 == item.getOnline()) {
                    item.setOnlineStr("离线");
                } else {
                    item.setOnlineStr("未知");
                }
        params.setDeptTag(-1);
        params.setDeviceType(1);
                // 离线时间截断(保留最后2条)
                List<String> offLineTime = item.getOffLineTimeStr();
                if (!CollectionUtils.isEmpty(offLineTime) && offLineTime.size() > 1) {
                    item.setOffLineTimeStr(offLineTime.subList(offLineTime.size() - 2, offLineTime.size()));
                }
        //卡片统计
        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));
                // 添加动态列数据
                List<DynamicColumnVO> dynamicColumns = dynamicColumnMapper.getDynamicColumnByTable(
                        TableNameConstants.COLUMN_NAME_VIDEO_POINT,
                        item.getNo()
                );
                item.setDynamicColumnList(dynamicColumns);
            });
        }
        // 构建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;
        else if (DataCenterMethodNameEnum.DEPT_VIDEO_POINT_ONLINE_RATE.name().equals(tag)
        || DataCenterMethodNameEnum.VIDEO_IMPORTANT_POINT_ONLINE_RATE.name().equals(tag)){
            resultList.forEach(item -> {
                if (item.getPingOnline() == null) {
                    item.setPingOnlineStr("未知");
                } else if (item.getPingOnline()) {
                    item.setPingOnlineStr("在线");
                } else if (!item.getPingOnline()) {
                    item.setPingOnlineStr("离线");
                }
                if (1 == item.getOnline()) {
                    item.setOnlineStr("在线");
                } else if (-1 == item.getOnline()) {
                    item.setOnlineStr("离线");
                } else {
                    item.setOnlineStr("未知");
                }
            });
        }
        BigDecimal onlineRate = BigDecimal.ZERO;
        if (totalCount!=0) {
            onlineRate = new BigDecimal(onlineCount).divide(new BigDecimal(totalCount), 3,RoundingMode.DOWN).multiply(new BigDecimal("100"));
        }
//        /** 查询当天在线率 */
//        List<CheckIndexVideo> videoList = new LambdaQueryChainWrapper<>(checkIndexVideoService.getBaseMapper())
//                .select(CheckIndexVideo::getSiteOnline)
//                .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, params.getStartTime(), params.getEndTime())
//                .list();
//
//        BigDecimal onlineRate = BigDecimal.ZERO;
//        if (CollectionUtils.isNotEmpty(videoList)) {
//            BigDecimal sum = videoList.stream().map(CheckIndexVideo::getSiteOnline).reduce(BigDecimal.ZERO, BigDecimal::add);
//            BigDecimal count = BigDecimal.valueOf(videoList.size());
//            onlineRate = sum.divide(count, 4, RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(100));
//        }
        HashMap<String, Object> map = new HashMap<>();
        map.put("count", Arrays.asList(totalCount + "", onlineCount + "", offlineCount + "", unknownCount + "", this.remove0(onlineRate)));
        map.put("list", resultList);
        return Result.ok().data(map).total(total);
    }
    /**
     * 视频:部级点位在线率
     * 卡片统计计算
     */
    private StatisticsResult calculateStatistics(DataCenterQuery params, AreaDeptEnum areaDeptEnum,String tag) {
        int totalCount = 0, onlineCount = 0, offlineCount = 0, unknownCount = 0;
        // 计算在线率
        BigDecimal onlineRate = BigDecimal.ZERO;
        if (DataCenterMethodNameEnum.VIDEO_POINT_ONLINE_RATE.name().equals(tag)){
            // 构建统计条件
            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()));
            // 权限过滤
            if (areaDeptEnum != null) {
                criteriaList.add(Criteria.where("no").regex("^" + areaDeptEnum.getCode()));
            }
            // 数据类型过滤(省/部门标签)
            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));
            }
            // MongoDB 聚合查询
            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()) {
                onlineCount = (Integer) result.getOrDefault("onlineCount", 0);
                offlineCount = (Integer) result.getOrDefault("offlineCount", 0);
                unknownCount = (Integer) result.getOrDefault("unknownCount", 0);
                totalCount = onlineCount + offlineCount + unknownCount;
            }
            if (totalCount != 0) {
                onlineRate = new BigDecimal(onlineCount)
                        .divide(new BigDecimal(totalCount), 3, RoundingMode.DOWN)
                        .multiply(new BigDecimal("100"));
            }
        }
        else if (DataCenterMethodNameEnum.DEPT_VIDEO_POINT_ONLINE_RATE.name().equals(tag)) {
            // 构建统计条件
            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()));
            //部级视频标签 差异点
            criteriaList.add(Criteria.where("deptTag").is(Boolean.TRUE));
            // 权限过滤
            if (areaDeptEnum != null) {
                criteriaList.add(Criteria.where("no").regex("^" + areaDeptEnum.getCode()));
            }
            // 数据类型过滤(省/部门标签)
            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));
            }
            // MongoDB 聚合查询
            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()) {
                onlineCount = (Integer) result.getOrDefault("onlineCount", 0);
                offlineCount = (Integer) result.getOrDefault("offlineCount", 0);
                unknownCount = (Integer) result.getOrDefault("unknownCount", 0);
                totalCount = onlineCount + offlineCount + unknownCount;
            }
            if (totalCount != 0) {
                onlineRate = new BigDecimal(onlineCount)
                        .divide(new BigDecimal(totalCount), 3, RoundingMode.DOWN)
                        .multiply(new BigDecimal("100"));
            }
        }
        else if (DataCenterMethodNameEnum.VIDEO_IMPORTANT_POINT_ONLINE_RATE.name().equals(tag)){
            // 构建统计条件
            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()));
            criteriaList.add(Criteria.where("importantTag").is(Boolean.TRUE));
            // 权限过滤
            if (areaDeptEnum != null) {
                criteriaList.add(Criteria.where("no").regex("^" + areaDeptEnum.getCode()));
            }
            // 数据类型过滤(省/部门标签)
            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));
            }
            // MongoDB 聚合查询
            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()) {
                onlineCount = (Integer) result.getOrDefault("onlineCount", 0);
                offlineCount = (Integer) result.getOrDefault("offlineCount", 0);
                unknownCount = (Integer) result.getOrDefault("unknownCount", 0);
                totalCount = onlineCount + offlineCount + unknownCount;
            }
            if (totalCount != 0) {
                onlineRate = new BigDecimal(onlineCount)
                        .divide(new BigDecimal(totalCount), 3, RoundingMode.DOWN)
                        .multiply(new BigDecimal("100"));
            }
        }
        return new StatisticsResult(totalCount, onlineCount, offlineCount, unknownCount, onlineRate);
    }
    /**
     * 视频:点位在线率优化线程
     *
     * @param params
     * @return
     */
    @Override
    public Result deptVideoPointOnlineRate(DataCenterQuery params) {
   public Result videoPointOnlineRate(DataCenterQuery params) {
        List<String> likeFileds = Arrays.asList("name", "no", "ip");
        Query query = MongoUtil.getQuery(params, TIME_FIELD, likeFileds, null);
        //查视频设备
        final Query query;
        SysDept sysDept = getSysDeptByLoginUser();
        final AreaDeptEnum areaDeptEnum; // 声明为final
        if (sysDept != null) {
            areaDeptEnum = AreaDeptEnum.fromDept(Math.toIntExact(sysDept.getDeptId()));
            if (areaDeptEnum != null) {
                query = MongoUtil.getQueryDataCenter(areaDeptEnum.getCode(), params, TIME_FIELD, likeFileds, null, "no");
            } else {
                query = MongoUtil.getQuery(params, TIME_FIELD, likeFileds, null);
            }
        } else {
            //需要初始化 不然下方引入 多线程会报未初始化
            areaDeptEnum = null;
            query = MongoUtil.getQuery(params, TIME_FIELD, likeFileds, null);
        }
        query.addCriteria(Criteria.where("monitorType").regex(".*" + CheckConstants.Rule_Category_Video + ".*"));
        if (params.getOption() != null) {
            query.addCriteria(Criteria.where("online").is(params.getOption()));
        }
        Sort sort = Sort.by(
                Sort.Order.asc("pingOnline"),
                Sort.Order.desc("offLineCount")
        );
        query.with(sort);
        long total = mongoTemplate.count(query, TMonitorResult.class);
        //运行分页查询线程
        CompletableFuture<List<TMonitorResult>> listFuture = CompletableFuture.supplyAsync(() -> {
            try {
                MongoUtil.setPage(query, params, TIME_FIELD);
                List<TMonitorResult> resultList = mongoTemplate.find(query, TMonitorResult.class);
                //构建列表数据
                formatResultList(resultList,DataCenterMethodNameEnum.VIDEO_POINT_ONLINE_RATE.name());
                return resultList;
            } catch (Exception e) {
                throw new CompletionException("视频设备列表查询失败:" + e.getMessage(), e);
            }
        }, taskExecutor);
        //运行统计线程
        CompletableFuture<StatisticsResult> statsFuture = CompletableFuture.supplyAsync(() -> {
            try {
                return calculateStatistics(params, areaDeptEnum,DataCenterMethodNameEnum.VIDEO_POINT_ONLINE_RATE.name()); // 现在可安全引用
            } catch (Exception e) {
                throw new CompletionException("视频设备状态统计失败:" + e.getMessage(), e);
            }
        }, taskExecutor);
        try {
            CompletableFuture.allOf(listFuture, statsFuture).join();
            List<TMonitorResult> resultList = listFuture.get();
            StatisticsResult statsResult = statsFuture.get();
            HashMap<String, Object> map = new HashMap<>();
            map.put("count", Arrays.asList(
                    String.valueOf(statsResult.totalCount),
                    String.valueOf(statsResult.onlineCount),
                    String.valueOf(statsResult.offlineCount),
                    String.valueOf(statsResult.unknownCount),
                    this.remove0(statsResult.onlineRate)
            ));
            map.put("list", resultList);
            return Result.ok().data(map).total(total);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            return Result.error("查询被中断,请稍后重试");
        } catch (ExecutionException e) {
            Throwable rootCause = e.getCause();
            String errorMsg = rootCause != null ? rootCause.getMessage() : "视频设备数据查询失败";
            return Result.error(errorMsg);
        }
    }
//    @Override
//    public Result videoPointOnlineRate(DataCenterQuery params) {
//        List<String> likeFileds = Arrays.asList("name", "no", "ip");
//        //此处新增了根据用户权限查询的情况
//        Query query = null;
//        SysDept sysDept = getSysDeptByLoginUser();
//        AreaDeptEnum areaDeptEnum = null;
//        if (sysDept !=null){
//            areaDeptEnum = AreaDeptEnum.fromDept(Math.toIntExact(sysDept.getDeptId()));
//            if (areaDeptEnum != null){
//                query = MongoUtil.getQueryDataCenter(areaDeptEnum.getCode(),params,TIME_FIELD,likeFileds,null,"no");
//
//            }else{
//                query = MongoUtil.getQuery(params, TIME_FIELD, likeFileds, null);
//            }
//        }else {
//            query = MongoUtil.getQuery(params, TIME_FIELD, likeFileds, null);
//        }
//
//        //查视频设备
//        query.addCriteria(Criteria.where("monitorType").regex(".*" + CheckConstants.Rule_Category_Video + ".*"));
//        //下拉框在线情况查询条件
//        if (params.getOption() != null) {
//            query.addCriteria(Criteria.where("online").is(params.getOption()));
//        }
//        Sort sort = Sort.by(
//                Sort.Order.asc("pingOnline"), // 首先按照 pingOnline 升序排序
//                Sort.Order.desc("offLineCount") // 首先按照 pingOnline 升序排序
//        );
//        // 通过pingOnline字段排序,为false的排在前面
//        query.with(sort);
//        //分页数量
//        long total = mongoTemplate.count(query, TMonitorResult.class);
//
//
//
//        MongoUtil.setPage(query, params, TIME_FIELD);
//        List<TMonitorResult> resultList = mongoTemplate.find(query, TMonitorResult.class);
//
//        resultList.forEach(item -> {
//            if (item.getPingOnline() == null) {
//                item.setPingOnlineStr("未知");
//            } else if (item.getPingOnline()) {
//                item.setPingOnlineStr("在线");
//            } else if (!item.getPingOnline()) {
//                item.setPingOnlineStr("离线");
//            }
//            if (1 == item.getOnline()) {
//                item.setOnlineStr("在线");
//            } else if (-1 == item.getOnline()) {
//                item.setOnlineStr("离线");
//            } else {
//                item.setOnlineStr("未知");
//            }
//            List<String> offLineTime = item.getOffLineTimeStr();
//            if (!CollectionUtils.isEmpty(offLineTime)) {
//                if (offLineTime.size() > 1) {
//                    offLineTime = offLineTime.subList(offLineTime.size() - 2, offLineTime.size());
//                }
//                item.setOffLineTimeStr(offLineTime);
//            }
//            //添加动态数据
//            List<DynamicColumnVO> list = dynamicColumnMapper.getDynamicColumnByTable(TableNameConstants.COLUMN_NAME_VIDEO_POINT,item.getNo());
//            item.setDynamicColumnList(list);
//        });
//
//
//        params.setDeptTag(-1);
//        params.setDeviceType(1);
//
//        //卡片统计
//        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()));
//        //此处新增了根据用户权限查询的情况
//        if (areaDeptEnum != null){
//            criteriaList.add(Criteria.where("no").regex("^" +areaDeptEnum.getCode()));
//        }
//        // 根据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"));
//        }
//        HashMap<String, Object> map = new HashMap<>();
//        map.put("count", Arrays.asList(totalCount + "", onlineCount + "", offlineCount + "", unknownCount + "", this.remove0(onlineRate)));
//        map.put("list", resultList);
//        return Result.ok().data(map).total(total);
//    }
    /**
     * 视频:部级点位在线率优化线程
     *
     * @param params
     * @return
     */
    @Override
    public Result deptVideoPointOnlineRate(DataCenterQuery params){
        List<String> likeFileds  =Arrays.asList("name","no","ip");
        final Query query;
        SysDept sysDept = getSysDeptByLoginUser();
        final AreaDeptEnum areaDeptEnum;
        if (sysDept !=null){
            areaDeptEnum = AreaDeptEnum.fromDept(Math.toIntExact(sysDept.getDeptId()));
            if (areaDeptEnum != null){
                query = MongoUtil.getQueryDataCenter(areaDeptEnum.getCode(),params,TIME_FIELD,likeFileds,null,"no");
            }else{
                query = MongoUtil.getQuery(params, TIME_FIELD, likeFileds, null);
            }
        }else {
            areaDeptEnum = null;
            query = MongoUtil.getQuery(params, TIME_FIELD, likeFileds, null);
        }
        query.addCriteria(Criteria.where("monitorType").regex(".*" + CheckConstants.Rule_Category_Video + ".*"));
        query.addCriteria(Criteria.where("deptTag").is(Boolean.TRUE));
        //下拉框在线情况查询条件
@@ -674,84 +1154,258 @@
        query.with(Sort.by(Sort.Order.asc("pingOnline")));
        //分页数量
        long total = mongoTemplate.count(query, TMonitorResult.class);
        MongoUtil.setPage(query, params, TIME_FIELD);
        List<TMonitorResult> resultList = mongoTemplate.find(query, TMonitorResult.class);
        resultList.forEach(item -> {
            if (item.getPingOnline() == null) {
                item.setPingOnlineStr("未知");
            } else if (item.getPingOnline()) {
                item.setPingOnlineStr("在线");
            } else if (!item.getPingOnline()) {
                item.setPingOnlineStr("离线");
        CompletableFuture<List<TMonitorResult>> listFuture = CompletableFuture.supplyAsync(() ->{
            MongoUtil.setPage(query,params,TIME_FIELD);
            List<TMonitorResult> resultList = mongoTemplate.find(query, TMonitorResult.class);
            formatResultList(resultList,DataCenterMethodNameEnum.DEPT_VIDEO_POINT_ONLINE_RATE.name());
            return resultList;
        },taskExecutor);
        CompletableFuture<StatisticsResult> statsFuture = CompletableFuture.supplyAsync(()->{
            try {
                return calculateStatistics(params, areaDeptEnum,DataCenterMethodNameEnum.DEPT_VIDEO_POINT_ONLINE_RATE.name()); // 现在可安全引用
            } catch (Exception e) {
                throw new CompletionException("视频设备状态统计失败:" + e.getMessage(), e);
            }
            if (1 == item.getOnline()) {
                item.setOnlineStr("在线");
            } else if (-1 == item.getOnline()) {
                item.setOnlineStr("离线");
            } else {
                item.setOnlineStr("未知");
            }
        });
        // 统计设备数量
        //卡片统计
        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()));
        criteriaList.add(Criteria.where("deptTag").is(Boolean.TRUE));
        // 根据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));
        },taskExecutor);
        try {
            CompletableFuture.allOf(listFuture, statsFuture).join();
            List<TMonitorResult> resultList = listFuture.get();
            StatisticsResult statsResult = statsFuture.get();
            HashMap<String, Object> map = new HashMap<>();
            map.put("count", Arrays.asList(
                    String.valueOf(statsResult.totalCount),
                    String.valueOf(statsResult.onlineCount),
                    String.valueOf(statsResult.offlineCount),
                    String.valueOf(statsResult.unknownCount),
                    this.remove0(statsResult.onlineRate)
            ));
            map.put("list", resultList);
            return Result.ok().data(map).total(total);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            return Result.error("查询被中断,请稍后重试");
        } catch (ExecutionException e) {
            Throwable rootCause = e.getCause();
            String errorMsg = rootCause != null ? rootCause.getMessage() : "视频设备数据查询失败";
            return Result.error(errorMsg);
        }
        // 构建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"));
        }
//        params.setDeptTag(1);
//        params.setDeviceType(1);
//        List<CheckIndexVideo> videoList = new LambdaQueryChainWrapper<>(checkIndexVideoService.getBaseMapper())
//                .select(CheckIndexVideo::getMinistrySiteOnline)
//                .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, params.getStartTime(), params.getEndTime())
//                .list();
//        BigDecimal onlineRate = BigDecimal.ZERO;
//        if (CollectionUtils.isNotEmpty(videoList)) {
//            BigDecimal sum = videoList.stream().map(CheckIndexVideo::getMinistrySiteOnline).reduce(BigDecimal.ZERO, BigDecimal::add);
//            BigDecimal count = BigDecimal.valueOf(videoList.size());
//            onlineRate = sum.divide(count, 4, RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(100));
//        }
        HashMap<String, Object> map = new HashMap<>();
        map.put("count", Arrays.asList(totalCount + "", onlineCount + "", offlineCount + "", unknownCount + "", this.remove0(onlineRate)));
        map.put("list", resultList);
        return Result.ok().data(map).total(total);
    }
//    @Override
//    public Result deptVideoPointOnlineRate(DataCenterQuery params) {
//        List<String> likeFileds = Arrays.asList("name", "no", "ip");
//        //此处新增了根据用户权限查询的情况
//        Query query = null;
//        SysDept sysDept = getSysDeptByLoginUser();
//        AreaDeptEnum areaDeptEnum = null;
//        if (sysDept !=null){
//            areaDeptEnum = AreaDeptEnum.fromDept(Math.toIntExact(sysDept.getDeptId()));
//            if (areaDeptEnum != null){
//                query = MongoUtil.getQueryDataCenter(areaDeptEnum.getCode(),params,TIME_FIELD,likeFileds,null,"no");
//
//            }else{
//                query = MongoUtil.getQuery(params, TIME_FIELD, likeFileds, null);
//            }
//        }else {
//            query = MongoUtil.getQuery(params, TIME_FIELD, likeFileds, null);
//        }
//        //查视频设备
//        query.addCriteria(Criteria.where("monitorType").regex(".*" + CheckConstants.Rule_Category_Video + ".*"));
//        query.addCriteria(Criteria.where("deptTag").is(Boolean.TRUE));
//        //下拉框在线情况查询条件
//        if (params.getOption() != null) {
//            query.addCriteria(Criteria.where("online").is(params.getOption()));
//        }
//        // 通过pingOnline字段排序,为false的排在前面
//        query.with(Sort.by(Sort.Order.asc("pingOnline")));
//        //分页数量
//        long total = mongoTemplate.count(query, TMonitorResult.class);
//        MongoUtil.setPage(query, params, TIME_FIELD);
//        List<TMonitorResult> resultList = mongoTemplate.find(query, TMonitorResult.class);
//        resultList.forEach(item -> {
//            if (item.getPingOnline() == null) {
//                item.setPingOnlineStr("未知");
//            } else if (item.getPingOnline()) {
//                item.setPingOnlineStr("在线");
//            } else if (!item.getPingOnline()) {
//                item.setPingOnlineStr("离线");
//            }
//            if (1 == item.getOnline()) {
//                item.setOnlineStr("在线");
//            } else if (-1 == item.getOnline()) {
//                item.setOnlineStr("离线");
//            } else {
//                item.setOnlineStr("未知");
//            }
//        });
//        // 统计设备数量
//        //卡片统计
//        int totalCount = 0;
//        int onlineCount = 0;
//        int offlineCount = 0;
//        int unknownCount = 0;
//        //构建条件
//        List<Criteria> criteriaList = new ArrayList<>();
//        //此处新增了根据用户权限查询的情况
//        if (areaDeptEnum != null){
//            criteriaList.add(Criteria.where("no").regex("^" +areaDeptEnum.getCode()));
//        }
//        // 添加固定条件
//        criteriaList.add(Criteria.where("monitorType").regex(".*" + CheckConstants.Rule_Category_Video + ".*"));
//        criteriaList.add(Criteria.where("mongoCreateTime").gte(params.getStartTime()).lte(params.getEndTime()));
//        criteriaList.add(Criteria.where("deptTag").is(Boolean.TRUE));
//        // 根据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"));
//        }
////        params.setDeptTag(1);
////        params.setDeviceType(1);
////        List<CheckIndexVideo> videoList = new LambdaQueryChainWrapper<>(checkIndexVideoService.getBaseMapper())
////                .select(CheckIndexVideo::getMinistrySiteOnline)
////                .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, params.getStartTime(), params.getEndTime())
////                .list();
////        BigDecimal onlineRate = BigDecimal.ZERO;
////        if (CollectionUtils.isNotEmpty(videoList)) {
////            BigDecimal sum = videoList.stream().map(CheckIndexVideo::getMinistrySiteOnline).reduce(BigDecimal.ZERO, BigDecimal::add);
////            BigDecimal count = BigDecimal.valueOf(videoList.size());
////            onlineRate = sum.divide(count, 4, RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(100));
////        }
//        HashMap<String, Object> map = new HashMap<>();
//        map.put("count", Arrays.asList(totalCount + "", onlineCount + "", offlineCount + "", unknownCount + "", this.remove0(onlineRate)));
//        map.put("list", resultList);
//        return Result.ok().data(map).total(total);
//    }
//    @Override
//    public Result videoImportantPointOnlineRate(DataCenterQuery params) {
//        List<String> likeFileds = Arrays.asList("name", "no", "ip");
//        //此处新增了根据用户权限查询的情况
//        Query query = null;
//        SysDept sysDept = getSysDeptByLoginUser();
//        AreaDeptEnum areaDeptEnum = null;
//        if (sysDept !=null){
//            areaDeptEnum = AreaDeptEnum.fromDept(Math.toIntExact(sysDept.getDeptId()));
//            if (areaDeptEnum != null){
//                query = MongoUtil.getQueryDataCenter(areaDeptEnum.getCode(),params,TIME_FIELD,likeFileds,null,"no");
//
//            }else{
//                query = MongoUtil.getQuery(params, TIME_FIELD, likeFileds, null);
//            }
//        }else {
//            query = MongoUtil.getQuery(params, TIME_FIELD, likeFileds, null);
//        }
//        //查视频设备
//        query.addCriteria(Criteria.where("monitorType").regex(".*" + CheckConstants.Rule_Category_Video + ".*"));
//        query.addCriteria(Criteria.where("importantTag").is(Boolean.TRUE));
//        //下拉框在线情况查询条件
//        if (params.getOption() != null) {
//            query.addCriteria(Criteria.where("online").is(params.getOption()));
//        }
//        // 通过pingOnline字段排序,为false的排在前面
//        query.with(Sort.by(Sort.Order.asc("pingOnline")));
//        //分页数量
//        long total = mongoTemplate.count(query, TMonitorResult.class);
//        MongoUtil.setPage(query, params, TIME_FIELD);
//        List<TMonitorResult> resultList = mongoTemplate.find(query, TMonitorResult.class);
//        params.setDeptTag(3);
//        params.setDeviceType(1);
//        resultList.forEach(item -> {
//            if (item.getPingOnline() == null) {
//                item.setPingOnlineStr("未知");
//            } else if (item.getPingOnline()) {
//                item.setPingOnlineStr("在线");
//            } else if (!item.getPingOnline()) {
//                item.setPingOnlineStr("离线");
//            }
//            if (1 == item.getOnline()) {
//                item.setOnlineStr("在线");
//            } else if (-1 == item.getOnline()) {
//                item.setOnlineStr("离线");
//            } else {
//                item.setOnlineStr("未知");
//            }
//        });
//
//        // 统计设备数量
//        //卡片统计
//        int totalCount = 0;
//        int onlineCount = 0;
//        int offlineCount = 0;
//        int unknownCount = 0;
//        //构建条件
//        List<Criteria> criteriaList = new ArrayList<>();
//        //此处新增了根据用户权限查询的情况
//        if (areaDeptEnum != null){
//            criteriaList.add(Criteria.where("no").regex("^" +areaDeptEnum.getCode()));
//        }
//        // 添加固定条件
//        criteriaList.add(Criteria.where("monitorType").regex(".*" + CheckConstants.Rule_Category_Video + ".*"));
//        criteriaList.add(Criteria.where("mongoCreateTime").gte(params.getStartTime()).lte(params.getEndTime()));
//        criteriaList.add(Criteria.where("importantTag").is(Boolean.TRUE));
//        // 根据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"));
//        }
//        HashMap<String, Object> map = new HashMap<>();
//        map.put("count", Arrays.asList(totalCount + "", onlineCount + "", offlineCount + "", unknownCount + "", this.remove0(onlineRate)));
//        map.put("list", resultList);
//        return Result.ok().data(map).total(total);
//    }
    /**
     * 视频:重点点位在线率
     *
@@ -759,9 +1413,24 @@
     * @return
     */
    @Override
    public Result videoImportantPointOnlineRate(DataCenterQuery params) {
    public Result videoImportantPointOnlineRate(DataCenterQuery params){
        List<String> likeFileds = Arrays.asList("name", "no", "ip");
        Query query = MongoUtil.getQuery(params, TIME_FIELD, likeFileds, null);
        //此处新增了根据用户权限查询的情况
        final Query query;
        SysDept sysDept = getSysDeptByLoginUser();
        final AreaDeptEnum areaDeptEnum;
        if (sysDept !=null){
            areaDeptEnum = AreaDeptEnum.fromDept(Math.toIntExact(sysDept.getDeptId()));
            if (areaDeptEnum != null){
                query = MongoUtil.getQueryDataCenter(areaDeptEnum.getCode(),params,TIME_FIELD,likeFileds,null,"no");
            }else{
                query = MongoUtil.getQuery(params, TIME_FIELD, likeFileds, null);
            }
        }else {
            areaDeptEnum = null;
            query = MongoUtil.getQuery(params, TIME_FIELD, likeFileds, null);
        }
        //查视频设备
        query.addCriteria(Criteria.where("monitorType").regex(".*" + CheckConstants.Rule_Category_Video + ".*"));
        query.addCriteria(Criteria.where("importantTag").is(Boolean.TRUE));
@@ -771,85 +1440,53 @@
        }
        // 通过pingOnline字段排序,为false的排在前面
        query.with(Sort.by(Sort.Order.asc("pingOnline")));
        //分页数量
        long total = mongoTemplate.count(query, TMonitorResult.class);
        MongoUtil.setPage(query, params, TIME_FIELD);
        List<TMonitorResult> resultList = mongoTemplate.find(query, TMonitorResult.class);
        params.setDeptTag(3);
        params.setDeviceType(1);
        resultList.forEach(item -> {
            if (item.getPingOnline() == null) {
                item.setPingOnlineStr("未知");
            } else if (item.getPingOnline()) {
                item.setPingOnlineStr("在线");
            } else if (!item.getPingOnline()) {
                item.setPingOnlineStr("离线");
            }
            if (1 == item.getOnline()) {
                item.setOnlineStr("在线");
            } else if (-1 == item.getOnline()) {
                item.setOnlineStr("离线");
            } else {
                item.setOnlineStr("未知");
            }
        });
        // 统计设备数量
        //卡片统计
        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()));
        criteriaList.add(Criteria.where("importantTag").is(Boolean.TRUE));
        // 根据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));
        CompletableFuture<List<TMonitorResult>> listFuture = CompletableFuture.supplyAsync(()->{
            try {
                MongoUtil.setPage(query, params, TIME_FIELD);
                List<TMonitorResult> resultList = mongoTemplate.find(query, TMonitorResult.class);
                //构建列表数据
                formatResultList(resultList,DataCenterMethodNameEnum.VIDEO_IMPORTANT_POINT_ONLINE_RATE.name());
                return resultList;
            } catch (Exception e) {
                throw new CompletionException("视频设备列表查询失败:" + e.getMessage(), e);
            }
        },taskExecutor);
        CompletableFuture<StatisticsResult> statsFuture = CompletableFuture.supplyAsync(()->{
            try {
                return calculateStatistics(params, areaDeptEnum, DataCenterMethodNameEnum.VIDEO_IMPORTANT_POINT_ONLINE_RATE.name());
            }catch (Exception e){
                throw new CompletionException("视频设备状态统计失败:" + e.getMessage(), e);
            }
        },taskExecutor);
        try {
            CompletableFuture.allOf(listFuture, statsFuture).join();
            List<TMonitorResult> resultList = listFuture.get();
            StatisticsResult statsResult = statsFuture.get();
            HashMap<String, Object> map = new HashMap<>();
            map.put("count", Arrays.asList(
                    String.valueOf(statsResult.totalCount),
                    String.valueOf(statsResult.onlineCount),
                    String.valueOf(statsResult.offlineCount),
                    String.valueOf(statsResult.unknownCount),
                    this.remove0(statsResult.onlineRate)
            ));
            map.put("list", resultList);
            return Result.ok().data(map).total(total);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            return Result.error("查询被中断,请稍后重试");
        } catch (ExecutionException e) {
            Throwable rootCause = e.getCause();
            String errorMsg = rootCause != null ? rootCause.getMessage() : "视频设备数据查询失败";
            return Result.error(errorMsg);
        }
        // 构建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"));
        }
//        List<CheckIndexVideo> videoList = new LambdaQueryChainWrapper<>(checkIndexVideoService.getBaseMapper())
//                .select(CheckIndexVideo::getKeySiteOnline)
//                .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, params.getStartTime(), params.getEndTime())
//                .list();
//        BigDecimal onlineRate = BigDecimal.ZERO;
//        if (CollectionUtils.isNotEmpty(videoList)) {
//            BigDecimal sum = videoList.stream().map(CheckIndexVideo::getKeySiteOnline).reduce(BigDecimal.ZERO, BigDecimal::add);
//            BigDecimal count = BigDecimal.valueOf(videoList.size());
//            onlineRate = sum.divide(count, 4, RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(100));
//        }
        HashMap<String, Object> map = new HashMap<>();
        map.put("count", Arrays.asList(totalCount + "", onlineCount + "", offlineCount + "", unknownCount + "", this.remove0(onlineRate)));
        map.put("list", resultList);
        return Result.ok().data(map).total(total);
    }
    /**
@@ -861,7 +1498,21 @@
    @Override
    public Result videoImportantPointImageOnlineRate(DataCenterQuery params) {
        List<String> likeFileds = Arrays.asList("name", "no", "ip");
        Query query = MongoUtil.getQuery(params, TIME_FIELD, likeFileds, null);
        //此处新增了根据用户权限查询的情况
        Query query = null;
        SysDept sysDept = getSysDeptByLoginUser();
        AreaDeptEnum areaDeptEnum = null;
        if (sysDept !=null){
            areaDeptEnum = AreaDeptEnum.fromDept(Math.toIntExact(sysDept.getDeptId()));
            if (areaDeptEnum != null){
                query = MongoUtil.getQueryDataCenter(areaDeptEnum.getCode(),params,TIME_FIELD,likeFileds,null,"no");
            }else{
                query = MongoUtil.getQuery(params, TIME_FIELD, likeFileds, null);
            }
        }else {
            query = MongoUtil.getQuery(params, TIME_FIELD, likeFileds, null);
        }
        //查视频设备
        query.addCriteria(Criteria.where("monitorType").regex(".*" + CheckConstants.Rule_Category_Video + ".*"));
        query.addCriteria(Criteria.where("importantCommandImageTag").is(Boolean.TRUE));
@@ -903,6 +1554,10 @@
        int unknownCount = 0;
        //构建条件
        List<Criteria> criteriaList = new ArrayList<>();
        //此处新增了根据用户权限查询的情况
        if (areaDeptEnum != null){
            criteriaList.add(Criteria.where("no").regex("^" +areaDeptEnum.getCode()));
        }
        // 添加固定条件
        criteriaList.add(Criteria.where("monitorType").regex(".*" + CheckConstants.Rule_Category_Video + ".*"));
        criteriaList.add(Criteria.where("mongoCreateTime").gte(params.getStartTime()).lte(params.getEndTime()));
@@ -962,7 +1617,19 @@
    @Override
    public Result videoOneMachineDocumentRegister(DataCenterQuery params) {
        List<String> likeFileds = Arrays.asList("ip.showValue", "name.showValue", "serialNumber.showValue");
        List<Criteria> andCriteria = MongoUtil.getAndCriteria(params, TIME_FIELD, likeFileds, null);
        SysDept sysDept = getSysDeptByLoginUser();
        List<Criteria> andCriteria;
        AreaDeptEnum areaDeptEnum = null;
        if (sysDept != null) {
            areaDeptEnum = AreaDeptEnum.fromDept(Math.toIntExact(sysDept.getDeptId()));
            if (areaDeptEnum != null) {
                andCriteria = MongoUtil.getAndCriteriaDateCenter(areaDeptEnum.getCode(),params, TIME_FIELD, likeFileds, null);
            }else {
                andCriteria = MongoUtil.getAndCriteria(params, TIME_FIELD, likeFileds, null);
            }
        }else {
            andCriteria = MongoUtil.getAndCriteria(params, TIME_FIELD, likeFileds, null);
        }
        Query query = new Query();
        Criteria and = new Criteria();
        if (params.getOption() != null) {
@@ -985,12 +1652,23 @@
        // 统计数量
        MongoDatabase database = mongoTemplate.getDb();
        MongoCollection<Document> collection = database.getCollection("uy_monitor_qualify");
        Document areDocument = null;
        if (areaDeptEnum != null) {
            String areaCodePrefix = areaDeptEnum.getCode();
            areDocument = new Document("deviceNo", new Document("$regex", "^" + areaCodePrefix));
        }
        //总数
        List<Document> dList1 = new ArrayList<>(2);
        if(areDocument != null){
            dList1.add(areDocument);
        }
        setTag(params, dList1);
        Document totalFilter = new Document("$and", dList1);
        //新设备数
        List<Document> dList2 = new ArrayList<>(2);
        if(areDocument != null){
            dList1.add(areDocument);
        }
        setTag(params, dList2);
        dList2.add(new Document("newDevice", Boolean.TRUE));
        Document newFilter = new Document("$and", dList2);
@@ -1046,7 +1724,20 @@
    @Override
    public Result videoOneMachineDocumentQualified(DataCenterQuery params) {
        List<String> likeFileds = Arrays.asList("ip.showValue", "name.showValue", "serialNumber.showValue");
        List<Criteria> andCriteria = MongoUtil.getAndCriteria(params, TIME_FIELD, likeFileds, null);
        SysDept sysDept = getSysDeptByLoginUser();
        List<Criteria> andCriteria;
        AreaDeptEnum areaDeptEnum = null;
        if (sysDept != null) {
            areaDeptEnum = AreaDeptEnum.fromDept(Math.toIntExact(sysDept.getDeptId()));
            if (areaDeptEnum != null) {
                andCriteria = MongoUtil.getAndCriteriaDateCenter(areaDeptEnum.getCode(),params, TIME_FIELD, likeFileds, null);
            }else {
                andCriteria = MongoUtil.getAndCriteria(params, TIME_FIELD, likeFileds, null);
            }
        }else {
            andCriteria = MongoUtil.getAndCriteria(params, TIME_FIELD, likeFileds, null);
        }
        Query query = new Query();
        Criteria and = new Criteria();
        and.andOperator(andCriteria);
@@ -1098,12 +1789,25 @@
        // 统计数量
        MongoDatabase database = mongoTemplate.getDb();
        MongoCollection<Document> collection = database.getCollection("uy_monitor_qualify");
        Document areDocument = null;
        if (areaDeptEnum != null) {
            String areaCodePrefix = areaDeptEnum.getCode();
            areDocument = new Document("deviceNo", new Document("$regex", "^" + areaCodePrefix));
        }
        //总数
        List<Document> dList1 = new ArrayList<>(2);
        if (areDocument != null){
            dList1.add(areDocument);
        }
        setTag(params, dList1);
        Document totalFilter = new Document("$and", dList1);
        //list1
        //合格数
        List<Document> dList2 = new ArrayList<>(2);
        if (areDocument != null){
            dList2.add(areDocument);
        }
        dList2.add(new Document("serialNumber.error", Boolean.FALSE));
        dList2.add(new Document("name.error", Boolean.FALSE));
        dList2.add(new Document("civilCode.error", Boolean.FALSE));
@@ -1120,6 +1824,9 @@
        Document qualifyFilter = new Document("$and", dList2);
        //不合格数
        List<Document> dList3 = new ArrayList<>(2);
        if (areDocument != null){
            dList3.add(areDocument);
        }
        setTag(params, dList3);
        List<Document> errorConditions = new ArrayList<>();
        errorConditions.add(new Document("serialNumber.error", new Document("$eq", Boolean.TRUE)));
@@ -1160,18 +1867,6 @@
        if (!StringUtils.isEmpty(rList.get(0)) && !"0".equals(rList.get(0))) {
            onlineRate = new BigDecimal(rList.get(1)).divide(new BigDecimal(rList.get(0)), 3,RoundingMode.DOWN).multiply(new BigDecimal("100"));
        }
//        List<CheckIndexVideo> videoList = new LambdaQueryChainWrapper<>(checkIndexVideoService.getBaseMapper())
//                .select(CheckIndexVideo::getMonitorQualification)
//                .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::getMonitorQualification).reduce(BigDecimal.ZERO, BigDecimal::add);
//            BigDecimal count = BigDecimal.valueOf(videoList.size());
//            onlineRate = sum.divide(count, 4, RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(100));
//        }
        rList.add(this.remove0(onlineRate));
        HashMap<String, Object> map = new HashMap<>();
        map.put("count", rList);
@@ -1261,6 +1956,22 @@
    }
    private final ISysConfigService configService;
    public double getSySMinTime(){
        //获取系统参数
        String dictLabel =  configService.selectConfigByKey("recording_min_time");
        double recordingMinTime;
        try {
            recordingMinTime = Double.parseDouble(dictLabel) / 60; // 如果 dictLabel 是以小时为单位,则无需除以 60
        } catch (Exception e) {
            log.error("配置的删除时间范围格式不正确: {}", dictLabel, e);
            return  12.0; // 默认 12 小时(以小时为单位)
        }
        return recordingMinTime;
    }
    private final TMonitorMapper tMonitorMapper;
    /**
     * 视频:录像可用率
     *
@@ -1268,21 +1979,26 @@
     * @return
     */
    @Override
    public Result videoAvailabilityRate(DataCenterQuery params) {
        //获取系统参数
        String dictLabel =  configService.selectConfigByKey("recording_min_time");
        double recordingMinTime;
        try {
            recordingMinTime = Double.parseDouble(dictLabel) / 60; // 如果 dictLabel 是以小时为单位,则无需除以 60
        } catch (Exception e) {
            log.error("配置的删除时间范围格式不正确: {}", dictLabel, e);
            recordingMinTime = 12.0; // 默认 12 小时(以小时为单位)
        List<String> noString = tMonitorMapper.getIdListVideo();
        List<String> likeFileds = Arrays.asList("deviceId", "deviceName");
        SysDept sysDept = getSysDeptByLoginUser();
        AreaDeptEnum areaDeptEnum = null;
        Query query = null;
        if (sysDept !=null){
            areaDeptEnum = AreaDeptEnum.fromDept(Math.toIntExact(sysDept.getDeptId()));
            if (areaDeptEnum != null){
                query = MongoUtil.getQueryDataCenter(areaDeptEnum.getCode(),params,"createTime",likeFileds,null,"no");
            }else{
                query = MongoUtil.getQuery(params, "createTime", likeFileds, null);
            }
        }else {
            query = MongoUtil.getQuery(params, "createTime", likeFileds, null);
        }
        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()));
@@ -1296,96 +2012,227 @@
        //翻译行政区域
        resultList.forEach(item -> {
            String areaCode = item.getArealayername().substring(0, 6);
            AreaDeptEnum areaDeptEnum = AreaDeptEnum.fromCode(areaCode);
            if (areaDeptEnum != null) item.setArealayername(areaDeptEnum.getName());
            AreaDeptEnum areaDeptEnumInfo = AreaDeptEnum.fromCode(areaCode);
            if (areaDeptEnumInfo != null) item.setArealayername(areaDeptEnumInfo.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)));
            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 = recordingMinTime;
        List<Document> documentList = new ArrayList<>(3);
        setTag(params, documentList);
        Document recording = new Document("recordDuration",new Document("$gte", 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);
//        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));
//        // 统计数量
//        MongoDatabase database = mongoTemplate.getDb();
//        MongoCollection<Document> collection = database.getCollection("uy_record_meta_d_sum");
//
//        List<Integer> status = Arrays.asList(1, 0, -1);
//        AreaDeptEnum finalAreaDeptEnum = areaDeptEnum;
//        List<String> resultCount = status.stream().map(item -> {
//            List<Document> dList = new ArrayList<>(2);
//
//            dList.add(new Document("recordStatus", new Document("$eq", item)));
//            if(finalAreaDeptEnum != null){
//                dList.add(new Document("$and", Arrays.asList(
//                        new Document("no", new Document("$in", noString)),
//                        new Document("no", new Document("$regex", "^" + finalAreaDeptEnum.getCode()))
//                )));
//            }else {
//                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);
//        if(finalAreaDeptEnum != null){
//            documentList.add(new Document("$and", Arrays.asList(
//                    new Document("no", new Document("$in", noString)),
//                    new Document("no", new Document("$regex", "^" + finalAreaDeptEnum.getCode()))
//            )));
//        }else {
//            documentList.add(new Document("no", new Document("$in", noString)));
//        }
        //加一个总数
        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))) {
            onlineRate = new BigDecimal(uniqueDeviceIdCount).divide(new BigDecimal(resultCount.get(0)), 3,RoundingMode.DOWN).multiply(new BigDecimal("100"));
        }
        resultCount.add(this.remove0(onlineRate));
//        //        documentList.add(new Document("$and", Arrays.asList(
//        //                new Document("no", new Document("$in", noString)),
//        //                new Document("no", new Document("$regex", "^" + finalAreaDeptEnum.getCode()))
//        //        )));
//        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字段的总数
//            onlineRate = new BigDecimal(uniqueDeviceIdCount).divide(new BigDecimal(resultCount.get(0)), 3,RoundingMode.DOWN).multiply(new BigDecimal("100"));
//        }
//        resultCount.add(this.remove0(onlineRate));
        HashMap<String, Object> map = new HashMap<>();
        map.put("count", resultCount);
        map.put("count", this.buildCount(areaDeptEnum,noString,params,DataCenterMethodNameEnum.VIDEO_AVAILABILITY_RATE.name()));
        map.put("list", resultList);
        return Result.ok().data(map).total(total);
    }
    public List<String> buildCount(AreaDeptEnum areaDeptEnum,List<String> noString,DataCenterQuery params,String tag){
        MongoDatabase databaes= mongoTemplate.getDb();
        MongoCollection<Document> collection = databaes.getCollection("uy_record_meta_d_sum");
        AreaDeptEnum finalAreaDeptEnum = areaDeptEnum;
        double finalRecordingMinTime = getSySMinTime();
        // 2. 构建聚合管道(核心:一次管道统计所有指标)
        List<Document> pipeline = new ArrayList<>();
        // 阶段1:$match - 基础过滤(复用两次查询的共同条件)
        List<Document> baseFilterList = new ArrayList<>();
        if (DataCenterMethodNameEnum.DEPT_VIDEO_POINT_ONLINE_RATE.name().equals(tag)){
            baseFilterList.add(new Document("deptTag", new Document("$eq", Boolean.TRUE)));
        }
        if (DataCenterMethodNameEnum.VIDEO_IMPORTANT_POINT_AVAILABILITY_RATE.name().equals(tag)){
            baseFilterList.add(new Document("importantTag", new Document("$eq", Boolean.TRUE)));
        }
        // 条件1:no的过滤(in + 可选前缀匹配,和你原代码逻辑一致)
        if (finalAreaDeptEnum != null) {
            baseFilterList.add(new Document("$and", Arrays.asList(
                    new Document("no", new Document("$in", noString)),
                    new Document("no", new Document("$regex", "^" + finalAreaDeptEnum.getCode()))
            )));
        } else {
            baseFilterList.add(new Document("no", new Document("$in", noString)));
        }
        setTag(params, baseFilterList);
        Document matchStage = new Document("$match", new Document("$and", baseFilterList));
        pipeline.add(matchStage);
        // 阶段2:$group - 按deviceId去重,标记各条件是否满足
        // --------------------------
        // 逻辑:每个设备只统计一次,用$cond标记“是否符合某条件”(符合=1,不符合=0)
        Document groupByDeviceStage = new Document("$group",
                new Document("_id", "$deviceId") // 按设备ID分组(去重核心)
                        // 标记:该设备是否满足 recordStatus=1
                        .append("status1Flag", new Document("$sum",
                                new Document("$cond", Arrays.asList(
                                        new Document("$eq", Arrays.asList("$recordStatus", 1)), // 判断条件
                                        1, // 符合:记1
                                        0  // 不符合:记0
                                ))
                        ))
                        // 标记:该设备是否满足 recordStatus=0
                        .append("status0Flag", new Document("$sum",
                                new Document("$cond", Arrays.asList(
                                        new Document("$eq", Arrays.asList("$recordStatus", 0)),
                                        1,
                                        0
                                ))
                        ))
                        // 标记:该设备是否满足 recordStatus=-1
                        .append("statusMinus1Flag", new Document("$sum",
                                new Document("$cond", Arrays.asList(
                                        new Document("$eq", Arrays.asList("$recordStatus", -1)),
                                        1,
                                        0
                                ))
                        ))
                        // 标记:该设备是否满足 missDuration ≤ finalRecordingMinTime(原第二段查询条件)
                        .append("missOkFlag", new Document("$sum",
                                new Document("$cond", Arrays.asList(
                                        new Document("$lte", Arrays.asList("$missDuration", finalRecordingMinTime)),
                                        1,
                                        0
                                ))
                        ))
        );
        pipeline.add(groupByDeviceStage);
        // --------------------------
        // 阶段3:$group - 全局统计(累加所有设备的标记,得到最终数量)
        // --------------------------
        // 逻辑:无分组键(_id: null),将所有设备的标记累加,得到总计数
        Document groupGlobalStage = new Document("$group",
                new Document("_id", null) // 全局分组(统计所有设备)
                        // 原第一段查询结果1:status=1的设备数
                        .append("status1Count", new Document("$sum", "$status1Flag"))
                        // 原第一段查询结果2:status=0的设备数
                        .append("status0Count", new Document("$sum", "$status0Flag"))
                        // 原第一段查询结果3:status=-1的设备数
                        .append("statusMinus1Count", new Document("$sum", "$statusMinus1Flag"))
                        // 原第二段查询结果:missDuration符合条件的设备数
                        .append("missOkCount", new Document("$sum", "$missOkFlag"))
        );
        pipeline.add(groupGlobalStage);
        // --------------------------
        // 执行聚合查询,提取所有统计结果
        // --------------------------
        AggregateIterable<Document> aggregateResult = collection.aggregate(pipeline);
        Document statDoc = null;
        for (Document doc : aggregateResult) { // 全局分组只会返回1条结果
            statDoc = doc;
            break;
        }
        // 初始化默认值(避免空指针)
        int status1Count = 0, status0Count = 0, statusMinus1Count = 0, missOkCount = 0;
        if (statDoc != null) {
            status1Count = statDoc.getInteger("status1Count", 0);
            status0Count = statDoc.getInteger("status0Count", 0);
            statusMinus1Count = statDoc.getInteger("statusMinus1Count", 0);
            missOkCount = statDoc.getInteger("missOkCount", 0);
        }
        int total = status1Count + status0Count + statusMinus1Count;
        BigDecimal onlineRate = BigDecimal.ZERO;
        if (total != 0) { // 只有当total不为0时,才计算比率
            onlineRate = new BigDecimal(missOkCount)
                    .divide(new BigDecimal(total), 3, RoundingMode.DOWN)
                    .multiply(new BigDecimal("100"));
        }
        List<String> list = new ArrayList<>();
        list.add(total +"");
        list.add(status1Count +"");
        list.add(status0Count +"");
        list.add(statusMinus1Count +"");
        list.add(this.remove0(onlineRate));
        return list;
    }
    /**
@@ -1396,77 +2243,45 @@
     */
    @Override
    public Result deptVideoAvailabilityRate(DataCenterQuery params) {
        List<String> noString = tMonitorMapper.getIdListVideo();
        List<String> likeFileds = Arrays.asList("deviceId", "deviceName");
        Query query = MongoUtil.getQuery(params, "createTime", likeFileds, 1);
        SysDept sysDept = getSysDeptByLoginUser();
        AreaDeptEnum areaDeptEnum = null;
        Query query = null;
        if (sysDept !=null){
            areaDeptEnum = AreaDeptEnum.fromDept(Math.toIntExact(sysDept.getDeptId()));
            if (areaDeptEnum != null){
                query = MongoUtil.getQueryDataCenter(areaDeptEnum.getCode(),params,"createTime",likeFileds,null,"no");
            }else{
                query = MongoUtil.getQuery(params, "createTime", likeFileds, null);
            }
        }else {
            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()));
        }
        //新增部级判断
        query.addCriteria(Criteria.where("deptTag").is(Boolean.TRUE));
        long total = mongoTemplate.count(query, RecordMetaDSumResult.class);
        MongoUtil.setPage(query, params, "createTime");
        List<RecordMetaDSumResult> resultList = mongoTemplate.find(query, RecordMetaDSumResult.class);
        //翻译行政区域
        resultList.forEach(item -> {
            String areaCode = item.getArealayername().substring(0, 6);
            AreaDeptEnum areaDeptEnum = AreaDeptEnum.fromCode(areaCode);
            if (areaDeptEnum != null) item.setArealayername(areaDeptEnum.getName());
            AreaDeptEnum areaDeptEnumInfo = AreaDeptEnum.fromCode(areaCode);
            if (areaDeptEnumInfo != null) item.setArealayername(areaDeptEnumInfo.getName());
        });
        // 统计数量
        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<>(4);
            dList.add(new Document("deptTag", new Document("$eq", Boolean.TRUE)));
            dList.add(new Document("recordStatus", new Document("$eq", item)));
            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());
//        List<CheckIndexVideo> videoList = new LambdaQueryChainWrapper<>(checkIndexVideoService.getBaseMapper())
//                .select(CheckIndexVideo::getMinistryVideoAvailable)
//                .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::getMinistryVideoAvailable).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);
        }
        resultCount.add(0, totalCount + "");
        BigDecimal onlineRate = BigDecimal.ZERO;
        if (!StringUtils.isEmpty(resultCount.get(0)) && !"0".equals(resultCount.get(0))) {
            onlineRate = new BigDecimal(resultCount.get(1)).divide(new BigDecimal(resultCount.get(0)), 3,RoundingMode.DOWN).multiply(new BigDecimal("100"));
        }
        resultCount.add(this.remove0(onlineRate));
        HashMap<String, Object> map = new HashMap<>();
        map.put("count", resultCount);
        map.put("count", this.buildCount(areaDeptEnum,noString,params,DataCenterMethodNameEnum.DEPT_VIDEO_POINT_ONLINE_RATE.name()));
        map.put("list", resultList);
        return Result.ok().data(map).total(total);
    }
    /**
     * 视频:重点点位录像可用率
     *
@@ -1475,73 +2290,118 @@
     */
    @Override
    public Result videoImportantPointAvailabilityRate(DataCenterQuery params) {
        List<String> noString = tMonitorMapper.getIdListVideo();
        List<String> likeFileds = Arrays.asList("deviceId", "deviceName");
        Query query = MongoUtil.getQuery(params, "createTime", likeFileds, 3);
        SysDept sysDept = getSysDeptByLoginUser();
        AreaDeptEnum areaDeptEnum = null;
        Query query = null;
        if (sysDept !=null){
            areaDeptEnum = AreaDeptEnum.fromDept(Math.toIntExact(sysDept.getDeptId()));
            if (areaDeptEnum != null){
                query = MongoUtil.getQueryDataCenter(areaDeptEnum.getCode(),params,"createTime",likeFileds,null,"no");
            }else{
                query = MongoUtil.getQuery(params, "createTime", likeFileds, null);
            }
        }else {
            query = MongoUtil.getQuery(params, "createTime", likeFileds, null);
        }
        query.addCriteria(Criteria.where("importantTag").is(Boolean.TRUE));
        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);
        //翻译行政区域
        resultList.forEach(item -> {
            String areaCode = item.getArealayername().substring(0, 6);
            AreaDeptEnum areaDeptEnum = AreaDeptEnum.fromCode(areaCode);
            if (areaDeptEnum != null) item.setArealayername(areaDeptEnum.getName());
            AreaDeptEnum areaDeptEnumInfo = AreaDeptEnum.fromCode(areaCode);
            if (areaDeptEnumInfo != null) item.setArealayername(areaDeptEnumInfo.getName());
        });
        // 统计数量
        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<>(4);
            dList.add(new Document("importantTag", new Document("$eq", Boolean.TRUE)));
            dList.add(new Document("recordStatus", new Document("$eq", item)));
            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());
//        List<CheckIndexVideo> videoList = new LambdaQueryChainWrapper<>(checkIndexVideoService.getBaseMapper())
//                .select(CheckIndexVideo::getKeyVideoAvailable)
//                .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::getKeyVideoAvailable).reduce(BigDecimal.ZERO, BigDecimal::add);
//            BigDecimal count = BigDecimal.valueOf(videoList.size());
//            onlineRate = sum.divide(count, 4, RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(100));
//        MongoDatabase database = mongoTemplate.getDb();
//        MongoCollection<Document> collection = database.getCollection("uy_record_meta_d_sum");
//        List<Integer> status = Arrays.asList(1, 0, -1);
//        AreaDeptEnum finalAreaDeptEnum = areaDeptEnum;
//        List<String> resultCount = status.stream().map(item -> {
//            List<Document> dList = new ArrayList<>(4);
//            dList.add(new Document("importantTag", new Document("$eq", Boolean.TRUE)));
//            dList.add(new Document("recordStatus", new Document("$eq", item)));
//            setTag(params, dList);
//            if (finalAreaDeptEnum != null){
//                dList.add(new Document("$and", Arrays.asList(
////                    new Document("no", new Document("$in", noString)),
//                        new Document("no", new Document("$regex", "^" + finalAreaDeptEnum.getCode()))
//                )));
//            }
//            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 database2 = mongoTemplate.getDb();
//        MongoCollection<Document> collection2 = database2.getCollection("uy_record_meta_d_sum");
//        double finalRecordingMinTime = getSySMinTime();
//
//        List<Document> documentList = new ArrayList<>(4);
//        documentList.add(new Document("importantTag", new Document("$eq", Boolean.TRUE)));
//        setTag(params, documentList);
//        Document recording = new Document("missDuration",new Document("$lte", finalRecordingMinTime));
//        documentList.add(recording);
//        if (finalAreaDeptEnum != null){
//            documentList.add(new Document("$and", Arrays.asList(
////                    new Document("no", new Document("$in", noString)),
//                    new Document("no", new Document("$regex", "^" + finalAreaDeptEnum.getCode()))
//            )));
//        }
        //加一个总数
        int totalCount = 0;
        for (String s : resultCount) {
            totalCount += Integer.parseInt(s);
        }
        resultCount.add(0, totalCount + "");
        BigDecimal onlineRate = BigDecimal.ZERO;
        if (!StringUtils.isEmpty(resultCount.get(0)) && !"0".equals(resultCount.get(0))) {
            onlineRate = new BigDecimal(resultCount.get(1)).divide(new BigDecimal(resultCount.get(0)), 3,RoundingMode.DOWN).multiply(new BigDecimal("100"));
        }
        resultCount.add(this.remove0(onlineRate));
//        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;
//        if (!StringUtils.isEmpty(resultCount.get(0)) && !"0".equals(resultCount.get(0))) {
//            onlineRate = new BigDecimal(uniqueDeviceIdCount).divide(new BigDecimal(resultCount.get(0)), 3,RoundingMode.DOWN).multiply(new BigDecimal("100"));
//        }
//        resultCount.add(this.remove0(onlineRate));
        HashMap<String, Object> map = new HashMap<>();
        map.put("count", resultCount);
        map.put("count", this.buildCount(areaDeptEnum,noString,params,DataCenterMethodNameEnum.VIDEO_IMPORTANT_POINT_AVAILABILITY_RATE.name()));
        map.put("list", resultList);
        return Result.ok().data(map).total(total);
    }
@@ -1559,12 +2419,32 @@
        long total = mongoTemplate.count(query, RecordMetaDSumResult.class);
        List<RecordMetaDSumResult> resultList = mongoTemplate.find(query, RecordMetaDSumResult.class);
        Query nonNetworkQuery;
        Query networkQuery;
        Query videoQuery;
        Query carQuery;
        Query faceQuery;
//        if (areaDeptEnum == null){
            nonNetworkQuery = new Query().addCriteria(Criteria.where("LWSX").is("0"));
            networkQuery = new Query().addCriteria(Criteria.where("LWSX").is("1"));
            videoQuery = new Query().addCriteria(Criteria.where("SXJGNLX").regex(".*1.*"));
            carQuery = new Query().addCriteria(Criteria.where("SXJGNLX").regex(".*2.*"));
            faceQuery = new Query().addCriteria(Criteria.where("SXJGNLX").regex(".*3.*"));
//        }
//        else {
//            nonNetworkQuery = new Query().addCriteria(Criteria.where("LWSX").is("0")).addCriteria(Criteria.where("no").regex("^" + Pattern.quote(areaDeptEnum.getCode())));
//            networkQuery = new Query().addCriteria(Criteria.where("LWSX").is("1")).addCriteria(Criteria.where("no").regex("^" + Pattern.quote(areaDeptEnum.getCode())));
//            videoQuery = new Query().addCriteria(Criteria.where("SXJGNLX").regex(".*1.*")).addCriteria(Criteria.where("no").regex("^" + Pattern.quote(areaDeptEnum.getCode())));
//            carQuery = new Query().addCriteria(Criteria.where("SXJGNLX").regex(".*2.*")).addCriteria(Criteria.where("no").regex("^" + Pattern.quote(areaDeptEnum.getCode())));
//            faceQuery = new Query().addCriteria(Criteria.where("SXJGNLX").regex(".*3.*")).addCriteria(Criteria.where("no").regex("^" + Pattern.quote(areaDeptEnum.getCode())));
//        }
        // 统计数
        long nonNetwork = mongoTemplate.count(new Query().addCriteria(Criteria.where("LWSX").is("0")), RecordMetaDSumResult.class);
        long network = mongoTemplate.count(new Query().addCriteria(Criteria.where("LWSX").is("1")), RecordMetaDSumResult.class);
        long video = mongoTemplate.count(new Query().addCriteria(Criteria.where("SXJGNLX").regex(".*1.*")), RecordMetaDSumResult.class);
        long car = mongoTemplate.count(new Query().addCriteria(Criteria.where("SXJGNLX").regex(".*2.*")), RecordMetaDSumResult.class);
        long face = mongoTemplate.count(new Query().addCriteria(Criteria.where("SXJGNLX").regex(".*3.*")), RecordMetaDSumResult.class);
        long nonNetwork = mongoTemplate.count(nonNetworkQuery, RecordMetaDSumResult.class);
        long network = mongoTemplate.count(networkQuery, RecordMetaDSumResult.class);
        long video = mongoTemplate.count(videoQuery, RecordMetaDSumResult.class);
        long car = mongoTemplate.count(carQuery, RecordMetaDSumResult.class);
        long face = mongoTemplate.count(faceQuery, RecordMetaDSumResult.class);
        HashMap<String, Object> map = new HashMap<>();
        map.put("count", Arrays.asList(nonNetwork, network, video, car, face));
        map.put("list", resultList);
@@ -1580,12 +2460,26 @@
    @Override
    public Result videoImportantPointLabelingAccuracy(DataCenterQuery params) {
        List<String> likeFileds = Arrays.asList("deviceNo", "osdName");
        List<Criteria> andCriteria = MongoUtil.getAndCriteria(params, "checkTime", likeFileds, null);
        SysDept sysDept = getSysDeptByLoginUser();
        List<Criteria> andCriteria;
        AreaDeptEnum areaDeptEnum = null;
        if (sysDept != null) {
            areaDeptEnum = AreaDeptEnum.fromDept(Math.toIntExact(sysDept.getDeptId()));
            if (areaDeptEnum != null) {
                andCriteria = MongoUtil.getAndCriteriaDateCenter(areaDeptEnum.getCode(),params, "checkTime", likeFileds, null);
            }else {
                andCriteria = MongoUtil.getAndCriteria(params, "checkTime", likeFileds, null);
            }
        }else {
            andCriteria = MongoUtil.getAndCriteria(params, "checkTime", likeFileds, null);
        }
        Query query = new Query();
        Criteria and = new Criteria();
        and.andOperator(andCriteria);
        query = Query.query(and);
        //下拉框标注正确查询条件
        query.addCriteria(Criteria.where("importantTag").is(Boolean.TRUE));
        // 下拉框标注正确查询条件
        if (params.getOption() != null) {
            if (params.getOption() == 1) {
                andCriteria.add(Criteria.where("osdNameCorrect").is(1));
@@ -1626,13 +2520,26 @@
        // 统计数量
        MongoDatabase database = mongoTemplate.getDb();
        MongoCollection<Document> collection = database.getCollection("osd_check_result");
        //总数
        // 确保在统计查询中也应用相同的过滤条件
        Document areDocument = null;
        if (areaDeptEnum != null) {
            String areaCodePrefix = areaDeptEnum.getCode();
            areDocument = new Document("deviceNo", new Document("$regex", "^" + areaCodePrefix));
        }
        // 总数
        List<Document> dList = new ArrayList<>(2);
        if (areDocument != null){
            dList.add(areDocument);
        }
        dList.add(new Document("importantTag", Boolean.TRUE));
        setTag(params, dList);
        Document osdFilter = new Document("$and", dList);
        //正常数
        // 正常数
        List<Document> dList1 = new ArrayList<>(2);
        if (areDocument != null){
            dList1.add(areDocument);
        }
        dList1.add(new Document("importantTag", Boolean.TRUE));
        dList1.add(new Document("osdNameCorrect", new Document("$eq", 1)));
        dList1.add(new Document("osdTimeCorrect", new Document("$eq", 1)));
@@ -1640,9 +2547,13 @@
        dList1.add(new Document("osdCityCorrect", new Document("$eq", 1)));
        dList1.add(new Document("osdPartCorrect", new Document("$eq", 1)));
        setTag(params, dList1);
        Document osdCorrectFilter = new Document("$and", dList1);
        //异常数
        List<Document> dList2 = new ArrayList<>(2);
        if (areDocument != null){
            dList2.add(areDocument);
        }
        setTag(params, dList2);
        Document importantTagCondition = new Document("importantTag", Boolean.TRUE);
        dList2.add(importantTagCondition);
@@ -1654,9 +2565,14 @@
        errorConditions.add(new Document("osdPartCorrect", new Document("$eq", -1)));
        Document errorFilter = new Document("$or", errorConditions);
        dList2.add(errorFilter);
        Document osdErrorFilter = new Document("$and", dList2);
        //未知数
        // 未知数
        List<Document> dList3 = new ArrayList<>(2);
        if (areDocument != null){
            dList3.add(areDocument);
        }
        setTag(params, dList3);
        dList3.add(importantTagCondition);
        List<Document> unknownConditions = new ArrayList<>();
@@ -1665,9 +2581,9 @@
        unknownConditions.add(new Document("osdProvinceCorrect", new Document("$eq", 0)));
        unknownConditions.add(new Document("osdCityCorrect", new Document("$eq", 0)));
        unknownConditions.add(new Document("osdPartCorrect", new Document("$eq", 0)));
        // 使用$or逻辑组合剩余的条件
        Document unknownFilter = new Document("$or", unknownConditions);
        dList3.add(unknownFilter);
        Document osdUnknownFilter = new Document("$and", dList3);
        List<Document> lists = Arrays.asList(osdFilter, osdCorrectFilter, osdErrorFilter, osdUnknownFilter);
@@ -1689,18 +2605,6 @@
            return uniqueDeviceIdCount + "";
        }).collect(Collectors.toList());
//        List<CheckIndexVideo> videoList = new LambdaQueryChainWrapper<>(checkIndexVideoService.getBaseMapper())
//                .select(CheckIndexVideo::getKeyAnnotationAccuracy)
//                .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::getKeyAnnotationAccuracy).reduce(BigDecimal.ZERO, BigDecimal::add);
//            BigDecimal count = BigDecimal.valueOf(videoList.size());
//            onlineRate = sum.divide(count, 4, RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(100));
//        }
        BigDecimal onlineRate = BigDecimal.ZERO;
        if (!StringUtils.isEmpty(rList.get(0)) && !"0".equals(rList.get(0))) {
            onlineRate = new BigDecimal(rList.get(1)).divide(new BigDecimal(rList.get(0)), 3,RoundingMode.DOWN).multiply(new BigDecimal("100"));
@@ -1807,7 +2711,25 @@
    @Override
    public Result videoImportantPointCheckTimeAccuracy(DataCenterQuery params) {
        List<String> likeFileds = Arrays.asList("deviceNo", "osdName");
        Query query = MongoUtil.getQuery(params, "checkTime", likeFileds, null);
        SysDept sysDept = getSysDeptByLoginUser();
        List<Criteria> andCriteria;
        AreaDeptEnum areaDeptEnum = null;
        if (sysDept != null) {
            areaDeptEnum = AreaDeptEnum.fromDept(Math.toIntExact(sysDept.getDeptId()));
            if (areaDeptEnum != null) {
                andCriteria = MongoUtil.getAndCriteriaDateCenter(areaDeptEnum.getCode(),params, "checkTime", likeFileds, null);
            }else {
                andCriteria = MongoUtil.getAndCriteria(params, "checkTime", likeFileds, null);
            }
        }else {
            andCriteria = MongoUtil.getAndCriteria(params, "checkTime", likeFileds, null);
        }
        Query query = new Query();
        Criteria and = new Criteria();
        and.andOperator(andCriteria);
        query = Query.query(and);
        query.addCriteria(Criteria.where("importantTag").is(Boolean.TRUE));
        //下拉框标注正确查询条件
        if (params.getOption() != null) {
            if (params.getOption() == 1) {
@@ -1822,6 +2744,11 @@
        long total = mongoTemplate.count(query, OsdCheckResult.class);
        MongoUtil.setPage(query, params, "checkTime");
        List<OsdCheckResult> resultList = mongoTemplate.find(query, OsdCheckResult.class);
        Document areDocument = null;
        if (areaDeptEnum != null) {
            String areaCodePrefix = areaDeptEnum.getCode();
            areDocument = new Document("deviceNo", new Document("$regex", "^" + areaCodePrefix));
        }
        for (OsdCheckResult osdCheckResult : resultList) {
            OsdCheckResult.getError(osdCheckResult);
@@ -1830,7 +2757,10 @@
        MongoDatabase database = mongoTemplate.getDb();
        MongoCollection<Document> collection = database.getCollection("osd_check_result");
        //总数
        List<Document> dList = new ArrayList<>(2);
        List<Document> dList = new ArrayList<>(3);
        if (areDocument != null){
            dList.add(areDocument);
        }
        dList.add(new Document("importantTag", Boolean.TRUE));
        setTag(params, dList);
        Document osdFilter = new Document("$and", dList);
@@ -1842,10 +2772,16 @@
        dList1.add(new Document("osdProvinceCorrect", new Document("$eq", 1)));
        dList1.add(new Document("osdCityCorrect", new Document("$eq", 1)));
        dList1.add(new Document("osdPartCorrect", new Document("$eq", 1)));
        if (areDocument != null){
            dList1.add(areDocument);
        }
        setTag(params, dList1);
        Document osdCorrectFilter = new Document("$and", dList1);
        //异常数
        List<Document> dList2 = new ArrayList<>(2);
        if (areDocument != null){
            dList2.add(areDocument);
        }
        setTag(params, dList2);
        Document importantTagCondition = new Document("importantTag", Boolean.TRUE);
        dList2.add(importantTagCondition);
@@ -1860,6 +2796,9 @@
        Document osdErrorFilter = new Document("$and", dList2);
        //未知数
        List<Document> dList3 = new ArrayList<>(2);
        if (areDocument != null){
            dList3.add(areDocument);
        }
        setTag(params, dList3);
        dList3.add(importantTagCondition);
        List<Document> unknownConditions = new ArrayList<>();
@@ -1925,7 +2864,20 @@
    @Override
    public Result vehicleViewDockStable(DataCenterQuery params) {
        List<String> likeFileds = Arrays.asList("externalIndexCode", "deviceName");
        Query query = MongoUtil.getQuery(params, TIME_FIELD, likeFileds, null);
        Query query = null;
        SysDept sysDept = getSysDeptByLoginUser();
        AreaDeptEnum areaDeptEnum = null;
        if (sysDept !=null){
            areaDeptEnum = AreaDeptEnum.fromDept(Math.toIntExact(sysDept.getDeptId()));
            if (areaDeptEnum != null){
                query = MongoUtil.getQueryDataCenter(areaDeptEnum.getCode(),params,TIME_FIELD,likeFileds,null,"no");
            }else{
                query = MongoUtil.getQuery(params, TIME_FIELD, likeFileds, null);
            }
        }else {
            query = MongoUtil.getQuery(params, TIME_FIELD, likeFileds, null);
        }
        //加DataType为车辆
        query.addCriteria(Criteria.where("dataType").is(ApiConstants.HK_DataType_CAR));
        if (params.getOption() != null) {
@@ -1943,23 +2895,41 @@
        MongoUtil.setPage(query, params, TIME_FIELD);
        List<SnapshotDataMonitorResult> resultList = mongoTemplate.find(query, SnapshotDataMonitorResult.class);
        resultList.forEach(item -> item.setResultTypeText(item.getResultTypeText()));
        Document areDocument = null;
        if (areaDeptEnum != null) {
            String areaCodePrefix = areaDeptEnum.getCode();
            areDocument = new Document("deviceNo", new Document("$regex", "^" + areaCodePrefix));
        }
        // 统计数量
        MongoDatabase database = mongoTemplate.getDb();
        MongoCollection<Document> collection = database.getCollection("hk_snapshot_data_monitor");
        List<Document> dList2 = new ArrayList<>(2);
        if (areDocument != null){
            dList2.add(areDocument);
        }
        dList2.add(new Document("resultType", new Document("$eq", 1)));
        dList2.add(new Document("dataType", new Document("$eq", ApiConstants.HK_DataType_CAR)));
        setTag(params, dList2);
        List<Document> dList3 = new ArrayList<>(2);
        if (areDocument != null){
            dList3.add(areDocument);
        }
        dList3.add(new Document("resultType", new Document("$eq", 2)));
        dList3.add(new Document("dataType", new Document("$eq", ApiConstants.HK_DataType_CAR)));
        setTag(params, dList3);
        List<Document> dList4 = new ArrayList<>(2);
        if (areDocument != null){
            dList4.add(areDocument);
        }
        dList4.add(new Document("resultType", new Document("$eq", 3)));
        dList4.add(new Document("dataType", new Document("$eq", ApiConstants.HK_DataType_CAR)));
        setTag(params, dList4);
        List<Document> dList5 = new ArrayList<>(2);
        if (areDocument != null){
            dList5.add(areDocument);
        }
        dList5.add(new Document("resultType", new Document("$eq", 4)));
        dList5.add(new Document("dataType", new Document("$eq", ApiConstants.HK_DataType_CAR)));
        setTag(params, dList5);
@@ -2029,6 +2999,24 @@
        return Result.ok().data(map).total(total);
    }
    public Query buildQuery(DataCenterQuery params,List<String> likeFileds,String fileName){
        Query query = null;
        SysDept sysDept = getSysDeptByLoginUser();
        AreaDeptEnum areaDeptEnum = null;
        if (sysDept !=null){
            areaDeptEnum = AreaDeptEnum.fromDept(Math.toIntExact(sysDept.getDeptId()));
            if (areaDeptEnum != null){
                query = MongoUtil.getQueryDataCenter(areaDeptEnum.getCode(),params,TIME_FIELD,likeFileds,null,"no");
            }else{
                query = MongoUtil.getQuery(params, TIME_FIELD, likeFileds, null);
            }
        }else {
            query = MongoUtil.getQuery(params, TIME_FIELD, likeFileds, null);
        }
        return query;
    }
    /**
     * 车辆:点位在线率
     *
@@ -2038,7 +3026,20 @@
    @Override
    public Result vehiclePointOnlineRate(DataCenterQuery params) {
        List<String> likeFileds = Arrays.asList("name", "no", "ip");
        Query query = MongoUtil.getQuery(params, TIME_FIELD, likeFileds, null);
        Query query = null;
        SysDept sysDept = getSysDeptByLoginUser();
        AreaDeptEnum areaDeptEnum = null;
        if (sysDept !=null){
            areaDeptEnum = AreaDeptEnum.fromDept(Math.toIntExact(sysDept.getDeptId()));
            if (areaDeptEnum != null){
                query = MongoUtil.getQueryDataCenter(areaDeptEnum.getCode(),params,TIME_FIELD,likeFileds,null,"no");
            }else{
                query = MongoUtil.getQuery(params, TIME_FIELD, likeFileds, null);
            }
        }else {
            query = MongoUtil.getQuery(params, TIME_FIELD, likeFileds, null);
        }
        //查车辆设备
        query.addCriteria(Criteria.where("monitorType").regex(".*" + CheckConstants.Rule_Category_Car + ".*"));
        //下拉框在线情况查询条件
@@ -2094,6 +3095,9 @@
        int unknownCount = 0;
        //构建条件
        List<Criteria> criteriaList = new ArrayList<>();
        if (areaDeptEnum != null){
            criteriaList.add(Criteria.where("no").regex("^" +areaDeptEnum.getCode()));
        }
        // 添加固定条件
        criteriaList.add(Criteria.where("monitorType").regex(".*" + CheckConstants.Rule_Category_Car + ".*"));
        criteriaList.add(Criteria.where("mongoCreateTime").gte(params.getStartTime()).lte(params.getEndTime()));
@@ -2153,7 +3157,19 @@
    @Override
    public Result vehicleNetDeviceDirectoryConsistency(DataCenterQuery params) {
        List<String> likeFileds = Arrays.asList("ip.showValue", "name.showValue", "serialNumber.showValue");
        List<Criteria> andCriteria = MongoUtil.getAndCriteria(params, TIME_FIELD, likeFileds, null);
        SysDept sysDept = getSysDeptByLoginUser();
        List<Criteria> andCriteria;
        AreaDeptEnum areaDeptEnum = null;
        if (sysDept != null) {
            areaDeptEnum = AreaDeptEnum.fromDept(Math.toIntExact(sysDept.getDeptId()));
            if (areaDeptEnum != null) {
                andCriteria = MongoUtil.getAndCriteriaDateCenter(areaDeptEnum.getCode(),params, "checkTime", likeFileds, null);
            }else {
                andCriteria = MongoUtil.getAndCriteria(params, "checkTime", likeFileds, null);
            }
        }else {
            andCriteria = MongoUtil.getAndCriteria(params, "checkTime", likeFileds, null);
        }
        // 1/2/3 视频/车辆/人脸
        Pattern pattern = Pattern.compile(".*2.*");
        andCriteria.add(Criteria.where("sxjgnlx.value").regex(pattern));
@@ -2179,13 +3195,25 @@
        //统计数量
        MongoDatabase database = mongoTemplate.getDb();
        MongoCollection<Document> collection = database.getCollection("uy_monitor_qualify");
        Document areDocument = null;
        if (areaDeptEnum != null) {
            String areaCodePrefix = areaDeptEnum.getCode();
            areDocument = new Document("no", new Document("$regex", "^" + areaCodePrefix));
        }
        //总数
        List<Document> dList1 = new ArrayList<>(2);
        if (areDocument != null){
            dList1.add(areDocument);
        }
        setTag(params, dList1);
        dList1.add(new Document("sxjgnlx.value", new Document("$regex", ".*2.*")));
        Document totalFilter = new Document("$and", dList1);
        //新设备数
        List<Document> dList2 = new ArrayList<>(2);
        if (areDocument != null){
            dList2.add(areDocument);
        }
        setTag(params, dList2);
        dList2.add(new Document("sxjgnlx.value", new Document("$regex", ".*2.*")));
        dList2.add(new Document("newDevice", Boolean.TRUE));