ycl-common/src/main/java/constant/ApiConstants.java
@@ -72,9 +72,5 @@ /** 考核指标 条件参数 */ //车辆考核,点位在线率,区县不少于40路 public final static Integer Check_Car_SiteOnline = 40; //车辆在线率 Redis 每月数据中断次数 Hash key public final static String Check_Car_ViewConnect = "ViewConnectNoData"; } ycl-common/src/main/java/constant/CheckThreadConstants.java
New file @@ -0,0 +1,19 @@ package constant; /** * 考核指标计算阈值 */ public class CheckThreadConstants { //视频档案考核比不低于90% public final static String Check_Video_Archive ="0.9"; //视频点位在线率,区县不少于100路 public final static Integer Check_Video_SiteOnline =100; public final static Integer Check_Video_ImportantSite =10; //车辆、人脸考核,点位在线率,区县不少于40路 public final static Integer Check_Car_SiteOnline = 40; public final static Integer Check_Face_SiteOnline = 40; //车辆、人脸在线率 Redis 每月数据中断次数 Hash key public final static String Check_Car_ViewConnect = "CarViewConnectNoData"; public final static String Check_Face_ViewConnect = "FaceViewConnectNoData"; } ycl-pojo/src/main/java/com/ycl/platform/domain/result/HK/FaceDeviceSamplingResult.java
@@ -60,7 +60,8 @@ /** * 人脸合格性相关数据 */ private FaceEligibility faceElig; //TODO:参数名修改看接口是否有参数 private FaceEligibility faceEligibility; // 内嵌对象定义 ycl-server/src/main/java/com/ycl/calculate/CarSnapshopDataCalculation.java
@@ -10,6 +10,7 @@ import com.ycl.utils.DateUtils; import constant.ApiConstants; import constant.CheckSnapCountConstants; import constant.CheckThreadConstants; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.RedisTemplate; @@ -73,7 +74,7 @@ // 判断今天是否是本月的第一天 if (today.equals(firstDayOfMonth)) { // 如果是,则清除Redis中记录中断次数的数据 redisTemplate.delete(ApiConstants.Check_Car_ViewConnect); redisTemplate.delete(CheckThreadConstants.Check_Car_ViewConnect); } for (SnapshotDataMonitorResult result : list) { TMonitorVO monitor = monitorMap.get(result.getExternalIndexCode()); @@ -111,7 +112,6 @@ /** * 累计总点位数、离线数、总抓拍量 */ //TODO:无数据处理 private void updateAreaStats(Map<String, AreaStats> areaStatsMap, String key, SnapshotDataMonitorResult result) { //返回对象的引用,如果不存在会放入新的key,value AreaStats stats = areaStatsMap.computeIfAbsent(key, k -> new AreaStats()); @@ -145,7 +145,7 @@ } //调用点位在线计算方法 if (stats.totalSites >= ApiConstants.Check_Car_SiteOnline) { if (stats.totalSites >= CheckThreadConstants.Check_Car_SiteOnline) { Map<String, Object> siteOnlineParam = new HashMap<>(); siteOnlineParam.put("totalSites", stats.totalSites); siteOnlineParam.put("onlineSites", stats.onlineSites); @@ -156,7 +156,7 @@ } //视图库对接稳定性 //Redis记录该区县当月无数据上传次数 Integer noDateCount = (Integer) redisTemplate.opsForHash().get(ApiConstants.Check_Car_ViewConnect, key); Integer noDateCount = (Integer) redisTemplate.opsForHash().get(CheckThreadConstants.Check_Car_ViewConnect, key); // 如果值为null,则初始化为0 if (noDateCount == null) { noDateCount = 0; @@ -174,7 +174,7 @@ noDateCount++; } // 将新的值放回Hash中 redisTemplate.opsForHash().put(ApiConstants.Check_Car_ViewConnect, key, noDateCount); redisTemplate.opsForHash().put(CheckThreadConstants.Check_Car_ViewConnect, key, noDateCount); return checkIndexCar; } } ycl-server/src/main/java/com/ycl/calculate/FaceConsistentCalculation.java
@@ -27,7 +27,7 @@ import java.util.stream.Collectors; /** * 计算车辆目录一致率 * 计算人脸目录一致率 * 获取分省厅、区域的map<k,v> k为deptId或者Province_deptId * 更新或新增 */ @@ -62,7 +62,7 @@ } //获取省厅国标码集合 List<String> provinceIds = getProvince(); //未注册车辆设备 //未注册人脸设备 Map<String,TMonitor> newMonitorMap = new HashMap<>(); //Mongo一机一档同步Mysql时放入Redis 筛选出车辆档案 String json = (String) redisTemplate.opsForValue().get(RedisConstant.New_Monitor_Set); ycl-server/src/main/java/com/ycl/calculate/FaceDeviceSampleCalculation.java
@@ -93,15 +93,19 @@ //返回对象的引用,如果不存在会放入新的key,value AreaStats stats = areaStatsMap.computeIfAbsent(key, k -> new AreaStats()); FaceDeviceSamplingResult.BigUsefulness bigUseful = result.getBigUseful(); FaceDeviceSamplingResult.FaceEligibility faceElig = result.getFaceElig(); FaceDeviceSamplingResult.FaceEligibility faceElig = result.getFaceEligibility(); stats.totalSites++; //90%及以上数据合格则此人脸设备被视为图片合格 if (faceElig.getFaceEligPercent() >= 0.9) { stats.picQualifySites++; if (faceElig != null) { if (faceElig.getFaceEligPercent() >= 0.9) { stats.picQualifySites++; } } //大图可用率大于90%视为合格 if (bigUseful.getBigUsefulPercent() >= 0.9) { stats.picUsabilitySites++; if (bigUseful != null) { if (bigUseful.getBigUsefulPercent() >= 0.9) { stats.picUsabilitySites++; } } } ycl-server/src/main/java/com/ycl/calculate/FaceSnapshotDataCalculation.java
@@ -14,8 +14,10 @@ import constant.ApiConstants; import constant.CheckConstants; import constant.CheckSnapCountConstants; import constant.CheckThreadConstants; 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; @@ -23,6 +25,7 @@ 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; @@ -46,6 +49,8 @@ private SysConfigMapper sysConfigMapper; @Autowired private TMonitorMapper monitorMapper; @Autowired private RedisTemplate redisTemplate; //区域人脸点位在线指标的内部类 private static class AreaStats { @@ -67,7 +72,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(CheckThreadConstants.Check_Face_ViewConnect); } for (SnapshotDataMonitorResult result : list) { TMonitorVO monitor = monitorMap.get(result.getExternalIndexCode()); if (monitor == null) continue; @@ -129,18 +142,36 @@ return null; } //调用点位在线计算方法 Map<String, Object> siteOnlineParam = new HashMap<>(); siteOnlineParam.put("totalSites", stats.totalSites); siteOnlineParam.put("onlineSites", stats.onlineSites); BigDecimal siteOnline = siteOnline(siteOnlineParam); checkIndexFace.setSiteOnline(siteOnline); if (stats.totalSites >= CheckThreadConstants.Check_Face_SiteOnline) { Map<String, Object> siteOnlineParam = new HashMap<>(); siteOnlineParam.put("totalSites", stats.totalSites); siteOnlineParam.put("onlineSites", stats.onlineSites); BigDecimal siteOnline = siteOnline(siteOnlineParam); checkIndexFace.setSiteOnline(siteOnline); } else { checkIndexFace.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); checkIndexFace.setViewConnectStability(viewConnectStability); //Redis记录该区县当月无数据上传次数 Integer noDateCount = (Integer) redisTemplate.opsForHash().get(CheckThreadConstants.Check_Face_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); checkIndexFace.setViewConnectStability(viewConnectStability); } else { noDateCount++; } // 将新的值放回Hash中 redisTemplate.opsForHash().put(CheckThreadConstants.Check_Face_ViewConnect, key, noDateCount); return checkIndexFace; } } ycl-server/src/main/java/com/ycl/calculate/FaceSnapshotDelayCalculation.java
@@ -120,7 +120,7 @@ param.put("delayCount2", stats.delayCount2); param.put("delayCount3", stats.delayCount3); BigDecimal index = snapshopDelay(param); checkIndexFace.setSiteOnline(index); checkIndexFace.setFaceUploadTimeliness(index); return checkIndexFace; } } ycl-server/src/main/java/com/ycl/calculate/MonitorRegistrationCalculation.java
@@ -10,6 +10,7 @@ import com.ycl.platform.mapper.TMonitorMapper; import com.ycl.platform.service.ICheckIndexVideoService; import constant.ApiConstants; import constant.CheckThreadConstants; import constant.RedisConstant; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; @@ -59,18 +60,18 @@ } //获得国标码为key的设备map Map<String, TMonitorVO> monitorMap = new HashMap<>(); if(!CollectionUtils.isEmpty(list)){ if (!CollectionUtils.isEmpty(list)) { monitorMap = list.stream().collect(Collectors.toMap(TMonitorVO::getSerialNumber, Function.identity())); } //获取省厅国标码集合 List<String> provinceIds = getProvince(); //未注册设备 Map<String,TMonitor> newMonitorMap = new HashMap<>(); Map<String, TMonitor> newMonitorMap = new HashMap<>(); //Mongo一机一档同步Mysql时放入Redis String json = (String) redisTemplate.opsForValue().get(RedisConstant.New_Monitor_Set); if (!StringUtils.isEmpty(json)) { List<TMonitor> newMonitors = JSONArray.parseArray(json, TMonitor.class); if(!CollectionUtils.isEmpty(newMonitors)){ if (!CollectionUtils.isEmpty(newMonitors)) { newMonitorMap = newMonitors.stream().collect(Collectors.toMap(TMonitor::getSerialNumber, Function.identity())); } } @@ -83,11 +84,11 @@ if (monitor == null) continue; String deptId = monitor.getDeptId().toString(); updateAreaStats(areaStatsMap, deptId, result,newMonitorMap,todayMonitor); updateAreaStats(areaStatsMap, deptId, result, newMonitorMap, todayMonitor); // 处理省厅数据 if (!CollectionUtils.isEmpty(provinceIds) && provinceIds.contains(monitor.getSerialNumber())) { String provinceKey = ApiConstants.Province + deptId; updateAreaStats(areaStatsMap, provinceKey, result,newMonitorMap,todayMonitor); updateAreaStats(areaStatsMap, provinceKey, result, newMonitorMap, todayMonitor); } } @@ -109,15 +110,15 @@ /** * 累计总点位数、在线点位数、重点点位数、重点点位在线数、指挥图像数、指挥图像在线数 */ private void updateAreaStats(Map<String, AreaStats> areaStatsMap, String key, TMonitorVO result,Map<String,TMonitor> newMonitors,List<String> todayMonitor) { private void updateAreaStats(Map<String, AreaStats> areaStatsMap, String key, TMonitorVO result, Map<String, TMonitor> newMonitors, List<String> todayMonitor) { //返回对象的引用,如果不存在会放入新的key,value AreaStats stats = areaStatsMap.computeIfAbsent(key, k -> new AreaStats()); stats.totalSites++; stats.allFiles++; if(newMonitors.containsKey(result.getSerialNumber())){ if (newMonitors.containsKey(result.getSerialNumber())) { stats.newSites++; } if(todayMonitor.contains(result.getSerialNumber())){ if (todayMonitor.contains(result.getSerialNumber())) { stats.todayFiles++; } } @@ -141,7 +142,12 @@ archiveParam.put("allFiles", stats.allFiles); archiveParam.put("todayFiles", stats.todayFiles); BigDecimal archivesRate = archivesRate(archiveParam); checkIndexVideo.setArchivesRate(archivesRate); //如果档案考核比低于0.9不得分 if (new BigDecimal(CheckThreadConstants.Check_Video_Archive).compareTo(archivesRate) <= 0) { checkIndexVideo.setArchivesRate(archivesRate); } else { checkIndexVideo.setArchivesRate(BigDecimal.ZERO); } return checkIndexVideo; } ycl-server/src/main/java/com/ycl/calculate/VideoOnlineCalculation.java
@@ -13,6 +13,7 @@ import com.ycl.platform.service.ICheckIndexVideoService; import com.ycl.platform.service.ITMonitorService; import constant.ApiConstants; import constant.CheckThreadConstants; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @@ -141,6 +142,10 @@ param.put("onlineSites", stats.onlineSites); BigDecimal siteOnline = siteOnline(param); checkIndexVideo.setSiteOnline(siteOnline); //区县不少于100路 if(stats.totalSites < CheckThreadConstants.Check_Video_SiteOnline){ checkIndexVideo.setSiteOnline(BigDecimal.ZERO); } //调用点位在线率计算方法 计算重点点位在线率 if(stats.importantSites!=0) { Map<String, Object> importantParam = new HashMap<>(); @@ -151,6 +156,12 @@ }else { log.info("重点点位数为0"); } //区县视频重点点位数不少于10路 if(stats.importantSites<CheckThreadConstants.Check_Video_ImportantSite){ checkIndexVideo.setKeySiteOnline(BigDecimal.ZERO); } //调用点位在线率计算方法 计算指挥图像在线率 if(stats.commandSites!=0) { Map<String, Object> commandParam = new HashMap<>(); ycl-server/src/main/java/com/ycl/task/CarTask.java
@@ -34,7 +34,7 @@ @Autowired private TMonitorMapper monitorMapper; public void siteOnlineTask() { log.info("开始计算点位在线率和视图库对接稳定性"); log.info("开始计算车辆点位在线率和视图库对接稳定性"); Date yesterday = DateUtils.addDays(new Date(), -1); //TODO:时间写死了 Date date = DateUtils.getDay(2024,7,13); ycl-server/src/main/java/com/ycl/task/FaceTask.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; @@ -34,63 +35,85 @@ 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_FACE)); List<SnapshotDataMonitorResult> results = mongoTemplate.find(query, SnapshotDataMonitorResult.class); CalculationStrategy calculator = IndexCalculationFactory.getCalculator(CalculationStrategyConstants.Face_SiteOnline_ViewStability); calculator.calculate(results); log.info("结束计算人脸点位在线率和视图库对接稳定性"); } public void deviceSampleTask() { 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<FaceDeviceSamplingResult> results = mongoTemplate.find(query, FaceDeviceSamplingResult.class); CalculationStrategy calculator = IndexCalculationFactory.getCalculator(CalculationStrategyConstants.Face_DataAccuracy_PicUsability); calculator.calculate(results); log.info("结束计算人脸图片合格率、大图可用性"); } 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<MonitoringDetailResult> results = mongoTemplate.find(query, MonitoringDetailResult.class); CalculationStrategy calculator = IndexCalculationFactory.getCalculator(CalculationStrategyConstants.Face_InfoAccuracy); calculator.calculate(results); log.info("结束计算人脸卡口信息采集准确率"); } public void snapShopDelay(){ 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_FACE)); List<SnapshotDelayMonitorResult> results = mongoTemplate.find(query, SnapshotDelayMonitorResult.class); CalculationStrategy calculator = IndexCalculationFactory.getCalculator(CalculationStrategyConstants.Face_SnapshotDelay); 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<FaceDeviceInspectionResult> results = mongoTemplate.find(query, FaceDeviceInspectionResult.class); CalculationStrategy calculator = IndexCalculationFactory.getCalculator(CalculationStrategyConstants.Face_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_Face + "")).collect(Collectors.toList()); List<TMonitorVO> list = tMonitorVOS.stream().filter(tMonitorVO ->!StringUtils.isEmpty(tMonitorVO.getCameraFunType()) && tMonitorVO.getCameraFunType().contains(CheckConstants.Rule_Category_Face + "")).collect(Collectors.toList()); CalculationStrategy calculator = IndexCalculationFactory.getCalculator(CalculationStrategyConstants.Face_DirectConsistent); calculator.calculate(list); log.info("结束计算人脸目录一致率"); } } ycl-server/src/main/resources/mapper/zgyw/CheckIndexFaceMapper.xml
@@ -112,7 +112,7 @@ </delete> <select id="selectToday" resultType="com.ycl.platform.domain.entity.CheckIndexFace"> select * from t_check_index_car where DATE(create_time) = #{today} select * from t_check_index_face where DATE(create_time) = #{today} </select> <select id="dashboard" resultType="com.ycl.platform.domain.entity.CheckIndexFace">