package com.ycl.calculate; import com.ycl.platform.domain.entity.CheckIndexVideo; import com.ycl.platform.domain.result.UY.PyOsdResult; import com.ycl.platform.domain.result.UY.VideoOnlineResult; import com.ycl.platform.domain.vo.TMonitorVO; import com.ycl.platform.mapper.CheckIndexVideoMapper; import com.ycl.platform.mapper.TMonitorMapper; import com.ycl.platform.service.ICheckIndexVideoService; import constant.ApiConstants; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; import utils.DateUtils; import java.math.BigDecimal; import java.time.Duration; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.function.Function; import java.util.stream.Collectors; /** * 计算视频设备Osd标注信息、时间准确信息 * 获取分省厅、区域的map k为deptId或者Province_deptId * 更新或新增 */ @Component @Slf4j public class VideoOsdCalculation extends IndexCalculationServe implements CalculationStrategy { @Autowired private CheckIndexVideoMapper checkIndexVideoMapper; @Autowired private TMonitorMapper monitorMapper; @Autowired private ICheckIndexVideoService checkIndexVideoService; //区域视频在线率的内部类 private static class AreaStats { int totalSites = 0; int osdAccuracySites = 0; int timeAccuracySites = 0; int importantTotalSites = 0; int importantOsdAccuracySites = 0; int importantTimeAccuracySites = 0; } @Override public void calculate(List list) { if (CollectionUtils.isEmpty(list)) { log.info("数据为空"); return; } //获得国标码为key的设备map Map monitorMap = monitorMapper.selectListByIds(list.stream().map(PyOsdResult::getDeviceNo).collect(Collectors.toList())) .stream().collect(Collectors.toMap(TMonitorVO::getSerialNumber, Function.identity())); //获取省厅国标码集合 List provinceIds = getProvince(); //重点点位集合 List important = getImportant(); Map areaStatsMap = new HashMap<>(); for (PyOsdResult result : list) { TMonitorVO monitor = monitorMap.get(result.getDeviceNo()); if (monitor == null) continue; String deptId = monitor.getDeptId().toString(); updateAreaStats(areaStatsMap, deptId, result, important); // 处理省厅数据 if (!CollectionUtils.isEmpty(provinceIds) && provinceIds.contains(monitor.getSerialNumber())) { String provinceKey = ApiConstants.Province + deptId; updateAreaStats(areaStatsMap, provinceKey, result, important); } } // 查询是否index表已经存在今日数据 List checkIndexVideoList = checkIndexVideoMapper.selectToday(DateUtils.getDate()); List checkIndexVideos = new ArrayList<>(); areaStatsMap.forEach((deptId, stats) -> { if (stats.totalSites > 0) { CheckIndexVideo CheckIndexVideo = createOrUpdateCheckIndexVideo(deptId, stats, checkIndexVideoList); if (CheckIndexVideo != null) { checkIndexVideos.add(CheckIndexVideo); } } }); checkIndexVideoService.saveOrUpdateBatch(checkIndexVideos); } /** * 累计osd合格数、时间偏差合格数 */ private void updateAreaStats(Map areaStatsMap, String key, PyOsdResult result, List important) { //返回对象的引用,如果不存在会放入新的key,value AreaStats stats = areaStatsMap.computeIfAbsent(key, k -> new AreaStats()); stats.totalSites++; //校验osd if (checkOsd(result)) { stats.osdAccuracySites++; } //校验时间偏差 if (checkTime(result)) { stats.timeAccuracySites++; } //重点点位 if (important.contains(result.getDeviceNo())) { stats.importantTotalSites++; if (checkOsd(result)) { stats.importantOsdAccuracySites++; } if (checkTime(result)) { stats.importantTimeAccuracySites++; } } } private Boolean checkOsd(PyOsdResult result) { return ApiConstants.PY_OSD_Correct.equals(result.getOsd1Province()) && ApiConstants.PY_OSD_Correct.equals(result.getOsd1City()) && ApiConstants.PY_OSD_Correct.equals(result.getOsd1Part()) && ApiConstants.PY_OSD_Correct.equals(result.getOsd1LB()) && ApiConstants.PY_OSD_Correct.equals(result.getOsd1OSD()) && ApiConstants.PY_OSD_Correct.equals(result.getOsd1TimeFormat()) && ApiConstants.PY_OSD_Correct.equals(result.getOsd1OsdSet()); } private Boolean checkTime(PyOsdResult result) { DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); // 解析时间字符串 LocalDateTime checkTime = LocalDateTime.parse(result.getCheckTime(), formatter); LocalDateTime osdTime = LocalDateTime.parse(result.getSetTime(), formatter); // 计算时间差(Duration) Duration duration = Duration.between(checkTime, osdTime); // 将时间差转换为秒 long secondsBetween = duration.getSeconds(); // 判断时间差是否在60秒以内 return secondsBetween <= 60; } /** * 视频点位在线率 */ private CheckIndexVideo createOrUpdateCheckIndexVideo(String key, AreaStats stats, List checkIndexVideoList) { CheckIndexVideo checkIndexVideo = getCheckIndex(key, checkIndexVideoList, CheckIndexVideo.class); if (checkIndexVideo == null) { return null; } //调用osd标注计算方法 Map param = new HashMap<>(); param.put("totalSites", stats.totalSites); param.put("osdAccuracySites", stats.osdAccuracySites); BigDecimal osdAccuracy = osdAccuracy(param); checkIndexVideo.setAnnotationAccuracy(osdAccuracy); //调用osd标注计算方法 计算重点osd标注 Map importantParam = new HashMap<>(); importantParam.put("totalSites", stats.importantTotalSites); importantParam.put("osdAccuracySites", stats.importantOsdAccuracySites); BigDecimal imOsdAccuracy = osdAccuracy(importantParam); checkIndexVideo.setKeyAnnotationAccuracy(imOsdAccuracy); //调用osd时间准确率 Map timeParam = new HashMap<>(); timeParam.put("totalSites", stats.totalSites); timeParam.put("timeAccuracySites", stats.timeAccuracySites); BigDecimal osdTimeAccuracy = osdTimeAccuracy(timeParam); checkIndexVideo.setTimingAccuracy(osdTimeAccuracy); //调用osd时间准确率,计算重点 Map importantTimeParam = new HashMap<>(); importantTimeParam.put("totalSites", stats.importantTotalSites); importantTimeParam.put("timeAccuracySites", stats.importantTimeAccuracySites); BigDecimal imOsdTimeAccuracy = osdTimeAccuracy(importantTimeParam); checkIndexVideo.setKeyTimingAccuracy(imOsdTimeAccuracy); return checkIndexVideo; } }