| | |
| | | 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.vo.home.HomeVideoVO; |
| | | import com.ycl.platform.domain.vo.screen.MonitorRateVO; |
| | | import com.ycl.platform.domain.vo.screen.MonitorTotalVO; |
| | | import com.ycl.platform.mapper.DynamicColumnMapper; |
| | | import com.ycl.platform.mapper.TMonitorMapper; |
| | | import com.ycl.platform.mapper.WorkOrderMapper; |
| | | import com.ycl.platform.mapper.YwPointMapper; |
| | | 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 java.util.regex.Pattern; |
| | | import java.util.stream.Collectors; |
| | | |
| | | import static com.ycl.utils.PageUtils.startPage; |
| | | |
| | | /** |
| | | * 设备资产Service业务层处理 |
| | | * |
| | |
| | | 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() != null && monitor.getWorkOrderNo().equals(workOrderVO.getWorkOrderNo())) { |
| | | monitor.setUnitContact(workOrderVO.getUnitContact()); |
| | | monitor.setUnitContactPhone(workOrderVO.getUnitContactPhone()); |
| | | monitor.setYwPeopleName(workOrderVO.getYwPeopleName()); |
| | | monitor.setErrorType(workOrderVO.getErrorType()); |
| | | //设备编号 |
| | | 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()); |
| | | } |
| | | } |
| | | } |
| | | //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)); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | return monitors; |
| | | } |
| | | //设备编号 |
| | | 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()); |
| | | } |
| | | } |
| | | } |
| | | //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); |
| | | //抓拍量、时钟、上传 |
| | | 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 (Objects.equals(tMonitor.getCameraFunType(), "2")) { |
| | | //属性一致率、大图 |
| | | 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()); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | 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); |
| | | //人脸合格、大图 |
| | | if (!CollectionUtils.isEmpty(sampleResults)) { |
| | | for (FaceDeviceSamplingResult sampleResult : sampleResults) { |
| | | if (monitor.getSerialNumber().equals(sampleResult.getNo())) { |
| | | if (sampleResult.getBigUseful() != null) { |
| | | monitor.setBigUsefulPercent(sampleResult.getBigUseful().getBigUsefulPercent()); |
| | | 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); |
| | | } |
| | | |
| | |
| | | ExcelUtilManySheet<List<ExcelExp>> util = new ExcelUtilManySheet<>(mysheet); |
| | | util.exportExcelManySheet(response, mysheet); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 导出每日在线数据 |
| | | */ |
| | | @Override |
| | | public void exportVideoOnline(HttpServletResponse response, VideoExportForm exportForm) throws IOException, NoSuchFieldException, IllegalAccessException { |
| | | log.error("开始导出数据"); |
| | | log.error("传入的月份:{}",exportForm.getMonth()); |
| | | //默认查所有部门 |
| | | log.info("开始导出数据"); |
| | | log.info("传入的月份:{}", exportForm.getMonth()); |
| | | |
| | | // 默认查所有部门 |
| | | if (CollectionUtils.isEmpty(exportForm.getDeptIds())) { |
| | | List<Integer> deptIds = new ArrayList<>(); |
| | | List<Integer> deptIds = new ArrayList<>(AreaDeptEnum.values().length); |
| | | 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); |
| | | |
| | | // 使用线程安全的List,预先指定容量 |
| | | List<ExcelExp> mysheet = Collections.synchronizedList(new ArrayList<>()); |
| | | VideoExportForm.convertTags(exportForm); |
| | | Query query = getQuery(exportForm); |
| | | //月份每日在线数据 |
| | | Query query = getQuery(exportForm);//装配条件 |
| | | // 月份每日在线数据 |
| | | |
| | | List<TMonitorResult> onlineResult = mongoTemplate.find(query, TMonitorResult.class); |
| | | log.error("月份在线数据:{}条数",onlineResult.size()); |
| | | // 使用 Collectors.toMap 去重,保留每个 No 的第一个遇到的元素 |
| | | log.info("大小:{}",onlineResult.size()); |
| | | //此处需要过滤掉设备全景在线 细节不在线的情况 可以按 point分组 分我许多组之后再做处理 |
| | | Map<String, List<TMonitorResult>> ipToDevices = onlineResult.stream() |
| | | .collect(Collectors.groupingBy(TMonitorResult::getIp)); |
| | | |
| | | // 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> 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()); |
| | | log.error("去重后大小:{}",tMonitorResults.size()); |
| | | //获取动态列数据 |
| | | 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)); |
| | | log.info("去重后大小:{}", tMonitorResults.size()); |
| | | |
| | | |
| | | |
| | | // 获取动态列数据并构建缓存Map |
| | | Map<Integer, List<DynamicColumnVO>> dynamicColumnMap = new HashMap<>(); |
| | | if (!tMonitorResults.isEmpty()) { |
| | | //获取点位集合 |
| | | 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 key为 区域 |
| | | Map<Integer, List<VideoDailyExp>> map = new HashMap<>(); |
| | | List<CompletableFuture<List<VideoDailyExp>>> futures = new ArrayList<>(); |
| | | |
| | | // 按部门分组,减少后续循环中的过滤操作 |
| | | Map<Integer, List<TMonitorResult>> deptMonitorMap = tMonitorResults.stream() |
| | | .collect(Collectors.groupingBy(TMonitorResult::getDeptId)); |
| | | |
| | | // 按设备编号分组onlineResult,加速后续查找 |
| | | Map<String, List<TMonitorResult>> noToOnlineMap = onlineResult.stream() |
| | | .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()) { |
| | | CompletableFuture<List<VideoDailyExp>> future = CompletableFuture.supplyAsync(() -> { |
| | | List<VideoDailyExp> videoDailyExps = new ArrayList<>(); |
| | | //筛选部门数据 |
| | | List<TMonitorResult> monitors = tMonitorResults.stream() |
| | | .filter(tMonitorResult -> deptId.equals(tMonitorResult.getDeptId())) |
| | | .collect(Collectors.toList()); |
| | | if (CollectionUtils.isEmpty(monitors)) return videoDailyExps; |
| | | // 使用部门ID的最终变量 |
| | | final Integer currentDeptId = deptId; |
| | | CompletableFuture<ExcelExp> future = CompletableFuture.supplyAsync(() -> { |
| | | // 直接从预分组的Map中获取,避免每次过滤 |
| | | List<TMonitorResult> monitors = deptMonitorMap.getOrDefault(currentDeptId, Collections.emptyList()); |
| | | |
| | | List<String> ids = monitors.stream() |
| | | .map(BaseResult::getNo) |
| | | .collect(Collectors.toList()); |
| | | //筛选mongo区县数据 |
| | | List<TMonitorResult> onlines = onlineResult.stream() |
| | | .filter(result -> ids.contains(result.getNo())) |
| | | .collect(Collectors.toList()); |
| | | |
| | | AreaDeptEnum areaDeptEnum = AreaDeptEnum.fromDept(deptId); |
| | | |
| | | 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); |
| | | |
| | | videoDailyExp.setArea(areaDeptEnum == null ? "未知" : areaDeptEnum.getName()); |
| | | // 构建标签字符串 |
| | | StringBuilder tag = new StringBuilder(); |
| | | if (result.getProvinceTag()) tag.append("省厅、"); |
| | | if (result.getImportantTag()) tag.append("重点点位、"); |
| | | if (result.getImportantCommandImageTag()) tag.append("重点指挥图像、"); |
| | | if (result.getDeptTag()) tag.append("部级、"); |
| | | |
| | | StringBuilder tag = new StringBuilder("" + |
| | | (result.getProvinceTag() ? "省厅、" : "") + |
| | | (result.getImportantTag() ? "重点点位、" : "") + |
| | | (result.getImportantCommandImageTag() ? "重点指挥图像、" : "") + |
| | | (result.getDeptTag() ? "部级、" : "")); |
| | | |
| | | //动态列处理加在标签里 |
| | | if (!CollectionUtils.isEmpty(result.getDynamicColumnList())) { |
| | | for (DynamicColumnVO dynamicColumnVO : result.getDynamicColumnList()) { |
| | | // 处理动态列 |
| | | List<DynamicColumnVO> dynamicColumns = result.getDynamicColumnList(); |
| | | if (!dynamicColumns.isEmpty()) { |
| | | for (DynamicColumnVO dynamicColumnVO : dynamicColumns) { |
| | | tag.append(dynamicColumnVO.getColumnValue()).append("、"); |
| | | } |
| | | } |
| | | // 删除字符串末尾的"、" |
| | | if (tag.toString().endsWith("、")) { |
| | | tag = new StringBuilder(tag.substring(0, tag.length() - 1)); |
| | | |
| | | // 移除末尾的"、" |
| | | if (tag.length() > 0) { |
| | | tag.setLength(tag.length() - 1); |
| | | } |
| | | videoDailyExp.setTag(tag.toString()); |
| | | |
| | | // 设置在线数据 |
| | | try { |
| | | // 从预构建的Map中获取,避免每次过滤 |
| | | List<TMonitorResult> onlines = noToOnlineMap.getOrDefault(result.getNo(), Collections.emptyList()); |
| | | setOnlineDaily(videoDailyExp, result, onlines); |
| | | } catch (Exception e) { |
| | | log.error(e.getMessage()); |
| | | log.error("设置在线数据异常", e); |
| | | } |
| | | |
| | | videoDailyExps.add(videoDailyExp); |
| | | } |
| | | |
| | | ExcelExp excelExp = new ExcelExp( |
| | | areaDeptEnum == null ? "未知" : areaDeptEnum.getName(), |
| | | videoDailyExps, |
| | | VideoDailyExp.class |
| | | ); |
| | | mysheet.add(excelExp); |
| | | // 存储结果到线程安全的Map |
| | | deptExpMap.put(currentDeptId, videoDailyExps); |
| | | |
| | | |
| | | return videoDailyExps; |
| | | return new ExcelExp(areaName, videoDailyExps, VideoDailyExp.class); |
| | | }, threadPoolTaskExecutor); |
| | | |
| | | futures.add(future); |
| | | map.put(deptId,future.join()); |
| | | } |
| | | // 获取全量数据 |
| | | List<VideoDailyExp> totalExps = futures.stream() |
| | | .map(CompletableFuture::join) |
| | | |
| | | // 等待所有并行任务完成 |
| | | 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()); |
| | | ExcelExp excelExp = new ExcelExp("全量", totalExps, VideoDailyExp.class); |
| | | mysheet.add(excelExp); |
| | | |
| | | long face = totalExps.stream().filter(item -> item.getType().contains("1")).count(); |
| | | long car = totalExps.stream().filter(item -> item.getType().contains("2")).count(); |
| | | long video = totalExps.stream().filter(item -> item.getType().contains("3")).count(); |
| | | log.error("人脸数:{}",face); |
| | | log.error("car数:{}",car); |
| | | log.error("video数:{}",video); |
| | | //添加新的sheet 离线数统计表 |
| | | List<VideoTypeOffOnlineExp> videoTypeOffOnlineExps = new ArrayList<>(); |
| | | mysheet.add(new ExcelExp("全量", totalExps, VideoDailyExp.class)); |
| | | |
| | | //在线率统计表 |
| | | List<VideoOnlineRateExp> videoOnlineRateExps = new ArrayList<>(); |
| | | |
| | | for (Integer deptId : map.keySet()){ |
| | | List<VideoDailyExp> list = map.get(deptId); |
| | | AreaDeptEnum areaDeptEnum = AreaDeptEnum.fromDept(deptId); |
| | | // 添加离线表记录 |
| | | //设备类型 1人脸 2车辆 3视频 |
| | | //人脸 |
| | | log.error("传入部门集合大小:{} + 部门id:{}" ,list.size(),deptId); |
| | | VideoTypeOffOnlineExp faceVideoTypeOffOnlineExp = this.getListOfflineCountInfo(list,"1",areaDeptEnum); |
| | | //卡口 |
| | | VideoTypeOffOnlineExp carVideoTypeOffOnlineExp =this.getListOfflineCountInfo(list,"2",areaDeptEnum); |
| | | //视频 |
| | | VideoTypeOffOnlineExp videoTypeOffOnlineExp = this.getListOfflineCountInfo(list,"3",areaDeptEnum); |
| | | |
| | | VideoOnlineRateExp faceVideoOnlineRateExp = this.getListOnLineCountInfo(list,"1",areaDeptEnum); |
| | | //卡口 |
| | | VideoOnlineRateExp carVideoOnlineRateExp =this.getListOnLineCountInfo(list,"2",areaDeptEnum); |
| | | //视频 |
| | | VideoOnlineRateExp VideoOnlineRateExp = this.getListOnLineCountInfo(list,"3",areaDeptEnum); |
| | | |
| | | |
| | | //将该区域类三种设备类型的 信息 放入 excel对象内 |
| | | //放入当前区域的人脸设备相关详细 |
| | | videoTypeOffOnlineExps.add(faceVideoTypeOffOnlineExp); |
| | | //放入当前区域的车辆设备相关详细 |
| | | videoTypeOffOnlineExps.add(carVideoTypeOffOnlineExp); |
| | | //放入当前区域的视频设备相关详细 |
| | | videoTypeOffOnlineExps.add(videoTypeOffOnlineExp); |
| | | |
| | | videoOnlineRateExps.add(faceVideoOnlineRateExp); |
| | | videoOnlineRateExps.add(carVideoOnlineRateExp); |
| | | videoOnlineRateExps.add(VideoOnlineRateExp); |
| | | // 统计各类型设备数量 |
| | | 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++; |
| | | } |
| | | |
| | | //计算自贡市合计 |
| | | //插入excel时确保数据出现在最后 |
| | | List<VideoTypeOffOnlineExp> allVideoTypeOffOnlineExps = new ArrayList<>(); |
| | | //插入excel时确保数据出现在最后 |
| | | List<VideoOnlineRateExp> allVideoOnlineRateExps = new ArrayList<>(); |
| | | log.info("人脸数:{}", face); |
| | | log.info("car数:{}", car); |
| | | log.info("video数:{}", video); |
| | | |
| | | //所有离线数据中,各区设备为人脸的对象 合计装配对象 |
| | | VideoTypeOffOnlineExp allFaceVideosOffline = new VideoTypeOffOnlineExp(); |
| | | setAllVideoTypeOffOnlineExpCount(videoTypeOffOnlineExps,allFaceVideosOffline,"人脸"); |
| | | // 处理离线数统计和在线率统计 |
| | | List<VideoTypeOffOnlineExp> videoTypeOffOnlineExps = new ArrayList<>(); |
| | | List<VideoOnlineRateExp> videoOnlineRateExps = new ArrayList<>(); |
| | | |
| | | VideoTypeOffOnlineExp allCarVideosOffline = new VideoTypeOffOnlineExp(); |
| | | setAllVideoTypeOffOnlineExpCount(videoTypeOffOnlineExps,allCarVideosOffline,"卡口"); |
| | | for (Map.Entry<Integer, List<VideoDailyExp>> entry : deptExpMap.entrySet()) { |
| | | Integer deptId = entry.getKey(); |
| | | List<VideoDailyExp> list = entry.getValue(); |
| | | AreaDeptEnum areaDeptEnum = AreaDeptEnum.fromDept(deptId); |
| | | |
| | | VideoTypeOffOnlineExp allVideosOffline = new VideoTypeOffOnlineExp(); |
| | | setAllVideoTypeOffOnlineExpCount(videoTypeOffOnlineExps,allVideosOffline,"视频"); |
| | | // 批量处理三种设备类型 |
| | | addDeviceStats(list, areaDeptEnum, "1", "人脸", videoTypeOffOnlineExps, videoOnlineRateExps); |
| | | addDeviceStats(list, areaDeptEnum, "2", "卡口", videoTypeOffOnlineExps, videoOnlineRateExps); |
| | | addDeviceStats(list, areaDeptEnum, "3", "视频", videoTypeOffOnlineExps, videoOnlineRateExps); |
| | | } |
| | | |
| | | allVideoTypeOffOnlineExps.add(allFaceVideosOffline); |
| | | allVideoTypeOffOnlineExps.add(allCarVideosOffline); |
| | | allVideoTypeOffOnlineExps.add(allVideosOffline); |
| | | // 计算合计数据 |
| | | addTotalStats(videoTypeOffOnlineExps, videoOnlineRateExps, face, car, video); |
| | | |
| | | //所有在线数据 合计装配对象 |
| | | VideoOnlineRateExp allFaceVideosOnline = new VideoOnlineRateExp(); |
| | | setAllVideoTypeOnlineExpCount(face,videoOnlineRateExps,allFaceVideosOnline,"人脸"); |
| | | // 添加统计sheet |
| | | mysheet.add(new ExcelExp("离线数统计", videoTypeOffOnlineExps, VideoTypeOffOnlineExp.class)); |
| | | mysheet.add(new ExcelExp("在线率统计", videoOnlineRateExps, VideoOnlineRateExp.class)); |
| | | |
| | | |
| | | VideoOnlineRateExp allCarVideosOnline = new VideoOnlineRateExp(); |
| | | setAllVideoTypeOnlineExpCount(car,videoOnlineRateExps,allCarVideosOnline,"卡口"); |
| | | |
| | | VideoOnlineRateExp allVideosOnline = new VideoOnlineRateExp(); |
| | | setAllVideoTypeOnlineExpCount(video,videoOnlineRateExps,allVideosOnline,"视频"); |
| | | |
| | | |
| | | allVideoOnlineRateExps.add(allFaceVideosOnline); |
| | | allVideoOnlineRateExps.add(allCarVideosOnline); |
| | | allVideoOnlineRateExps.add(allVideosOnline); |
| | | |
| | | videoTypeOffOnlineExps.addAll(allVideoTypeOffOnlineExps); |
| | | videoOnlineRateExps.addAll(allVideoOnlineRateExps); |
| | | log.error("打印计算离线的信息:{}" ,videoTypeOffOnlineExps ); |
| | | log.error("打印在线的信息:{}" ,videoOnlineRateExps ); |
| | | //添加合计数据 |
| | | |
| | | ExcelExp excelTypeOffLineExp = new ExcelExp("离线数统计", videoTypeOffOnlineExps, VideoTypeOffOnlineExp.class); |
| | | mysheet.add(excelTypeOffLineExp); |
| | | |
| | | //添加在线率表 |
| | | ExcelExp excelOnlineRateExp = new ExcelExp("在线率统计",videoOnlineRateExps, VideoOnlineRateExp.class); |
| | | mysheet.add(excelOnlineRateExp); |
| | | |
| | | // 导出Excel |
| | | ExcelUtilManySheet<List<ExcelExp>> util = new ExcelUtilManySheet<>(mysheet); |
| | | util.exportExcelManySheet(response, mysheet); |
| | | log.error("导出结束"); |
| | | 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, |
| | |
| | | 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); |
| | |
| | | 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)) { |
| | |
| | | @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); |