| | |
| | | import annotation.DataScope; |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import com.mongodb.client.AggregateIterable; |
| | | import com.mongodb.client.MongoCollection; |
| | | import com.mongodb.client.MongoDatabase; |
| | | import com.ycl.platform.domain.entity.MonitorConstruction; |
| | | import com.ycl.platform.domain.entity.TMonitor; |
| | | import com.ycl.platform.domain.excel.*; |
| | | import com.ycl.platform.domain.form.VideoExportForm; |
| | | import com.ycl.platform.domain.query.DashboardQuery; |
| | | import com.ycl.platform.domain.query.DataCenterQuery; |
| | | import com.ycl.platform.domain.query.HomeQuery; |
| | | import com.ycl.platform.domain.result.HK.FaceDeviceInspectionResult; |
| | | import com.ycl.platform.domain.result.HK.FaceDeviceSamplingResult; |
| | | import com.ycl.platform.domain.result.HK.VehicleDeviceInspectionResult; |
| | | import com.ycl.platform.domain.result.HK.VehicleDeviceSamplingResult; |
| | | import com.ycl.platform.domain.result.BaseResult; |
| | | import com.ycl.platform.domain.result.HK.*; |
| | | import com.ycl.platform.domain.result.SYS.TMonitorResult; |
| | | import com.ycl.platform.domain.result.UY.MonitorQualifyResult; |
| | | import com.ycl.platform.domain.result.UY.OsdCheckResult; |
| | | import com.ycl.platform.domain.result.UY.RecordMetaDSumResult; |
| | | import com.ycl.platform.domain.vo.DynamicColumnVO; |
| | | import com.ycl.platform.domain.vo.TMonitorVO; |
| | | import com.ycl.platform.domain.vo.WorkOrderVO; |
| | | import com.ycl.platform.domain.vo.home.BaseHomeVO; |
| | | import com.ycl.platform.domain.vo.home.HomeCarVO; |
| | | import com.ycl.platform.domain.vo.home.HomeFaceVO; |
| | | import com.ycl.platform.domain.vo.home.HomeVideoVO; |
| | | import com.ycl.platform.domain.vo.screen.MonitorRateVO; |
| | | import com.ycl.platform.domain.vo.screen.MonitorTotalVO; |
| | | import com.ycl.platform.mapper.TMonitorMapper; |
| | | import com.ycl.platform.mapper.WorkOrderMapper; |
| | | import com.ycl.platform.mapper.*; |
| | | import com.ycl.platform.service.IMonitorConstructionService; |
| | | import com.ycl.platform.service.ITMonitorService; |
| | | import com.ycl.system.Result; |
| | | import com.ycl.system.entity.SysDictData; |
| | | import com.ycl.system.mapper.SysDictDataMapper; |
| | | import com.ycl.system.page.PageUtil; |
| | | import com.ycl.system.service.ISysConfigService; |
| | | import com.ycl.utils.DateUtils; |
| | | import com.ycl.utils.StringUtils; |
| | | import com.ycl.utils.poi.ExcelUtil; |
| | | import constant.ApiConstants; |
| | | import enumeration.general.AreaDeptEnum; |
| | | import jakarta.servlet.http.HttpServletResponse; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.apache.commons.lang3.ObjectUtils; |
| | | import org.apache.commons.lang3.Validate; |
| | | import org.bson.Document; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.data.mongodb.core.MongoTemplate; |
| | | 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 org.springframework.transaction.annotation.Transactional; |
| | | import org.springframework.util.CollectionUtils; |
| | | import pojo.ExcelExp; |
| | | import utils.poi.ExcelUtilManySheet; |
| | | |
| | | import java.io.IOException; |
| | | import java.lang.reflect.Field; |
| | | import java.lang.reflect.InvocationTargetException; |
| | | import java.math.BigDecimal; |
| | | import java.math.RoundingMode; |
| | | import java.text.ParseException; |
| | | import java.text.SimpleDateFormat; |
| | | import java.time.LocalDate; |
| | | import java.time.YearMonth; |
| | | import java.time.format.DateTimeFormatter; |
| | | import java.util.*; |
| | | import java.util.concurrent.*; |
| | | import java.util.function.Function; |
| | | import java.util.regex.Pattern; |
| | | import java.util.stream.Collectors; |
| | | |
| | | import static com.ycl.utils.PageUtils.startPage; |
| | | |
| | | /** |
| | | * 设备资产Service业务层处理 |
| | |
| | | * @date 2024-03-04 |
| | | */ |
| | | @Service |
| | | @Slf4j |
| | | public class TMonitorServiceImpl extends ServiceImpl<TMonitorMapper, TMonitor> implements ITMonitorService { |
| | | @Autowired |
| | | private TMonitorMapper tMonitorMapper; |
| | | @Autowired |
| | | private YwPointMapper pointMapper; |
| | | @Autowired |
| | | private ISysConfigService configService; |
| | | @Autowired |
| | | private MongoTemplate mongoTemplate; |
| | | @Autowired |
| | | private WorkOrderMapper workOrderMapper; |
| | | @Autowired |
| | | private SysDictDataMapper dictDataMapper; |
| | | @Autowired |
| | | private DynamicColumnMapper dynamicColumnMapper; |
| | | @Autowired |
| | | private ThreadPoolTaskExecutor threadPoolTaskExecutor; |
| | | @Autowired |
| | | private IMonitorConstructionService monitorConstructionService; |
| | | /** |
| | | * 查询设备资产 |
| | | * |
| | |
| | | } |
| | | tMonitor.setTime(time); |
| | | } |
| | | List<TMonitorVO> monitors = tMonitorMapper.selectTMonitorList(tMonitor); |
| | | // 异常恢复监控 |
| | | if(Objects.equals(tMonitor.getRecovery(), 1L)){ |
| | | //工单号 |
| | | List<String> orders = monitors.stream().map(TMonitorVO::getWorkOrderNo).collect(Collectors.toList()); |
| | | if(CollectionUtils.isEmpty(orders)){ |
| | | List<TMonitorVO> monitors = new ArrayList<>(); |
| | | if (StringUtils.isNotBlank(tMonitor.getConstructionType())){ |
| | | List<MonitorConstruction> list = |
| | | monitorConstructionService.getSerialNumberListByConstructionType(tMonitor.getConstructionType()); |
| | | log.info("打印查询设备标签数:{},建设类型标签:{}",list.size(), tMonitor.getConstructionType() ); |
| | | //获得设备编号集合 通过建设类型标签 |
| | | if(!CollectionUtils.isEmpty(list)){ |
| | | tMonitor.setIds( |
| | | list.stream().map(MonitorConstruction::getSerialNumber).collect(Collectors.toList())); |
| | | |
| | | startPage(); |
| | | monitors = tMonitorMapper.selectTMonitorListAndIds(tMonitor); |
| | | } |
| | | |
| | | }else{ |
| | | startPage(); |
| | | monitors = tMonitorMapper.selectTMonitorList(tMonitor); |
| | | } |
| | | // 异常恢复监控 |
| | | if (Objects.equals(tMonitor.getRecovery(), 1L)) { |
| | | //工单号 |
| | | List<String> orders = monitors.stream().map(TMonitorVO::getWorkOrderNo).collect(Collectors.toList()); |
| | | if (CollectionUtils.isEmpty(orders)) { |
| | | return monitors; |
| | | } |
| | | List<WorkOrderVO> voList = workOrderMapper.getRecoveryInfo(orders); |
| | | for (TMonitorVO monitor : monitors) { |
| | | if (!CollectionUtils.isEmpty(voList)) { |
| | | for (WorkOrderVO workOrderVO : voList) { |
| | | if (monitor.getWorkOrderNo() != null && monitor.getWorkOrderNo().equals(workOrderVO.getWorkOrderNo())) { |
| | | monitor.setUnitContact(workOrderVO.getUnitContact()); |
| | | monitor.setUnitContactPhone(workOrderVO.getUnitContactPhone()); |
| | | monitor.setYwPeopleName(workOrderVO.getYwPeopleName()); |
| | | monitor.setErrorType(workOrderVO.getErrorType()); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | return monitors; |
| | | } |
| | | List<WorkOrderVO> voList = workOrderMapper.getRecoveryInfo(orders); |
| | | for (TMonitorVO monitor : monitors) { |
| | | if(!CollectionUtils.isEmpty(voList)){ |
| | | for (WorkOrderVO workOrderVO : voList) { |
| | | if(monitor.getWorkOrderNo().equals(workOrderVO.getWorkOrderNo())){ |
| | | monitor.setUnitContact(workOrderVO.getUnitContact()); |
| | | monitor.setUnitContactPhone(workOrderVO.getUnitContactPhone()); |
| | | monitor.setYwPeopleName(workOrderVO.getYwPeopleName()); |
| | | monitor.setErrorType(workOrderVO.getErrorType()); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | return monitors; |
| | | } |
| | | //设备编号 |
| | | List<String> numbers = monitors.stream().map(TMonitorVO::getSerialNumber).collect(Collectors.toList()); |
| | | Query query = new Query(); |
| | | //TODO:本地测试 |
| | | // Date now = new Date() |
| | | Date now = DateUtils.getDay(2024, 7, 13); |
| | | query.addCriteria(Criteria.where("no").in(numbers) |
| | | .and("mongoCreateTime").gte(DateUtils.getDayStart(now)).lt(DateUtils.getDayEnd(now)) |
| | | ); |
| | | //一机一档信息 |
| | | List<MonitorQualifyResult> monitorQualifyResults = mongoTemplate.find(query, MonitorQualifyResult.class); |
| | | // 视频监控设备 |
| | | if (Objects.equals(tMonitor.getCameraFunType(), "1")) { |
| | | //OSD信息 |
| | | List<OsdCheckResult> osdCheckResults = mongoTemplate.find(query, OsdCheckResult.class); |
| | | //录像可用信息 |
| | | List<RecordMetaDSumResult> videoResults = mongoTemplate.find(query, RecordMetaDSumResult.class); |
| | | for (TMonitorVO monitor : monitors) { |
| | | monitor.setMongoCreateTime(now); |
| | | //一机一档 |
| | | setOneFile(monitorQualifyResults, monitor); |
| | | //录像 |
| | | if (!CollectionUtils.isEmpty(videoResults)) { |
| | | for (RecordMetaDSumResult videoResult : videoResults) { |
| | | if (monitor.getSerialNumber().equals(videoResult.getNo())) { |
| | | monitor.setVideoComplete(videoResult.getRecordStatus()); |
| | | monitor.setVideoLoseTime(videoResult.getMissDuration()); |
| | | } |
| | | } |
| | | } |
| | | //OSD |
| | | if (!CollectionUtils.isEmpty(osdCheckResults)) { |
| | | for (OsdCheckResult osdCheckResult : osdCheckResults) { |
| | | if (monitor.getSerialNumber().equals(osdCheckResult.getNo())) { |
| | | monitor.setOSD(OsdCheckResult.checkOsd(osdCheckResult)); |
| | | monitor.setOSDTime(OsdCheckResult.checkTime(osdCheckResult)); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | // 车辆监控设备 |
| | | if (Objects.equals(tMonitor.getCameraFunType(), "2")) { |
| | | //属性一致率、大图、url |
| | | List<VehicleDeviceSamplingResult> sampleResults = mongoTemplate.find(query, VehicleDeviceSamplingResult.class); |
| | | //抓拍量、时钟、上传 |
| | | List<VehicleDeviceInspectionResult> inspectResults = mongoTemplate.find(query, VehicleDeviceInspectionResult.class); |
| | | for (TMonitorVO monitor : monitors) { |
| | | monitor.setMongoCreateTime(now); |
| | | //一机一档 |
| | | setOneFile(monitorQualifyResults, monitor); |
| | | //属性一致率、大图、url |
| | | if (!CollectionUtils.isEmpty(sampleResults)) { |
| | | for (VehicleDeviceSamplingResult sampleResult : sampleResults) { |
| | | if (monitor.getSerialNumber().equals(sampleResult.getNo())) { |
| | | if (sampleResult.getBigUseful() != null) { |
| | | monitor.setBigUsefulPercent(sampleResult.getBigUseful().getBigUsefulPercent()); |
| | | monitor.setUrlPercent(VehicleDeviceSamplingResult.BigUsefulness.calUrl(sampleResult.getBigUseful())); |
| | | //设备编号 |
| | | List<String> numbers = monitors.stream().map(TMonitorVO::getSerialNumber).collect(Collectors.toList()); |
| | | Query query = new Query(); |
| | | Date now = new Date(); |
| | | query.addCriteria(Criteria.where("no").in(numbers) |
| | | .and("mongoCreateTime").gte(DateUtils.getDayStart(now)).lt(DateUtils.getDayEnd(now)) |
| | | ); |
| | | //一机一档信息 |
| | | List<MonitorQualifyResult> monitorQualifyResults = mongoTemplate.find(query, MonitorQualifyResult.class); |
| | | // 视频监控设备 |
| | | if (Objects.equals(tMonitor.getCameraFunType(), "1")) { |
| | | //OSD信息 |
| | | List<OsdCheckResult> osdCheckResults = mongoTemplate.find(query, OsdCheckResult.class); |
| | | //录像可用信息 |
| | | List<RecordMetaDSumResult> videoResults = mongoTemplate.find(query, RecordMetaDSumResult.class); |
| | | for (TMonitorVO monitor : monitors) { |
| | | monitor.setMongoCreateTime(now); |
| | | //一机一档 |
| | | setOneFile(monitorQualifyResults, monitor); |
| | | //录像 |
| | | if (!CollectionUtils.isEmpty(videoResults)) { |
| | | for (RecordMetaDSumResult videoResult : videoResults) { |
| | | if (monitor.getSerialNumber().equals(videoResult.getNo())) { |
| | | monitor.setVideoComplete(videoResult.getRecordStatus()); |
| | | monitor.setVideoLoseTime(videoResult.getMissDuration()); |
| | | } |
| | | if (sampleResult.getVehDiff() != null) { |
| | | monitor.setImportantConPercent(sampleResult.getVehDiff().getImportantConPercent()); |
| | | monitor.setMajorConPercent(sampleResult.getVehDiff().getMajorConPercent()); |
| | | } |
| | | } |
| | | //OSD |
| | | if (!CollectionUtils.isEmpty(osdCheckResults)) { |
| | | for (OsdCheckResult osdCheckResult : osdCheckResults) { |
| | | if (monitor.getSerialNumber().equals(osdCheckResult.getNo())) { |
| | | monitor.setOSD(OsdCheckResult.checkOsd(osdCheckResult)); |
| | | monitor.setOSDTime(OsdCheckResult.checkTime(osdCheckResult)); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | // 车辆监控设备 |
| | | if (Objects.equals(tMonitor.getCameraFunType(), "2")) { |
| | | //属性一致率、大图 |
| | | List<VehicleDeviceSamplingResult> sampleResults = mongoTemplate.find(query, VehicleDeviceSamplingResult.class); |
| | | List<PicAccessResult> picAccessResults = mongoTemplate.find(query, PicAccessResult.class); |
| | | //抓拍量、时钟、上传 |
| | | if (!CollectionUtils.isEmpty(inspectResults)) { |
| | | for (VehicleDeviceInspectionResult inspectResult : inspectResults) { |
| | | if (monitor.getSerialNumber().equals(inspectResult.getNo())) { |
| | | monitor.setSnapResult(inspectResult.getSnapResult()); |
| | | monitor.setSnapCount(inspectResult.getDataCount()); |
| | | if (inspectResult.getSnapClock() != null) |
| | | monitor.setClockPercent(inspectResult.getSnapClock().getClockPercent()); |
| | | if (inspectResult.getSnapTimely() != null) |
| | | monitor.setUploadPercent(inspectResult.getSnapTimely().getTimelyPercent()); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | // 人脸监控设备 |
| | | if (Objects.equals(tMonitor.getCameraFunType(), "3")) { |
| | | //人脸合格、大图、url访问异常 |
| | | List<FaceDeviceSamplingResult> sampleResults = mongoTemplate.find(query, FaceDeviceSamplingResult.class); |
| | | //抓拍量、时钟、上传 |
| | | List<FaceDeviceInspectionResult> inspectResults = mongoTemplate.find(query, FaceDeviceInspectionResult.class); |
| | | for (TMonitorVO monitor : monitors) { |
| | | monitor.setMongoCreateTime(now); |
| | | //一机一档 |
| | | setOneFile(monitorQualifyResults, monitor); |
| | | //人脸合格、大图、url访问异常 |
| | | if (!CollectionUtils.isEmpty(sampleResults)) { |
| | | for (FaceDeviceSamplingResult sampleResult : sampleResults) { |
| | | if (monitor.getSerialNumber().equals(sampleResult.getNo())) { |
| | | if (sampleResult.getBigUseful() != null) { |
| | | monitor.setBigUsefulPercent(sampleResult.getBigUseful().getBigUsefulPercent()); |
| | | monitor.setUrlPercent(FaceDeviceSamplingResult.BigUsefulness.calUrl(sampleResult.getBigUseful())); |
| | | List<VehicleDeviceInspectionResult> inspectResults = mongoTemplate.find(query, VehicleDeviceInspectionResult.class); |
| | | for (TMonitorVO monitor : monitors) { |
| | | monitor.setMongoCreateTime(now); |
| | | //一机一档 |
| | | setOneFile(monitorQualifyResults, monitor); |
| | | //url |
| | | if (!CollectionUtils.isEmpty(sampleResults)) { |
| | | for (PicAccessResult picAccessResult : picAccessResults) { |
| | | if (monitor.getSerialNumber().equals(picAccessResult.getNo())) { |
| | | BigDecimal bigDecimal = PicAccessResult.calUrl(picAccessResult); |
| | | monitor.setUrlPercent(bigDecimal); |
| | | } |
| | | if (sampleResult.getFaceEligibility() != null) |
| | | monitor.setFacePercent(sampleResult.getFaceEligibility().getFaceEligPercent()); |
| | | } |
| | | } |
| | | } |
| | | //抓拍量、时钟、上传、建模失败率 |
| | | if (!CollectionUtils.isEmpty(inspectResults)) { |
| | | for (FaceDeviceInspectionResult inspectResult : inspectResults) { |
| | | if (monitor.getSerialNumber().equals(inspectResult.getNo())) { |
| | | monitor.setSnapResult(inspectResult.getSnapResult()); |
| | | monitor.setSnapCount(inspectResult.getDataCount()); |
| | | if (inspectResult.getSnapClock() != null) |
| | | monitor.setClockPercent(inspectResult.getSnapClock().getClockPercent()); |
| | | if (inspectResult.getSnapTimely() != null) |
| | | monitor.setUploadPercent(inspectResult.getSnapTimely().getTimelyPercent()); |
| | | if (inspectResult.getSnapValidity() != null) |
| | | monitor.setFailPercent(inspectResult.getSnapValidity().getFailPercent()); |
| | | //属性一致率、大图 |
| | | if (!CollectionUtils.isEmpty(sampleResults)) { |
| | | for (VehicleDeviceSamplingResult sampleResult : sampleResults) { |
| | | if (monitor.getSerialNumber().equals(sampleResult.getNo())) { |
| | | if (sampleResult.getBigUseful() != null) { |
| | | monitor.setBigUsefulPercent(sampleResult.getBigUseful().getBigUsefulPercent()); |
| | | } |
| | | if (sampleResult.getVehDiff() != null) { |
| | | monitor.setImportantConPercent(sampleResult.getVehDiff().getImportantConPercent()); |
| | | monitor.setMajorConPercent(sampleResult.getVehDiff().getMajorConPercent()); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | //抓拍量、时钟、上传 |
| | | if (!CollectionUtils.isEmpty(inspectResults)) { |
| | | for (VehicleDeviceInspectionResult inspectResult : inspectResults) { |
| | | if (monitor.getSerialNumber().equals(inspectResult.getNo())) { |
| | | monitor.setSnapResult(inspectResult.getSnapResult()); |
| | | monitor.setSnapCount(inspectResult.getDataCount()); |
| | | if (inspectResult.getSnapClock() != null) |
| | | monitor.setClockPercent(inspectResult.getSnapClock().getClockPercent()); |
| | | if (inspectResult.getSnapTimely() != null) |
| | | monitor.setUploadPercent(inspectResult.getSnapTimely().getTimelyPercent()); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | // 人脸监控设备 |
| | | if (Objects.equals(tMonitor.getCameraFunType(), "3")) { |
| | | //人脸合格、大图、url访问异常 |
| | | List<FaceDeviceSamplingResult> sampleResults = mongoTemplate.find(query, FaceDeviceSamplingResult.class); |
| | | //抓拍量、时钟、上传 |
| | | List<FaceDeviceInspectionResult> inspectResults = mongoTemplate.find(query, FaceDeviceInspectionResult.class); |
| | | for (TMonitorVO monitor : monitors) { |
| | | monitor.setMongoCreateTime(now); |
| | | //一机一档 |
| | | setOneFile(monitorQualifyResults, monitor); |
| | | //人脸合格、大图 |
| | | if (!CollectionUtils.isEmpty(sampleResults)) { |
| | | for (FaceDeviceSamplingResult sampleResult : sampleResults) { |
| | | if (monitor.getSerialNumber().equals(sampleResult.getNo())) { |
| | | if (sampleResult.getBigUseful() != null) { |
| | | monitor.setBigUsefulPercent(sampleResult.getBigUseful().getBigUsefulPercent()); |
| | | } |
| | | if (sampleResult.getFaceEligibility() != null) |
| | | monitor.setFacePercent(sampleResult.getFaceEligibility().getFaceEligPercent()); |
| | | } |
| | | } |
| | | } |
| | | //抓拍量、时钟、上传、建模失败率 |
| | | if (!CollectionUtils.isEmpty(inspectResults)) { |
| | | for (FaceDeviceInspectionResult inspectResult : inspectResults) { |
| | | if (monitor.getSerialNumber().equals(inspectResult.getNo())) { |
| | | monitor.setSnapResult(inspectResult.getSnapResult()); |
| | | monitor.setSnapCount(inspectResult.getDataCount()); |
| | | if (inspectResult.getSnapClock() != null) |
| | | monitor.setClockPercent(inspectResult.getSnapClock().getClockPercent()); |
| | | if (inspectResult.getSnapTimely() != null) |
| | | monitor.setUploadPercent(inspectResult.getSnapTimely().getTimelyPercent()); |
| | | if (inspectResult.getSnapValidity() != null) |
| | | monitor.setFailPercent(inspectResult.getSnapValidity().getFailPercent()); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | return monitors; |
| | | } |
| | | |
| | |
| | | @Override |
| | | @DataScope(deptAlias = "d", userAlias = "u") |
| | | public Map<String, String> getVideoCount(TMonitorVO tMonitor) { |
| | | |
| | | List<MonitorConstruction> list = |
| | | monitorConstructionService.getSerialNumberListByConstructionType(tMonitor.getConstructionType()); |
| | | //获得设备编号集合 通过建设类型标签 |
| | | tMonitor.setIds( |
| | | list.stream().map(MonitorConstruction::getSerialNumber).collect(Collectors.toList())); |
| | | |
| | | return tMonitorMapper.getVideoCount(tMonitor); |
| | | } |
| | | |
| | |
| | | return tMonitorMapper.recoveryException(monitor); |
| | | } |
| | | |
| | | /** |
| | | * 查mongo查某个月设备总数 |
| | | * 查看工单数量查看异常的数 |
| | | * |
| | | * @param monitorQuery 查询条件 |
| | | * @return |
| | | */ |
| | | @Override |
| | | public Map<String, Object> home(HomeQuery monitorQuery) { |
| | | System.out.println(monitorQuery + "~~~~~~~~~~~~~打印"); |
| | | Map<String, Object> dataMap = new HashMap<>(); |
| | | Map<String, Object> monthMap1 = new HashMap<>(); |
| | | Map<String, Object> monthMap2 = new HashMap<>(); |
| | | List<Map<String, Object>> home = baseMapper.home(monitorQuery); |
| | | if (ObjectUtils.isNotEmpty(home)) { |
| | | //拿到数据库 循环查询 |
| | | System.out.println(home + "~~~~~~~~~~~~~打印"); |
| | | for (Map<String, Object> map : home) { |
| | | //得到map的 months键的值 num1键的值 组装为新对象 |
| | | monthMap1.put(map.get("months").toString(), map.get("num1")); |
| | | //得到map的 months键的值 num2键的值 组装为新对象 |
| | | monthMap2.put(map.get("months").toString(), map.get("num2")); |
| | | } |
| | | //home 的下标0的 map的 name键的值 |
| | | dataMap.put("name", home.get(0).get("name")); |
| | | dataMap.put("state", monthMap1); |
| | | dataMap.put("state2", monthMap2); |
| | |
| | | } |
| | | |
| | | @Override |
| | | public List<MonitorTotalVO> monitorTotal(DashboardQuery dashboardQuery) { |
| | | return baseMapper.monitorTotal(dashboardQuery); |
| | | public Map<String, List<Map<String, Object>>> monitorTotal(DashboardQuery dashboardQuery) { |
| | | List<MonitorTotalVO> monitorTotalVOS = baseMapper.monitorTotal(dashboardQuery); |
| | | /** facilityData: { |
| | | * video:[ |
| | | * {value: 4589,title: '设备总数'}, |
| | | * {value: 4294,title: '设备正常数'}, |
| | | * {value: 295,title: '设备异常数'} |
| | | * ]} */ |
| | | Map<String, List<Map<String, Object>>> resultMap = new HashMap<>(); |
| | | for (MonitorTotalVO vo : monitorTotalVOS) { |
| | | List<Map<String, Object>> list = new ArrayList(); |
| | | Map<String, Object> total = new HashMap<>(); |
| | | total.put("value", vo.getTotalNum()); |
| | | total.put("title", "设备总数"); |
| | | Map<String, Object> normal = new HashMap<>(); |
| | | normal.put("value", vo.getNormalNum()); |
| | | normal.put("title", "正常数"); |
| | | Map<String, Object> error = new HashMap<>(); |
| | | error.put("value", vo.getErrorNum()); |
| | | error.put("title", "异常数"); |
| | | list.add(total); |
| | | list.add(normal); |
| | | list.add(error); |
| | | resultMap.put(vo.getType(), list); |
| | | } |
| | | return resultMap; |
| | | } |
| | | |
| | | @Override |
| | |
| | | baseMapper.assetManagement(page, query); |
| | | return Result.ok().data(page.getRecords()).total(page.getTotal()); |
| | | } |
| | | |
| | | /** |
| | | * 导出总量数据 |
| | | */ |
| | | @Override |
| | | public void exportVideoTotal(HttpServletResponse response, VideoExportForm exportForm) throws IOException { |
| | | //默认查所有部门 |
| | | if (CollectionUtils.isEmpty(exportForm.getDeptIds())) { |
| | | List<Integer> deptIds = new ArrayList<>(); |
| | | for (AreaDeptEnum value : AreaDeptEnum.values()) { |
| | | deptIds.add(value.getDeptId()); |
| | | } |
| | | exportForm.setDeptIds(deptIds); |
| | | } |
| | | List<ExcelExp> sheet = new ArrayList<>(); |
| | | //通过Collections静态方法,把list转为线程安全的list |
| | | List mysheet = Collections.synchronizedList(sheet); |
| | | VideoExportForm.convertTags(exportForm); |
| | | Query query = getQuery(exportForm); |
| | | //月份每日在线数据 |
| | | List<TMonitorResult> onlineResult = mongoTemplate.find(query, TMonitorResult.class); |
| | | // 使用 Collectors.toMap 去重,保留每个 No 的第一个遇到的元素 |
| | | Map<String, TMonitorResult> uniqueResultsMap = onlineResult.stream() |
| | | .collect(Collectors.toMap( |
| | | TMonitorResult::getNo, // keyMapper,这里假设 getNo() 返回 No 字段 |
| | | Function.identity(), // valueMapper,直接使用对象本身 |
| | | (existing, replacement) -> existing // mergeFunction,如果有重复,保留第一个 |
| | | )); |
| | | // 将 Map 转换为 List |
| | | List<TMonitorResult> tMonitorResults = new ArrayList<>(uniqueResultsMap.values()); |
| | | List<String> deviceIds = tMonitorResults.stream().map(BaseResult::getNo).collect(Collectors.toList()); |
| | | // 将年月字符串解析为YearMonth对象 |
| | | YearMonth yearMonth = YearMonth.parse(exportForm.getMonth()); |
| | | // 获取当月的第一天 |
| | | LocalDate start = yearMonth.atDay(1); |
| | | // 获取下个月的第一天(通过加上1个月并设置日为1) |
| | | YearMonth nextMonth = yearMonth.plusMonths(1); |
| | | LocalDate end = nextMonth.atDay(1); |
| | | //获取这个月份的部门数据,录像由于是前一天的所以不用createTime字段 |
| | | Query videoQuery = new Query(Criteria.where("statTime").gte(start).lt(end)); |
| | | videoQuery.addCriteria(Criteria.where("no").in(deviceIds)); |
| | | //月份每日录像数据 |
| | | List<RecordMetaDSumResult> recordResult = mongoTemplate.find(videoQuery, RecordMetaDSumResult.class); |
| | | DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); |
| | | String[] weeks = {"星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期日"}; |
| | | // 创建一个Map来存储每天的累加数据 |
| | | Map<String, VideoTotalExp> totalMap = new ConcurrentHashMap<>(); |
| | | List<CompletableFuture<Void>> futures = new ArrayList<>(); |
| | | //一个部门一个sheet |
| | | for (Integer deptId : exportForm.getDeptIds()) { |
| | | CompletableFuture<Void> future = CompletableFuture.runAsync(() -> { |
| | | SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd"); |
| | | //筛选部门数据 |
| | | Set<String> ids = onlineResult.stream().filter(tMonitorResult -> deptId.equals(tMonitorResult.getDeptId())).map(BaseResult::getNo).collect(Collectors.toSet()); |
| | | if (CollectionUtils.isEmpty(ids)) return; |
| | | //筛选部门数据 |
| | | List<TMonitorResult> onlineList = onlineResult.stream().filter(tMonitorResult -> deptId.equals(tMonitorResult.getDeptId())).collect(Collectors.toList()); |
| | | Map<LocalDate, List<TMonitorResult>> onlineMap = onlineList.stream() |
| | | .collect(Collectors.groupingBy(TMonitorResult::getMongoCreateTime)); |
| | | List<RecordMetaDSumResult> recordList = recordResult.stream().filter(result -> ids.contains(result.getNo())).collect(Collectors.toList()); |
| | | Map<Date, List<RecordMetaDSumResult>> recordMap = recordList.stream().collect(Collectors.groupingBy(RecordMetaDSumResult::getStatTime)); |
| | | List<VideoTotalExp> videoTotalExps = new ArrayList<>(); |
| | | for (int i = 0; i < 31; i++) { |
| | | String date = exportForm.getMonth(); |
| | | date += "-" + (i < 9 ? "0" + (i + 1) : (i + 1)); |
| | | //总量 |
| | | VideoTotalExp totalExp = totalMap.computeIfAbsent(date, k -> new VideoTotalExp()); |
| | | LocalDate parseTime = LocalDate.parse(date, formatter); |
| | | try { |
| | | Date parseDate = simpleDateFormat.parse(date); |
| | | //获取星期几 |
| | | String week = weeks[parseTime.getDayOfWeek().getValue() - 1]; |
| | | VideoTotalExp videoExp = new VideoTotalExp(); |
| | | videoExp.setDate(date); |
| | | videoExp.setWeek(week); |
| | | //设置点位在线总量 |
| | | List<TMonitorResult> onlines = onlineMap.get(parseTime); |
| | | if (!CollectionUtils.isEmpty(onlines)) { |
| | | videoExp.setTotal(onlines.size()); |
| | | long count = onlines.stream() |
| | | .filter(item -> ApiConstants.UY_OnlineSite_Online.equals(item.getOnline())) |
| | | .count(); |
| | | videoExp.setOnline(Integer.valueOf(count + "")); |
| | | videoExp.setOffline(videoExp.getTotal() - videoExp.getOnline()); |
| | | } |
| | | //设置存储情况 |
| | | List<RecordMetaDSumResult> records = recordMap.get(parseDate); |
| | | if (!CollectionUtils.isEmpty(records)) { |
| | | videoExp.setNoStore(Integer.valueOf(records.stream() |
| | | .filter(record -> ApiConstants.UY_RecordStatus_Abnormal.equals(record.getRecordStatus())) |
| | | .count() + "")); |
| | | videoExp.setPartStore(Integer.valueOf(records.stream() |
| | | .filter(record -> ApiConstants.UY_RecordStatus_Interval.equals(record.getRecordStatus())) |
| | | .count() + "")); |
| | | } |
| | | videoTotalExps.add(videoExp); |
| | | //累加作为全量表 |
| | | totalExp.setDate(date); |
| | | totalExp.setWeek(week); |
| | | totalExp.setTotal((totalExp.getTotal() == null ? 0 : totalExp.getTotal()) + (videoExp.getTotal() == null ? 0 : videoExp.getTotal())); |
| | | totalExp.setOnline((totalExp.getOnline() == null ? 0 : totalExp.getOnline()) + (videoExp.getOnline() == null ? 0 : videoExp.getOnline())); |
| | | totalExp.setOffline((totalExp.getOffline() == null ? 0 : totalExp.getOffline()) + (videoExp.getOffline() == null ? 0 : videoExp.getOffline())); |
| | | totalExp.setNoStore((totalExp.getNoStore() == null ? 0 : totalExp.getNoStore()) + (videoExp.getNoStore() == null ? 0 : videoExp.getNoStore())); |
| | | totalExp.setPartStore((totalExp.getPartStore() == null ? 0 : totalExp.getPartStore()) + (videoExp.getPartStore() == null ? 0 : videoExp.getPartStore())); |
| | | totalMap.put(date, totalExp); |
| | | } catch (ParseException e) { |
| | | e.printStackTrace(); |
| | | } |
| | | } |
| | | AreaDeptEnum areaDeptEnum = AreaDeptEnum.fromDept(deptId); |
| | | ExcelExp excelExp = new ExcelExp(areaDeptEnum == null ? "未知" : areaDeptEnum.getName(), videoTotalExps, VideoTotalExp.class); |
| | | mysheet.add(excelExp); |
| | | }, threadPoolTaskExecutor); |
| | | futures.add(future); |
| | | } |
| | | // 等待所有任务完成 |
| | | CompletableFuture<Void> allFutures = CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])); |
| | | allFutures.join(); // 这将阻塞直到所有任务完成 |
| | | //添加全量表 |
| | | List<VideoTotalExp> totalExps = new ArrayList<>(totalMap.values()); |
| | | totalExps = totalExps.stream().sorted(Comparator.comparing(VideoTotalExp::getDate)).collect(Collectors.toList()); |
| | | ExcelExp excelExp = new ExcelExp("全量", totalExps, VideoTotalExp.class); |
| | | mysheet.add(excelExp); |
| | | //导出 |
| | | ExcelUtilManySheet<List<ExcelExp>> util = new ExcelUtilManySheet<>(mysheet); |
| | | util.exportExcelManySheet(response, mysheet); |
| | | } |
| | | /** |
| | | * 导出每日在线数据 |
| | | */ |
| | | @Override |
| | | public void exportVideoOnline(HttpServletResponse response, VideoExportForm exportForm) throws IOException, NoSuchFieldException, IllegalAccessException { |
| | | log.info("开始导出数据"); |
| | | log.info("传入的月份:{}", exportForm.getMonth()); |
| | | |
| | | // 默认查所有部门 |
| | | if (CollectionUtils.isEmpty(exportForm.getDeptIds())) { |
| | | List<Integer> deptIds = new ArrayList<>(AreaDeptEnum.values().length); |
| | | for (AreaDeptEnum value : AreaDeptEnum.values()) { |
| | | deptIds.add(value.getDeptId()); |
| | | } |
| | | exportForm.setDeptIds(deptIds); |
| | | } |
| | | |
| | | // 使用线程安全的List,预先指定容量 |
| | | List<ExcelExp> mysheet = Collections.synchronizedList(new ArrayList<>()); |
| | | VideoExportForm.convertTags(exportForm); |
| | | Query query = getQuery(exportForm);//装配条件 |
| | | // 月份每日在线数据 |
| | | |
| | | List<TMonitorResult> onlineResult = mongoTemplate.find(query, TMonitorResult.class); |
| | | log.info("大小:{}",onlineResult.size()); |
| | | //此处需要过滤掉设备全景在线 细节不在线的情况 可以按 point分组 分我许多组之后再做处理 |
| | | // Map<String, List<TMonitorResult>> ipToDevices = onlineResult.stream() |
| | | // .collect(Collectors.groupingBy(TMonitorResult::getIp)); //重要操作 按ip分组 |
| | | |
| | | // onlineResult = ipToDevices.values().stream() |
| | | // .map(devices -> { |
| | | // // 检查分组中是否有 online = true 的设备 |
| | | // List<TMonitorResult> onlineDevices = devices.stream() |
| | | // .filter(monitor -> monitor.getOnline() == 1) // 假设online字段的getter是isOnline() |
| | | // .collect(Collectors.toList()); |
| | | // |
| | | // if (!onlineDevices.isEmpty()) { |
| | | // // 若存在online=true的设备,只保留第一个(或取任意一个,按需调整) |
| | | // return onlineDevices.get(0); |
| | | // } else { |
| | | // // 若全为online=false,只保留第一个 |
| | | // return devices.get(0); |
| | | // } |
| | | // }) |
| | | // .collect(Collectors.toList()); |
| | | |
| | | |
| | | |
| | | log.info("月份在线数据:{}条数", onlineResult.size()); |
| | | // 使用Collectors.toMap去重,保留每个No的第一个遇到的元素 |
| | | Map<String, TMonitorResult> fullDataMap = onlineResult.stream() |
| | | .collect(Collectors.toMap( |
| | | TMonitorResult::getNo, // keyMapper,这里假设 getNo() 返回 No 字段 |
| | | Function.identity(), // valueMapper,直接使用对象本身 |
| | | (existing, replacement) -> existing // mergeFunction,如果有重复,保留第一个 |
| | | )); |
| | | |
| | | |
| | | // 将 Map 转换为 List 去重后减少数据库消耗 |
| | | List<TMonitorResult> tMonitorResults = new ArrayList<>(fullDataMap.values()); |
| | | // log.info("去重后大小:{}", tMonitorResults.size()); |
| | | |
| | | // 获取动态列数据并构建缓存Map |
| | | Map<Integer, List<DynamicColumnVO>> dynamicColumnMap = new HashMap<>(); |
| | | if (!tMonitorResults.isEmpty()) { |
| | | //获取ip集合 |
| | | List<Integer> pointIds = tMonitorResults.stream() |
| | | .map(TMonitorResult::getPointId) |
| | | .distinct() // 去重,减少数据库查询 |
| | | .collect(Collectors.toList()); |
| | | |
| | | |
| | | //获取集合点位的补充列信息 |
| | | List<DynamicColumnVO> dynamics = dynamicColumnMapper.getDynamicsByIds("t_yw_point", pointIds); |
| | | if (!CollectionUtils.isEmpty(dynamics)) { |
| | | dynamicColumnMap = dynamics.stream() |
| | | .collect(Collectors.groupingBy(DynamicColumnVO::getRefId)); |
| | | } |
| | | |
| | | // 补充动态列数据 |
| | | // 去重后的动态列信息 |
| | | for (TMonitorResult result : tMonitorResults) { |
| | | result.setDynamicColumnList(dynamicColumnMap.getOrDefault(result.getPointId(), Collections.emptyList())); |
| | | } |
| | | } |
| | | // 按部门分组,减少后续循环中的过滤操作 |
| | | Map<Integer, List<TMonitorResult>> deptMonitorMap = tMonitorResults.stream() //去重后指向 每个设备只有第一天的数据 |
| | | .collect(Collectors.groupingBy(TMonitorResult::getDeptId)); |
| | | |
| | | // 按设备编号分组onlineResult,加速后续查找 |
| | | Map<String, List<TMonitorResult>> noToOnlineMap = onlineResult.stream() //这里值所以数据以设备标号分组,得到其详情 如 1号到31号的录像情况 |
| | | .collect(Collectors.groupingBy(TMonitorResult::getNo)); |
| | | |
| | | // 并行处理各部门数据 |
| | | List<CompletableFuture<ExcelExp>> futures = new ArrayList<>(exportForm.getDeptIds().size());//按前端传入的 部门编号 来判断需要开多少个线程 |
| | | |
| | | Map<Integer, List<VideoDailyExp>> deptExpMap = new ConcurrentHashMap<>(); |
| | | for (Integer deptId : exportForm.getDeptIds()) { |
| | | // 使用部门ID的最终变量 |
| | | final Integer currentDeptId = deptId; |
| | | CompletableFuture<ExcelExp> future = CompletableFuture.supplyAsync(() -> { |
| | | // deptMonitorMap上面已经在去重后分过组了(这里只是体现了去重的作用,下方每日数据是通过no在noToOnlineMap中取到的) |
| | | |
| | | List<TMonitorResult> monitors = deptMonitorMap.getOrDefault(currentDeptId, Collections.emptyList()); |
| | | |
| | | if (monitors.isEmpty()) { |
| | | return null; |
| | | } |
| | | List<VideoDailyExp> videoDailyExps = new ArrayList<>(monitors.size()); |
| | | AreaDeptEnum areaDeptEnum = AreaDeptEnum.fromDept(currentDeptId); |
| | | String areaName = areaDeptEnum == null ? "未知" : areaDeptEnum.getName(); |
| | | |
| | | for (TMonitorResult result : monitors) { |
| | | VideoDailyExp videoDailyExp = new VideoDailyExp(); |
| | | videoDailyExp.setSerialNumber(result.getNo()); |
| | | videoDailyExp.setDeviceName(result.getName()); |
| | | videoDailyExp.setType(result.getMonitorType()); |
| | | videoDailyExp.setArea(areaName); |
| | | |
| | | // 构建标签字符串 |
| | | StringBuilder tag = new StringBuilder(); |
| | | if (result.getProvinceTag()) tag.append("省厅、"); |
| | | if (result.getImportantTag()) tag.append("重点点位、"); |
| | | if (result.getImportantCommandImageTag()) tag.append("重点指挥图像、"); |
| | | if (result.getDeptTag()) tag.append("部级、"); |
| | | |
| | | // 处理动态列 |
| | | List<DynamicColumnVO> dynamicColumns = result.getDynamicColumnList(); |
| | | if (!dynamicColumns.isEmpty()) { |
| | | for (DynamicColumnVO dynamicColumnVO : dynamicColumns) { |
| | | tag.append(dynamicColumnVO.getColumnValue()).append("、"); |
| | | } |
| | | } |
| | | |
| | | // 移除末尾的"、" |
| | | if (tag.length() > 0) { |
| | | tag.setLength(tag.length() - 1); |
| | | } |
| | | videoDailyExp.setTag(tag.toString()); |
| | | |
| | | // 设置在线数据重点位置 |
| | | try { |
| | | // 从预构建的Map中获取,避免每次过滤 正确获得在线数据位置 |
| | | List<TMonitorResult> onlines = noToOnlineMap.getOrDefault(result.getNo(), Collections.emptyList()); |
| | | // 重点查看下面这个方法 videoDailyExp 传入需要组装对象的 videoDailyExp 和 数据源result包含动态列信息的对象 和他对应1到31天的在离线状态 |
| | | setOnlineDaily(videoDailyExp, result, onlines); |
| | | } catch (Exception e) { |
| | | log.error("设置在线数据异常", e); |
| | | } |
| | | // |
| | | videoDailyExps.add(videoDailyExp); |
| | | } |
| | | // |
| | | // 存储结果到线程安全的Map 结果如 按区分分组 对应设备的 1到31日的在离线详情 |
| | | deptExpMap.put(currentDeptId, videoDailyExps); |
| | | // |
| | | return new ExcelExp(areaName, videoDailyExps, VideoDailyExp.class); |
| | | }, threadPoolTaskExecutor); |
| | | |
| | | futures.add(future); |
| | | } |
| | | |
| | | // 等待所有并行任务完成 |
| | | CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join(); |
| | | |
| | | // 收集所有部门的ExcelExp结果 |
| | | for (CompletableFuture<ExcelExp> future : futures) { |
| | | ExcelExp excelExp = future.join(); |
| | | if (excelExp != null) { |
| | | mysheet.add(excelExp); |
| | | } |
| | | } |
| | | |
| | | // 获取全量数据并添加"全量"sheet |
| | | List<VideoDailyExp> totalExps = deptExpMap.values().stream() |
| | | .flatMap(List::stream) |
| | | .collect(Collectors.toList()); |
| | | |
| | | mysheet.add(new ExcelExp("全量", totalExps, VideoDailyExp.class)); |
| | | |
| | | // 统计各类型设备数量 |
| | | long face = 0, car = 0, video = 0; |
| | | for (VideoDailyExp exp : totalExps) { |
| | | String type = exp.getType(); |
| | | if (type.contains("1")) face++; |
| | | if (type.contains("2")) car++; |
| | | if (type.contains("3")) video++; |
| | | } |
| | | |
| | | log.info("人脸数:{}", face); |
| | | log.info("car数:{}", car); |
| | | log.info("video数:{}", video); |
| | | |
| | | // 离线数统计 |
| | | List<VideoTypeOffOnlineExp> videoTypeOffOnlineExps = new ArrayList<>(); |
| | | // 在线率统计 |
| | | List<VideoOnlineRateExp> videoOnlineRateExps = new ArrayList<>(); |
| | | |
| | | for (Map.Entry<Integer, List<VideoDailyExp>> entry : deptExpMap.entrySet()) { |
| | | Integer deptId = entry.getKey(); |
| | | List<VideoDailyExp> list = entry.getValue(); |
| | | AreaDeptEnum areaDeptEnum = AreaDeptEnum.fromDept(deptId); |
| | | |
| | | // 批量处理三种设备类型 每个设备1到31号在离线情况 |
| | | addDeviceStats(list, areaDeptEnum, "1", "人脸", videoTypeOffOnlineExps, videoOnlineRateExps); |
| | | addDeviceStats(list, areaDeptEnum, "2", "卡口", videoTypeOffOnlineExps, videoOnlineRateExps); |
| | | addDeviceStats(list, areaDeptEnum, "3", "视频", videoTypeOffOnlineExps, videoOnlineRateExps); |
| | | } |
| | | |
| | | // 计算合计数据 |
| | | addTotalStats(videoTypeOffOnlineExps, videoOnlineRateExps, face, car, video); |
| | | |
| | | // 添加统计sheet |
| | | mysheet.add(new ExcelExp("离线数统计", videoTypeOffOnlineExps, VideoTypeOffOnlineExp.class)); |
| | | mysheet.add(new ExcelExp("在线率统计", videoOnlineRateExps, VideoOnlineRateExp.class)); |
| | | |
| | | // 导出Excel |
| | | ExcelUtilManySheet<List<ExcelExp>> util = new ExcelUtilManySheet<>(mysheet); |
| | | util.exportExcelManySheet(response, mysheet); |
| | | log.info("导出结束"); |
| | | } |
| | | |
| | | // 新增辅助方法:批量添加设备统计信息 |
| | | private void addDeviceStats(List<VideoDailyExp> list, AreaDeptEnum areaDeptEnum, |
| | | String typeCode, String typeName, |
| | | List<VideoTypeOffOnlineExp> offLineList, |
| | | List<VideoOnlineRateExp> onlineList) { |
| | | offLineList.add(getListOfflineCountInfo(list, typeCode, areaDeptEnum)); |
| | | onlineList.add(getListOnLineCountInfo(list, typeCode, areaDeptEnum)); |
| | | } |
| | | |
| | | // 新增辅助方法:添加合计统计 |
| | | private void addTotalStats(List<VideoTypeOffOnlineExp> offLineList, |
| | | List<VideoOnlineRateExp> onlineList, |
| | | long face, long car, long video) throws NoSuchFieldException, IllegalAccessException { |
| | | // 离线统计合计 |
| | | VideoTypeOffOnlineExp allFaceVideosOffline = new VideoTypeOffOnlineExp(); |
| | | setAllVideoTypeOffOnlineExpCount(offLineList, allFaceVideosOffline, "人脸"); |
| | | |
| | | VideoTypeOffOnlineExp allCarVideosOffline = new VideoTypeOffOnlineExp(); |
| | | setAllVideoTypeOffOnlineExpCount(offLineList, allCarVideosOffline, "卡口"); |
| | | |
| | | VideoTypeOffOnlineExp allVideosOffline = new VideoTypeOffOnlineExp(); |
| | | setAllVideoTypeOffOnlineExpCount(offLineList, allVideosOffline, "视频"); |
| | | |
| | | offLineList.add(allFaceVideosOffline); |
| | | offLineList.add(allCarVideosOffline); |
| | | offLineList.add(allVideosOffline); |
| | | |
| | | // 在线统计合计 |
| | | VideoOnlineRateExp allFaceVideosOnline = new VideoOnlineRateExp(); |
| | | setAllVideoTypeOnlineExpCount(face, onlineList, allFaceVideosOnline, "人脸"); |
| | | |
| | | VideoOnlineRateExp allCarVideosOnline = new VideoOnlineRateExp(); |
| | | setAllVideoTypeOnlineExpCount(car, onlineList, allCarVideosOnline, "卡口"); |
| | | |
| | | VideoOnlineRateExp allVideosOnline = new VideoOnlineRateExp(); |
| | | setAllVideoTypeOnlineExpCount(video, onlineList, allVideosOnline, "视频"); |
| | | |
| | | onlineList.add(allFaceVideosOnline); |
| | | onlineList.add(allCarVideosOnline); |
| | | onlineList.add(allVideosOnline); |
| | | } |
| | | |
| | | |
| | | |
| | | //离线设备数据,合计对象,信息装配 |
| | | public void setAllVideoTypeOffOnlineExpCount(List<VideoTypeOffOnlineExp> videoTypeOffOnlineExps, |
| | | VideoTypeOffOnlineExp videoTypeOffOnlineExp, |
| | | String type) throws NoSuchFieldException, IllegalAccessException { |
| | | List<VideoTypeOffOnlineExp> filterExps = videoTypeOffOnlineExps.stream().filter(exp -> type.equals(exp.getType())).collect(Collectors.toList()); |
| | | long allCount = 0; |
| | | for (VideoTypeOffOnlineExp obj :filterExps){ |
| | | //obj 对象代表了该区 筛选了的指定type的设备的对象 |
| | | //计算总的设备离线总数 |
| | | long count = Long.parseLong(obj.getOfflineCount()); |
| | | allCount += count; |
| | | //计算每日 |
| | | for (int i =1 ;i <= 31; i++){ |
| | | String fieldName = "day" + i; |
| | | Field dayField = obj.getClass().getDeclaredField(fieldName); |
| | | dayField.setAccessible(true); |
| | | Object value = dayField.get(obj); //获取字段值 |
| | | if (value != null) { |
| | | long newFieldValue = Long.parseLong(value.toString()); |
| | | //获取需要填充的字段 |
| | | Field videoTypeOffOnlineExpField = videoTypeOffOnlineExp.getClass().getDeclaredField(fieldName); |
| | | videoTypeOffOnlineExpField.setAccessible(true); |
| | | //先获取一次 |
| | | Object oldValue = videoTypeOffOnlineExpField.get(videoTypeOffOnlineExp); |
| | | |
| | | //为null 第一次直接诶赋值 |
| | | if (oldValue == null){ |
| | | videoTypeOffOnlineExpField.set(videoTypeOffOnlineExp,newFieldValue + ""); |
| | | }else { |
| | | //存在旧值 相加覆盖 |
| | | videoTypeOffOnlineExpField.set(videoTypeOffOnlineExp, (Long.parseLong(oldValue.toString()) + newFieldValue) + ""); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | } |
| | | |
| | | } |
| | | videoTypeOffOnlineExp.setOfflineCount(String.valueOf(allCount)); |
| | | videoTypeOffOnlineExp.setArea("自贡市"); |
| | | videoTypeOffOnlineExp.setType(type + "合计"); |
| | | } |
| | | // 在线设备数据,合计对象,信息装配 |
| | | public void setAllVideoTypeOnlineExpCount( |
| | | long allVideoCount,List<VideoOnlineRateExp> videoOnlineRateExps, |
| | | VideoOnlineRateExp videoOnlineRateExp, |
| | | String type) throws NoSuchFieldException, IllegalAccessException{ |
| | | List<VideoOnlineRateExp> filterExps = videoOnlineRateExps.stream().filter(item -> type.equals(item.getType())).collect(Collectors.toList()); |
| | | |
| | | for (VideoOnlineRateExp obj :filterExps){ |
| | | for (int i = 1;i <= 31; i++){ |
| | | String countFileName = "count" +i; |
| | | Field countField = obj.getClass().getDeclaredField(countFileName); |
| | | countField.setAccessible(true); |
| | | long newFieldValue = countField.getLong(obj); |
| | | Field videoOnlineRateExpField = obj.getClass().getDeclaredField(countFileName); |
| | | videoOnlineRateExpField.setAccessible(true); |
| | | Object oldValue = videoOnlineRateExpField.get(videoOnlineRateExp); |
| | | if (oldValue == null){ |
| | | videoOnlineRateExpField.setLong(videoOnlineRateExp,newFieldValue); |
| | | }else { |
| | | //存在旧值 相加覆盖 |
| | | videoOnlineRateExpField.setLong(videoOnlineRateExp, Long.parseLong(oldValue.toString()) + newFieldValue); |
| | | } |
| | | } |
| | | } |
| | | //计算完每日在线设备数 |
| | | //循环一个月 |
| | | for (int i = 1;i <= 31 ;i++){ |
| | | //在线率计算 |
| | | String countFileName = "count" +i; |
| | | Field countField = videoOnlineRateExp.getClass().getDeclaredField(countFileName); |
| | | countField.setAccessible(true); |
| | | long newFieldValue = countField.getLong(videoOnlineRateExp); |
| | | String fieldName = "day" + i; |
| | | //每日在线率 |
| | | double rate = (double) newFieldValue / allVideoCount; |
| | | //反射添加到对象属性中 |
| | | Field field = videoOnlineRateExp.getClass().getDeclaredField(fieldName); |
| | | //设置每日在线设备设备数 |
| | | field.setAccessible(true); |
| | | String rateStr = String.format("%.2f", rate * 100) +"%"; |
| | | if (!"0.00%".equals(rateStr)){ |
| | | field.set(videoOnlineRateExp, rateStr); |
| | | } |
| | | |
| | | } |
| | | |
| | | |
| | | videoOnlineRateExp.setArea("自贡市"); |
| | | videoOnlineRateExp.setType(type + "合计"); |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | /** |
| | | * 计算离线设备excel对象信息 |
| | | * @param videoDailyExps 传入的设备集合信息 |
| | | * @param type 设备类型 1人脸 2车辆 3视频 |
| | | * @param areaDeptEnum 区域 |
| | | * @return |
| | | */ |
| | | public VideoTypeOffOnlineExp getListOfflineCountInfo(List<VideoDailyExp> videoDailyExps, |
| | | String type, |
| | | AreaDeptEnum areaDeptEnum |
| | | ){ |
| | | VideoTypeOffOnlineExp videoTypeOffOnlineExp = new VideoTypeOffOnlineExp(); |
| | | |
| | | List<VideoDailyExp> list = videoDailyExps.stream() |
| | | .filter(device ->device.getType() != null && device.getType().contains(type)).collect(Collectors.toList()); |
| | | log.error("筛选完设备类型 :{} 后集合的大小:{}",type,list.size()); |
| | | //离线数量 |
| | | try { |
| | | //设置离线数量 以及每日离线数量 |
| | | setVideoTypeOffOnlineExpCountAndDays(list,videoTypeOffOnlineExp); |
| | | } catch (Exception e) { |
| | | log.error(e.getMessage()); |
| | | } |
| | | //设备类型 |
| | | if ("1".equals(type)){ |
| | | videoTypeOffOnlineExp.setType("人脸"); |
| | | }else if ("2".equals(type)){ |
| | | videoTypeOffOnlineExp.setType("卡口"); |
| | | } |
| | | else if ("3".equals(type)){ |
| | | videoTypeOffOnlineExp.setType("视频"); |
| | | } |
| | | |
| | | //修改区域 |
| | | videoTypeOffOnlineExp.setArea(areaDeptEnum == null ? "未知" : areaDeptEnum.getName()); |
| | | return videoTypeOffOnlineExp; |
| | | } |
| | | |
| | | private void setVideoTypeOffOnlineExpCountAndDays(List<VideoDailyExp> videoDailyExps,VideoTypeOffOnlineExp videoTypeOffOnlineExp)throws NoSuchFieldException, IllegalAccessException { |
| | | //循环一个月 |
| | | //离线总数 |
| | | long AllOffLineCount = 0; |
| | | for (VideoDailyExp videoDailyExp : videoDailyExps) { |
| | | if (videoDailyExp.isAllOfflineByMonth()) { |
| | | AllOffLineCount++; |
| | | } |
| | | } |
| | | //是合计数据不需要下方数据 |
| | | |
| | | for (int i = 1; i <= 31; i++) { |
| | | //每日离线数 |
| | | long count = 0; |
| | | String fieldName = "day" + i; |
| | | for (VideoDailyExp videoDailyExp : videoDailyExps) { |
| | | // 构造字段名 |
| | | Field field = videoDailyExp.getClass().getDeclaredField(fieldName); |
| | | // 确保字段是私有的可以访问 |
| | | field.setAccessible(true); |
| | | // 获取字段值 |
| | | String value = (String) field.get(videoDailyExp); |
| | | if ("离线".equals(value)) { |
| | | count++; |
| | | } |
| | | } |
| | | //反射添加到对象属性中 |
| | | Field field = videoTypeOffOnlineExp.getClass().getDeclaredField(fieldName); |
| | | field.setAccessible(true); |
| | | String rateStr = count + ""; |
| | | if (!"0".equals(rateStr)) { |
| | | field.set(videoTypeOffOnlineExp, rateStr); |
| | | } |
| | | |
| | | } |
| | | // } |
| | | videoTypeOffOnlineExp.setOfflineCount(String.valueOf(AllOffLineCount)); |
| | | } |
| | | |
| | | /** |
| | | * 计算在线设备excel对象信息 |
| | | * @param videoDailyExps 传入的设备集合信息 |
| | | * @param type 设备类型 1人脸 2车辆 3视频 |
| | | * @param areaDeptEnum 区域 |
| | | * @return |
| | | */ |
| | | public VideoOnlineRateExp getListOnLineCountInfo(List<VideoDailyExp> videoDailyExps, |
| | | String type, |
| | | AreaDeptEnum areaDeptEnum |
| | | ){ |
| | | VideoOnlineRateExp videoOnlineRateExp = new VideoOnlineRateExp(); |
| | | |
| | | List<VideoDailyExp> list = videoDailyExps.stream() |
| | | .filter(device ->device.getType() != null && device.getType().contains(type)).collect(Collectors.toList()); |
| | | log.error("筛选完设备类型 :{} 后集合的大小:{}",type,list.size()); |
| | | //离线数量 |
| | | try { |
| | | setVideoOnlineRateExpCountAndDays(list,videoOnlineRateExp); |
| | | } catch (Exception e) { |
| | | log.error(e.getMessage()); |
| | | } |
| | | //设备类型 |
| | | if ("1".equals(type)) { |
| | | videoOnlineRateExp.setType("人脸"); |
| | | } else if ("2".equals(type)) { |
| | | videoOnlineRateExp.setType("卡口"); |
| | | } else if ("3".equals(type)) { |
| | | videoOnlineRateExp.setType("视频"); |
| | | } |
| | | //修改区域 |
| | | videoOnlineRateExp.setArea(areaDeptEnum == null ? "未知" : areaDeptEnum.getName()); |
| | | return videoOnlineRateExp; |
| | | } |
| | | |
| | | |
| | | private void setVideoOnlineRateExpCountAndDays(List<VideoDailyExp> videoDailyExps,VideoOnlineRateExp videoOnlineRateExp)throws NoSuchFieldException, IllegalAccessException { |
| | | //循环一个月 |
| | | for (int i = 1;i <= 31 ;i++){ |
| | | //在线率计算 |
| | | long count = 0; |
| | | String fieldName = "day" + i; |
| | | String countName = "count" + i; |
| | | for(VideoDailyExp videoDailyExp: videoDailyExps){ |
| | | try { |
| | | // 构造字段名 |
| | | Field field = videoDailyExp.getClass().getDeclaredField(fieldName); |
| | | // 确保字段是私有的可以访问 |
| | | field.setAccessible(true); |
| | | // 获取字段值 |
| | | String value = (String) field.get(videoDailyExp); |
| | | if ("在线".equals(value)) { |
| | | count ++; |
| | | } |
| | | } catch (NoSuchFieldException e) { |
| | | // 字段不存在时跳过当前循环,记录日志 |
| | | log.warn("VideoDailyExp 不存在字段: {}", fieldName, e); |
| | | } catch (IllegalAccessException e) { |
| | | // 字段访问异常时跳过,记录日志 |
| | | log.error("访问字段 {} 失败", fieldName, e); |
| | | } |
| | | } |
| | | //每日在线率 |
| | | double rate = (double) count / videoDailyExps.size(); |
| | | log.info("打印计算出的count:{}",count); |
| | | //反射添加到对象属性中 |
| | | Field field = videoOnlineRateExp.getClass().getDeclaredField(fieldName); |
| | | Field countField = videoOnlineRateExp.getClass().getDeclaredField(countName); |
| | | countField.setAccessible(true); |
| | | //设置每日在线设备设备数 |
| | | countField.setLong(videoOnlineRateExp, count); |
| | | field.setAccessible(true); |
| | | String rateStr = String.format("%.2f", rate * 100) +"%"; |
| | | if (!"0.00%".equals(rateStr)){ |
| | | field.set(videoOnlineRateExp, rateStr); |
| | | } |
| | | |
| | | } |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 导出每日录像情况数据 |
| | | */ |
| | | @Override |
| | | public void exportVideoRecord(HttpServletResponse response, VideoExportForm exportForm) throws IOException, NoSuchFieldException, IllegalAccessException { |
| | | //默认查所有部门 |
| | | if (CollectionUtils.isEmpty(exportForm.getDeptIds())) { |
| | | List<Integer> deptIds = new ArrayList<>(); |
| | | for (AreaDeptEnum value : AreaDeptEnum.values()) { |
| | | deptIds.add(value.getDeptId()); |
| | | } |
| | | exportForm.setDeptIds(deptIds); |
| | | } |
| | | |
| | | VideoExportForm.convertTags(exportForm); |
| | | Query query = getQuery(exportForm); |
| | | //月份每日在线数据 |
| | | List<TMonitorResult> onlineResult = mongoTemplate.find(query, TMonitorResult.class); |
| | | |
| | | // 使用 Collectors.toMap 去重,保留每个 No 的第一个遇到的元素 |
| | | Map<String, TMonitorResult> uniqueResultsMap = onlineResult.stream() |
| | | .collect(Collectors.toMap( |
| | | TMonitorResult::getNo, // keyMapper,这里假设 getNo() 返回 No 字段 |
| | | Function.identity(), // valueMapper,直接使用对象本身 |
| | | (existing, replacement) -> existing // mergeFunction,如果有重复,保留第一个 |
| | | )); |
| | | // 将 Map 转换为 List |
| | | List<TMonitorResult> tMonitorResults = new ArrayList<>(uniqueResultsMap.values()); |
| | | List<String> deviceIds = tMonitorResults.stream().map(BaseResult::getNo).collect(Collectors.toList()); |
| | | //获取动态列数据 |
| | | List<Integer> pointIds = tMonitorResults.stream().map(TMonitorResult::getPointId).collect(Collectors.toList()); |
| | | List<DynamicColumnVO> dynamics = dynamicColumnMapper.getDynamicsByIds("t_yw_point", pointIds); |
| | | //补充动态列数据 |
| | | if (!CollectionUtils.isEmpty(dynamics)) { |
| | | Map<Integer, List<DynamicColumnVO>> map = dynamics.stream().collect(Collectors.groupingBy(DynamicColumnVO::getRefId)); |
| | | for (TMonitorResult tMonitorResult : tMonitorResults) { |
| | | Integer pointId = tMonitorResult.getPointId(); |
| | | tMonitorResult.setDynamicColumnList(map.get(pointId)); |
| | | } |
| | | } |
| | | |
| | | // 将年月字符串解析为YearMonth对象 |
| | | YearMonth yearMonth = YearMonth.parse(exportForm.getMonth()); |
| | | // 获取当月的第一天 |
| | | LocalDate start = yearMonth.atDay(1); |
| | | // 获取下个月的第一天(通过加上1个月并设置日为1) |
| | | YearMonth nextMonth = yearMonth.plusMonths(1); |
| | | LocalDate end = nextMonth.atDay(1); |
| | | //获取这个月份的部门数据,录像由于是前一天的所以不用createTime字段 |
| | | Query videoQuery = new Query(Criteria.where("statTime").gte(start).lt(end)); |
| | | videoQuery.addCriteria(Criteria.where("no").in(deviceIds)); |
| | | //月份每日录像线数据 |
| | | List<RecordMetaDSumResult> recordResult = mongoTemplate.find(videoQuery, RecordMetaDSumResult.class); |
| | | |
| | | // 预先按部门ID分组 |
| | | Map<Integer, List<TMonitorResult>> monitorsByDept = tMonitorResults.stream() |
| | | .collect(Collectors.groupingBy(TMonitorResult::getDeptId)); |
| | | // 预先构建映射 |
| | | Map<String, List<RecordMetaDSumResult>> recordMap = recordResult.stream() |
| | | .collect(Collectors.groupingBy(RecordMetaDSumResult::getNo)); |
| | | List<CompletableFuture<List<VideoDailyExp>>> futures = new ArrayList<>(); |
| | | for (Integer deptId : exportForm.getDeptIds()) { |
| | | CompletableFuture<List<VideoDailyExp>> future = CompletableFuture.supplyAsync(() -> { |
| | | List<VideoDailyExp> videoDailyExps = new ArrayList<>(); |
| | | // 获取当前部门的数据 |
| | | List<TMonitorResult> monitors = monitorsByDept.getOrDefault(deptId, Collections.emptyList()); |
| | | if (CollectionUtils.isEmpty(monitors)) return videoDailyExps; |
| | | AreaDeptEnum areaDeptEnum = AreaDeptEnum.fromDept(deptId); |
| | | for (TMonitorResult result : monitors) { |
| | | VideoDailyExp videoDailyExp = new VideoDailyExp(); |
| | | videoDailyExp.setSerialNumber(result.getNo()); |
| | | videoDailyExp.setDeviceName(result.getName()); |
| | | videoDailyExp.setArea(areaDeptEnum == null ? "未知" : areaDeptEnum.getName()); |
| | | StringBuilder tag = new StringBuilder("" + (result.getProvinceTag() ? "省厅、" : "") + (result.getImportantTag() ? "重点点位、" : "") + (result.getImportantCommandImageTag() ? "重点指挥图像、" : "") + (result.getDeptTag() ? "部级、" : "")); |
| | | //动态列处理加在标签里 |
| | | if (!CollectionUtils.isEmpty(result.getDynamicColumnList())) { |
| | | List<DynamicColumnVO> dynamicColumnList = result.getDynamicColumnList(); |
| | | for (DynamicColumnVO dynamicColumnVO : dynamicColumnList) { |
| | | tag.append(dynamicColumnVO.getColumnValue()).append("、"); |
| | | } |
| | | } |
| | | // 删除字符串末尾的“、” |
| | | if (tag.toString().endsWith("、")) { |
| | | tag = new StringBuilder(tag.substring(0, tag.length() - 1)); |
| | | } |
| | | videoDailyExp.setTag(tag.toString()); |
| | | // 使用Map直接获取记录,避免filter操作 |
| | | List<RecordMetaDSumResult> recordsResult = recordMap.get(result.getNo()); |
| | | try { |
| | | if (!CollectionUtils.isEmpty(recordsResult)) |
| | | setRecordDaily(videoDailyExp, result, recordsResult); |
| | | } catch (Exception e) { |
| | | log.error(e.getMessage()); |
| | | } |
| | | //区县表 |
| | | videoDailyExps.add(videoDailyExp); |
| | | } |
| | | return videoDailyExps; |
| | | }, threadPoolTaskExecutor); |
| | | futures.add(future); |
| | | } |
| | | // 等待所有任务完成 |
| | | CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join(); |
| | | // 每个部门的数据单独保存 |
| | | List<List<VideoDailyExp>> results = futures.stream() |
| | | .map(CompletableFuture::join) // 获取每个Future的结果 |
| | | .collect(Collectors.toList()); |
| | | List<VideoDailyExp> totalExps = new ArrayList<>(); |
| | | List<ExcelExp> mysheet = new ArrayList<>(); |
| | | for (List<VideoDailyExp> result : results) { |
| | | ExcelExp excelExp = new ExcelExp( |
| | | result.get(0).getArea() == null ? "未知" : result.get(0).getArea(), |
| | | result, |
| | | VideoDailyExp.class); |
| | | mysheet.add(excelExp); |
| | | totalExps.addAll(result); |
| | | } |
| | | |
| | | ExcelExp excelExp = new ExcelExp("全量", totalExps, VideoDailyExp.class); |
| | | mysheet.add(excelExp); |
| | | ExcelUtilManySheet<List<ExcelExp>> util = new ExcelUtilManySheet<>(mysheet); |
| | | util.exportExcelManySheet(response, mysheet); |
| | | } |
| | | |
| | | /** |
| | | * 导出每日录像缺失时长 |
| | | */ |
| | | @Override |
| | | public void exportVideoLoseTime(HttpServletResponse response, VideoExportForm exportForm) throws NoSuchFieldException, IllegalAccessException, IOException { |
| | | //默认查所有部门 |
| | | if (CollectionUtils.isEmpty(exportForm.getDeptIds())) { |
| | | List<Integer> deptIds = new ArrayList<>(); |
| | | for (AreaDeptEnum value : AreaDeptEnum.values()) { |
| | | deptIds.add(value.getDeptId()); |
| | | } |
| | | exportForm.setDeptIds(deptIds); |
| | | } |
| | | Query query = getQuery(exportForm); |
| | | |
| | | |
| | | //月份每日在线数据 |
| | | List<TMonitorResult> onlineResult = mongoTemplate.find(query, TMonitorResult.class); |
| | | // 使用 Collectors.toMap 去重,保留每个 No 的第一个遇到的元素 |
| | | Map<String, TMonitorResult> uniqueResultsMap = onlineResult.stream() |
| | | .collect(Collectors.toMap( |
| | | TMonitorResult::getNo, // keyMapper,这里假设 getNo() 返回 No 字段 |
| | | Function.identity(), // valueMapper,直接使用对象本身 |
| | | (existing, replacement) -> existing // mergeFunction,如果有重复,保留第一个 |
| | | )); |
| | | |
| | | // 将 Map 转换为 List |
| | | List<TMonitorResult> tMonitorResults = new ArrayList<>(uniqueResultsMap.values()); |
| | | //获取动态列数据 |
| | | List<Integer> pointIds = tMonitorResults.stream().map(TMonitorResult::getPointId).collect(Collectors.toList()); |
| | | List<DynamicColumnVO> dynamics = dynamicColumnMapper.getDynamicsByIds("t_yw_point", pointIds); |
| | | //补充动态列数据 |
| | | if (!CollectionUtils.isEmpty(dynamics)) { |
| | | Map<Integer, List<DynamicColumnVO>> map = dynamics.stream().collect(Collectors.groupingBy(DynamicColumnVO::getRefId)); |
| | | for (TMonitorResult tMonitorResult : tMonitorResults) { |
| | | Integer pointId = tMonitorResult.getPointId(); |
| | | tMonitorResult.setDynamicColumnList(map.get(pointId)); |
| | | } |
| | | } |
| | | List<String> deviceIds = tMonitorResults.stream().map(BaseResult::getNo).collect(Collectors.toList()); |
| | | // 将年月字符串解析为YearMonth对象 |
| | | YearMonth yearMonth = YearMonth.parse(exportForm.getMonth()); |
| | | // 获取当月的第一天 |
| | | LocalDate start = yearMonth.atDay(1); |
| | | // 获取下个月的第一天(通过加上1个月并设置日为1) |
| | | YearMonth nextMonth = yearMonth.plusMonths(1); |
| | | LocalDate end = nextMonth.atDay(1); |
| | | //获取这个月份的部门数据,录像由于是前一天的所以不用createTime字段 |
| | | Query videoQuery = new Query(Criteria.where("statTime").gte(start).lt(end)); |
| | | videoQuery.addCriteria(Criteria.where("no").in(deviceIds)); |
| | | //月份每日录像线数据 |
| | | List<RecordMetaDSumResult> recordResult = mongoTemplate.find(videoQuery, RecordMetaDSumResult.class); |
| | | // 预先按部门ID分组 |
| | | Map<Integer, List<TMonitorResult>> monitorsByDept = tMonitorResults.stream() |
| | | .collect(Collectors.groupingBy(TMonitorResult::getDeptId)); |
| | | // 预先构建映射 |
| | | Map<String, List<RecordMetaDSumResult>> recordMap = recordResult.stream() |
| | | .collect(Collectors.groupingBy(RecordMetaDSumResult::getNo)); |
| | | |
| | | List<CompletableFuture<List<VideoDailyExp>>> futures = new ArrayList<>(); |
| | | for (Integer deptId : exportForm.getDeptIds()) { |
| | | CompletableFuture<List<VideoDailyExp>> future = CompletableFuture.supplyAsync(() -> { |
| | | List<VideoDailyExp> videoDailyExps = new ArrayList<>(); |
| | | // 获取当前部门的数据 |
| | | List<TMonitorResult> monitors = monitorsByDept.getOrDefault(deptId, Collections.emptyList()); |
| | | if (CollectionUtils.isEmpty(monitors)) return videoDailyExps; |
| | | AreaDeptEnum areaDeptEnum = AreaDeptEnum.fromDept(deptId); |
| | | for (TMonitorResult result : monitors) { |
| | | VideoDailyExp videoDailyExp = new VideoDailyExp(); |
| | | videoDailyExp.setSerialNumber(result.getNo()); |
| | | videoDailyExp.setDeviceName(result.getName()); |
| | | videoDailyExp.setArea(areaDeptEnum == null ? "未知" : areaDeptEnum.getName()); |
| | | StringBuilder tag = new StringBuilder("" + (result.getProvinceTag() ? "省厅、" : "") + (result.getImportantTag() ? "重点点位、" : "") + (result.getImportantCommandImageTag() ? "重点指挥图像、" : "") + (result.getDeptTag() ? "部级、" : "")); |
| | | //动态列处理加在标签里 |
| | | if (!CollectionUtils.isEmpty(result.getDynamicColumnList())) { |
| | | List<DynamicColumnVO> dynamicColumnList = result.getDynamicColumnList(); |
| | | for (DynamicColumnVO dynamicColumnVO : dynamicColumnList) { |
| | | tag.append(dynamicColumnVO.getColumnValue()).append("、"); |
| | | } |
| | | } |
| | | // 删除字符串末尾的“、” |
| | | if (tag.toString().endsWith("、")) { |
| | | tag = new StringBuilder(tag.substring(0, tag.length() - 1)); |
| | | } |
| | | videoDailyExp.setTag(tag.toString()); |
| | | // 使用Map直接获取记录,避免filter操作 |
| | | List<RecordMetaDSumResult> recordsResult = recordMap.get(result.getNo()); |
| | | try { |
| | | if (!CollectionUtils.isEmpty(recordsResult)) setLoseDaily(videoDailyExp, recordsResult); |
| | | } catch (Exception e) { |
| | | log.error(e.getMessage()); |
| | | } |
| | | videoDailyExps.add(videoDailyExp); |
| | | } |
| | | return videoDailyExps; |
| | | }, threadPoolTaskExecutor); |
| | | futures.add(future); |
| | | } |
| | | // 等待所有任务完成 |
| | | CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join(); |
| | | |
| | | // 每个部门的数据单独保存 |
| | | List<List<VideoDailyExp>> results = futures.stream() |
| | | .map(CompletableFuture::join) // 获取每个Future的结果 |
| | | .collect(Collectors.toList()); |
| | | List<VideoDailyExp> totalExps = new ArrayList<>(); |
| | | List<ExcelExp> mysheet = new ArrayList<>(); |
| | | for (List<VideoDailyExp> result : results) { |
| | | ExcelExp excelExp = new ExcelExp( |
| | | result.get(0).getArea() == null ? "未知" : result.get(0).getArea(), |
| | | result, |
| | | VideoDailyExp.class); |
| | | mysheet.add(excelExp); |
| | | totalExps.addAll(result); |
| | | } |
| | | ExcelExp excelExp = new ExcelExp("全量", totalExps, VideoDailyExp.class); |
| | | mysheet.add(excelExp); |
| | | ExcelUtilManySheet<List<ExcelExp>> util = new ExcelUtilManySheet<>(mysheet); |
| | | util.exportExcelManySheet(response, mysheet); |
| | | } |
| | | |
| | | //首页视频报表 |
| | | @Override |
| | | public Map<String, Object> videoHome(HomeQuery monitorQuery) throws ParseException, InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException { |
| | | List<HomeVideoVO> results = new ArrayList<>(); |
| | | |
| | | String month = monitorQuery.getDate(); |
| | | if (StringUtils.isEmpty(month)) { |
| | | //如果为空查本月的数据 |
| | | SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM"); |
| | | month = simpleDateFormat.format(new Date()); |
| | | } |
| | | // 创建一个SimpleDateFormat对象来解析日期字符串 |
| | | SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM"); |
| | | Date date = sdf.parse(month); |
| | | // 创建一个Calendar对象并设置时间为解析出的Date |
| | | Calendar calendar = Calendar.getInstance(); |
| | | calendar.setTime(date); |
| | | // 设置Calendar为月份的第一天 |
| | | calendar.set(Calendar.DAY_OF_MONTH, 1); |
| | | // 获取月份第一天的Date |
| | | Date startDate = calendar.getTime(); |
| | | log.info("首页查询开始日期:{}",startDate); |
| | | // 设置Calendar为月份的最后一天(通过增加一个月份然后减去一天) |
| | | calendar.add(Calendar.MONTH, 1); |
| | | calendar.add(Calendar.DAY_OF_MONTH, -1); |
| | | // 获取月份最后一天的Date |
| | | Date endDate = calendar.getTime(); |
| | | log.info("首页查询结束日期:{}",endDate); |
| | | String constructionType = monitorQuery.getConstructionType(); |
| | | List<String> deviceNoList = new ArrayList<>(); |
| | | if (StringUtils.isNotBlank(constructionType)){ |
| | | List<MonitorConstruction> serialNumberListByConstructionType = monitorConstructionService.getSerialNumberListByConstructionType(constructionType); |
| | | if (!CollectionUtils.isEmpty(serialNumberListByConstructionType)){ |
| | | deviceNoList = serialNumberListByConstructionType.stream().map(MonitorConstruction::getSerialNumber).collect(Collectors.toList()); |
| | | } |
| | | } |
| | | if (StringUtils.isNotBlank(constructionType) && deviceNoList.isEmpty()) { |
| | | // 当constructionType有值但无对应设备时,返回包含空列表的Map |
| | | Map<String, Object> emptyResult = new HashMap<>(); |
| | | emptyResult.put("list", results); // results此时为空列表 |
| | | emptyResult.put("baseLine", 0); // 可根据业务默认基准线值调整 |
| | | return emptyResult; |
| | | } |
| | | //mongo查录像状态 |
| | | MongoDatabase database = mongoTemplate.getDb(); |
| | | MongoCollection<Document> collection = database.getCollection("uy_record_meta_d_sum"); |
| | | Integer examineTag = monitorQuery.getExamineTag(); |
| | | String arealayerno = monitorQuery.getArea(); |
| | | Document matchConditions = new Document("statTime", new Document("$gte", startDate).append("$lte", endDate)); |
| | | if (!deviceNoList.isEmpty()) { |
| | | log.info("打印分建类型no集合:{}",deviceNoList); |
| | | matchConditions.append("no", new Document("$in", deviceNoList)); |
| | | } |
| | | // 根据examineTag的值动态添加额外的条件 |
| | | if (examineTag != null && examineTag.equals(1)) { |
| | | matchConditions.append("provinceTag", true); |
| | | } else if (examineTag != null && examineTag.equals(2)) { |
| | | matchConditions.append("deptTag", true); |
| | | } else if(StringUtils.isNotBlank(arealayerno)){ |
| | | matchConditions.append("arealayerno", |
| | | new Document("$regex", "^" + arealayerno)); |
| | | } |
| | | Document noExpr = new Document("$and", Arrays.asList( |
| | | new Document("$gte", Arrays.asList(new Document("$strLenCP", "$no"), 3)), |
| | | new Document("$ne", Arrays.asList( |
| | | new Document("$substrCP", Arrays.asList( |
| | | "$no", |
| | | new Document("$subtract", Arrays.asList(new Document("$strLenCP", "$no"), 3)), |
| | | 1 |
| | | )), |
| | | "3" |
| | | )) |
| | | )); |
| | | // 正确添加$expr条件(键为"$expr",值为上面定义的条件) |
| | | matchConditions.append("$expr", noExpr); |
| | | // 构建聚合管道 |
| | | List<Document> pipeline = Arrays.asList( |
| | | new Document("$match", matchConditions), |
| | | new Document("$group", new Document("_id", "$statTime") |
| | | .append("normalCount", new Document("$sum", |
| | | new Document("$cond", Arrays.asList( |
| | | new Document("$eq", Arrays.asList("$recordStatus", 1)), |
| | | 1, |
| | | 0 |
| | | )) |
| | | )) |
| | | .append("loseCount", new Document("$sum", |
| | | new Document("$cond", Arrays.asList( |
| | | new Document("$eq", Arrays.asList("$recordStatus", 0)), |
| | | 1, |
| | | 0 |
| | | )) |
| | | )) |
| | | .append("errCount", new Document("$sum", |
| | | new Document("$cond", Arrays.asList( |
| | | new Document("$eq", Arrays.asList("$recordStatus", -1)), |
| | | 1, |
| | | 0 |
| | | )) |
| | | )) |
| | | ) |
| | | ); |
| | | // 执行聚合查询并获取结果 |
| | | AggregateIterable<Document> result = collection.aggregate(pipeline); |
| | | for (Document doc : result) { |
| | | HomeVideoVO homeVideoVO = new HomeVideoVO(); |
| | | homeVideoVO.setCreateDate(doc.getDate("_id")); |
| | | homeVideoVO.setIntegrityNum(doc.getInteger("normalCount")); |
| | | homeVideoVO.setLoseNum(doc.getInteger("loseCount")); |
| | | homeVideoVO.setErrNum(doc.getInteger("errCount")); |
| | | |
| | | results.add(homeVideoVO); |
| | | } |
| | | |
| | | //mongo查点位在线 |
| | | MongoCollection<Document> onlineCollection = database.getCollection("t_monitor_online"); |
| | | // 构建基本的$match条件 |
| | | List<Document> onlineMatch = new ArrayList<>(); |
| | | onlineMatch.add(new Document("mongoCreateTime", new Document("$gte", startDate).append("$lte", endDate))); |
| | | onlineMatch.add(new Document("monitorType", new Document("$regex", "1"))); |
| | | if (!deviceNoList.isEmpty()) { |
| | | onlineMatch.add(new Document("no", new Document("$in", deviceNoList))); |
| | | } |
| | | if (examineTag != null && examineTag.equals(1)) { |
| | | onlineMatch.add(new Document("provinceTag", true)); |
| | | } else if (examineTag != null && examineTag.equals(2)) { |
| | | onlineMatch.add(new Document("deptTag", true)); |
| | | } else if(StringUtils.isNotBlank(arealayerno)){ |
| | | Document noStartsWith = new Document("no", new Document("$regex", "^" + arealayerno)); |
| | | |
| | | // 构建倒数第三位不是3的条件 |
| | | Document noThirdLastNot3 = new Document("$expr", new Document("$and", Arrays.asList( |
| | | new Document("$gte", Arrays.asList(new Document("$strLenCP", "$no"), 3)), |
| | | new Document("$ne", Arrays.asList( |
| | | new Document("$substrCP", Arrays.asList( |
| | | "$no", |
| | | new Document("$subtract", Arrays.asList(new Document("$strLenCP", "$no"), 3)), |
| | | 1 |
| | | )), |
| | | "3" |
| | | )) |
| | | ))); |
| | | // 将两个条件用$and组合后添加到条件列表 |
| | | onlineMatch.add(new Document("$and", Arrays.asList(noStartsWith, noThirdLastNot3))); |
| | | } |
| | | // 构建聚合管道 |
| | | List<Document> onlinePipeline = Arrays.asList( |
| | | new Document("$match", new Document("$and", onlineMatch)), |
| | | new Document("$group", new Document("_id", "$mongoCreateTime") |
| | | .append("onlineCount", new Document("$sum", |
| | | new Document("$cond", Arrays.asList( |
| | | new Document("$eq", Arrays.asList("$online", ApiConstants.UY_OnlineSite_Online)), |
| | | 1, |
| | | 0 |
| | | )) |
| | | )) |
| | | ) |
| | | ); |
| | | //排除卡口集合 |
| | | |
| | | |
| | | |
| | | // 执行聚合查询并获取结果 |
| | | AggregateIterable<Document> onlineResult = onlineCollection.aggregate(onlinePipeline); |
| | | for (Document doc : onlineResult) { |
| | | HomeVideoVO vo = findOrCreateVO(doc, results, HomeVideoVO.class); |
| | | vo.setOnline(doc.getInteger("onlineCount")); |
| | | } |
| | | results = results.stream().sorted(Comparator.comparing(BaseHomeVO::getCreateDate)).collect(Collectors.toList()); |
| | | Map<String, Object> resultMap = new HashMap<>(); |
| | | resultMap.put("list", results); |
| | | //从字典获取基准线 |
| | | List<SysDictData> baseLines = dictDataMapper.selectDictDataByType("home_baseLine"); |
| | | String condition; |
| | | if (examineTag != null && examineTag == 1) { |
| | | condition = "video_province_baseLine"; |
| | | } else if (examineTag != null && examineTag == 2) { |
| | | condition = "video_dept_baseLine"; |
| | | } else { |
| | | condition = "video_all_baseLine"; |
| | | } |
| | | Optional<SysDictData> first = baseLines.stream().filter(sysDictData -> condition.equals(sysDictData.getDictLabel())).findFirst(); |
| | | if (first.isPresent()) { |
| | | SysDictData sysDictData = first.get(); |
| | | resultMap.put("baseLine", Integer.valueOf(sysDictData.getDictValue())); |
| | | } |
| | | return resultMap; |
| | | } |
| | | |
| | | /** |
| | | * 列表导出 |
| | | * |
| | | * @param response |
| | | * @param tMonitor |
| | | */ |
| | | @Override |
| | | public void export(HttpServletResponse response, TMonitorVO tMonitor) { |
| | | List<TMonitorExp> monitors = tMonitorMapper.exportTMonitorList(tMonitor); |
| | | //过滤出设备建设类型 |
| | | if (StringUtils.isNotBlank(tMonitor.getConstructionType())){ |
| | | List<MonitorConstruction> list = |
| | | monitorConstructionService.getSerialNumberListByConstructionType(tMonitor.getConstructionType()); |
| | | //获得设备编号集合 通过建设类型标签 |
| | | List<String> serialNumberList = list.stream().map(MonitorConstruction::getSerialNumber).collect(Collectors.toList()); |
| | | monitors = monitors.stream() |
| | | .filter(result -> { |
| | | String sn = result.getSerialNumber(); |
| | | // 任一字段非空且在集合中即可 |
| | | return (sn != null && serialNumberList.contains(sn)); |
| | | }) |
| | | .collect(Collectors.toList()); |
| | | } |
| | | |
| | | |
| | | //获取动态列数据 |
| | | List<Integer> pointIds = monitors.stream().map(TMonitorExp::getPointId).collect(Collectors.toList()); |
| | | List<DynamicColumnVO> dynamics = dynamicColumnMapper.getDynamicsByIds("t_yw_point", pointIds); |
| | | //补充动态列数据 |
| | | if (!CollectionUtils.isEmpty(dynamics)) { |
| | | Map<Integer, List<DynamicColumnVO>> map = dynamics.stream().collect(Collectors.groupingBy(DynamicColumnVO::getRefId)); |
| | | for (TMonitorExp tMonitorResult : monitors) { |
| | | Integer pointId = tMonitorResult.getPointId(); |
| | | tMonitorResult.setDynamicColumnList(map.get(pointId)); |
| | | } |
| | | } |
| | | monitors.forEach(monitor -> { |
| | | String cameraFunType = monitor.getCameraFunType(); |
| | | if (!StringUtils.isEmpty(cameraFunType)) { |
| | | String video = cameraFunType.replaceAll("1", "视频"); |
| | | String car = video.replaceAll("2", "车辆"); |
| | | String type = car.replaceAll("3", "人脸"); |
| | | monitor.setCameraFunType(type); |
| | | } |
| | | StringBuilder tag = new StringBuilder("" + (monitor.getProvinceTagVideo() ? "省厅视频、" : "") + (monitor.getProvinceTagCar() ? "省厅车辆、" : "") + (monitor.getProvinceTagFace() ? "省厅人脸、" : "") + (monitor.getImportantTag() ? "重点点位、" : "") + (monitor.getImportantCommandImageTag() ? "重点指挥图像、" : "") + (monitor.getDeptTag() ? "部级、" : "")); |
| | | //动态列处理加在标签里 |
| | | if (!CollectionUtils.isEmpty(monitor.getDynamicColumnList())) { |
| | | List<DynamicColumnVO> dynamicColumnList = monitor.getDynamicColumnList(); |
| | | for (DynamicColumnVO dynamicColumnVO : dynamicColumnList) { |
| | | tag.append(dynamicColumnVO.getColumnValue()).append("、"); |
| | | } |
| | | } |
| | | // 删除字符串末尾的“、” |
| | | if (tag.toString().endsWith("、")) { |
| | | tag = new StringBuilder(tag.substring(0, tag.length() - 1)); |
| | | } |
| | | monitor.setTag(tag.toString()); |
| | | }); |
| | | ExcelUtil<TMonitorExp> util = new ExcelUtil<>(TMonitorExp.class); |
| | | String sheetName = ""; |
| | | if ("1".equals(tMonitor.getCameraFunType())) { |
| | | sheetName = "视频"; |
| | | } else if ("2".equals(tMonitor.getCameraFunType())) { |
| | | sheetName = "车辆"; |
| | | } else if ("3".equals(tMonitor.getCameraFunType())) { |
| | | sheetName = "人脸"; |
| | | } |
| | | util.exportExcel(response, monitors, sheetName); |
| | | } |
| | | |
| | | /** |
| | | * 清理一机一档 |
| | | * @return |
| | | */ |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public Result clearMonitor() { |
| | | tMonitorMapper.clearMonitor(); |
| | | pointMapper.clearMonitor(); |
| | | return Result.ok(); |
| | | } |
| | | |
| | | @Override |
| | | public Result assetManagementCount(DataCenterQuery query) { |
| | | Map<String, String> map =tMonitorMapper.assetManagementCount(); |
| | | return Result.ok().data(map); |
| | | } |
| | | |
| | | |
| | | //首页车辆报表 |
| | | @Override |
| | | public Map<String, Object> carHome(HomeQuery monitorQuery) throws ParseException, InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException { |
| | | List<HomeCarVO> results = new ArrayList<>(); |
| | | String month = monitorQuery.getDate(); |
| | | if (StringUtils.isEmpty(month)) { |
| | | //如果为空查本月的数据 |
| | | SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM"); |
| | | month = simpleDateFormat.format(new Date()); |
| | | } |
| | | // 创建一个SimpleDateFormat对象来解析日期字符串 |
| | | SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM"); |
| | | Date date = sdf.parse(month); |
| | | // 创建一个Calendar对象并设置时间为解析出的Date |
| | | Calendar calendar = Calendar.getInstance(); |
| | | calendar.setTime(date); |
| | | // 设置Calendar为月份的第一天 |
| | | calendar.set(Calendar.DAY_OF_MONTH, 1); |
| | | // 获取月份第一天的Date |
| | | Date startDate = calendar.getTime(); |
| | | // 设置Calendar为月份的最后一天(通过增加一个月份然后减去一天) |
| | | calendar.add(Calendar.MONTH, 1); |
| | | calendar.add(Calendar.DAY_OF_MONTH, -1); |
| | | // 获取月份最后一天的Date |
| | | Date endDate = calendar.getTime(); |
| | | //mongo查抓拍量 |
| | | MongoDatabase database = mongoTemplate.getDb(); |
| | | MongoCollection<Document> collection = database.getCollection("hk_snapshot_data_monitor"); |
| | | Integer examineTag = monitorQuery.getExamineTag(); |
| | | // 构建基本的$match条件 |
| | | List<Document> matchConditions = new ArrayList<>(); |
| | | String arealayerno = monitorQuery.getArea(); |
| | | matchConditions.add(new Document("mongoCreateTime", new Document("$gte", startDate).append("$lte", endDate))); |
| | | matchConditions.add(new Document("dataType", new Document("$eq", ApiConstants.HK_DataType_CAR))); |
| | | if (examineTag != null && examineTag.equals(1)) { |
| | | matchConditions.add(new Document("provinceTag", true)); |
| | | }else if(StringUtils.isNotBlank(arealayerno)){ |
| | | matchConditions.add(new Document("orgCode",new Document("$eq", arealayerno))); |
| | | } |
| | | // 构建聚合管道 |
| | | List<Document> pipeline = Arrays.asList( |
| | | new Document("$match", new Document("$and", matchConditions)), |
| | | new Document("$group", new Document("_id", "$mongoCreateTime") |
| | | .append("dataCount", new Document("$sum", "$dataCount")) |
| | | ) |
| | | ); |
| | | // 执行聚合查询并获取结果 |
| | | AggregateIterable<Document> result = collection.aggregate(pipeline); |
| | | for (Document doc : result) { |
| | | HomeCarVO homecarVO = new HomeCarVO(); |
| | | homecarVO.setCreateDate(doc.getDate("_id")); |
| | | homecarVO.setSnapCount(doc.getInteger("dataCount")); |
| | | results.add(homecarVO); |
| | | } |
| | | |
| | | MongoCollection<Document> onlineCollection = database.getCollection("t_monitor_online"); |
| | | // 构建基本的$match条件 |
| | | List<Document> onlineMatch = new ArrayList<>(); |
| | | onlineMatch.add(new Document("mongoCreateTime", new Document("$gte", startDate).append("$lte", endDate))); |
| | | onlineMatch.add(new Document("monitorType", new Document("$regex", "2"))); |
| | | if (examineTag != null && examineTag.equals(1)) { |
| | | onlineMatch.add(new Document("provinceTag", true)); |
| | | }else if(StringUtils.isNotBlank(arealayerno)){ |
| | | onlineMatch.add(new Document("no", new Document("$regex", "^" + arealayerno))); |
| | | } |
| | | // 构建聚合管道 |
| | | List<Document> onlinePipeline = Arrays.asList( |
| | | new Document("$match", new Document("$and", onlineMatch)), |
| | | new Document("$group", new Document("_id", "$mongoCreateTime") |
| | | .append("onlineCount", new Document("$sum", |
| | | new Document("$cond", Arrays.asList( |
| | | new Document("$eq", Arrays.asList("$online", ApiConstants.UY_OnlineSite_Online)), |
| | | 1, |
| | | 0 |
| | | )) |
| | | )) |
| | | ) |
| | | ); |
| | | // 执行聚合查询并获取结果 |
| | | AggregateIterable<Document> onlineResult = onlineCollection.aggregate(onlinePipeline); |
| | | for (Document doc : onlineResult) { |
| | | HomeCarVO vo = findOrCreateVO(doc, results, HomeCarVO.class); |
| | | vo.setOnline(doc.getInteger("onlineCount")); |
| | | } |
| | | Map<String, Object> resultMap = new HashMap<>(); |
| | | //按时间排序 |
| | | results = results.stream().sorted(Comparator.comparing(BaseHomeVO::getCreateDate)).collect(Collectors.toList()); |
| | | //如果是默认或累和则进行累和以及获取基准线 |
| | | if (monitorQuery.getCategory() == null || monitorQuery.getCategory().equals(1)) { |
| | | int snapCount = 0; |
| | | for (HomeCarVO vo : results) { |
| | | if (vo.getSnapCount() != null) { |
| | | snapCount += vo.getSnapCount(); |
| | | } |
| | | vo.setSnapCount(snapCount); |
| | | } |
| | | //从字典获取基准线 |
| | | List<SysDictData> baseLines = dictDataMapper.selectDictDataByType("home_baseLine"); |
| | | String condition; |
| | | if (examineTag != null && examineTag == 1) { |
| | | condition = "car_province_baseLine"; |
| | | } else if (examineTag != null && examineTag == 2) { |
| | | condition = "car_dept_baseLine"; |
| | | } else { |
| | | condition = "car_all_baseLine"; |
| | | } |
| | | |
| | | Optional<SysDictData> first = baseLines.stream().filter(sysDictData -> condition.equals(sysDictData.getDictLabel())).findFirst(); |
| | | if (first.isPresent()) { |
| | | SysDictData sysDictData = first.get(); |
| | | resultMap.put("baseLine", Integer.valueOf(sysDictData.getDictValue())); |
| | | } |
| | | } |
| | | resultMap.put("list", results); |
| | | return resultMap; |
| | | } |
| | | |
| | | //首页人脸报表 |
| | | @Override |
| | | public Map<String, Object> faceHome(HomeQuery monitorQuery) throws ParseException, InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException { |
| | | List<HomeFaceVO> results = new ArrayList<>(); |
| | | String month = monitorQuery.getDate(); |
| | | if (StringUtils.isEmpty(month)) { |
| | | //如果为空查本月的数据 |
| | | SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM"); |
| | | month = simpleDateFormat.format(new Date()); |
| | | } |
| | | // 创建一个SimpleDateFormat对象来解析日期字符串 |
| | | SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM"); |
| | | Date date = sdf.parse(month); |
| | | // 创建一个Calendar对象并设置时间为解析出的Date |
| | | Calendar calendar = Calendar.getInstance(); |
| | | calendar.setTime(date); |
| | | // 设置Calendar为月份的第一天 |
| | | calendar.set(Calendar.DAY_OF_MONTH, 1); |
| | | // 获取月份第一天的Date |
| | | Date startDate = calendar.getTime(); |
| | | // 设置Calendar为月份的最后一天(通过增加一个月份然后减去一天) |
| | | calendar.add(Calendar.MONTH, 1); |
| | | calendar.add(Calendar.DAY_OF_MONTH, -1); |
| | | // 获取月份最后一天的Date |
| | | Date endDate = calendar.getTime(); |
| | | String arealayerno = monitorQuery.getArea(); |
| | | //mongo查抓拍量 |
| | | MongoDatabase database = mongoTemplate.getDb(); |
| | | MongoCollection<Document> collection = database.getCollection("hk_snapshot_data_monitor"); |
| | | Integer examineTag = monitorQuery.getExamineTag(); |
| | | // 构建基本的$match条件 |
| | | List<Document> matchConditions = new ArrayList<>(); |
| | | matchConditions.add(new Document("mongoCreateTime", new Document("$gte", startDate).append("$lte", endDate))); |
| | | matchConditions.add(new Document("dataType", new Document("$eq", ApiConstants.HK_DataType_FACE))); |
| | | if (examineTag != null && examineTag.equals(1)) { |
| | | matchConditions.add(new Document("provinceTag", true)); |
| | | }else if(StringUtils.isNotBlank(arealayerno)){ |
| | | matchConditions.add(new Document("orgCode",new Document("$eq", arealayerno))); |
| | | } |
| | | // 构建聚合管道 |
| | | List<Document> pipeline = Arrays.asList( |
| | | new Document("$match", new Document("$and", matchConditions)), |
| | | new Document("$group", new Document("_id", "$mongoCreateTime") |
| | | .append("dataCount", new Document("$sum", "$dataCount")) |
| | | ) |
| | | ); |
| | | |
| | | // 执行聚合查询并获取结果 |
| | | AggregateIterable<Document> result = collection.aggregate(pipeline); |
| | | for (Document doc : result) { |
| | | HomeFaceVO homefaceVO = new HomeFaceVO(); |
| | | homefaceVO.setCreateDate(doc.getDate("_id")); |
| | | homefaceVO.setSnapCount(doc.getInteger("dataCount")); |
| | | results.add(homefaceVO); |
| | | } |
| | | |
| | | //mongo查点位在线 |
| | | MongoCollection<Document> onlineCollection = database.getCollection("t_monitor_online"); |
| | | // 构建基本的$match条件 |
| | | List<Document> onlineMatch = new ArrayList<>(); |
| | | onlineMatch.add(new Document("mongoCreateTime", new Document("$gte", startDate).append("$lte", endDate))); |
| | | onlineMatch.add(new Document("monitorType", new Document("$regex", "3"))); |
| | | if (examineTag != null && examineTag.equals(1)) { |
| | | onlineMatch.add(new Document("provinceTag", true)); |
| | | }else if(StringUtils.isNotBlank(arealayerno)){ |
| | | onlineMatch.add(new Document("no", new Document("$regex", "^" + arealayerno))); |
| | | } |
| | | // 构建聚合管道 |
| | | List<Document> onlinePipeline = Arrays.asList( |
| | | new Document("$match", new Document("$and", onlineMatch)), |
| | | new Document("$group", new Document("_id", "$mongoCreateTime") |
| | | .append("onlineCount", new Document("$sum", |
| | | new Document("$cond", Arrays.asList( |
| | | new Document("$eq", Arrays.asList("$online", ApiConstants.UY_OnlineSite_Online)), |
| | | 1, |
| | | 0 |
| | | )) |
| | | )) |
| | | ) |
| | | ); |
| | | // 执行聚合查询并获取结果 |
| | | AggregateIterable<Document> onlineResult = onlineCollection.aggregate(onlinePipeline); |
| | | for (Document doc : onlineResult) { |
| | | HomeFaceVO vo = findOrCreateVO(doc, results, HomeFaceVO.class); |
| | | vo.setOnline(doc.getInteger("onlineCount")); |
| | | } |
| | | Map<String, Object> resultMap = new HashMap<>(); |
| | | //按时间排序 |
| | | results = results.stream().sorted(Comparator.comparing(BaseHomeVO::getCreateDate)).collect(Collectors.toList()); |
| | | //如果是默认或累和则进行累和以及获取基准线 |
| | | if (monitorQuery.getCategory() == null || monitorQuery.getCategory().equals(1)) { |
| | | int snapCount = 0; |
| | | for (HomeFaceVO vo : results) { |
| | | if (vo.getSnapCount() != null) { |
| | | snapCount += vo.getSnapCount(); |
| | | } |
| | | vo.setSnapCount(snapCount); |
| | | } |
| | | //从字典获取基准线 |
| | | List<SysDictData> baseLines = dictDataMapper.selectDictDataByType("home_baseLine"); |
| | | String condition; |
| | | if (examineTag != null && examineTag == 1) { |
| | | condition = "face_province_baseLine"; |
| | | } else if (examineTag != null && examineTag == 2) { |
| | | condition = "face_dept_baseLine"; |
| | | } else { |
| | | condition = "face_all_baseLine"; |
| | | } |
| | | Optional<SysDictData> first = baseLines.stream().filter(sysDictData -> condition.equals(sysDictData.getDictLabel())).findFirst(); |
| | | if (first.isPresent()) { |
| | | SysDictData sysDictData = first.get(); |
| | | resultMap.put("baseLine", Integer.valueOf(sysDictData.getDictValue())); |
| | | } |
| | | } |
| | | resultMap.put("list", results); |
| | | return resultMap; |
| | | } |
| | | |
| | | private <T extends BaseHomeVO> T findOrCreateVO(Document doc, List<T> results, Class<T> clazz) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException { |
| | | Date createDate = doc.getDate("_id"); |
| | | for (T vo : results) { |
| | | if (vo.getCreateDate().equals(createDate)) { |
| | | return vo; |
| | | } |
| | | } |
| | | // 如果没有找到匹配项,则创建一个新的VO |
| | | T vo = clazz.getDeclaredConstructor().newInstance(); |
| | | vo.setCreateDate(createDate); |
| | | results.add(vo); |
| | | return vo; |
| | | } |
| | | |
| | | private Query getQuery(VideoExportForm exportForm) { |
| | | String month = exportForm.getMonth(); |
| | | // 将年月字符串解析为YearMonth对象 |
| | | YearMonth yearMonth = YearMonth.parse(month); |
| | | // 获取当月的第一天 |
| | | LocalDate start = yearMonth.atDay(1); |
| | | // 获取下个月的第一天(通过加上1个月并设置日为1) |
| | | YearMonth nextMonth = yearMonth.plusMonths(1); |
| | | LocalDate end = nextMonth.atDay(1); |
| | | //获取这个月份的部门数据 |
| | | Query query = new Query(Criteria.where("mongoCreateTime").gte(start).lt(end)); |
| | | if (!CollectionUtils.isEmpty(exportForm.getDeptIds())) |
| | | query.addCriteria(Criteria.where("deptId").in(exportForm.getDeptIds())); |
| | | if (exportForm.getDeptTag() != null) query.addCriteria(Criteria.where("deptTag").is(exportForm.getDeptTag())); |
| | | if (exportForm.getProvinceTag() != null) |
| | | query.addCriteria(Criteria.where("provinceTag").is(exportForm.getProvinceTag())); |
| | | if (exportForm.getImportantTag() != null) |
| | | query.addCriteria(Criteria.where("importantTag").is(exportForm.getImportantTag())); |
| | | if (exportForm.getImportantCommandImageTag() != null) |
| | | query.addCriteria(Criteria.where("importantCommandImageTag").is(exportForm.getImportantCommandImageTag())); |
| | | return query; |
| | | } |
| | | |
| | | //设置每日在线数据 |
| | | private void setOnlineDaily(VideoDailyExp videoDailyExp, TMonitorResult result, List<TMonitorResult> onlines) throws NoSuchFieldException, IllegalAccessException { |
| | | //一个设备当月在线情况 |
| | | List<TMonitorResult> onlineResult = onlines.stream().filter(online -> online.getNo().equals(result.getNo())).collect(Collectors.toList()); |
| | | videoDailyExp.setOnlineStateList(onlineResult); |
| | | for (TMonitorResult monitorResult : onlineResult) { |
| | | //为空白的原因 如进入第1号时 monitorResult没有对应一号的数据,就是一号mongodb里面没有对应该设备的数据 |
| | | int dayOfMonth = monitorResult.getMongoCreateTime().getDayOfMonth(); |
| | | String online = ""; |
| | | if (ApiConstants.UY_OnlineSite_Online.equals(monitorResult.getOnline())) { |
| | | online += "在线"; |
| | | } else if (ApiConstants.UY_OnlineSite_Offline.equals(monitorResult.getOnline())) { |
| | | online += "离线"; |
| | | } else { |
| | | online += "未知"; |
| | | } |
| | | //反射赋值,字段统一定义为day+1,2,3... |
| | | Field field = videoDailyExp.getClass().getDeclaredField("day" + dayOfMonth); |
| | | field.setAccessible(true); |
| | | field.set(videoDailyExp, online); |
| | | } |
| | | } |
| | | |
| | | //设置每日录像数据 |
| | | private void setRecordDaily(VideoDailyExp videoDailyExp, TMonitorResult result, List<RecordMetaDSumResult> recordResults) throws NoSuchFieldException, IllegalAccessException { |
| | | for (RecordMetaDSumResult recordResult : recordResults) { |
| | | int dayOfMonth = DateUtils.getDayOfMonth(recordResult.getStatTime()); |
| | | Integer status = recordResult.getRecordStatus(); |
| | | String text = ""; |
| | | if (ApiConstants.UY_RecordStatus_Interval.equals(status)) { |
| | | text += "间歇"; |
| | | } else if (ApiConstants.UY_RecordStatus_Abnormal.equals(status)) { |
| | | text += "缺失"; |
| | | } else if (ApiConstants.UY_RecordStatus_Integrity.equals(status)) { |
| | | text += "完整"; |
| | | } |
| | | //反射赋值,字段统一定义为day+1,2,3... |
| | | Field field = videoDailyExp.getClass().getDeclaredField("day" + dayOfMonth); |
| | | field.setAccessible(true); |
| | | field.set(videoDailyExp, text); |
| | | } |
| | | } |
| | | |
| | | //设置每日录像缺失时长数据 |
| | | private void setLoseDaily(VideoDailyExp videoDailyExp, List<RecordMetaDSumResult> recordResults) throws NoSuchFieldException, IllegalAccessException { |
| | | //一个设备当月在线情况 |
| | | for (RecordMetaDSumResult recordResult : recordResults) { |
| | | int dayOfMonth = DateUtils.getDayOfMonth(recordResult.getStatTime()); //获取启动日期是当月第几天 |
| | | //反射赋值,字段统一定义为day+1,2,3... |
| | | Field field = videoDailyExp.getClass().getDeclaredField("day" + dayOfMonth); |
| | | field.setAccessible(true); |
| | | //防止转换为科学计数法 |
| | | BigDecimal bigDecimal = BigDecimal.valueOf(recordResult.getMissDuration() == null ? 0 : (recordResult.getMissDuration()) * 60); |
| | | field.set(videoDailyExp, bigDecimal.setScale(2, RoundingMode.HALF_UP).toString()); |
| | | } |
| | | } |
| | | } |