Procházet zdrojové kódy

pms 瑞都看板 瑞恒看板 设备利用率 添加近6个月曲线

zhangcl před 1 týdnem
rodič
revize
2b82d1c6a0

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

@@ -121,6 +121,7 @@ import java.sql.Timestamp;
 import java.text.DecimalFormat;
 import java.time.LocalDate;
 import java.time.LocalDateTime;
+import java.time.YearMonth;
 import java.time.format.DateTimeFormatter;
 import java.time.temporal.ChronoUnit;
 import java.util.*;
@@ -1368,7 +1369,6 @@ public class IotStaticController {
                 .map(day -> day.minusDays(1))
                 .map(day -> day.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")))
                 .collect(Collectors.toList());
-        // List<String> lastSevenDays = getLastSevenDays();
         String first = lastSevenDays.get(0);
         String last = lastSevenDays.get(lastSevenDays.size() - 1);
         LocalDateTime startOfDay = getStartOfDay(last);
@@ -1469,28 +1469,125 @@ public class IotStaticController {
         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)));
 
     }
 
+    /**
+     * 瑞恒 近6个月的设备利用率(包含当前月)
+     */
+    @Operation(summary = "瑞恒 近6个月的设备利用率")
+    @GetMapping("/rh/device/sixMonthUtilization")
+    @PermitAll
+    public CommonResult<Map<String, Object>> rhSixMonthUtilization() {
+
+        // 1. 获取最近6个月份(升序:最早月 ~ 当前月)
+        List<String> lastSixMonths = getLastSixMonths();
+
+        // 2. 获取瑞恒所有队伍ID(与 sevenDayUtilization 逻辑完全一致)
+        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)) {
+                    mainDeviceCategoryIds.add(Long.valueOf(value));
+                }
+            });
+        }
+
+        Set<Long> allRhChildDeptIds = deptService.getChildDeptIdListFromCache(157L);
+        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 -> {
+                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());
+                }
+            });
+        }
+
+        // 3. 按月统计设备利用率
+        Map<String, BigDecimal> monthUtilizationMap = new LinkedHashMap<>(); // 保持月份顺序
+
+        for (String month : lastSixMonths) {
+            // 解析年月
+            String[] parts = month.split("-");
+            int year = Integer.parseInt(parts[0]);
+            int monthValue = Integer.parseInt(parts[1]);
+            YearMonth yearMonth = YearMonth.of(year, monthValue);
+
+            // 当月起始时间
+            LocalDateTime startOfMonth = yearMonth.atDay(1).atStartOfDay();
+            LocalDateTime endOfMonth = yearMonth.atEndOfMonth().atTime(23, 59, 59);
+            LocalDateTime[] createTime = new LocalDateTime[]{startOfMonth, endOfMonth};
+
+            // 查询该月所有日报
+            IotRhDailyReportPageReqVO pageReqVO = new IotRhDailyReportPageReqVO();
+            pageReqVO.setCreateTime(createTime);
+            pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
+            PageResult<IotRhDailyReportDO> pageReports = iotRhDailyReportMapper.selectPage(pageReqVO);
+
+            // 统计该月满足条件的日报数量
+            int qualifiedCount = 0;
+            if (ObjUtil.isNotEmpty(pageReports) && CollUtil.isNotEmpty(pageReports.getList())) {
+                List<IotRhDailyReportDO> reports = pageReports.getList();
+                for (IotRhDailyReportDO report : reports) {
+                    Long deptId = report.getDeptId();
+                    BigDecimal dailyGasInjection = report.getDailyGasInjection() != null ? report.getDailyGasInjection() : BigDecimal.ZERO;
+                    BigDecimal dailyWaterInjection = report.getDailyWaterInjection() != null ? report.getDailyWaterInjection() : BigDecimal.ZERO;
+                    if (haveDeviceDeptIds.contains(deptId) &&
+                            (dailyGasInjection.compareTo(BigDecimal.ZERO) > 0 || dailyWaterInjection.compareTo(BigDecimal.ZERO) > 0)) {
+                        qualifiedCount++;
+                    }
+                }
+            }
+
+            // 计算月利用率:分子=合格日报数,分母=队伍数 × 当月天数
+            BigDecimal utilization = BigDecimal.ZERO;
+            if (CollUtil.isNotEmpty(teamIds)) {
+                int daysInMonth = yearMonth.lengthOfMonth();
+                long denominator = (long) teamIds.size() * daysInMonth;
+                if (denominator > 0) {
+                    utilization = BigDecimal.valueOf(qualifiedCount)
+                            .divide(BigDecimal.valueOf(denominator), 4, RoundingMode.HALF_UP);
+                }
+            }
+            monthUtilizationMap.put(month, utilization);
+        }
+
+        // 4. 构建返回结果(与 sevenDayUtilization 结构完全一致)
+        LinkedList<Object> xAxis = new LinkedList<>(monthUtilizationMap.keySet());
+        LinkedList<Object> data = new LinkedList<>(monthUtilizationMap.values());
+
+        ImmutableMap<String, Serializable> series = ImmutableMap.of(
+                "name", "设备利用率~~en**device utilization",
+                "data", data
+        );
+
+        return success(ImmutableMap.of(
+                "xAxis", xAxis,
+                "series", ImmutableList.of(series)
+        ));
+    }
+
     @Operation(summary = "瑞都 近1周的设备利用率")
     @GetMapping("/rd/device/sevenDayUtilization")
     @PermitAll
