Przeglądaj źródła

Merge remote-tracking branch 'origin/master'

Zimo 22 godzin temu
rodzic
commit
522c508fa6

+ 202 - 1
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/stat/IotStaticController.java

@@ -1,6 +1,8 @@
 package cn.iocoder.yudao.module.pms.controller.admin.stat;
 
 import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.date.DatePattern;
+import cn.hutool.core.date.LocalDateTimeUtil;
 import cn.hutool.core.util.NumberUtil;
 import cn.hutool.core.util.ObjUtil;
 import cn.hutool.core.util.StrUtil;
@@ -956,6 +958,63 @@ public class IotStaticController {
         return dateMap;
     }
 
+    public static LinkedHashMap<String, Double> sumTotalByDates(List<Map<String, Object>> records, int days, String key) {
+        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
+        LocalDate today = LocalDate.now();
+
+        // 生成近days天的日期列表,初始值为0
+        LinkedHashMap<String, Double> dateMap = new LinkedHashMap<>();
+        for (int i = days - 1; i >= 0; i--) {
+            LocalDate date = today.minusDays(i);
+            dateMap.put(date.format(formatter), 0.0);
+        }
+
+        // 统计每天的total字段之和
+        Map<String, Double> sumMap = records.stream()
+                .collect(Collectors.groupingBy(
+                        record -> {
+                            try {
+                                // 提取日期部分(假设createTime格式为yyyy-MM-dd...)
+                                return String.valueOf(record.get("createTime")).substring(0, 10);
+                            } catch (Exception e) {
+                                System.err.println("日期格式错误: " + record.get("createTime"));
+                                return "invalid_date";
+                            }
+                        },
+                        // 累加每天的total字段值,处理可能的格式问题
+                        Collectors.summingDouble(record -> {
+                            try {
+                                Object totalObj = record.get(key);
+                                if (totalObj instanceof Number) {
+                                    return ((Number) totalObj).doubleValue();
+                                } else if (totalObj instanceof String) {
+                                    return Double.parseDouble((String) totalObj);
+                                } else {
+                                    return Double.parseDouble(String.valueOf(totalObj));
+                                }
+                            } catch (Exception e) {
+                                System.err.println("处理total字段出错: " + e.getMessage());
+                                return 0.0;
+                            }
+                        })
+                ));
+
+        // 合并结果,转为“万方”并保留两位小数
+        dateMap.forEach((date, defaultValue) -> {
+            if (sumMap.containsKey(date)) {
+                double totalFang = sumMap.get(date);          // 原始值,单位:方
+                double totalWanFang = totalFang / 10000.0;    // 转换为万方
+                // 四舍五入保留两位小数
+                double rounded = Math.round(totalWanFang * 100.0) / 100.0;
+                dateMap.put(date, rounded);
+            } else {
+                dateMap.put(date, 0.0);
+            }
+        });
+
+        return dateMap;
+    }
+
     public static LinkedHashMap<String, Long> countYwcbByDate(List<IotOutboundDO> records, int days) {
         DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
         LocalDate today = LocalDate.now();
@@ -1234,7 +1293,7 @@ public class IotStaticController {
             abc.put("today", e.getDailyGasInjection());
             return abc;
         }).collect(Collectors.toList());
