| | |
| | | import annotation.DataScope; |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import com.mongodb.ExplainVerbosity; |
| | | import com.mongodb.client.AggregateIterable; |
| | | import com.mongodb.client.MongoCollection; |
| | | import com.mongodb.client.MongoDatabase; |
| | | import com.ycl.platform.domain.entity.TMonitor; |
| | | import com.ycl.platform.domain.excel.TMonitorExp; |
| | | import com.ycl.platform.domain.excel.VideoDailyExp; |
| | | import com.ycl.platform.domain.excel.VideoTotalExp; |
| | | 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.service.ITMonitorService; |
| | | import com.ycl.system.Result; |
| | | import com.ycl.system.entity.SysDictData; |
| | | import com.ycl.system.mapper.SysConfigMapper; |
| | | import com.ycl.system.mapper.SysDictDataMapper; |
| | | import com.ycl.system.page.PageUtil; |
| | | import com.ycl.system.service.ISysConfigService; |
| | |
| | | import com.ycl.utils.StringUtils; |
| | | import com.ycl.utils.poi.ExcelUtil; |
| | | import constant.ApiConstants; |
| | | import constant.CheckConstants; |
| | | import enumeration.general.AreaDeptEnum; |
| | | import jakarta.servlet.http.HttpServletResponse; |
| | | import lombok.SneakyThrows; |
| | | 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.BeanUtils; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.data.mongodb.core.MongoTemplate; |
| | | import org.springframework.data.mongodb.core.query.Criteria; |
| | |
| | | import java.lang.reflect.Field; |
| | | import java.lang.reflect.InvocationTargetException; |
| | | import java.math.BigDecimal; |
| | | import java.text.DecimalFormat; |
| | | import java.math.RoundingMode; |
| | | import java.text.ParseException; |
| | | import java.text.SimpleDateFormat; |
| | | import java.time.LocalDate; |
| | | import java.time.YearMonth; |
| | | import java.time.ZoneId; |
| | | import java.time.format.DateTimeFormatter; |
| | | import java.time.temporal.TemporalAdjusters; |
| | | import java.util.*; |
| | | import java.util.concurrent.*; |
| | | import java.util.function.BinaryOperator; |
| | | import java.util.function.Function; |
| | | import java.util.stream.Collectors; |
| | | |
| | |
| | | * @date 2024-03-04 |
| | | */ |
| | | @Service |
| | | @Slf4j |
| | | public class TMonitorServiceImpl extends ServiceImpl<TMonitorMapper, TMonitor> implements ITMonitorService { |
| | | @Autowired |
| | | private TMonitorMapper tMonitorMapper; |
| | |
| | | */ |
| | | @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 void exportVideoOnline(HttpServletResponse response, VideoExportForm exportForm) throws IOException, NoSuchFieldException, IllegalAccessException { |
| | | log.error("开始导出数据"); |
| | | log.error("传入的月份:{}",exportForm.getMonth()); |
| | | //默认查所有部门 |
| | | if (CollectionUtils.isEmpty(exportForm.getDeptIds())) { |
| | | List<Integer> deptIds = new ArrayList<>(); |
| | |
| | | Query query = getQuery(exportForm); |
| | | //月份每日在线数据 |
| | | List<TMonitorResult> onlineResult = mongoTemplate.find(query, TMonitorResult.class); |
| | | log.error("月份在线数据:{}条数",onlineResult.size()); |
| | | // 使用 Collectors.toMap 去重,保留每个 No 的第一个遇到的元素 |
| | | Map<String, TMonitorResult> uniqueResultsMap = onlineResult.stream() |
| | | .collect(Collectors.toMap( |
| | |
| | | )); |
| | | // 将 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); |
| | |
| | | tMonitorResult.setDynamicColumnList(map.get(pointId)); |
| | | } |
| | | } |
| | | //存放区域 与 设备列表 map key为 区域 |
| | | Map<Integer, List<VideoDailyExp>> map = new HashMap<>(); |
| | | List<CompletableFuture<List<VideoDailyExp>>> futures = new ArrayList<>(); |
| | | for (Integer deptId : exportForm.getDeptIds()) { |
| | | CompletableFuture<List<VideoDailyExp>> future = CompletableFuture.supplyAsync(() -> { |
| | |
| | | VideoDailyExp videoDailyExp = new VideoDailyExp(); |
| | | videoDailyExp.setSerialNumber(result.getNo()); |
| | | videoDailyExp.setDeviceName(result.getName()); |
| | | videoDailyExp.setType(result.getMonitorType()); |
| | | |
| | | videoDailyExp.setArea(areaDeptEnum == null ? "未知" : areaDeptEnum.getName()); |
| | | |
| | | StringBuilder tag = new StringBuilder("" + |
| | |
| | | ); |
| | | mysheet.add(excelExp); |
| | | |
| | | |
| | | return videoDailyExps; |
| | | }, threadPoolTaskExecutor); |
| | | futures.add(future); |
| | | map.put(deptId,future.join()); |
| | | } |
| | | // 获取全量数据 |
| | | List<VideoDailyExp> totalExps = futures.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<>(); |
| | | |
| | | //在线率统计表 |
| | | 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); |
| | | } |
| | | |
| | | //计算自贡市合计 |
| | | //插入excel时确保数据出现在最后 |
| | | List<VideoTypeOffOnlineExp> allVideoTypeOffOnlineExps = new ArrayList<>(); |
| | | //插入excel时确保数据出现在最后 |
| | | List<VideoOnlineRateExp> allVideoOnlineRateExps = new ArrayList<>(); |
| | | |
| | | //所有离线数据中,各区设备为人脸的对象 合计装配对象 |
| | | VideoTypeOffOnlineExp allFaceVideosOffline = new VideoTypeOffOnlineExp(); |
| | | setAllVideoTypeOffOnlineExpCount(videoTypeOffOnlineExps,allFaceVideosOffline,"人脸"); |
| | | |
| | | VideoTypeOffOnlineExp allCarVideosOffline = new VideoTypeOffOnlineExp(); |
| | | setAllVideoTypeOffOnlineExpCount(videoTypeOffOnlineExps,allCarVideosOffline,"卡口"); |
| | | |
| | | VideoTypeOffOnlineExp allVideosOffline = new VideoTypeOffOnlineExp(); |
| | | setAllVideoTypeOffOnlineExpCount(videoTypeOffOnlineExps,allVideosOffline,"视频"); |
| | | |
| | | allVideoTypeOffOnlineExps.add(allFaceVideosOffline); |
| | | allVideoTypeOffOnlineExps.add(allCarVideosOffline); |
| | | allVideoTypeOffOnlineExps.add(allVideosOffline); |
| | | |
| | | //所有在线数据 合计装配对象 |
| | | VideoOnlineRateExp allFaceVideosOnline = new VideoOnlineRateExp(); |
| | | setAllVideoTypeOnlineExpCount(face,videoOnlineRateExps,allFaceVideosOnline,"人脸"); |
| | | |
| | | |
| | | 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); |
| | | |
| | | ExcelUtilManySheet<List<ExcelExp>> util = new ExcelUtilManySheet<>(mysheet); |
| | | util.exportExcelManySheet(response, mysheet); |
| | | log.error("导出结束"); |
| | | } |
| | | //离线设备数据,合计对象,信息装配 |
| | | 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){ |
| | | // 构造字段名 |
| | | Field field = videoDailyExp.getClass().getDeclaredField(fieldName); |
| | | // 确保字段是私有的可以访问 |
| | | field.setAccessible(true); |
| | | // 获取字段值 |
| | | String value = (String) field.get(videoDailyExp); |
| | | if ("在线".equals(value)) { |
| | | count ++; |
| | | } |
| | | } |
| | | //每日在线率 |
| | | double rate = (double) count / videoDailyExps.size(); |
| | | //反射添加到对象属性中 |
| | | 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); |
| | | } |
| | | |
| | | } |
| | | } |
| | | |
| | | |
| | |
| | | Function.identity(), // valueMapper,直接使用对象本身 |
| | | (existing, replacement) -> existing // mergeFunction,如果有重复,保留第一个 |
| | | )); |
| | | |
| | | // 将 Map 转换为 List |
| | | List<TMonitorResult> tMonitorResults = new ArrayList<>(uniqueResultsMap.values()); |
| | | //获取动态列数据 |
| | |
| | | )) |
| | | .append("loseCount", new Document("$sum", |
| | | new Document("$cond", Arrays.asList( |
| | | new Document("$in", Arrays.asList("$recordStatus", Arrays.asList(-1, 0))), |
| | | 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 |
| | | )) |
| | |
| | | homeVideoVO.setCreateDate(doc.getDate("_id")); |
| | | homeVideoVO.setIntegrityNum(doc.getInteger("normalCount")); |
| | | homeVideoVO.setLoseNum(doc.getInteger("loseCount")); |
| | | homeVideoVO.setErrNum(doc.getInteger("errCount")); |
| | | results.add(homeVideoVO); |
| | | } |
| | | |
| | |
| | | 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) { |
| | | int dayOfMonth = monitorResult.getMongoCreateTime().getDayOfMonth(); |
| | | String online = ""; |
| | |
| | | field.setAccessible(true); |
| | | field.set(videoDailyExp, online); |
| | | } |
| | | |
| | | |
| | | } |
| | | |
| | | //设置每日录像数据 |
| | |
| | | private void setLoseDaily(VideoDailyExp videoDailyExp, List<RecordMetaDSumResult> recordResults) throws NoSuchFieldException, IllegalAccessException { |
| | | //一个设备当月在线情况 |
| | | for (RecordMetaDSumResult recordResult : recordResults) { |
| | | int dayOfMonth = DateUtils.getDayOfMonth(recordResult.getStatTime()); |
| | | 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()); |
| | | field.set(videoDailyExp, bigDecimal.toString()); |
| | | BigDecimal bigDecimal = BigDecimal.valueOf(recordResult.getMissDuration() == null ? 0 : (recordResult.getMissDuration()) * 60); |
| | | field.set(videoDailyExp, bigDecimal.setScale(2, RoundingMode.HALF_UP).toString()); |
| | | } |
| | | } |
| | | } |