@@ -1605,6 +1702,124 @@ public class IotStaticController {
 
     }
 
+    /**
+     * 获取最近6个月(包括当前月)的月份列表,按时间升序排列
+     * 例如当前为 2026-07,则返回 ["2026-02", "2026-03", "2026-04", "2026-05", "2026-06", "2026-07"]
+     */
+    private List<String> getLastSixMonths() {
+        List<String> months = new ArrayList<>();
+        LocalDate now = LocalDate.now();
+        for (int i = 5; i >= 0; i--) {
+            LocalDate monthDate = now.minusMonths(i);
+            String monthStr = monthDate.format(DateTimeFormatter.ofPattern("yyyy-MM"));
+            months.add(monthStr);
+        }
+        return months;
+    }
+
+    /**
+     * 瑞都 近6个月的设备利用率(包含当前月)
+     */
+    @Operation(summary = "瑞都 近6个月的设备利用率")
+    @GetMapping("/rd/device/sixMonthUtilization")
+    @PermitAll
+    public CommonResult<Map<String, Object>> rdSixMonthUtilization() {
+
+        // 1. 获取最近6个月份(升序,从最早到当前月)
+        List<String> lastSixMonths = getLastSixMonths(); // 实现见下方
+
+        // 2. 获取所有非封存的压裂/连油主设备(AB类设备)
+        Set<Long> allRhChildDeptIds = deptService.getChildDeptIdListFromCache(163L);
+        Set<Long> mainDeviceIds = new HashSet<>();
+        IotDeviceAssociatePageReqVO deviceAssocReqVO = new IotDeviceAssociatePageReqVO();
+        deviceAssocReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
+        deviceAssocReqVO.setDeptIds(allRhChildDeptIds);
+        PageResult<IotDeviceAssociateDO> pageResult = iotDeviceAssociateMapper.selectPage(deviceAssocReqVO);
+        if (ObjUtil.isNotEmpty(pageResult) && CollUtil.isNotEmpty(pageResult.getList())) {
+            pageResult.getList().forEach(assoc -> mainDeviceIds.add(assoc.getDeviceId()));
+        }
+
+        Set<Long> abDeviceIds = new HashSet<>();
+        if (CollUtil.isNotEmpty(mainDeviceIds)) {
+            IotDevicePageReqVO deviceReqVO = new IotDevicePageReqVO();
+            deviceReqVO.setDeviceIds(new ArrayList<>(mainDeviceIds));
+            List<IotDeviceDO> mainDevices = iotDeviceMapper.selectListAlone(deviceReqVO);
+            if (CollUtil.isNotEmpty(mainDevices)) {
+                mainDevices.forEach(device -> {
+                    // 过滤掉封存设备("fc")
+                    // if (!"fc".equals(device.getDeviceStatus())) {
+                        abDeviceIds.add(device.getId());
+                    // }
+                });
+            }
+        }
+
+        // 3. 按月统计设备利用率
+        Map<String, BigDecimal> monthUtilizationMap = new LinkedHashMap<>(); // 保持顺序
+
+        for (String month : lastSixMonths) {
+            // 解析年月
+            String[] parts = month.split("-");
+            int year = Integer.parseInt(parts[0]);
+            int monthValue = Integer.parseInt(parts[1]);
+            YearMonth yearMonth = YearMonth.of(year, monthValue);
+
+            // 当月第一天 00:00:00 和最后一天 23:59:59
+            LocalDate firstDay = yearMonth.atDay(1);
+            LocalDate lastDay = yearMonth.atEndOfMonth();
+            LocalDateTime startOfMonth = firstDay.atStartOfDay();
+            LocalDateTime endOfMonth = lastDay.atTime(23, 59, 59);
+            LocalDateTime[] createTime = new LocalDateTime[]{startOfMonth, endOfMonth};
+
+            // 查询该月所有日报
+            IotRdDailyReportPageReqVO pageReqVO = new IotRdDailyReportPageReqVO();
+            pageReqVO.setCreateTime(createTime);
+            pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
+            PageResult<IotRdDailyReportDO> pageReports = iotRdDailyReportMapper.selectPage(pageReqVO);
+
+            // 收集该月所有日报中出现的AB设备ID(不去重,累加次数)
+            List<Long> monthReportMainDeviceIds = new ArrayList<>();
+            if (ObjUtil.isNotEmpty(pageReports) && CollUtil.isNotEmpty(pageReports.getList())) {
+                List<IotRdDailyReportDO> reports = pageReports.getList();
+                for (IotRdDailyReportDO report : reports) {
+                    Set<Long> deviceIds = report.getDeviceIds();
+                    if (CollUtil.isNotEmpty(deviceIds)) {
+                        // 只保留AB类设备
+                        deviceIds.stream()
+                                .filter(abDeviceIds::contains)
+                                .forEach(monthReportMainDeviceIds::add);
+                    }
+                }
+            }
+
+            // 计算当月设备利用率:分子=当月所有日报中AB设备出现总次数,分母=AB设备总数 × 当月天数
+            BigDecimal utilization = BigDecimal.ZERO;
+            if (CollUtil.isNotEmpty(abDeviceIds)) {
+                int daysInMonth = yearMonth.lengthOfMonth();
+                long denominator = (long) abDeviceIds.size() * daysInMonth;
+                if (denominator > 0) {
+                    utilization = BigDecimal.valueOf(monthReportMainDeviceIds.size())
+                            .divide(BigDecimal.valueOf(denominator), 4, RoundingMode.HALF_UP);
+                }
+            }
+            monthUtilizationMap.put(month, utilization);
+        }
+
+        // 4. 构建返回数据(与 rdSevenDayUtilization 结构一致)
+        LinkedList<Object> xAxis = new LinkedList<>(monthUtilizationMap.keySet());
+        LinkedList<Object> data = new LinkedList<>(monthUtilizationMap.values());
+
+        ImmutableMap<String, Serializable> series = ImmutableMap.of(
+                "name", "设备利用率~~en**device utilization",
+                "data", data
+        );
+
+        return success(ImmutableMap.of(
+                "xAxis", xAxis,
+                "series", ImmutableList.of(series)
+        ));
+    }
+
     /**
      * 无日报时直接返回全0序列
      */