ycl-common/src/main/java/constant/ApiConstants.java
@@ -69,4 +69,12 @@ //省厅前缀 public final static String Province = "Province_"; /** 考核指标 条件参数 */ //车辆考核,点位在线率,区县不少于40路 public final static Integer Check_Car_SiteOnline = 40; //车辆在线率 Redis 每月数据中断次数 Hash key public final static String Check_Car_ViewConnect = "ViewConnectNoData"; } ycl-pojo/src/main/java/com/ycl/platform/domain/entity/CheckIndexCar.java
@@ -16,7 +16,7 @@ * @author ruoyi * @date 2024-04-29 */ @TableName("check_index_car") @TableName("t_check_index_car") public class CheckIndexCar extends CheckIndex { private static final long serialVersionUID = 1L; ycl-server/src/main/java/com/ycl/calculate/CarDataIntegrityCalculation.java
@@ -102,8 +102,8 @@ if (result.getMainNoIntegrityPercent() <= 0.1) { stats.integritySites++; } //重点点位为六项属性 if (importantIds.contains(key)) { //重点点位为六项属性完整 if (importantIds.contains(result.getExternalIndexCode())) { stats.importantTotalSites++; if (result.getNoIntegrityPercent() <= 0.1) { stats.importantIntegritySites++; ycl-server/src/main/java/com/ycl/calculate/CarDeviceSampleCalculation.java
@@ -108,7 +108,7 @@ stats.accuracySites++; } //重点点位为六项属性 if (importantIds.contains(key)) { if (importantIds.contains(result.getExternalIndexCode())) { stats.importantTotalSites++; if (vehDiff.getImportantConPercent() >= 0.9) { stats.importantAccuracySites++; @@ -118,13 +118,15 @@ if (bigUseful.getBigUsefulPercent() >= 0.9) { stats.picUsabilitySites++; } //图片访问正常量 = 抽检量-异常量 BigDecimal picNormalCount = new BigDecimal(bigUseful.getSampleCount() - bigUseful.getBigPicExpCount()); //图片抽检量 BigDecimal sampleCount = new BigDecimal(bigUseful.getSampleCount()); //图片访问率>=90% 视为合格 if (picNormalCount.divide(sampleCount, 4, RoundingMode.HALF_UP).compareTo(new BigDecimal("0.9")) >= 0) { stats.urlUsabilitySites++; if (bigUseful.getSampleCount() != 0) { //图片访问正常量 = 抽检量-异常量 BigDecimal picNormalCount = new BigDecimal(bigUseful.getSampleCount() - bigUseful.getBigPicExpCount()); //图片抽检量 BigDecimal sampleCount = new BigDecimal(bigUseful.getSampleCount()); //图片访问率>=90% 视为合格 if (picNormalCount.divide(sampleCount, 4, RoundingMode.HALF_UP).compareTo(new BigDecimal("0.9")) >= 0) { stats.urlUsabilitySites++; } } } ycl-server/src/main/java/com/ycl/calculate/CarSnapshopDataCalculation.java
@@ -1,28 +1,25 @@ package com.ycl.calculate; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.ycl.platform.domain.entity.CheckIndexCar; import com.ycl.platform.domain.entity.TMonitor; import com.ycl.platform.domain.result.HK.CrossDetailResult; import com.ycl.platform.domain.result.HK.SnapshotDataMonitorResult; import com.ycl.platform.domain.vo.TMonitorVO; import com.ycl.platform.mapper.CheckIndexCarMapper; import com.ycl.platform.mapper.TMonitorMapper; import com.ycl.platform.service.ICheckIndexCarService; import com.ycl.platform.service.ITMonitorService; import com.ycl.system.mapper.SysConfigMapper; import com.ycl.utils.DateUtils; import constant.ApiConstants; import constant.CheckConstants; import constant.CheckSnapCountConstants; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; import utils.DateUtils; import java.math.BigDecimal; import java.math.RoundingMode; import java.time.LocalDate; import java.time.temporal.TemporalAdjusters; import java.util.*; import java.util.function.Function; import java.util.stream.Collectors; @@ -45,6 +42,8 @@ private TMonitorMapper monitorMapper; @Autowired private ICheckIndexCarService checkIndexCarService; @Autowired private RedisTemplate redisTemplate; //区域车辆点位在线指标的内部类 private static class AreaStats { @@ -67,6 +66,15 @@ List<String> provinceIds = getProvince(); Map<String, AreaStats> areaStatsMap = new HashMap<>(); // 获取当前日期 LocalDate today = LocalDate.now(); // 获取本月的第一天 LocalDate firstDayOfMonth = today.with(TemporalAdjusters.firstDayOfMonth()); // 判断今天是否是本月的第一天 if (today.equals(firstDayOfMonth)) { // 如果是,则清除Redis中记录中断次数的数据 redisTemplate.delete(ApiConstants.Check_Car_ViewConnect); } for (SnapshotDataMonitorResult result : list) { TMonitorVO monitor = monitorMap.get(result.getExternalIndexCode()); if (monitor == null) continue; @@ -88,9 +96,9 @@ // 查询是否index表已经存在今日数据 List<CheckIndexCar> checkIndexCarList = checkIndexCarMapper.selectToday(DateUtils.getDate()); List<CheckIndexCar> checkIndexCars = new ArrayList<>(); areaStatsMap.forEach((deptId, stats) -> { areaStatsMap.forEach((key, stats) -> { if (stats.totalSites > 0) { CheckIndexCar checkIndexCar = createOrUpdateCheckIndexCar(deptId, stats, cityCountAvg, countyCountAvg, checkIndexCarList); CheckIndexCar checkIndexCar = createOrUpdateCheckIndexCar(key, stats, cityCountAvg, countyCountAvg, checkIndexCarList); if (checkIndexCar != null) { checkIndexCars.add(checkIndexCar); } @@ -103,15 +111,17 @@ /** * 累计总点位数、离线数、总抓拍量 */ //TODO:无数据处理 private void updateAreaStats(Map<String, AreaStats> areaStatsMap, String key, SnapshotDataMonitorResult result) { //返回对象的引用,如果不存在会放入新的key,value AreaStats stats = areaStatsMap.computeIfAbsent(key, k -> new AreaStats()); stats.totalSites++; if (ApiConstants.HK_SnapCount_ResultType_Null != result.getResultType()) { stats.onlineSites++; } else { stats.totalDataSum += result.getDataCount(); } } /** @@ -133,19 +143,38 @@ if (checkIndexCar == null) { return null; } //调用点位在线计算方法 Map<String, Object> siteOnlineParam = new HashMap<>(); siteOnlineParam.put("totalSites", stats.totalSites); siteOnlineParam.put("onlineSites", stats.onlineSites); BigDecimal siteOnline = siteOnline(siteOnlineParam); checkIndexCar.setSiteOnline(siteOnline); if (stats.totalSites >= ApiConstants.Check_Car_SiteOnline) { Map<String, Object> siteOnlineParam = new HashMap<>(); siteOnlineParam.put("totalSites", stats.totalSites); siteOnlineParam.put("onlineSites", stats.onlineSites); BigDecimal siteOnline = siteOnline(siteOnlineParam); checkIndexCar.setSiteOnline(siteOnline.min(BigDecimal.ONE)); } else { checkIndexCar.setSiteOnline(BigDecimal.ZERO); } //视图库对接稳定性 BigDecimal avgCount = key.startsWith(ApiConstants.Province) ? cityCountAvg : countyCountAvg; Map<String, Object> viewConnectParam = new HashMap<>(); viewConnectParam.put("totalDataSum", stats.totalDataSum); viewConnectParam.put("avgCount", avgCount); BigDecimal viewConnectStability = viewConnectStability(viewConnectParam); checkIndexCar.setViewConnectStability(viewConnectStability); //Redis记录该区县当月无数据上传次数 Integer noDateCount = (Integer) redisTemplate.opsForHash().get(ApiConstants.Check_Car_ViewConnect, key); // 如果值为null,则初始化为0 if (noDateCount == null) { noDateCount = 0; } Double deductScore = 0.1 * noDateCount; if (stats.totalDataSum != 0) { BigDecimal avgCount = key.startsWith(ApiConstants.Province) ? cityCountAvg : countyCountAvg; Map<String, Object> viewConnectParam = new HashMap<>(); viewConnectParam.put("totalDataSum", stats.totalDataSum); viewConnectParam.put("avgCount", avgCount); BigDecimal viewConnectStability = viewConnectStability(viewConnectParam); viewConnectStability = viewConnectStability.subtract(new BigDecimal(deductScore)).max(BigDecimal.ZERO).min(BigDecimal.ONE); checkIndexCar.setViewConnectStability(viewConnectStability); } else { noDateCount++; } // 将新的值放回Hash中 redisTemplate.opsForHash().put(ApiConstants.Check_Car_ViewConnect, key, noDateCount); return checkIndexCar; } } ycl-server/src/main/java/com/ycl/calculate/CarSnapshotDelayCalculation.java
@@ -126,7 +126,7 @@ param.put("delayCount2", stats.delayCount2); param.put("delayCount3", stats.delayCount3); BigDecimal index = snapshopDelay(param); checkIndexCar.setSiteOnline(index); checkIndexCar.setVehicleUploadTimeliness(index); return checkIndexCar; } } ycl-server/src/main/java/com/ycl/calculate/IndexCalculationServe.java
@@ -100,7 +100,7 @@ //视图库对接稳定性 public BigDecimal viewConnectStability(Map<String, Object> param) { BigDecimal totalDataSum = new BigDecimal((Integer) param.get("totalDataSum")); BigDecimal avgCount = new BigDecimal((Integer) param.get("avgCount")); BigDecimal avgCount = (BigDecimal) param.get("avgCount"); return avgCount.divide(totalDataSum, 4, RoundingMode.HALF_UP); } @@ -118,9 +118,9 @@ BigDecimal delayCount2 = new BigDecimal((Integer) param.get("delayCount2")); BigDecimal delayCount3 = new BigDecimal((Integer) param.get("delayCount3")); BigDecimal result = delayCount1.divide(totalCount, 10, RoundingMode.HALF_UP).multiply(BigDecimal.ONE) BigDecimal result = BigDecimal.ONE.subtract(delayCount1.divide(totalCount, 10, RoundingMode.HALF_UP).multiply(BigDecimal.ONE) .add(delayCount2.divide(totalCount, 10, RoundingMode.HALF_UP).multiply(new BigDecimal("0.8"))) .add(delayCount3.divide(totalCount, 10, RoundingMode.HALF_UP).multiply(new BigDecimal("0.6"))); .add(delayCount3.divide(totalCount, 10, RoundingMode.HALF_UP).multiply(new BigDecimal("0.6")))); return result.setScale(4, RoundingMode.HALF_UP); } @@ -131,7 +131,7 @@ BigDecimal integritySites = new BigDecimal((Integer) param.get("integritySites")); BigDecimal importantIntegritySites = new BigDecimal((Integer) param.get("importantIntegritySites")); BigDecimal result = integritySites.divide(totalSites, 10, RoundingMode.HALF_UP) .add(importantIntegritySites.divide(importantTotalSites, 10, RoundingMode.HALF_UP)); .multiply(importantIntegritySites.divide(importantTotalSites, 10, RoundingMode.HALF_UP)); return result.setScale(4, RoundingMode.HALF_UP); } ycl-server/src/main/java/com/ycl/calculate/VideoOnlineCalculation.java
@@ -142,17 +142,25 @@ BigDecimal siteOnline = siteOnline(param); checkIndexVideo.setSiteOnline(siteOnline); //调用点位在线率计算方法 计算重点点位在线率 Map<String, Object> importantParam = new HashMap<>(); importantParam.put("totalSites", stats.importantSites); importantParam.put("onlineSites", stats.importantOnlineSites); BigDecimal importantSiteOnline = siteOnline(importantParam); checkIndexVideo.setKeySiteOnline(importantSiteOnline); if(stats.importantSites!=0) { Map<String, Object> importantParam = new HashMap<>(); importantParam.put("totalSites", stats.importantSites); importantParam.put("onlineSites", stats.importantOnlineSites); BigDecimal importantSiteOnline = siteOnline(importantParam); checkIndexVideo.setKeySiteOnline(importantSiteOnline); }else { log.info("重点点位数为0"); } //调用点位在线率计算方法 计算指挥图像在线率 Map<String, Object> commandParam = new HashMap<>(); commandParam.put("totalSites", stats.commandSites); commandParam.put("onlineSites", stats.commandOnlineSites); BigDecimal commandSiteOnline = siteOnline(commandParam); checkIndexVideo.setKeyCommandImageOnline(commandSiteOnline); if(stats.commandSites!=0) { Map<String, Object> commandParam = new HashMap<>(); commandParam.put("totalSites", stats.commandSites); commandParam.put("onlineSites", stats.commandOnlineSites); BigDecimal commandSiteOnline = siteOnline(commandParam); checkIndexVideo.setKeyCommandImageOnline(commandSiteOnline); }else { log.info("指挥图像点位数为0"); } return checkIndexVideo; } } ycl-server/src/main/java/com/ycl/task/CarTask.java
@@ -7,6 +7,7 @@ import com.ycl.platform.domain.vo.TMonitorVO; import com.ycl.platform.mapper.TMonitorMapper; import com.ycl.utils.DateUtils; import com.ycl.utils.StringUtils; import constant.ApiConstants; import constant.CalculationStrategyConstants; import constant.CheckConstants; @@ -33,79 +34,105 @@ @Autowired private TMonitorMapper monitorMapper; public void siteOnlineTask() { log.info("开始计算点位在线率和视图库对接稳定性"); Date yesterday = DateUtils.addDays(new Date(), -1); //TODO:时间写死了 Date date = DateUtils.getDay(2024,7,13); //计算点位在线率和视图库对接稳定性 Query query = new Query(); query.addCriteria(Criteria .where("mongoCreateTime").gte(DateUtils.getDayStart(yesterday)).lt(DateUtils.getDayEnd(yesterday)) .where("mongoCreateTime").gte(DateUtils.getDayStart(date)).lt(DateUtils.getDayEnd(date)) .and("dataType").is(ApiConstants.HK_DataType_CAR)); List<SnapshotDataMonitorResult> results = mongoTemplate.find(query, SnapshotDataMonitorResult.class); CalculationStrategy<SnapshotDataMonitorResult> calculator = IndexCalculationFactory.getCalculator(CalculationStrategyConstants.Car_SiteOnline_ViewStability); calculator.calculate(results); log.info("结束计算点位在线率和视图库对接稳定性"); } public void deviceSampleTask() { log.info("开始计算车辆卡口设备数据识别准确性、url可用性、大图可用性"); Date yesterday = DateUtils.addDays(new Date(), -1); //TODO:时间写死了 Date date = DateUtils.getDay(2024,7,13); //计算车辆卡口设备数据识别准确性、url可用性、大图可用性 Query query = new Query(); query.addCriteria(Criteria .where("mongoCreateTime").gte(DateUtils.getDayStart(yesterday)).lt(DateUtils.getDayEnd(yesterday))); .where("mongoCreateTime").gte(DateUtils.getDayStart(date)).lt(DateUtils.getDayEnd(date))); List<VehicleDeviceSamplingResult> results = mongoTemplate.find(query, VehicleDeviceSamplingResult.class); CalculationStrategy calculator = IndexCalculationFactory.getCalculator(CalculationStrategyConstants.Car_DataAccuracy_Url_PicUsability); calculator.calculate(results); log.info("结束计算车辆卡口设备数据识别准确性、url可用性、大图可用性"); } public void infoAccuracyTask() { log.info("开始计算车辆卡口信息采集准确率"); Date yesterday = DateUtils.addDays(new Date(), -1); //TODO:时间写死了 Date date = DateUtils.getDay(2024,7,13); //计算车辆卡口信息采集准确率 Query query = new Query(); query.addCriteria(Criteria .where("mongoCreateTime").gte(DateUtils.getDayStart(yesterday)).lt(DateUtils.getDayEnd(yesterday))); .where("mongoCreateTime").gte(DateUtils.getDayStart(date)).lt(DateUtils.getDayEnd(date))); List<CrossDetailResult> results = mongoTemplate.find(query, CrossDetailResult.class); CalculationStrategy calculator = IndexCalculationFactory.getCalculator(CalculationStrategyConstants.Car_InfoAccuracy); calculator.calculate(results); log.info("结束计算车辆卡口信息采集准确率"); } public void snapShopDelay() { public void snapShopDelayTask() { log.info("开始计算车辆抓拍数据上传及时性"); Date yesterday = DateUtils.addDays(new Date(), -1); //TODO:时间写死了 Date date = DateUtils.getDay(2024,7,13); //计算车辆抓拍数据上传及时性 Query query = new Query(); query.addCriteria(Criteria .where("mongoCreateTime").gte(DateUtils.getDayStart(yesterday)).lt(DateUtils.getDayEnd(yesterday)) .where("mongoCreateTime").gte(DateUtils.getDayStart(date)).lt(DateUtils.getDayEnd(date)) .and("dataType").is(ApiConstants.HK_DataType_CAR)); List<SnapshotDelayMonitorResult> results = mongoTemplate.find(query, SnapshotDelayMonitorResult.class); CalculationStrategy calculator = IndexCalculationFactory.getCalculator(CalculationStrategyConstants.Car_SnapshotDelay); calculator.calculate(results); log.info("结束计算车辆抓拍数据上传及时性"); } public void snapShopDataIntegrity() { log.info("开始计算车辆数据抓拍完整性"); Date yesterday = DateUtils.addDays(new Date(), -1); //TODO:时间写死了 Date date = DateUtils.getDay(2024,7,13); //计算车辆数据抓拍完整性 Query query = new Query(); query.addCriteria(Criteria .where("mongoCreateTime").gte(DateUtils.getDayStart(yesterday)).lt(DateUtils.getDayEnd(yesterday))); .where("mongoCreateTime").gte(DateUtils.getDayStart(date)).lt(DateUtils.getDayEnd(date))); List<DataIntegrityMonitoringResult> results = mongoTemplate.find(query, DataIntegrityMonitoringResult.class); CalculationStrategy calculator = IndexCalculationFactory.getCalculator(CalculationStrategyConstants.Car_DataIntegrity); calculator.calculate(results); log.info("结束计算车辆数据抓拍完整性"); } public void clockAccuracyTask() { log.info("开始计算车辆卡口设备时钟准确性"); Date yesterday = DateUtils.addDays(new Date(), -1); //TODO:时间写死了 Date date = DateUtils.getDay(2024,7,13); //计算车辆卡口设备时钟准确性 Query query = new Query(); query.addCriteria(Criteria .where("mongoCreateTime").gte(DateUtils.getDayStart(yesterday)).lt(DateUtils.getDayEnd(yesterday))); .where("mongoCreateTime").gte(DateUtils.getDayStart(date)).lt(DateUtils.getDayEnd(date))); List<VehicleDeviceInspectionResult> results = mongoTemplate.find(query, VehicleDeviceInspectionResult.class); CalculationStrategy calculator = IndexCalculationFactory.getCalculator(CalculationStrategyConstants.Car_ClockAccuracy); calculator.calculate(results); log.info("结束计算车辆卡口设备时钟准确性"); } public void directConsistentTask() { log.info("开始计算车辆目录一致率"); //车辆目录一致率 List<TMonitorVO> tMonitorVOS = monitorMapper.selectMonitorVOList(); List<TMonitorVO> list = tMonitorVOS.stream().filter(tMonitorVO -> tMonitorVO.getCameraFunType().contains(CheckConstants.Rule_Category_Car + "")).collect(Collectors.toList()); List<TMonitorVO> list = tMonitorVOS.stream().filter(tMonitorVO -> !StringUtils.isEmpty(tMonitorVO.getCameraFunType()) && tMonitorVO.getCameraFunType().contains(CheckConstants.Rule_Category_Car + "")).collect(Collectors.toList()); CalculationStrategy calculator = IndexCalculationFactory.getCalculator(CalculationStrategyConstants.Car_DirectConsistent); calculator.calculate(list); log.info("结束计算车辆目录一致率"); } }