ycl-server/src/main/java/com/ycl/platform/service/DataCenterService.java
@@ -12,8 +12,7 @@ import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; import java.math.BigDecimal; import java.util.List; /** * 数据中心接口 @@ -32,8 +31,6 @@ Result updateDynamicValue(UpdateDynamicValueForm form); //zxl BigDecimal videoPointOnlineRateCount(DataCenterQuery params); /** * 视频:点位在线率 @@ -76,8 +73,6 @@ */ Result videoAssessmentFileRatio(DataCenterQuery query); //zxl BigDecimal videoAvailabilityRateCount(DataCenterQuery params); /** * 视频:录像可用率 ycl-server/src/main/java/com/ycl/platform/service/impl/CheckIndexVideoServiceImpl.java
@@ -101,31 +101,8 @@ return checkIndexVideoMapper.deleteCheckIndexVideoById(id); } public final DataCenterService dataCenterService; @Override public CheckIndexVideo dashboard(DashboardQuery dashboardQuery) { //修改 录像可用率 和 点位在线率在今天 if(dashboardQuery.getDeptId() == null){ DataCenterQuery dataCenterQuery = new DataCenterQuery(); dataCenterQuery.setDate(new Date()); dataCenterQuery.setTime(); //区县 2 省厅 1 公安部3 if(dashboardQuery.getDataScope() == 2){ dataCenterQuery.setDataType(0); }else if(dashboardQuery.getDataScope() == 1){ dataCenterQuery.setDataType(1); }else if(dashboardQuery.getDataScope() == 3){ dataCenterQuery.setDataType(2); } //全部0 省厅1 公安部2 CheckIndexVideo checkIndexVideo = checkIndexVideoMapper.dashboard(dashboardQuery); checkIndexVideo.setSiteOnline(dataCenterService.videoPointOnlineRateCount(dataCenterQuery)); checkIndexVideo.setVideoAvailable(dataCenterService.videoAvailabilityRateCount(dataCenterQuery)); return checkIndexVideo; } return checkIndexVideoMapper.dashboard(dashboardQuery); } } ycl-server/src/main/java/com/ycl/platform/service/impl/DataCenterServiceImpl.java
@@ -632,49 +632,7 @@ } //zxl @Override public BigDecimal videoPointOnlineRateCount(DataCenterQuery params){ //卡片统计 int totalCount = 0; int onlineCount = 0; int offlineCount = 0; int unknownCount = 0; //构建条件 List<Criteria> criteriaList = new ArrayList<>(); // 添加固定条件 criteriaList.add(Criteria.where("monitorType").regex(".*" + CheckConstants.Rule_Category_Video + ".*")); criteriaList.add(Criteria.where("mongoCreateTime").gte(params.getStartTime()).lte(params.getEndTime())); // 根据dataType动态添加条件 if (params.getDataType() == 1) { criteriaList.add(Criteria.where("provinceTag").is(Boolean.TRUE)); } else if (params.getDataType() == 2) { criteriaList.add(Criteria.where("deptTag").is(Boolean.TRUE)); } // 构建match操作 MatchOperation match = Aggregation.match( new Criteria().andOperator(criteriaList.toArray(new Criteria[0])) ); GroupOperation group = Aggregation.group() .sum(ConditionalOperators.when(Criteria.where("online").is(ApiConstants.UY_OnlineSite_Online)).then(1).otherwise(0)).as("onlineCount") .sum(ConditionalOperators.when(Criteria.where("online").is(ApiConstants.UY_OnlineSite_Offline)).then(1).otherwise(0)).as("offlineCount") .sum(ConditionalOperators.when(Criteria.where("online").is(ApiConstants.UY_OnlineSite_Unknown)).then(1).otherwise(0)).as("unknownCount"); // 将匹配阶段和分组阶段组合起来 Aggregation aggregation = Aggregation.newAggregation(match, group); // 执行聚合查询 AggregationResults<Map> results = mongoTemplate.aggregate(aggregation, "t_monitor_online", Map.class); // 替换为你的集合名称 for (Map<String, Object> result : results.getMappedResults()) { offlineCount = (Integer) result.getOrDefault("offlineCount", 0L); unknownCount = (Integer) result.getOrDefault("unknownCount", 0L); onlineCount = (Integer) result.getOrDefault("onlineCount", 0L); totalCount = offlineCount + unknownCount + onlineCount; } BigDecimal onlineRate = BigDecimal.ZERO; if (totalCount!=0) { onlineRate = new BigDecimal(onlineCount).divide(new BigDecimal(totalCount), 3,RoundingMode.DOWN).multiply(new BigDecimal("100")); } return onlineRate; } /** * 视频:点位在线率 @@ -1415,88 +1373,6 @@ return recordingMinTime; } private final TMonitorMapper tMonitorMapper; //zxl @Override public BigDecimal videoAvailabilityRateCount(DataCenterQuery params){ System.out.println("------------------------------------------------------------------------------------"); System.out.println(params); // 统计数量 List<String> noString = tMonitorMapper.getIdListVideo(); MongoDatabase database = mongoTemplate.getDb(); MongoCollection<Document> collection = database.getCollection("uy_record_meta_d_sum"); List<Integer> status = Arrays.asList(1, 0, -1); List<String> resultCount = status.stream().map(item -> { List<Document> dList = new ArrayList<>(2); dList.add(new Document("recordStatus", new Document("$eq", item))); dList.add(new Document("no", new Document("$in", noString))); setTag(params, dList); Document filter = new Document("$and", dList); // 构建聚合管道 List<Document> pipeline = Arrays.asList( new Document("$match", filter), // $group 去重 new Document("$group", new Document("_id", "$deviceId")), new Document("$count", "uniqueDeviceIds") ); // 执行聚合查询并获取结果 AggregateIterable<Document> result = collection.aggregate(pipeline); Integer uniqueDeviceIdCount = 0; for (Document doc : result) { uniqueDeviceIdCount = doc.getInteger("uniqueDeviceIds"); break; // 不需要继续遍历,因为 $count 只会产生一个结果 } return uniqueDeviceIdCount + ""; }).collect(Collectors.toList()); //计算录像可用率 MongoDatabase databaes2 = mongoTemplate.getDb(); MongoCollection<Document> collection2 = databaes2.getCollection("uy_record_meta_d_sum"); double finalRecordingMinTime = getSySMinTime(); List<Document> documentList = new ArrayList<>(2); documentList.add(new Document("no", new Document("$in", noString))); setTag(params, documentList); Document recording = new Document("missDuration",new Document("$lte", finalRecordingMinTime)); documentList.add(recording); Document filter = new Document("$and", documentList); // 构建聚合管道 List<Document> pipeline = Arrays.asList( new Document("$match", filter), // $group 去重 new Document("$group", new Document("_id", "$deviceId")), new Document("$count", "uniqueDeviceIds") ); AggregateIterable<Document> result = collection2.aggregate(pipeline); Integer uniqueDeviceIdCount = 0; for (Document doc : result) { uniqueDeviceIdCount = doc.getInteger("uniqueDeviceIds"); break; // 不需要继续遍历,因为 $count 只会产生一个结果 } 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")); } System.out.println(resultCount); System.out.println(onlineRate); return onlineRate; } /** * 视频:录像可用率 ycl-server/src/main/java/com/ycl/task/ContractTask.java
@@ -24,6 +24,7 @@ import enumeration.general.WorkOrderStatusEnum; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.dao.DataAccessException; import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.data.mongodb.core.query.Criteria; import org.springframework.data.mongodb.core.query.Query; @@ -365,65 +366,87 @@ * 海康取人脸车辆 */ public void randomDeductPic() { log.info("开始抽查图片完整状态"); //这个月随机抽取一天 Date date = getRandomDate(); SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); //准备批量打分的集合 List<ContractScore> contractScoreList = new ArrayList<>(); //查询报备列表 List<String> reportNumbers = reportMapper.selectNumberList(AuditStatus_Pass, DateUtils.getDate()); //查图片完整性规则 获取key为合同id,value为规则的map Map<Integer, List<CalculateRuleVO>> contractMap = contractMapper.getCalculateRule(new Date()).stream() .filter(calculateRuleVO -> ContractRule.CONTRACT_RULE_PicComplete.getName().equals(calculateRuleVO.getRuleName())) .collect(Collectors.groupingBy(CalculateRuleVO::getContractId)); try { log.info("开始抽查图片完整状态"); //这个月随机抽取一天 // Date date = getRandomDate(); Calendar calendar = Calendar.getInstance(); calendar.add(Calendar.MONTH, -1); // 上个月 calendar.set(Calendar.DAY_OF_MONTH, 1); // 设置为1号 //判断车辆、人脸图片是否可用 Query query = new Query(Criteria .where("mongoCreateTime").gte(DateUtils.getDayStart(date)).lt(DateUtils.getDayEnd(date))); List<PicAccessResult> picAccessResults = mongoTemplate.find(query, PicAccessResult.class); List<String> serialNumbers = picAccessResults.stream().map(PicAccessResult::getExternalIndexCode).collect(Collectors.toList()); QueryWrapper<YwPoint> queryWrapper = new QueryWrapper<>(); queryWrapper.in("serial_number", serialNumbers); //获取公司所运维的设备集合,key为unitId value为设备国标码集合 Map<Long, List<String>> unitMonitorMap = ywPointMapper.selectList(queryWrapper).stream() .filter(ywPoint -> ywPoint.getUnitId() != null).collect(Collectors.groupingBy(YwPoint::getUnitId, Collectors.mapping( YwPoint::getSerialNumber, Collectors.toList()))); if (!CollectionUtils.isEmpty(contractMap)) { contractMap.forEach((contractId, ruleList) -> { boolean deduct = false; String serialNumber = null; //此规则对应的unitId均相等 CalculateRuleVO ruleVO = ruleList.get(0); Integer unitId = ruleVO.getUnitId(); List<String> monitorList = unitMonitorMap.get(Long.parseLong(unitId + "")); for (PicAccessResult picAccessResult : picAccessResults) { //判断是否报备过 if (!CollectionUtils.isEmpty(reportNumbers)) { if (reportNumbers.contains(picAccessResult.getExternalIndexCode())) continue; } //判断是否是该公司运维 if (monitorList.contains(picAccessResult.getExternalIndexCode())) { //存在图片访问异常数据量,需要扣减 if (picAccessResult.getExpCount() > 0) { deduct = true; serialNumber = picAccessResult.getExternalIndexCode(); break; int lastDay = calendar.getActualMaximum(Calendar.DAY_OF_MONTH); Random random = new Random(); int randomDay = random.nextInt(lastDay) + 1; calendar.set(Calendar.DAY_OF_MONTH, randomDay); Date date = calendar.getTime(); SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); //准备批量打分的集合 List<ContractScore> contractScoreList = new ArrayList<>(); //查询报备列表 通过审核并且创建时间在当前日期的报备id列表 List<String> reportNumbers = reportMapper.selectNumberList(AuditStatus_Pass, DateUtils.getDate()); //查图片完整性规则 获取key为合同id,value为规则的map Map<Integer, List<CalculateRuleVO>> contractMap = contractMapper.getCalculateRule(new Date()).stream() .filter(calculateRuleVO -> ContractRule.CONTRACT_RULE_PicComplete.getName().equals(calculateRuleVO.getRuleName())) .collect(Collectors.groupingBy(CalculateRuleVO::getContractId)); //判断车辆、人脸图片是否可用 Query query = new Query(Criteria .where("mongoCreateTime").gte(DateUtils.getDayStart(date)).lt(DateUtils.getDayEnd(date))); List<PicAccessResult> picAccessResults = mongoTemplate.find(query, PicAccessResult.class); List<String> serialNumbers = picAccessResults.stream().map(PicAccessResult::getExternalIndexCode).collect(Collectors.toList()); QueryWrapper<YwPoint> queryWrapper = new QueryWrapper<>(); queryWrapper.in("serial_number", serialNumbers); //获取公司所运维的设备集合,key为unitId value为设备国标码集合 Map<Long, List<String>> unitMonitorMap = ywPointMapper.selectList(queryWrapper).stream() .filter(ywPoint -> ywPoint.getUnitId() != null).collect(Collectors.groupingBy(YwPoint::getUnitId, Collectors.mapping( YwPoint::getSerialNumber, Collectors.toList()))); if (!CollectionUtils.isEmpty(contractMap)) { contractMap.forEach((contractId, ruleList) -> { boolean deduct = false; String serialNumber = null; //此规则对应的unitId均相等 CalculateRuleVO ruleVO = ruleList.get(0); Integer unitId = ruleVO.getUnitId(); List<String> monitorList = unitMonitorMap.get(Long.parseLong(unitId + "")); for (PicAccessResult picAccessResult : picAccessResults) { //判断是否报备过 if (!CollectionUtils.isEmpty(reportNumbers)) { if (reportNumbers.contains(picAccessResult.getExternalIndexCode())) continue; } //判断是否是该公司运维 if (monitorList.contains(picAccessResult.getExternalIndexCode())) { //存在图片访问异常数据量,需要扣减 if (picAccessResult.getExpCount() > 0) { deduct = true; serialNumber = picAccessResult.getExternalIndexCode(); break; } } } } if (deduct) { //需要扣除的分数,此规则只有一条不需要判断范围 Double deductScore = ruleVO.getCalcFraction(); ContractScore contractScore = getContractScore(ruleVO, deductScore, "1", Remark + "国标码为:" + serialNumber + "时间:" + format.format(date) + "存在大图不可用数据"); contractScoreList.add(contractScore); } }); if (deduct) { //需要扣除的分数,此规则只有一条不需要判断范围 Double deductScore = ruleVO.getCalcFraction(); ContractScore contractScore = getContractScore(ruleVO, deductScore, "1", Remark + "国标码为:" + serialNumber + "时间:" + format.format(date) + "存在大图不可用数据"); contractScoreList.add(contractScore); } }); } contractScoreService.saveBatch(contractScoreList); log.info("结束抽查图片完整状态"); }catch (NullPointerException e) { log.error("空指针异常,抽查图片完整状态失败: {}", e.getMessage(), e); } catch (DataAccessException e) { log.error("数据库访问异常,抽查图片完整状态失败: {}", e.getMessage(), e); } catch (IllegalArgumentException e) { log.error("参数不合法异常,抽查图片完整状态失败: {}", e.getMessage(), e); } catch (Exception e) { log.error("未知异常,抽查图片完整状态失败: ", e); // 注意这里使用逗号而不是+,可以打印完整堆栈 // 如果需要可以抛出运行时异常 throw new RuntimeException("抽查图片完整状态失败", e); } contractScoreService.saveBatch(contractScoreList); log.info("结束抽查图片完整状态"); } @@ -432,6 +455,7 @@ * 优云取录像 */ public void randomDeductVideo() { try{ log.info("开始抽查录像完整状态"); //这个月随机抽取一天 Date date = getRandomDate(); @@ -503,6 +527,17 @@ }); } contractScoreService.saveBatch(contractScoreList); }catch (NullPointerException e) { log.error("空指针异常,抽查图片完整状态失败: {}", e.getMessage(), e); } catch (DataAccessException e) { log.error("数据库访问异常,抽查图片完整状态失败: {}", e.getMessage(), e); } catch (IllegalArgumentException e) { log.error("参数不合法异常,抽查图片完整状态失败: {}", e.getMessage(), e); } catch (Exception e) { log.error("未知异常,抽查图片完整状态失败: ", e); // 注意这里使用逗号而不是+,可以打印完整堆栈 // 如果需要可以抛出运行时异常 throw new RuntimeException("抽查图片完整状态失败", e); } } private Date getRandomDate() { ycl-server/src/main/java/com/ycl/task/UYTask.java
@@ -351,6 +351,7 @@ } }); pointService.setDeviceTagByGB(records,CheckConstants.Rule_Category_Video); log.error("点位在线率插入数据大小{}",records.size()); //存放在mongo中 mongoTemplate.insertAll(records); //更新point表在线状态 @@ -438,7 +439,6 @@ count.getAndSet(count.get() + 1); if (item.getMissDuration() > minTime){ log.error("改变数据status{}:",item.getRecordStatus()); item.setRecordStatus(0); }else if (item.getMissDuration() < minTime){ item.setRecordStatus(1);