-        LinkedHashMap<String, Long> fillMap = sumTotalByDate(fills, 7,"today");
+        LinkedHashMap<String, Double> fillMap = sumTotalByDates(fills, 7,"today");
         LinkedList<Object> xAxis = new LinkedList<>();
         LinkedList<Object> fillData = new LinkedList<>();
         fillMap.forEach( (k,v)->{
@@ -1265,6 +1324,148 @@ public class IotStaticController {
 
     }
 
+    @Operation(summary = "近1周的设备利用率")
+    @GetMapping("/rh/device/sevenDayUtilization")
+    @PermitAll
+    public CommonResult<Map<String, Object>> sevenDayUtilization() {
+
+        List<String> lastSevenDays = getLastSevenDays();
+        String first = lastSevenDays.get(0);
+        String last = lastSevenDays.get(lastSevenDays.size() - 1);
+        LocalDateTime startOfDay = getStartOfDay(last);
+        LocalDateTime endOfDay = getEndOfDay(first);
+        LocalDateTime[] createTime = new LocalDateTime[]{startOfDay, endOfDay};
+
+        IotRhDailyReportPageReqVO iotRhDailyReportPageReqVO = new IotRhDailyReportPageReqVO();
+        iotRhDailyReportPageReqVO.setCreateTime(createTime);
+        iotRhDailyReportPageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
+        PageResult<IotRhDailyReportDO> pageReports = iotRhDailyReportMapper.selectPage(iotRhDailyReportPageReqVO);
+        if (ObjUtil.isEmpty(pageReports)) {
+            return buildEmptyResult(lastSevenDays);
+        }
+        List<IotRhDailyReportDO> reports = pageReports.getList();
+        if (CollUtil.isEmpty(reports)) {
+            return buildEmptyResult(lastSevenDays);
+        }
+        List<Map<String, Object>> fills = reports.stream().map(e -> {
+            Map<String, Object> abc = new HashMap<>();
+            abc.put("id", e.getId());
+            abc.put("createTime", e.getCreateTime());
+            abc.put("today", e.getDailyGasInjection());
+            return abc;
+        }).collect(Collectors.toList());
+
+        // 计算最近7天公司整体的设备利用率
+        // 筛选瑞恒 主设备 rq_iot_rh_main_device_category
+        Set<Long> mainDeviceCategoryIds = new HashSet<>();
+        List<DictDataDO> constructionStatusDictData = dictDataService.getDictDataListByDictType("rq_iot_rh_main_device_category");
+        if (CollUtil.isNotEmpty(constructionStatusDictData)) {
+            constructionStatusDictData.forEach(data -> {
+                String value = data.getValue();
+                if (NumberUtil.isNumber(value)) {
+                    Long longValue = Long.valueOf(value);
+                    mainDeviceCategoryIds.add(longValue);
+                }
+            });
+        }
+        Set<Long> allRhChildDeptIds = deptService.getChildDeptIdListFromCache(157l);
+        // 包含设备的部门id集合
+        Set<Long> haveDeviceDeptIds = new HashSet<>();
+        IotDevicePageReqVO deviceReqVO = new IotDevicePageReqVO();
+        deviceReqVO.setDeptIds(new ArrayList<>(allRhChildDeptIds));
+        List<IotDeviceDO> devices = iotDeviceMapper.selectListAlone(deviceReqVO);
+        if (CollUtil.isNotEmpty(devices)) {
+            devices.forEach(device -> {
+                // 20260605 筛选包含主设备的队伍
+                if (mainDeviceCategoryIds.contains(device.getAssetClass())) {
+                    haveDeviceDeptIds.add(device.getDeptId());
+                }
+            });
+        }
+        Map<Long, DeptDO> allDeptPair = deptService.getDeptMap(allRhChildDeptIds);
+        Set<Long> teamIds = new HashSet<>();
+        if (CollUtil.isNotEmpty(allDeptPair)) {
+            allDeptPair.forEach((deptId, dept) -> {
+                // 队伍
+                if ("3".equals(dept.getType()) && haveDeviceDeptIds.contains(deptId)) {
+                    teamIds.add(dept.getId());
+                }
+            });
+        }
+        // key日期2026-06-08   value日期对应的日报数量
+        Map<String, Integer> dateReportCountPair = new HashMap<>();
+        reports.forEach(report -> {
+            // 按照日期维度统计各 工作量数据 累计用电量 累计油耗 累计注气量 累计注水量
+            LocalDateTime reportLocalDate = report.getCreateTime();
+            // 将日期格式转换成 字符串
+            String reportDateStr = LocalDateTimeUtil.format(reportLocalDate, DatePattern.NORM_DATE_PATTERN);
+            Long deptId = report.getDeptId();
+            if (haveDeviceDeptIds.contains(deptId)) {
+                if (dateReportCountPair.containsKey(reportDateStr)) {
+                    Integer tempNum = dateReportCountPair.get(reportDateStr);
+                    dateReportCountPair.put(reportDateStr, ++tempNum);
+                } else {
+                    dateReportCountPair.put(reportDateStr, 1);
+                }
+            }
+        });
+        // 计算每天的设备利用率
+        Map<String, BigDecimal> dateReportUtilizationPair = new HashMap<>();
+        if (CollUtil.isNotEmpty(dateReportCountPair)) {
+            dateReportCountPair.forEach((reportDateStr, reportNum) -> {
+                if (CollUtil.isNotEmpty(teamIds)) {
+                    BigDecimal deviceUtilization = new BigDecimal((double) reportNum / (teamIds.size() * 1))
+                            .setScale(4, RoundingMode.HALF_UP);
+                    dateReportUtilizationPair.put(reportDateStr, deviceUtilization);
+                }
+            });
+        }
+        // 5. 按日期升序补全最近7天,缺失填0
+        List<String> sortedDays = lastSevenDays.stream()
+                .sorted()                                      // yyyy-MM-dd 字符串自然升序
+                .collect(Collectors.toList());
+        LinkedHashMap<String, BigDecimal> fillMap = new LinkedHashMap<>();
+        sortedDays.forEach(day ->
+                fillMap.put(day, dateReportUtilizationPair.getOrDefault(day, BigDecimal.ZERO))
+        );
+        /* LinkedHashMap<String, BigDecimal> fillMap = dateReportUtilizationPair.entrySet().stream()
+                .sorted(Map.Entry.comparingByKey())      // yyyy-MM-dd 字符串自然序即升序
+                .collect(Collectors.toMap(
+                        Map.Entry::getKey,
+                        Map.Entry::getValue,
+                        (e1, e2) -> e1,
+                        LinkedHashMap::new
+                )); */
+
+        // LinkedHashMap<String, Long> fillMap = sumTotalByDate(fills, 7,"today");
+        LinkedList<Object> xAxis = new LinkedList<>(fillMap.keySet());
+        LinkedList<Object> fillData = new LinkedList<>(fillMap.values());
+        /* fillMap.forEach( (k,v)->{
+            xAxis.add(k);
+            fillData.add(v);
+        }); */
+
+        ImmutableMap<String, Serializable> fillResult = ImmutableMap.of("name", "设备利用率~~en**device utilization", "data", fillData);
+        return success(ImmutableMap.of("xAxis", xAxis, "series", ImmutableList.of(fillResult)));
+
+    }
+
+    /**
+     * 无日报时直接返回全0序列
+     */
+    private CommonResult<Map<String, Object>> buildEmptyResult(List<String> lastSevenDays) {
+        List<String> sortedDays = lastSevenDays.stream().sorted().collect(Collectors.toList());
+        LinkedList<Object> xAxis = new LinkedList<>(sortedDays);
+        LinkedList<Object> fillData = sortedDays.stream()
+                .map(d -> BigDecimal.ZERO)
+                .collect(Collectors.toCollection(LinkedList::new));
+        ImmutableMap<String, Serializable> fillResult = ImmutableMap.of(
+                "name", "设备利用率~~en**device utilization",
+                "data", fillData
+        );
+        return success(ImmutableMap.of("xAxis", xAxis, "series", ImmutableList.of(fillResult)));
+    }
+
     @Operation(summary = "瑞恒当日注气量 累计注气量")
     @GetMapping("/rh/zql")
     @PermitAll

+ 1 - 1
yudao-module-pms/yudao-module-pms-biz/src/main/resources/mapper/static/iotprojecttask/IotRhDailyReportMapper.xml

@@ -91,7 +91,7 @@
             resultType="cn.iocoder.yudao.module.pms.controller.admin.stat.vo.YearTotalGas">
         SELECT
         DATE_FORMAT(create_time, '%Y-%m') AS month,
-        SUM(IFNULL(daily_gas_injection, 0)) AS total_gas
+        ROUND(SUM(IFNULL(daily_gas_injection, 0)) / 10000, 2) AS total_gas
         FROM
             rq_iot_rh_daily_report a
         WHERE