Просмотр исходного кода

pms 集团生产概况 钉钉消息推送

zhangcl 1 неделя назад
Родитель
Сommit
57a53812c0
13 измененных файлов с 1098 добавлено и 460 удалено
  1. 3 0
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/constant/PmsConstants.java
  2. 0 1
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/iotrddailyreport/IotRdDailyReportController.java
  3. 1 177
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/iotrhdailyreport/IotRhDailyReportController.java
  4. 1 186
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/iotrydailyreport/IotRyDailyReportController.java
  5. 0 41
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/dal/mysql/iotrydailyreport/IotRyDailyReportMapper.java
  6. 9 54
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/job/dailyreport/CreateRdDailyReportStatisticsJob.java
  7. 641 0
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/job/dailyreport/CreateYfDailyReportStatisticsJob.java
  8. 9 1
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/message/PmsMessage.java
  9. 6 0
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/service/iotrddailyreport/IotRdDailyReportServiceImpl.java
  10. 16 0
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/service/iotrhdailyreport/IotRhDailyReportService.java
  11. 190 0
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/service/iotrhdailyreport/IotRhDailyReportServiceImpl.java
  12. 17 0
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/service/iotrydailyreport/IotRyDailyReportService.java
  13. 205 0
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/service/iotrydailyreport/IotRyDailyReportServiceImpl.java

+ 3 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/constant/PmsConstants.java

@@ -52,4 +52,7 @@ public interface PmsConstants {
 
     // 瑞都日报汇总生产动态消息提醒
     String RD_PRODUCTION_STATUS = "rd-production-status";
+
+    // 油服日报汇总生产动态消息提醒
+    String YF_PRODUCTION_STATUS = "yf-production-status";
 }

+ 0 - 1
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/iotrddailyreport/IotRdDailyReportController.java

@@ -81,7 +81,6 @@ import java.time.temporal.ChronoUnit;
 import java.util.*;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.stream.Collectors;
-import java.util.stream.Stream;
 
 import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;

+ 1 - 177
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/iotrhdailyreport/IotRhDailyReportController.java

@@ -59,7 +59,6 @@ import java.math.BigDecimal;
 import java.math.RoundingMode;
 import java.text.DecimalFormat;
 import java.time.LocalDateTime;
-import java.time.temporal.ChronoUnit;
 import java.util.*;
 import java.util.concurrent.atomic.AtomicReference;
 import java.util.stream.Stream;
@@ -543,182 +542,7 @@ public class IotRhDailyReportController {
                 pageReqVO.setTaskIds(taskIds);
             }
         }
-        // 统计设备利用率
-        Long deptId = pageReqVO.getDeptId();
-        // 项目部名称集合
-        Set<String> projectDeptNames = new HashSet<>();
-        // 项目部id集合
-        Set<Long> projectDeptIds = new HashSet<>();
-        // 队伍id集合
-        Set<Long> teamIds = new HashSet<>();
-        // key项目部id   value项目部名称
-        Map<Long, String> projectPair = new HashMap<>();
-        // key施工队伍id   value状态为LY的项目部id
-        Map<Long, Long> teamProjectIdPair = new HashMap<>();
-        if (ObjUtil.isNotEmpty(deptId)) {
-            // 筛选瑞恒 主设备 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> childDeptIds = deptService.getChildDeptIdListFromCache(deptId);
-            childDeptIds.add(deptId);
-            Map<Long, DeptDO> allDeptPair = deptService.getDeptMap(childDeptIds);
-            // 查询 瑞恒 所有设备 只统计包含 施工 状态设备的队伍
-            IotDevicePageReqVO deviceReqVO = new IotDevicePageReqVO();
-            deviceReqVO.setDeptIds(new ArrayList<>(childDeptIds));
-            List<IotDeviceDO> allRhDevices = iotDeviceMapper.selectListAlone(deviceReqVO);
-            // 包含设备的部门id集合
-            Set<Long> haveDeviceDeptIds = new HashSet<>();
-            if (CollUtil.isNotEmpty(allRhDevices)) {
-                // 筛选出包含设备的队伍部门集合
-                allRhDevices.forEach(device -> {
-                    // 20260605 筛选包含主设备的队伍
-                    if (mainDeviceCategoryIds.contains(device.getAssetClass())) {
-                        haveDeviceDeptIds.add(device.getDeptId());
-                    }
-                });
-            }
-            if (CollUtil.isNotEmpty(allDeptPair)) {
-                allDeptPair.forEach((departmentId, dept) -> {
-                    // 项目部 只统计 email = LY 的项目部的 设备利用率
-                    if ("2".equals(dept.getType()) && "LY".equals(dept.getEmail())) {
-                        projectDeptIds.add(departmentId);
-                        projectDeptNames.add(dept.getName());
-                        projectPair.put(departmentId, dept.getName());
-                    }
-                    if ("3".equals(dept.getType())) {
-                        teamIds.add(departmentId);
-                    }
-                });
-                // 遍历所有部门 只筛选出有设备的队伍
-                allDeptPair.forEach((departmentId, dept) -> {
-                    // 不需要找出每个项目部下的队伍 根据筛选的日期和部门 统计数据
-                    if (haveDeviceDeptIds.contains(departmentId)) {
-                        if (projectPair.containsKey(dept.getParentId()) && teamIds.contains(departmentId)) {
-                            // 获得队伍的上级项目部(LY状态的项目部)
-                            teamProjectIdPair.put(dept.getId(), dept.getParentId());
-                        }
-                        if (allDeptPair.size() == 1) {
-                            // 查询单个队伍的情况
-                            teamProjectIdPair.put(dept.getId(), dept.getParentId());
-                        }
-                    }
-                });
-            }
-        }
-
-        List<IotRhDailyReportDO> list = iotRhDailyReportService.getIotRhDailyReportPage(pageReqVO).getList();
-        Map<String, BigDecimal> result = new HashMap<>();
-        // 累计注气量
-        BigDecimal totalGasInjection = BigDecimal.ZERO;
-        // 累计氮气注气量
-        BigDecimal totalN2GasInjection = BigDecimal.ZERO;
-        // 累计天然气注气量
-        BigDecimal totalNaturalGasInjection = BigDecimal.ZERO;
-
-        BigDecimal totalWaterInjection = BigDecimal.ZERO;
-        BigDecimal totalPowerConsumption = BigDecimal.ZERO;
-        BigDecimal totalFuelConsumption = BigDecimal.ZERO;
-        double rate = 0.0;
-        Integer reportCount = 0;
-        if (CollUtil.isNotEmpty(list)) {
-            // 筛选出指定搜索条件下日报关联任务的工艺 类别 N2 或 天然气
-            Set<Long> filteredTaskIds = new HashSet<>();
-            list.forEach(report -> {
-                if (ObjUtil.isNotEmpty(report.getTaskId())) {
-                    filteredTaskIds.add(report.getTaskId());
-                }
-            });
-            // 查询日报对应的任务列表 获得 任务的施工工艺 N2(2) 或 天然气(15)
-            IotProjectTaskPageReqVO taskReqVO = new IotProjectTaskPageReqVO();
-            taskReqVO.setTaskIds(new ArrayList<>(filteredTaskIds));
-            List<IotProjectTaskDO> tasks = iotProjectTaskService.projectTasks(taskReqVO);
-            Map<Long, String> taskTechniquePair = new HashMap<>();
-            if (CollUtil.isNotEmpty(tasks)) {
-                tasks.forEach(task -> {
-                    if (StrUtil.isNotBlank(task.getTechnique())) {
-                        taskTechniquePair.put(task.getId(), task.getTechnique());
-                    }
-                });
-            }
-
-            for (IotRhDailyReportDO report : list) {
-                // 统计出状态为 LY 的项目部下的施工队伍的日报数量
-                // 20260604 设备利用率计算逻辑调整 分子 注气量或注水量>0 的日报数量
-                if (teamProjectIdPair.containsKey(report.getDeptId()) &&
-                        (report.getDailyGasInjection().compareTo(BigDecimal.ZERO)>0 || report.getDailyWaterInjection().compareTo(BigDecimal.ZERO)>0)) {
-                    ++reportCount;
-                }
-                BigDecimal dailyGasInjection = report.getDailyGasInjection();
-                BigDecimal dailyWaterInjection = report.getDailyWaterInjection();
-                BigDecimal powerConsumption = report.getDailyPowerUsage();
-                BigDecimal oilConsumption = report.getDailyOilUsage();
-                if (ObjUtil.isNotEmpty(dailyGasInjection)) {
-                    totalGasInjection = totalGasInjection.add(dailyGasInjection);
-                    if (taskTechniquePair.containsKey(report.getTaskId())) {
-                        String technique = taskTechniquePair.get(report.getTaskId());
-                        if ("2".equals(technique)) {
-                            // 注氮气
-                            totalN2GasInjection = totalN2GasInjection.add(dailyGasInjection);
-                        }
-                        if ("15".equals(technique)) {
-                            // 注天然气
-                            totalNaturalGasInjection = totalNaturalGasInjection.add(dailyGasInjection);
-                        }
-                    }
-                }
-                if (ObjUtil.isNotEmpty(dailyWaterInjection)) {
-                    totalWaterInjection = totalWaterInjection.add(dailyWaterInjection);
-                }
-                if (ObjUtil.isNotEmpty(powerConsumption)) {
-                    totalPowerConsumption = totalPowerConsumption.add(powerConsumption);
-                }
-                if (ObjUtil.isNotEmpty(oilConsumption)) {
-                    totalFuelConsumption = totalFuelConsumption.add(oilConsumption);
-                }
-            }
-            // 计算筛选时间范围内 指定部门的设备利用率
-            long daysCount = 0l;
-            if (ObjUtil.isNotEmpty(pageReqVO.getCreateTime()) && pageReqVO.getCreateTime().length >= 2) {
-                LocalDateTime start = pageReqVO.getCreateTime()[0];
-                LocalDateTime end = pageReqVO.getCreateTime()[1];
-                if (ObjUtil.isNotEmpty(start) && ObjUtil.isNotEmpty(end) && !end.isBefore(start)) {
-                    // 使用ChronoUnit.DAYS.between计算天数差,并+1包含首尾两天
-                    daysCount = ChronoUnit.DAYS.between(
-                            start.toLocalDate(),
-                            end.toLocalDate()
-                    ) + 1;
-                }
-            }
-            // 所有LY状态的项目部包含的队伍数量>0 并且 指定时间区间天数大于0
-            if (daysCount > 0 && teamProjectIdPair.size() > 0) {
-                // 指定部门(公司or项目部or队伍) 设备利用率 公式 reportCount/(currentTeamNum*daysCount)
-                // 计算设备利用率(处理除数为0的情况)
-                rate = new BigDecimal((double) reportCount / (teamProjectIdPair.size() * daysCount))
-                        .setScale(4, RoundingMode.HALF_UP)  // 保留4位小数,四舍五入
-                        .doubleValue();
-            }
-            // 汇总 指定搜索时间段内的 累计注气量 累计注水量 累计用电量 累计油耗
-            result.put("totalGasInjection", totalGasInjection);
-            // 区分出 累计注气量 中的 氮气/天然气 注气量
-            result.put("totalN2GasInjection", totalN2GasInjection);
-            result.put("totalNaturalGasInjection", totalNaturalGasInjection);
-
-            result.put("totalWaterInjection", totalWaterInjection);
-            result.put("totalPowerConsumption", totalPowerConsumption);
-            result.put("totalFuelConsumption", totalFuelConsumption);
-            result.put("utilizationRate", BigDecimal.valueOf(rate));
-        }
+        Map<String, BigDecimal> result = iotRhDailyReportService.totalWorkload(pageReqVO);
         return success(result);
     }
 

+ 1 - 186
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/iotrydailyreport/IotRyDailyReportController.java

@@ -9,7 +9,6 @@ import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
 import cn.iocoder.yudao.framework.common.pojo.PageParam;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
-import cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils;
 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
 import cn.iocoder.yudao.framework.datapermission.core.util.DataPermissionUtils;
 import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
@@ -53,9 +52,7 @@ import java.io.IOException;
 import java.math.BigDecimal;
 import java.math.RoundingMode;
 import java.text.DecimalFormat;
-import java.time.LocalDate;
 import java.time.LocalDateTime;
-import java.time.temporal.ChronoUnit;
 import java.util.*;
 import java.util.concurrent.atomic.AtomicReference;
 import java.util.stream.Collectors;
@@ -2435,189 +2432,7 @@ public class IotRyDailyReportController {
 
         // 时间查询区间内如果包含 未发生的时间段(今年 本季度) 则设置 结束时间为 当前日期
         // 【调用公共方法】矫正未来时间区间
-        LocalDateTimeUtils.correctFutureTimeRange(pageReqVO.getCreateTime());
-
-        // 统计设备利用率
-        Long deptId = pageReqVO.getDeptId();
-        // 钻井或修井部门 队伍
-        List<Long> zjOrXjDeptIds = new ArrayList<>();
-        // 可用的部门id集合
-        Set<Long> availableDeptIds = new HashSet<>();
-        if (ObjUtil.isNotEmpty(deptId)) {
-            // 查询指定部门下所有子部门
-            Set<Long> childDeptIds = deptService.getChildDeptIdListFromCache(deptId);
-            Map<Long, DeptDO> allDeptPair = deptService.getDeptMap(childDeptIds);
-            // 过滤掉关闭的部门
-            if (CollUtil.isNotEmpty(allDeptPair)) {
-                allDeptPair.forEach((tempDeptId, dept) -> {
-                    if (0 == dept.getStatus()) {
-                        availableDeptIds.add(tempDeptId);
-                    }
-                });
-            }
-            // 钻井日报汇总 分母为 钻井施工队伍  修井日报汇总分母分母为修井施工队伍
-            // 1钻井  2修井
-            String projectClassification = pageReqVO.getProjectClassification();
-            // 查询钻井部门 修井 部门
-            IotDeptTypePageReqVO reqVO = new IotDeptTypePageReqVO();
-            if ("1".equals(projectClassification)) {
-                reqVO.setType("zj");
-            } else {
-                reqVO.setType("xj");
-            }
-            List<IotDeptTypeDO> deptTypes = iotDeptTypeMapper.selectList(reqVO);
-            if (CollUtil.isNotEmpty(deptTypes)) {
-                deptTypes.forEach(dept -> {
-                    zjOrXjDeptIds.add(dept.getDeptId());
-                });
-            }
-        }
-        // 取 availableDeptIds zjOrXjDeptIds 2个集合的交集 当前查询条件下 的钻井 或 修井 部门id集合
-        Set<Long> overlapDeptIds = Stream.of(availableDeptIds)
-                .filter(Objects::nonNull)
-                .flatMap(Set::stream)
-                .filter(tempDeptId -> CollUtil.isNotEmpty(zjOrXjDeptIds) && zjOrXjDeptIds.contains(tempDeptId))
-                .collect(Collectors.toSet());
-
-
-        // 统计设备利用率 查询非 dt zx 状态的日报
-        // 钻井:日报状态 过滤掉 ‘等停dt’    修井:日报状态过滤掉 ‘等停dt’、‘整修zx’
-        List<String> statuses = new ArrayList<>();
-        statuses.add("dt");
-        statuses.add("zx");
-        pageReqVO.setStatuses(statuses);
-        double rate = 0.0;
-        Integer reportCount = 0;
-        List<IotRyDailyReportDO> dailyReports = iotRyDailyReportMapper.dailyReports(pageReqVO);
-        if (CollUtil.isNotEmpty(dailyReports)) {
-            for (IotRyDailyReportDO dailyReport : dailyReports) {
-                if (overlapDeptIds.contains(dailyReport.getDeptId())) {
-                    ++reportCount;
-                }
-            }
-        }
-
-        // 计算筛选时间范围内 指定部门的设备利用率
-        long daysCount = 0l;
-        if (ObjUtil.isNotEmpty(pageReqVO.getCreateTime()) && pageReqVO.getCreateTime().length >= 2) {
-            LocalDateTime start = pageReqVO.getCreateTime()[0];
-            LocalDateTime end = pageReqVO.getCreateTime()[1];
-            if (ObjUtil.isNotEmpty(start) && ObjUtil.isNotEmpty(end) && !end.isBefore(start)) {
-                // 使用ChronoUnit.DAYS.between计算天数差,并+1包含首尾两天
-                daysCount = ChronoUnit.DAYS.between(
-                        start.toLocalDate(),
-                        end.toLocalDate()
-                ) + 1;
-            }
-        }
-
-        // 所有项目部包含的队伍数量>0 并且 指定时间区间天数大于0
-        if (daysCount > 0 && overlapDeptIds.size() > 0) {
-            // 当前项目部 设备利用率 公式 reportCount/(currentTeamNum*daysCount)
-            // 计算设备利用率(处理除数为0的情况)
-            rate = new BigDecimal((double) reportCount / (overlapDeptIds.size() * daysCount))
-                    .setScale(4, RoundingMode.HALF_UP)  // 保留4位小数,四舍五入
-                    .doubleValue();
-            System.out.println("瑞鹰设备利用率-分子:" + reportCount);
-            System.out.println("瑞鹰设备利用率-分母:" + overlapDeptIds.size());
-        }
-
-        // 查询指定部门 指定时间范围内的日报
-        List<IotRyDailyReportDO> list = iotRyDailyReportService.getIotRyDailyReportPage(pageReqVO).getList();
-        Map<String, BigDecimal> result = new HashMap<>();
-        // 总进尺
-        BigDecimal totalFootage = BigDecimal.ZERO;
-        // 总用电量
-        BigDecimal totalPowerConsumption = BigDecimal.ZERO;
-        // 总油耗
-        BigDecimal totalFuelConsumption = BigDecimal.ZERO;
-        // 平均油耗
-        BigDecimal averageFuelConsumption = BigDecimal.ZERO;
-        // key队伍id      value施工井数
-        BigDecimal constructionWells = BigDecimal.ZERO;
-        // key队伍id      value完工井数
-        BigDecimal completedWells = BigDecimal.ZERO;
-        // key施工队伍id    value施工井数量
-        Map<Long, Integer> totalTasksPair = new HashMap<>();
-        // key施工队伍id    value完工井数量
-        Map<Long, Integer> completedTasksPair = new HashMap<>();
-        // 瑞鹰修井 施工井数 完工井数 统计
-        Set<Long> ids = new HashSet<>();
-        if (Objects.nonNull(pageReqVO.getDeptId())) {
-            ids = deptService.getChildDeptIdListFromCache(pageReqVO.getDeptId());
-            ids.add(pageReqVO.getDeptId());
-            pageReqVO.setDeptIds(ids);
-        }
-        if (ObjUtil.isNotEmpty(pageReqVO.getCreateTime())) {
-            List<IotRyDailyReportTaskCountVO> repairDeptTasks = iotRyDailyReportService.countRepairTasksByDept(pageReqVO);
-            if (CollUtil.isNotEmpty(repairDeptTasks)) {
-                repairDeptTasks.forEach(task -> {
-                    totalTasksPair.put(task.getDeptId(), task.getTotalTaskCount());
-                    completedTasksPair.put(task.getDeptId(), task.getCompletedTaskCount());
-                });
-            }
-        }
-
-        if (CollUtil.isNotEmpty(list)) {
-            for (IotRyDailyReportDO report : list) {
-                BigDecimal dailyFootage = report.getDailyFootage();
-                BigDecimal powerConsumption = report.getDailyPowerUsage();
-                BigDecimal fuelConsumption = report.getDailyFuel();
-                if (ObjUtil.isNotEmpty(dailyFootage)) {
-                    totalFootage = totalFootage.add(dailyFootage);
-                }
-                if (ObjUtil.isNotEmpty(powerConsumption)) {
-                    totalPowerConsumption = totalPowerConsumption.add(powerConsumption);
-                }
-                if (ObjUtil.isNotEmpty(fuelConsumption)) {
-                    totalFuelConsumption = totalFuelConsumption.add(fuelConsumption);
-                }
-            }
-
-            // 施工井数
-            if (CollUtil.isNotEmpty(totalTasksPair)) {
-                for (Integer wellCount : totalTasksPair.values()) {
-                    constructionWells = constructionWells.add(new BigDecimal(wellCount));
-                }
-            }
-            // 完工井数
-            if (CollUtil.isNotEmpty(completedTasksPair)) {
-                for (Integer wellCount : completedTasksPair.values()) {
-                    completedWells = completedWells.add(new BigDecimal(wellCount));
-                }
-            }
-            // 累计用电量
-            result.put("totalPowerConsumption", totalPowerConsumption);
-            // 累计油耗
-            result.put("totalFuelConsumption", totalFuelConsumption);
-            // 平均油耗
-            if (ObjUtil.isNotEmpty(pageReqVO.getCreateTime())) {
-                LocalDateTime[] createTimes = pageReqVO.getCreateTime();
-                // 获取开始时间和结束时间
-                LocalDateTime startTime = createTimes[0];
-                LocalDateTime endTime = createTimes[1];
-                // 截断到日期(忽略时分秒)
-                LocalDate startDate = startTime.toLocalDate();
-                LocalDate endDate = endTime.toLocalDate();
-                // 计算天数:日期差 + 1(包含首尾两天)
-                long days = ChronoUnit.DAYS.between(startDate, endDate) + 1;
-                averageFuelConsumption = totalFuelConsumption.divide(new BigDecimal(days), 2, RoundingMode.HALF_UP);
-                result.put("averageFuelConsumption", averageFuelConsumption);
-            }
-
-            // 汇总 指定搜索时间段内的 总进尺  累计用电量 累计油耗
-            if ("1".equals(pageReqVO.getProjectClassification())) {
-                // 钻井日报
-                result.put("totalFootage", totalFootage);
-            } else if ("2".equals(pageReqVO.getProjectClassification())) {
-                // 累计施工井数
-                result.put("constructionWells", constructionWells);
-                // 累计完工井数
-                result.put("completedWells", completedWells);
-            }
-        }
-        // 设备利用率
-        result.put("utilizationRate", BigDecimal.valueOf(rate));
+        Map<String, BigDecimal> result = iotRyDailyReportService.totalWorkload(pageReqVO);
         return success(result);
     }
 

+ 0 - 41
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/dal/mysql/iotrydailyreport/IotRyDailyReportMapper.java

@@ -134,47 +134,6 @@ public interface IotRyDailyReportMapper extends BaseMapperX<IotRyDailyReportDO>
 
         // 获取查询参数中的 projectClassification 值
         String projectClassification = reqVO.getProjectClassification();
-        // LambdaQueryWrapperX<IotRyDailyReportDO> queryWrapper = new LambdaQueryWrapperX<IotRyDailyReportDO>();
-        // 创建查询包装器
-        /* queryWrapper
-                // .eqIfPresent(IotRyDailyReportDO::getDeptId, reqVO.getDeptId())
-                .inIfPresent(IotRyDailyReportDO::getDeptId, reqVO.getDeptIds())
-                .eqIfPresent(IotRyDailyReportDO::getProjectId, reqVO.getProjectId())
-                .inIfPresent(IotRyDailyReportDO::getProjectId, reqVO.getProjectIds())
-                .eqIfPresent(IotRyDailyReportDO::getTaskId, reqVO.getTaskId())
-                .inIfPresent(IotRyDailyReportDO::getTaskId, reqVO.getTaskIds())
-                .eqIfPresent(IotRyDailyReportDO::getRelocationDays, reqVO.getRelocationDays())
-                .betweenIfPresent(IotRyDailyReportDO::getLatestWellDoneTime, reqVO.getLatestWellDoneTime())
-                .eqIfPresent(IotRyDailyReportDO::getCurrentDepth, reqVO.getCurrentDepth())
-                .eqIfPresent(IotRyDailyReportDO::getDailyFootage, reqVO.getDailyFootage())
-                .eqIfPresent(IotRyDailyReportDO::getMonthlyFootage, reqVO.getMonthlyFootage())
-                .eqIfPresent(IotRyDailyReportDO::getAnnualFootage, reqVO.getAnnualFootage())
-                .eqIfPresent(IotRyDailyReportDO::getDailyPowerUsage, reqVO.getDailyPowerUsage())
-                .eqIfPresent(IotRyDailyReportDO::getMonthlyPowerUsage, reqVO.getMonthlyPowerUsage())
-                .eqIfPresent(IotRyDailyReportDO::getDailyFuel, reqVO.getDailyFuel())
-                .eqIfPresent(IotRyDailyReportDO::getMonthlyFuel, reqVO.getMonthlyFuel())
-                .betweenIfPresent(IotRyDailyReportDO::getNonProductionTime, reqVO.getNonProductionTime())
-                .eqIfPresent(IotRyDailyReportDO::getRyNptReason, reqVO.getRyNptReason())
-                .betweenIfPresent(IotRyDailyReportDO::getConstructionStartDate, reqVO.getConstructionStartDate())
-                .betweenIfPresent(IotRyDailyReportDO::getConstructionEndDate, reqVO.getConstructionEndDate())
-                .eqIfPresent(IotRyDailyReportDO::getProductionStatus, reqVO.getProductionStatus())
-                .eqIfPresent(IotRyDailyReportDO::getNextPlan, reqVO.getNextPlan())
-                .eqIfPresent(IotRyDailyReportDO::getRigStatus, reqVO.getRigStatus())
-                .eqIfPresent(IotRyDailyReportDO::getPersonnel, reqVO.getPersonnel())
-                .eqIfPresent(IotRyDailyReportDO::getMudDensity, reqVO.getMudDensity())
-                .eqIfPresent(IotRyDailyReportDO::getMudViscosity, reqVO.getMudViscosity())
-                .eqIfPresent(IotRyDailyReportDO::getLateralLength, reqVO.getLateralLength())
-                .eqIfPresent(IotRyDailyReportDO::getWellInclination, reqVO.getWellInclination())
-                .eqIfPresent(IotRyDailyReportDO::getAzimuth, reqVO.getAzimuth())
-                .eqIfPresent(IotRyDailyReportDO::getExtProperty, reqVO.getExtProperty())
-                .eqIfPresent(IotRyDailyReportDO::getSort, reqVO.getSort())
-                .eqIfPresent(IotRyDailyReportDO::getRemark, reqVO.getRemark())
-                .eqIfPresent(IotRyDailyReportDO::getStatus, reqVO.getStatus())
-                .eqIfPresent(IotRyDailyReportDO::getProcessInstanceId, reqVO.getProcessInstanceId())
-                .eqIfPresent(IotRyDailyReportDO::getAuditStatus, reqVO.getAuditStatus())
-                .betweenIfPresent(IotRyDailyReportDO::getCreateTime, reqVO.getCreateTime())
-                .orderByDesc(IotRyDailyReportDO::getCreateTime)
-                .orderByAsc(IotRyDailyReportDO::getId); */
 
         // 处理 statuses 条件:当 statuses 有值时,查询 rigStatus 或 repairStatus 不在 statuses 中的数据
         Collection<String> statuses = reqVO.getStatuses();

+ 9 - 54
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/job/dailyreport/CreateRdDailyReportStatisticsJob.java

@@ -13,7 +13,6 @@ import cn.iocoder.yudao.module.pms.controller.admin.iotrddailyreport.vo.IotRdDai
 import cn.iocoder.yudao.module.pms.dal.dataobject.iotrddailyreport.IotRdDailyReportDO;
 import cn.iocoder.yudao.module.pms.message.PmsMessage;
 import cn.iocoder.yudao.module.pms.service.iotrddailyreport.IotRdDailyReportService;
-import cn.iocoder.yudao.module.pms.service.iotrhdailyreport.IotRhDailyReportService;
 import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
 import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
 import cn.iocoder.yudao.module.system.dal.dataobject.permission.RoleDO;
@@ -46,8 +45,6 @@ public class CreateRdDailyReportStatisticsJob implements JobHandler {
     @Resource
     private AdminUserApi adminUserApi;
     @Resource
-    private IotRhDailyReportService iotRhDailyReportService;
-    @Resource
     private IotRdDailyReportService iotRdDailyReportService;
     @Resource(name = PMS_THREAD_POOL_TASK_EXECUTOR)
     private ThreadPoolTaskExecutor pmsThreadPoolTaskExecutor;
@@ -73,26 +70,25 @@ public class CreateRdDailyReportStatisticsJob implements JobHandler {
         LocalDateTime createTimeStart = yesterday.toLocalDate().atStartOfDay();
         LocalDateTime createTimeEnd = yesterday.toLocalDate().atTime(LocalTime.MAX);
 
-        // 查询瑞恒昨天的日报列表
-        // IotRhDailyReportPageReqVO reqVO = new IotRhDailyReportPageReqVO();
-        // 测试数据
-        /* reqVO.setCreateTime(new LocalDateTime[]{
-                LocalDate.of(2026, 6, 15).atStartOfDay(),
-                LocalDate.of(2026, 6, 15).atTime(23, 59, 59)
-        }); */
-
+        // 查询瑞都昨天的日报列表
         IotRdDailyReportPageReqVO reqVO = new IotRdDailyReportPageReqVO();
         reqVO.setCreateTime(new LocalDateTime[]{createTimeStart, createTimeEnd});
         reqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
         PageResult<IotRdDailyReportDO> pageReports = iotRdDailyReportService.getIotRdDailyReportPage(reqVO);
         List<IotRdDailyReportDO> dailyReports = pageReports.getList();
         if (CollUtil.isEmpty(dailyReports)) {
-            return "没有数据";
+            return "没有符合条件的数据";
         }
 
         List<IotRdDailyReportRespVO> reports = iotRdDailyReportService.getIotRdDailyReports(dailyReports);
         // 先 按照 项目部projectSort 排序 再按照 队伍teamSort 排序
-        // todo 只筛选 时效维护完成的日报记录
+        // 只筛选 时效维护完成 status = 1 的日报记录
+        reports = reports.stream()
+                .filter(r -> Objects.equals(r.getStatus(), 1))
+                .collect(Collectors.toList());
+        if (CollUtil.isEmpty(dailyReports)) {
+            return "没有符合条件的数据";
+        }
         // 1. 排序:先按项目部 sort,再按队伍 sort(null 排最后)
         reports.sort(Comparator
                 .comparing(IotRdDailyReportRespVO::getProjectSort,
@@ -111,18 +107,6 @@ public class CreateRdDailyReportStatisticsJob implements JobHandler {
         // 构建包含所有项目部的消息(每个项目部一块)
         StringBuilder finalMsgBuilder = new StringBuilder();
 
-        reports.forEach(report -> {
-            List<String> injectLines = new ArrayList<>();
-            List<String> rateLines = new ArrayList<>();
-            // 以项目部分组各队伍的日报 施工简报
-            String projectName = report.getProjectName();
-            String teamName = report.getDeptName();
-            String taskName = report.getTaskName();
-            String rdStatusLabel = report.getRdStatusLabel();
-            String techniqueNames = report.getTechniqueNames();
-            String brief = report.getConstructionBrief();
-        });
-
         int projectIndex = 0;
         int totalProjects = groupedByProject.size();
         for (Map.Entry<String, List<IotRdDailyReportRespVO>> entry : groupedByProject.entrySet()) {
@@ -155,35 +139,6 @@ public class CreateRdDailyReportStatisticsJob implements JobHandler {
             projectIndex++;
         }
 
-        // 日报汇总生产动态精简内容
-        /* String PRODUCTION_STATUS_MSG_TEMPLATE =
-                "**{}:**  \n" +
-                "队伍:{}  \n" +
-                "井号:{}  \n" +
-                "状态:{}  \n" +
-                "工艺:  \n{}  \n" +
-                "施工简要:  \n{}  \n"; */
-
-        /* for (int i = 0; i < productionStatuses.size(); i++) {
-            ProjectUtilizationRateVo status = productionStatuses.get(i);
-            String block = StrUtil.format(PRODUCTION_STATUS_MSG_TEMPLATE,
-                    status.getProjectDeptName(),
-                    status.getTeamCount(),
-                    status.getDmTeamCount(),
-                    status.getZbTeamCount(),
-                    status.getSgTeamCount(),
-                    // 注入量和运行时效已包含换行,直接放入
-                    status.getInjectionVolume(),
-                    status.getRunningAvailability()
-            );
-            finalMsgBuilder.append(block);
-            // 块之间用分隔线隔开(最后一块不加)
-            // 块之间添加纯文本分隔线,避免被识别为Markdown水平线
-            if (i < productionStatuses.size() - 1) {
-                finalMsgBuilder.append("  \n==========  \n");
-            }
-        } */
-
         String finalMsgTitle = finalMsgBuilder.toString();
 
         Set<Long> deptIds = new HashSet<>();

+ 641 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/job/dailyreport/CreateYfDailyReportStatisticsJob.java

@@ -0,0 +1,641 @@
+package cn.iocoder.yudao.module.pms.job.dailyreport;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.util.ObjUtil;
+import cn.hutool.core.util.StrUtil;
+import cn.iocoder.yudao.framework.common.pojo.PageParam;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.quartz.core.handler.JobHandler;
+import cn.iocoder.yudao.framework.tenant.core.util.TenantUtils;
+import cn.iocoder.yudao.module.pms.constant.PmsConstants;
+import cn.iocoder.yudao.module.pms.controller.admin.iotfivedailyreport.vo.IotFiveDailyReportPageReqVO;
+import cn.iocoder.yudao.module.pms.controller.admin.iotrddailyreport.vo.IotRdDailyReportPageReqVO;
+import cn.iocoder.yudao.module.pms.controller.admin.iotrddailyreport.vo.IotRdDailyReportStatisticsRespVO;
+import cn.iocoder.yudao.module.pms.controller.admin.iotrhdailyreport.vo.IotRhDailyReportPageReqVO;
+import cn.iocoder.yudao.module.pms.controller.admin.iotrydailyreport.vo.IotRyDailyReportPageReqVO;
+import cn.iocoder.yudao.module.pms.dal.dataobject.iotfivedailyreport.IotFiveDailyReportDO;
+import cn.iocoder.yudao.module.pms.dal.dataobject.iotprojecttaskattrs.IotTaskAttrModelProperty;
+import cn.iocoder.yudao.module.pms.dal.dataobject.iotrddailyreport.IotRdDailyReportDO;
+import cn.iocoder.yudao.module.pms.dal.dataobject.iotrhdailyreport.IotRhDailyReportDO;
+import cn.iocoder.yudao.module.pms.dal.dataobject.iotrydailyreport.IotRyDailyReportDO;
+import cn.iocoder.yudao.module.pms.message.PmsMessage;
+import cn.iocoder.yudao.module.pms.service.iotfivedailyreport.IotFiveDailyReportService;
+import cn.iocoder.yudao.module.pms.service.iotrddailyreport.IotRdDailyReportService;
+import cn.iocoder.yudao.module.pms.service.iotrhdailyreport.IotRhDailyReportService;
+import cn.iocoder.yudao.module.pms.service.iotrydailyreport.IotRyDailyReportService;
+import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
+import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
+import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO;
+import cn.iocoder.yudao.module.system.dal.dataobject.permission.RoleDO;
+import cn.iocoder.yudao.module.system.dal.dataobject.permission.UserRoleDO;
+import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
+import cn.iocoder.yudao.module.system.dal.mysql.permission.UserRoleMapper;
+import cn.iocoder.yudao.module.system.service.dept.DeptService;
+import cn.iocoder.yudao.module.system.service.permission.RoleService;
+import cn.iocoder.yudao.module.system.service.user.AdminUserService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.time.LocalDateTime;
+import java.util.*;
+import java.util.concurrent.CountDownLatch;
+import java.util.stream.Collectors;
+
+import static cn.iocoder.yudao.module.pms.framework.config.MultiThreadConfiguration.PMS_THREAD_POOL_TASK_EXECUTOR;
+
+/**
+ * 油服每天生成昨日的日报汇总 钉钉 推送消息
+ * 瑞恒 瑞都 瑞鹰 5#
+ */
+@Component
+@Slf4j
+public class CreateYfDailyReportStatisticsJob implements JobHandler {
+
+    @Resource
+    private AdminUserApi adminUserApi;
+    @Resource
+    private IotRhDailyReportService iotRhDailyReportService;
+    @Resource
+    private IotRyDailyReportService iotRyDailyReportService;
+    @Resource
+    private IotRdDailyReportService iotRdDailyReportService;
+    @Resource
+    private IotFiveDailyReportService iotFiveDailyReportService;
+    @Resource(name = PMS_THREAD_POOL_TASK_EXECUTOR)
+    private ThreadPoolTaskExecutor pmsThreadPoolTaskExecutor;
+    @Resource
+    private PmsMessage pmsMessage;
+    @Resource
+    private DeptService deptService;
+    @Resource
+    private AdminUserService adminUserService;
+    @Resource
+    private RoleService roleService;
+    @Resource
+    private UserRoleMapper userRoleMapper;
+
+    @Override
+    // @TenantIgnore
+    public String execute(String param) throws Exception {
+        TenantUtils.execute(1L, () -> {
+
+            // 获取当前时间
+            LocalDateTime currentDate = LocalDateTime.now();
+            // 根据当前日期生成前一天的日期
+            // LocalDateTime yesterday = currentDate.minusDays(1);
+            // 测试数据 2026年8月29日
+            LocalDateTime yesterday = LocalDateTime.of(2026, 8, 29, 0, 0);
+
+            LocalDateTime createTimeStart = yesterday.toLocalDate().atStartOfDay();
+            LocalDateTime createTimeEnd = yesterday.toLocalDate().atTime(23, 59, 59);
+            // 前一天的日期 所在月的起始时间 月开始日期 - 当前日期
+            LocalDateTime monthStart = yesterday.toLocalDate().withDayOfMonth(1).atStartOfDay();
+            // 前一天的日期 所在月的起始时间 年开始日期 - 当前日期
+            LocalDateTime yearStart = yesterday.toLocalDate().withDayOfYear(1).atStartOfDay();
+
+            // 计算瑞恒的 日注气量 月注气量 年注气量 设备利用率
+            // 瑞恒前一天的日报 日累计注气量 单位 万方
+            BigDecimal daySumWanGas = BigDecimal.ZERO;
+            // 瑞恒设备利用率 % 格式
+            String rhDeviceUtilization = StrUtil.EMPTY;
+            /* IotRhDailyReportPageReqVO rhYesterdayReqVO = new IotRhDailyReportPageReqVO();
+            rhYesterdayReqVO.setCreateTime(new LocalDateTime[]{createTimeStart, createTimeEnd});
+            List<IotRhDailyReportDO> rhYesterdayReports = iotRhDailyReportService.getDailyReports(rhYesterdayReqVO);
+
+            if (CollUtil.isNotEmpty(rhYesterdayReports)) {
+                // 求和:所有日报当日注气量(原始:方) → 换算成万方
+                BigDecimal totalGasCube = rhYesterdayReports.stream()
+                        .map(IotRhDailyReportDO::getDailyGasInjection)
+                        .filter(Objects::nonNull)
+                        .reduce(BigDecimal.ZERO, BigDecimal::add);
+                daySumWanGas = totalGasCube.divide(new BigDecimal("10000"), 2, java.math.RoundingMode.HALF_UP);
+            } */
+            // 计算瑞恒前一天日报的设备利用率
+            IotRhDailyReportPageReqVO rhWorkloadReqVO = new IotRhDailyReportPageReqVO();
+            rhWorkloadReqVO.setDeptId(157l);
+            rhWorkloadReqVO.setCreateTime(new LocalDateTime[]{createTimeStart, createTimeEnd});
+            Map<String, BigDecimal> totalWorkload = iotRhDailyReportService.totalWorkload(rhWorkloadReqVO);
+            BigDecimal rhReportCount = BigDecimal.ZERO;
+            BigDecimal rhTeamDeptIds = BigDecimal.ZERO;
+            if (CollUtil.isNotEmpty(totalWorkload)) {
+                if (totalWorkload.containsKey("totalGasInjection")) {
+                    // 日累计注气量
+                    BigDecimal totalGasCube = totalWorkload.get("totalGasInjection");
+                    daySumWanGas = totalGasCube.divide(new BigDecimal("10000"), 2, java.math.RoundingMode.HALF_UP);
+                }
+                if (totalWorkload.containsKey("utilizationRate")) {
+                    // 日设备利用率
+                    BigDecimal totalGasInjection = totalWorkload.get("utilizationRate");
+                    BigDecimal percent = totalGasInjection.multiply(new BigDecimal("100"))
+                            .setScale(2, RoundingMode.HALF_UP);
+                    rhDeviceUtilization = percent + " %";
+                }
+                if (totalWorkload.containsKey("reportCount")) {
+                    rhReportCount = totalWorkload.get("reportCount");
+                }
+                if (totalWorkload.containsKey("teamDeptIds")) {
+                    rhTeamDeptIds = totalWorkload.get("teamDeptIds");
+                }
+            }
+
+            // 瑞恒前一天所在月份的日报
+            IotRhDailyReportPageReqVO rhMonthReqVO = new IotRhDailyReportPageReqVO();
+            rhMonthReqVO.setCreateTime(new LocalDateTime[]{monthStart, createTimeEnd});
+            List<IotRhDailyReportDO> rhYesterdayMonthReports = iotRhDailyReportService.getDailyReports(rhMonthReqVO);
+            BigDecimal monthSumWanGas = BigDecimal.ZERO;
+            if (CollUtil.isNotEmpty(rhYesterdayMonthReports)) {
+                // 求和:所有日报当日注气量(原始:方) → 换算成万方
+                BigDecimal totalGasCube = rhYesterdayMonthReports.stream()
+                        .map(IotRhDailyReportDO::getDailyGasInjection)
+                        .filter(Objects::nonNull)
+                        .reduce(BigDecimal.ZERO, BigDecimal::add);
+                monthSumWanGas = totalGasCube.divide(new BigDecimal("10000"), 2, java.math.RoundingMode.HALF_UP);
+            }
+            // 瑞恒前一天所在年的日报
+            IotRhDailyReportPageReqVO rhYearReqVO = new IotRhDailyReportPageReqVO();
+            rhYearReqVO.setCreateTime(new LocalDateTime[]{yearStart, createTimeEnd});
+            List<IotRhDailyReportDO> rhYesterdayYearReports = iotRhDailyReportService.getDailyReports(rhYearReqVO);
+            BigDecimal yearSumWanGas = BigDecimal.ZERO;
+            if (CollUtil.isNotEmpty(rhYesterdayYearReports)) {
+                // 求和:所有日报当日注气量(原始:方) → 换算成万方
+                BigDecimal totalGasCube = rhYesterdayYearReports.stream()
+                        .map(IotRhDailyReportDO::getDailyGasInjection)
+                        .filter(Objects::nonNull)
+                        .reduce(BigDecimal.ZERO, BigDecimal::add);
+                yearSumWanGas = totalGasCube.divide(new BigDecimal("10000"), 2, java.math.RoundingMode.HALF_UP);
+            }
+
+            // 计算瑞鹰的 日进尺 月进尺 年进尺 日施工井 月完工井 年完工井 设备利用率
+            // 瑞鹰前一天的日报
+            IotRyDailyReportPageReqVO ryYesterdayReqVO = new IotRyDailyReportPageReqVO();
+            ryYesterdayReqVO.setCreateTime(new LocalDateTime[]{createTimeStart, createTimeEnd});
+            List<IotRyDailyReportDO> ryYesterdayReports = iotRyDailyReportService.getDailyReports(ryYesterdayReqVO);
+            BigDecimal daySumFootage = BigDecimal.ZERO;
+            // 日施工井
+            Integer dayConstructWell = 0;
+            if (CollUtil.isNotEmpty(ryYesterdayReports)) {
+                // 求和:所有日报当日进尺 米
+                daySumFootage = ryYesterdayReports.stream()
+                        .map(IotRyDailyReportDO::getDailyFootage)
+                        .filter(Objects::nonNull)
+                        .reduce(BigDecimal.ZERO, BigDecimal::add);
+                // 计算 修井 日施工井数量
+                dayConstructWell = (int) ryYesterdayReports.stream()
+                        .filter(r -> "2".equals(r.getProjectClassification()))
+                        .map(IotRyDailyReportDO::getTaskId)
+                        .filter(Objects::nonNull)
+                        .distinct()
+                        .count();
+            }
+            // 计算瑞鹰前一天的设备利用率 钻井 修井 分子相加 分母相加
+            // 钻井
+            IotRyDailyReportPageReqVO ryZjUtilizationReqVO = new IotRyDailyReportPageReqVO();
+            ryZjUtilizationReqVO.setDeptId(158l);
+            ryZjUtilizationReqVO.setProjectClassification("1");
+            ryZjUtilizationReqVO.setCreateTime(new LocalDateTime[]{createTimeStart, createTimeEnd});
+            Map<String, BigDecimal> ryZjTotalWorkload = iotRyDailyReportService.totalWorkload(ryZjUtilizationReqVO);
+            BigDecimal zjReportCount = BigDecimal.ZERO;
+            BigDecimal zjTeamDeptIds = BigDecimal.ZERO;
+            BigDecimal xjReportCount = BigDecimal.ZERO;
+            BigDecimal xjTeamDeptIds = BigDecimal.ZERO;
+            if (CollUtil.isNotEmpty(ryZjTotalWorkload)) {
+                if (ryZjTotalWorkload.containsKey("zjReportCount")) {
+                    zjReportCount = ryZjTotalWorkload.get("zjReportCount");
+                }
+                if (ryZjTotalWorkload.containsKey("zjTeamDeptIds")) {
+                    zjTeamDeptIds = ryZjTotalWorkload.get("zjTeamDeptIds");
+                }
+            }
+            // 修井
+            IotRyDailyReportPageReqVO ryXjUtilizationReqVO = new IotRyDailyReportPageReqVO();
+            ryXjUtilizationReqVO.setDeptId(158l);
+            ryXjUtilizationReqVO.setProjectClassification("2");
+            ryXjUtilizationReqVO.setCreateTime(new LocalDateTime[]{createTimeStart, createTimeEnd});
+            Map<String, BigDecimal> ryXjTotalWorkload = iotRyDailyReportService.totalWorkload(ryXjUtilizationReqVO);
+            if (CollUtil.isNotEmpty(ryXjTotalWorkload)) {
+                if (ryXjTotalWorkload.containsKey("xjReportCount")) {
+                    xjReportCount = ryXjTotalWorkload.get("xjReportCount");
+                }
+                if (ryXjTotalWorkload.containsKey("xjTeamDeptIds")) {
+                    xjTeamDeptIds = ryXjTotalWorkload.get("xjTeamDeptIds");
+                }
+            }
+            // 钻井 修井 分子 分母 分别相加
+            BigDecimal ryReportCount = BigDecimal.ZERO;
+            BigDecimal ryTeamDeptIds = BigDecimal.ZERO;
+            ryReportCount = zjReportCount.add(xjReportCount);
+            ryTeamDeptIds = zjTeamDeptIds.add(xjTeamDeptIds);
+            // 计算瑞鹰总的设备利用率
+            BigDecimal ryDeviceUtilizationRate = BigDecimal.ZERO;
+            // 瑞鹰设备利用统治
+            String ryDeviceUtilization = StrUtil.EMPTY;
+            if (ryTeamDeptIds.compareTo(BigDecimal.ZERO) > 0) {
+                ryDeviceUtilizationRate = ryReportCount.divide(ryTeamDeptIds, 4, RoundingMode.HALF_UP);
+                BigDecimal percent = ryDeviceUtilizationRate.multiply(new BigDecimal("100"))
+                        .setScale(2, RoundingMode.HALF_UP);
+                ryDeviceUtilization = percent + " %";
+            }
+
+            // 瑞鹰前一天所在月份的日报
+            IotRyDailyReportPageReqVO ryYesterdayMonthReqVO = new IotRyDailyReportPageReqVO();
+            ryYesterdayMonthReqVO.setCreateTime(new LocalDateTime[]{monthStart, createTimeEnd});
+            List<IotRyDailyReportDO> ryYesterdayMonthReports = iotRyDailyReportService.getDailyReports(ryYesterdayMonthReqVO);
+            BigDecimal monthSumFootage = BigDecimal.ZERO;
+            // 月完工井
+            Integer monthCompleteWell = 0;
+            if (CollUtil.isNotEmpty(ryYesterdayMonthReports)) {
+                // 求和:所有日报当日进尺 米
+                monthSumFootage = ryYesterdayMonthReports.stream()
+                        .map(IotRyDailyReportDO::getDailyFootage)
+                        .filter(Objects::nonNull)
+                        .reduce(BigDecimal.ZERO, BigDecimal::add);
+                // 计算 修井 月完工井数量
+                monthCompleteWell = (int) ryYesterdayMonthReports.stream()
+                        .filter(r -> "2".equals(r.getProjectClassification()))
+                        .filter(r -> "wg".equals(r.getRepairStatus()))
+                        .map(IotRyDailyReportDO::getTaskId)
+                        .filter(Objects::nonNull)
+                        .distinct()
+                        .count();
+            }
+            // 瑞鹰前一天所在年份的日报
+            IotRyDailyReportPageReqVO ryYesterdayYearReqVO = new IotRyDailyReportPageReqVO();
+            ryYesterdayYearReqVO.setCreateTime(new LocalDateTime[]{yearStart, createTimeEnd});
+            List<IotRyDailyReportDO> ryYesterdayYearReports = iotRyDailyReportService.getDailyReports(ryYesterdayYearReqVO);
+            BigDecimal yearSumFootage = BigDecimal.ZERO;
+            // 年完工井
+            Integer yearCompleteWell = 0;
+            if (CollUtil.isNotEmpty(ryYesterdayYearReports)) {
+                // 求和:所有日报当日进尺 米
+                yearSumFootage = ryYesterdayYearReports.stream()
+                        .map(IotRyDailyReportDO::getDailyFootage)
+                        .filter(Objects::nonNull)
+                        .reduce(BigDecimal.ZERO, BigDecimal::add);
+                // 计算 修井 年完工井数量
+                yearCompleteWell = (int) ryYesterdayYearReports.stream()
+                        .filter(r -> "2".equals(r.getProjectClassification()))
+                        .filter(r -> "wg".equals(r.getRepairStatus()))
+                        .map(IotRyDailyReportDO::getTaskId)
+                        .filter(Objects::nonNull)
+                        .distinct()
+                        .count();
+            }
+
+            // 查询瑞都各队伍 压裂 or 连油 属性
+            // 先查询瑞都所有部门 163l
+            Set<Long> rdChildDeptIds = deptService.getChildDeptIdListFromCache(163l);
+            List<DeptDO> departments =deptService.getDeptList(rdChildDeptIds);
+            Set<Long> lyTeamIds = new HashSet<>();
+            if (CollUtil.isNotEmpty(departments)) {
+                departments.forEach(dept -> {
+                    if ("3".equals(dept.getType()) && "LY".equals(dept.getEmail())) {
+                        lyTeamIds.add(dept.getId());
+                    }
+                });
+            }
+            // 查询瑞都昨天的日报列表
+            IotRdDailyReportPageReqVO reqVO = new IotRdDailyReportPageReqVO();
+            reqVO.setDeptId(163l);
+            reqVO.setCreateTime(new LocalDateTime[]{createTimeStart, createTimeEnd});
+            reqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
+            PageResult<IotRdDailyReportDO> pageReports = iotRdDailyReportService.getIotRdDailyReportPage(reqVO);
+            List<IotRdDailyReportDO> dailyReports = pageReports.getList();
+            // 累计 段数 累计施工-层
+            BigDecimal totalCumulativeWorkingLayers = BigDecimal.ZERO;
+            // 累计施工井
+            Set<Long> taskIds = new HashSet<>();
+            if (CollUtil.isNotEmpty(dailyReports)) {
+                for (IotRdDailyReportDO report : dailyReports) {
+                    // 日施工井
+                    Long deptId = report.getDeptId();
+                    Long taskId = report.getTaskId();
+                    if (ObjUtil.isNotEmpty(deptId) && ObjUtil.isNotEmpty(taskId) && lyTeamIds.contains(deptId)) {
+                        taskIds.add(taskId);
+                    }
+                    List<IotTaskAttrModelProperty> properties = report.getExtProperty();
+                    if (CollUtil.isNotEmpty(properties)) {
+                        for (IotTaskAttrModelProperty property : properties) {
+                            // 工作量单位
+                            String unit = property.getUnit();
+                            // 工作量属性的实际值
+                            String actualValueStr = property.getActualValue();
+                            BigDecimal actualValue = BigDecimal.ZERO;
+                            if (StrUtil.isNotBlank(actualValueStr)) {
+                                try {
+                                    actualValue = new BigDecimal(actualValueStr);
+                                } catch (NumberFormatException e) {
+                                    // 若字符串格式错误,默认按0处理(可根据业务调整)
+                                    actualValue = BigDecimal.ZERO;
+                                }
+                            }
+                            if ("段数".equals(unit)) {
+                                totalCumulativeWorkingLayers = totalCumulativeWorkingLayers.add(actualValue);
+                            }
+                        }
+                    }
+                }
+            }
+            // 设置瑞都的设备利用率
+            String rdDeviceUtilization = StrUtil.EMPTY;
+            BigDecimal rdReportCount = BigDecimal.ZERO;
+            BigDecimal rdTeamDeptIds = BigDecimal.ZERO;
+            IotRdDailyReportPageReqVO rdPageReqVO = new IotRdDailyReportPageReqVO();
+            rdPageReqVO.setDeptId(163l);
+            rdPageReqVO.setCreateTime(new LocalDateTime[]{createTimeStart, createTimeEnd});
+            List<IotRdDailyReportStatisticsRespVO> rdTotalWorkloads = iotRdDailyReportService.totalWorkload(rdPageReqVO);
+            if (CollUtil.isNotEmpty(rdTotalWorkloads)) {
+                for (IotRdDailyReportStatisticsRespVO rdTotalWorkload : rdTotalWorkloads) {
+                    if ("utilizationRate".equals(rdTotalWorkload.getDeptName())) {
+                        BigDecimal rdUtilization = rdTotalWorkload.getUtilizationRate();
+                        BigDecimal percent = rdUtilization.multiply(new BigDecimal("100"))
+                                .setScale(2, RoundingMode.HALF_UP);
+                        rdDeviceUtilization = percent + " %";
+                    }
+                    if ("reportCount".equals(rdTotalWorkload.getDeptName())) {
+                        rdReportCount = rdTotalWorkload.getUtilizationRate();
+                    }
+                    if ("teamDeptIds".equals(rdTotalWorkload.getDeptName())) {
+                        rdTeamDeptIds = rdTotalWorkload.getUtilizationRate();
+                    }
+                }
+            }
+
+            // 查询瑞都前一天日期所在的月度日报列表
+            IotRdDailyReportPageReqVO monthReqVO = new IotRdDailyReportPageReqVO();
+            monthReqVO.setDeptId(163l);
+            monthReqVO.setCreateTime(new LocalDateTime[]{monthStart, createTimeEnd});
+            monthReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
+            PageResult<IotRdDailyReportDO> monthPageReports = iotRdDailyReportService.getIotRdDailyReportPage(monthReqVO);
+            List<IotRdDailyReportDO> monthDailyReports = monthPageReports.getList();
+            // 累计 段数 累计施工-层
+            BigDecimal monthTotalCumulativeWorkingLayers = BigDecimal.ZERO;
+            // 月累计完工井
+            Set<Long> monthCompleteTaskIds = new HashSet<>();
+            if (CollUtil.isNotEmpty(monthDailyReports)) {
+                for (IotRdDailyReportDO report : monthDailyReports) {
+                    // 月完工井
+                    Long deptId = report.getDeptId();
+                    Long taskId = report.getTaskId();
+                    String rdStatus = report.getRdStatus();
+                    if (ObjUtil.isNotEmpty(deptId) && ObjUtil.isNotEmpty(taskId) && lyTeamIds.contains(deptId) && "wg".equals(rdStatus)) {
+                        monthCompleteTaskIds.add(taskId);
+                    }
+                    List<IotTaskAttrModelProperty> properties = report.getExtProperty();
+                    if (CollUtil.isNotEmpty(properties)) {
+                        for (IotTaskAttrModelProperty property : properties) {
+                            // 工作量单位
+                            String unit = property.getUnit();
+                            // 工作量属性的实际值
+                            String actualValueStr = property.getActualValue();
+                            BigDecimal actualValue = BigDecimal.ZERO;
+                            if (StrUtil.isNotBlank(actualValueStr)) {
+                                try {
+                                    actualValue = new BigDecimal(actualValueStr);
+                                } catch (NumberFormatException e) {
+                                    // 若字符串格式错误,默认按0处理(可根据业务调整)
+                                    actualValue = BigDecimal.ZERO;
+                                }
+                            }
+                            if ("段数".equals(unit)) {
+                                monthTotalCumulativeWorkingLayers = monthTotalCumulativeWorkingLayers.add(actualValue);
+                            }
+                        }
+                    }
+                }
+            }
+
+            // 查询瑞都前一天日期所在的年度日报列表
+            IotRdDailyReportPageReqVO yearReqVO = new IotRdDailyReportPageReqVO();
+            yearReqVO.setDeptId(163l);
+            yearReqVO.setCreateTime(new LocalDateTime[]{yearStart, createTimeEnd});
+            yearReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
+            PageResult<IotRdDailyReportDO> yearPageReports = iotRdDailyReportService.getIotRdDailyReportPage(yearReqVO);
+            List<IotRdDailyReportDO> yearDailyReports = yearPageReports.getList();
+            // 累计 段数 累计施工-层
+            BigDecimal yearTotalCumulativeWorkingLayers = BigDecimal.ZERO;
+            // 年累计完工井
+            Set<Long> yearCompleteTaskIds = new HashSet<>();
+            if (CollUtil.isNotEmpty(yearDailyReports)) {
+                for (IotRdDailyReportDO report : yearDailyReports) {
+                    // 月完工井
+                    Long deptId = report.getDeptId();
+                    Long taskId = report.getTaskId();
+                    String rdStatus = report.getRdStatus();
+                    if (ObjUtil.isNotEmpty(deptId) && ObjUtil.isNotEmpty(taskId) && lyTeamIds.contains(deptId) && "wg".equals(rdStatus)) {
+                        yearCompleteTaskIds.add(taskId);
+                    }
+                    List<IotTaskAttrModelProperty> properties = report.getExtProperty();
+                    if (CollUtil.isNotEmpty(properties)) {
+                        for (IotTaskAttrModelProperty property : properties) {
+                            // 工作量单位
+                            String unit = property.getUnit();
+                            // 工作量属性的实际值
+                            String actualValueStr = property.getActualValue();
+                            BigDecimal actualValue = BigDecimal.ZERO;
+                            if (StrUtil.isNotBlank(actualValueStr)) {
+                                try {
+                                    actualValue = new BigDecimal(actualValueStr);
+                                } catch (NumberFormatException e) {
+                                    // 若字符串格式错误,默认按0处理(可根据业务调整)
+                                    actualValue = BigDecimal.ZERO;
+                                }
+                            }
+                            if ("段数".equals(unit)) {
+                                yearTotalCumulativeWorkingLayers = yearTotalCumulativeWorkingLayers.add(actualValue);
+                            }
+                        }
+                    }
+                }
+            }
+
+            // 查询 5#公司 昨天的日报列表
+            IotFiveDailyReportPageReqVO fiveReqVO = new IotFiveDailyReportPageReqVO();
+            fiveReqVO.setDeptId(388l);
+            fiveReqVO.setCreateTime(new LocalDateTime[]{createTimeStart, createTimeEnd});
+            fiveReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
+            PageResult<IotFiveDailyReportDO> pageFiveReports = iotFiveDailyReportService.getIotFiveDailyReportPage(fiveReqVO);
+            List<IotFiveDailyReportDO> fiveReports = pageFiveReports.getList();
+            // 5号公司日压裂层
+            BigDecimal fiveDaySumLayers = BigDecimal.ZERO;
+            // 5号公司 日设备利用率
+            String fiveDeviceUtilization = StrUtil.EMPTY;
+            // 日报累计施工设备数量
+            BigDecimal fiveWorkDeviceNum = BigDecimal.ZERO;
+            // 日报累计主设备数量
+            BigDecimal fiveMainDeviceNum = BigDecimal.ZERO;
+            if (CollUtil.isNotEmpty(fiveReports)) {
+                // 求和:所有日报压裂层 单位:层
+                fiveDaySumLayers = fiveReports.stream()
+                        .map(IotFiveDailyReportDO::getDailyWorkingLayers)
+                        .filter(Objects::nonNull)
+                        .reduce(BigDecimal.ZERO, BigDecimal::add);
+                // 求和:所有日报施工设备数量
+                fiveWorkDeviceNum = fiveReports.stream()
+                        .map(IotFiveDailyReportDO::getWokDeviceNum)
+                        .filter(Objects::nonNull)
+                        .reduce(BigDecimal.ZERO, BigDecimal::add);
+                // 求和:所有日报主设备数量
+                fiveMainDeviceNum = fiveReports.stream()
+                        .map(IotFiveDailyReportDO::getMainDeviceNum)
+                        .filter(Objects::nonNull)
+                        .reduce(BigDecimal.ZERO, BigDecimal::add);
+            }
+            // 计算5#公司设备利用率
+            if (fiveMainDeviceNum.compareTo(BigDecimal.ZERO) > 0) {
+                BigDecimal fiveDeviceUtilizationRate = fiveWorkDeviceNum.divide(fiveMainDeviceNum, 4, RoundingMode.HALF_UP);
+                BigDecimal percent = fiveDeviceUtilizationRate.multiply(new BigDecimal("100"))
+                        .setScale(2, RoundingMode.HALF_UP);
+                fiveDeviceUtilization = percent + " %";
+            }
+
+            // 查询 5#公司 昨天所属月份的日报列表
+            IotFiveDailyReportPageReqVO fiveMonthReqVO = new IotFiveDailyReportPageReqVO();
+            fiveMonthReqVO.setDeptId(388l);
+            fiveMonthReqVO.setCreateTime(new LocalDateTime[]{monthStart, createTimeEnd});
+            fiveMonthReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
+            PageResult<IotFiveDailyReportDO> pageMonthFiveReports = iotFiveDailyReportService.getIotFiveDailyReportPage(fiveMonthReqVO);
+            List<IotFiveDailyReportDO> fiveMonthReports = pageMonthFiveReports.getList();
+            // 5号公司月完工井
+            BigDecimal fiveMonthCompleteWells = BigDecimal.ZERO;
+            Set<Long> fiveMonthCompleteTaskIds = new HashSet<>();
+            if (CollUtil.isNotEmpty(fiveMonthReports)) {
+                fiveMonthReports.forEach(report -> {
+                    Long taskId = report.getTaskId();
+                    String fiveStatus = report.getFiveStatus();
+                    if (ObjUtil.isNotEmpty(taskId) && "wg".equals(fiveStatus)) {
+                        fiveMonthCompleteTaskIds.add(taskId);
+                    }
+                });
+            }
+
+            // 查询 5#公司 昨天所属年份的日报列表
+            IotFiveDailyReportPageReqVO fiveYearReqVO = new IotFiveDailyReportPageReqVO();
+            fiveYearReqVO.setDeptId(388l);
+            fiveYearReqVO.setCreateTime(new LocalDateTime[]{yearStart, createTimeEnd});
+            fiveYearReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
+            PageResult<IotFiveDailyReportDO> pageYearFiveReports = iotFiveDailyReportService.getIotFiveDailyReportPage(fiveYearReqVO);
+            List<IotFiveDailyReportDO> fiveYearReports = pageYearFiveReports.getList();
+            // 5号公司 年完工井
+            BigDecimal fiveYearCompleteWells = BigDecimal.ZERO;
+            Set<Long> fiveYearCompleteTaskIds = new HashSet<>();
+            if (CollUtil.isNotEmpty(fiveYearReports)) {
+                fiveYearReports.forEach(report -> {
+                    Long taskId = report.getTaskId();
+                    String fiveStatus = report.getFiveStatus();
+                    if (ObjUtil.isNotEmpty(taskId) && "wg".equals(fiveStatus)) {
+                        fiveYearCompleteTaskIds.add(taskId);
+                    }
+                });
+            }
+
+            // 设置集团的设备利用率总和 各公司 日报数量/主设备数量
+            BigDecimal totalReportCount = rhReportCount.add(ryReportCount).add(rdReportCount).add(fiveWorkDeviceNum);
+            BigDecimal totalMainDevices = rhTeamDeptIds.add(ryTeamDeptIds).add(rdTeamDeptIds).add(fiveMainDeviceNum);
+            String totalUtilization = StrUtil.EMPTY;
+            if (totalMainDevices.compareTo(BigDecimal.ZERO) > 0) {
+                BigDecimal totalUtilizationRate = totalReportCount.divide(totalMainDevices, 4, RoundingMode.HALF_UP);
+                BigDecimal percent = totalUtilizationRate.multiply(new BigDecimal("100"))
+                        .setScale(2, RoundingMode.HALF_UP);
+                totalUtilization = percent + " %";
+            }
+
+            // ==================== 组装推送消息 ====================
+
+            StringBuilder finalMsgBuilder = new StringBuilder();
+            finalMsgBuilder.append("总设备利用率:").append(totalUtilization).append("  \n");
+            finalMsgBuilder.append("═ ═ ═ ═ ═ ═ ═ ═  \n");
+            finalMsgBuilder.append("公司:瑞恒兴域  \n");
+            finalMsgBuilder.append("日注气量:").append(daySumWanGas).append(" 万方  \n");
+            finalMsgBuilder.append("月注气量:").append(monthSumWanGas).append(" 万方  \n");
+            finalMsgBuilder.append("年注气量:").append(yearSumWanGas).append(" 万方  \n");
+            finalMsgBuilder.append("设备利用率:").append(rhDeviceUtilization).append("  \n");
+            finalMsgBuilder.append("═ ═ ═ ═ ═ ═ ═ ═  \n");
+            finalMsgBuilder.append("公司:瑞鹰国际  \n");
+            finalMsgBuilder.append("日钻进尺:").append(daySumFootage).append(" 米  \n");
+            finalMsgBuilder.append("月钻进尺:").append(monthSumFootage).append(" 米  \n");
+            finalMsgBuilder.append("年钻进尺:").append(yearSumFootage).append(" 米  \n");
+            finalMsgBuilder.append("日施工井:").append(dayConstructWell).append(" 井  \n");
+            finalMsgBuilder.append("月完工井:").append(monthCompleteWell).append(" 井  \n");
+            finalMsgBuilder.append("年完工井:").append(yearCompleteWell).append(" 井  \n");
+            finalMsgBuilder.append("设备利用率:").append(ryDeviceUtilization).append("  \n");
+            finalMsgBuilder.append("═ ═ ═ ═ ═ ═ ═ ═  \n");
+            finalMsgBuilder.append("公司:四川瑞都  \n");
+            finalMsgBuilder.append("日压裂层:").append(totalCumulativeWorkingLayers).append(" 层  \n");
+            finalMsgBuilder.append("月压裂层:").append(monthTotalCumulativeWorkingLayers).append(" 层  \n");
+            finalMsgBuilder.append("年压裂层:").append(yearTotalCumulativeWorkingLayers).append(" 层  \n");
+            finalMsgBuilder.append("日施工井:").append(taskIds.size()).append(" 井  \n");
+            finalMsgBuilder.append("月完工井:").append(monthCompleteTaskIds.size()).append(" 井  \n");
+            finalMsgBuilder.append("年完工井:").append(yearCompleteTaskIds.size()).append(" 井  \n");
+            finalMsgBuilder.append("设备利用率:").append(rdDeviceUtilization).append("  \n");
+            finalMsgBuilder.append("═ ═ ═ ═ ═ ═ ═ ═  \n");
+            finalMsgBuilder.append("公司:5#项目公司  \n");
+            finalMsgBuilder.append("日压裂层:").append(fiveDaySumLayers).append(" 层  \n");
+            finalMsgBuilder.append("月完工井:").append(fiveMonthCompleteTaskIds.size()).append(" 井  \n");
+            finalMsgBuilder.append("年完工井:").append(fiveYearCompleteTaskIds.size()).append(" 井  \n");
+            finalMsgBuilder.append("设备利用率:").append(fiveDeviceUtilization).append("  \n");
+            finalMsgBuilder.append("═ ═ ═ ═ ═ ═ ═ ═  \n");
+
+            String finalMsgTitle = finalMsgBuilder.toString();
+
+            Set<Long> deptIds = new HashSet<>();
+            Set<Long> userIds = new HashSet<>();
+
+            // 查询 集团 156l 下具有 集团生产概况推送 角色的人员
+            deptIds.add(156l);
+            List<AdminUserDO> companyUsers = adminUserService.getUserListByDeptIds(deptIds);
+            if (CollUtil.isNotEmpty(companyUsers)) {
+                companyUsers.forEach(user -> {
+                    userIds.add(user.getId());
+                });
+            }
+
+            // 将当前日期的前一天转换成 long 类型的数字
+            Long timeStamp = cn.hutool.core.date.DateUtil.toInstant(yesterday).toEpochMilli();
+
+            RoleDO role = roleService.getRoleByCode("集团生产概况推送");
+            if (ObjUtil.isNotEmpty(role)) {
+                Set<Long> roleIds = new HashSet<>();
+                roleIds.add(role.getId());
+                List<UserRoleDO> userRoles = userRoleMapper.selectListByRoleIds(roleIds);
+                if (CollUtil.isNotEmpty(userRoles)) {
+                    // 提取有审批角色的所有用户ID(去重+空值过滤)
+                    Set<Long> roleUserIds = userRoles.stream()
+                            .map(UserRoleDO::getUserId)
+                            .filter(Objects::nonNull) // 过滤空userId
+                            .collect(Collectors.toSet());
+                    // 计算两个集合的交集,得到最终目标用户ID
+                    Set<Long> targetUserIds = userIds.stream()
+                            .filter(roleUserIds::contains)
+                            .collect(Collectors.toSet());
+                    if (CollUtil.isNotEmpty(targetUserIds)) {
+                        Map<Long, AdminUserRespDTO> users = adminUserApi.getUserMap(targetUserIds);
+                        // 给多个用户发送 相同 的 提醒消息
+                        if (CollUtil.isNotEmpty(users)) {
+                            // 生成消息提醒 标题内容
+                            CountDownLatch latch = new CountDownLatch(users.size());
+                            users.forEach((userId, user) -> {
+                                pmsThreadPoolTaskExecutor.execute(() -> {
+                                    try {
+                                        String mobile = user.getMobile();
+                                        // 没有手机号也发送站内信消息
+                                        if (StrUtil.isNotBlank(finalMsgTitle)) {
+                                            pmsMessage.sendMessage(timeStamp, finalMsgTitle, PmsConstants.YF_PRODUCTION_STATUS,
+                                                    userId, mobile);
+                                        }
+                                    } finally {
+                                        latch.countDown();
+                                    }
+                                });
+                            });
+                        }
+                    }
+                }
+            }
+        });
+        return "创建成功";
+    }
+}

+ 9 - 1
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/message/PmsMessage.java

@@ -134,6 +134,14 @@ public class PmsMessage {
                 msg = "**四川瑞都 "+yesterdayPattern+" 施工简报**  \n" + name + "["+ DateUtil.format(new Date(),"yyyy-MM-dd hh:mm:ss")+"]";
             }
 
+            // 油服日报汇总生产动态提醒
+            if (PmsConstants.YF_PRODUCTION_STATUS.equals(businessType)) {
+                // businessId 时间戳 转换成 yyyy-MM-dd
+                LocalDateTime yesterday = LocalDateTime.ofInstant(Instant.ofEpochMilli(businessId),ZoneId.of("Asia/Shanghai"));
+                String yesterdayPattern = LocalDateTimeUtil.format(yesterday, DatePattern.NORM_DATE_PATTERN);
+                msg = "**集团生产概况 "+yesterdayPattern+"**  \n" + name + "["+ DateUtil.format(new Date(),"yyyy-MM-dd hh:mm:ss")+"]";
+            }
+
             // 瑞鹰项目启动设备整改
             if (PmsConstants.RY_IMPROVE_DAILY_REPORT.equals(businessType)) {
                 msg = "您有新的项目启动设备整改日报 " + name + "需要填报,请处理。"+"["+ DateUtil.format(new Date(),"yyyy-MM-dd hh:mm:ss")+"]";
@@ -182,7 +190,7 @@ public class PmsMessage {
                 //通知设备状态变更为观察使用
                 dingtalkSendApi.send(mobile, msg, "text",url,  title);
             } else if (PmsConstants.PRODUCTION_EXCEPTION.equals(businessType) || PmsConstants.RH_PRODUCTION_STATUS.equals(businessType)
-                    || PmsConstants.RD_PRODUCTION_STATUS.equals(businessType)) {
+                    || PmsConstants.RD_PRODUCTION_STATUS.equals(businessType) || PmsConstants.YF_PRODUCTION_STATUS.equals(businessType)) {
                 // markdown 类型消息 支持 文字加粗
                 dingtalkSendApi.send(mobile, msg, "markdown",url,  title);
             } else {

+ 6 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/service/iotrddailyreport/IotRdDailyReportServiceImpl.java

@@ -2132,6 +2132,12 @@ public class IotRdDailyReportServiceImpl implements IotRdDailyReportService {
                 utilizationResp.setUtilizationRate(deviceUtilization);
                 utilizationResp.setDeptName("utilizationRate");
                 result.add(utilizationResp);
+                IotRdDailyReportStatisticsRespVO reportCountResp = new IotRdDailyReportStatisticsRespVO();
+                reportCountResp.setUtilizationRate(new BigDecimal(reportMainDeviceIds.size()));
+                reportCountResp.setDeptName("reportCount");
+                IotRdDailyReportStatisticsRespVO teamDeptIdsResp = new IotRdDailyReportStatisticsRespVO();
+                teamDeptIdsResp.setUtilizationRate(new BigDecimal(abDeviceIds.size()));
+                teamDeptIdsResp.setDeptName("teamDeptIds");
                 System.out.println("瑞都设备利用率-分子:" + reportMainDeviceIds.size());
                 System.out.println("瑞都设备利用率-分母:" + abDeviceIds.size());
             }

+ 16 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/service/iotrhdailyreport/IotRhDailyReportService.java

@@ -182,4 +182,20 @@ public interface IotRhDailyReportService {
      * @return 瑞恒日报 非生产时效分析 列表
      */
     List<ProjectUtilizationRateVo> rhProductionStatusList(IotRhDailyReportPageReqVO pageReqVO);
+
+    /**
+     * 瑞恒日报列表
+     *
+     * @param pageReqVO 无分页查询
+     * @return 瑞恒日报 非生产时效分析 列表
+     */
+    List<IotRhDailyReportDO> getDailyReports(IotRhDailyReportPageReqVO pageReqVO);
+
+    /**
+     * 瑞恒日报统计卡片
+     *
+     * @param pageReqVO 无分页查询
+     * @return 瑞恒日报 非生产时效分析 列表
+     */
+    Map<String, BigDecimal> totalWorkload(IotRhDailyReportPageReqVO pageReqVO);
 }

+ 190 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/service/iotrhdailyreport/IotRhDailyReportServiceImpl.java

@@ -1762,6 +1762,196 @@ public class IotRhDailyReportServiceImpl implements IotRhDailyReportService {
         return rates;
     }
 
+    @Override
+    public List<IotRhDailyReportDO> getDailyReports(IotRhDailyReportPageReqVO pageReqVO) {
+        List<IotRhDailyReportDO> dailyReports = iotRhDailyReportMapper.dailyReports(pageReqVO);
+        return CollUtil.isNotEmpty(dailyReports) ? dailyReports : Collections.emptyList();
+    }
+
+    @Override
+    public Map<String, BigDecimal> totalWorkload(IotRhDailyReportPageReqVO pageReqVO) {
+        // 统计设备利用率
+        Long deptId = pageReqVO.getDeptId();
+        // 项目部名称集合
+        Set<String> projectDeptNames = new HashSet<>();
+        // 项目部id集合
+        Set<Long> projectDeptIds = new HashSet<>();
+        // 队伍id集合
+        Set<Long> teamIds = new HashSet<>();
+        // key项目部id   value项目部名称
+        Map<Long, String> projectPair = new HashMap<>();
+        // key施工队伍id   value状态为LY的项目部id
+        Map<Long, Long> teamProjectIdPair = new HashMap<>();
+        if (ObjUtil.isNotEmpty(deptId)) {
+            // 筛选瑞恒 主设备 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> childDeptIds = deptService.getChildDeptIdListFromCache(deptId);
+            childDeptIds.add(deptId);
+            Map<Long, DeptDO> allDeptPair = deptService.getDeptMap(childDeptIds);
+            // 查询 瑞恒 所有设备 只统计包含 施工 状态设备的队伍
+            IotDevicePageReqVO deviceReqVO = new IotDevicePageReqVO();
+            deviceReqVO.setDeptIds(new ArrayList<>(childDeptIds));
+            List<IotDeviceDO> allRhDevices = iotDeviceMapper.selectListAlone(deviceReqVO);
+            // 包含设备的部门id集合
+            Set<Long> haveDeviceDeptIds = new HashSet<>();
+            if (CollUtil.isNotEmpty(allRhDevices)) {
+                // 筛选出包含设备的队伍部门集合
+                allRhDevices.forEach(device -> {
+                    // 20260605 筛选包含主设备的队伍
+                    if (mainDeviceCategoryIds.contains(device.getAssetClass())) {
+                        haveDeviceDeptIds.add(device.getDeptId());
+                    }
+                });
+            }
+            if (CollUtil.isNotEmpty(allDeptPair)) {
+                allDeptPair.forEach((departmentId, dept) -> {
+                    // 项目部 只统计 email = LY 的项目部的 设备利用率
+                    if ("2".equals(dept.getType()) && "LY".equals(dept.getEmail())) {
+                        projectDeptIds.add(departmentId);
+                        projectDeptNames.add(dept.getName());
+                        projectPair.put(departmentId, dept.getName());
+                    }
+                    if ("3".equals(dept.getType())) {
+                        teamIds.add(departmentId);
+                    }
+                });
+                // 遍历所有部门 只筛选出有设备的队伍
+                allDeptPair.forEach((departmentId, dept) -> {
+                    // 不需要找出每个项目部下的队伍 根据筛选的日期和部门 统计数据
+                    if (haveDeviceDeptIds.contains(departmentId)) {
+                        if (projectPair.containsKey(dept.getParentId()) && teamIds.contains(departmentId)) {
+                            // 获得队伍的上级项目部(LY状态的项目部)
+                            teamProjectIdPair.put(dept.getId(), dept.getParentId());
+                        }
+                        if (allDeptPair.size() == 1) {
+                            // 查询单个队伍的情况
+                            teamProjectIdPair.put(dept.getId(), dept.getParentId());
+                        }
+                    }
+                });
+            }
+        }
+        // 查询筛选时间区间内所有数据
+        pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
+        List<IotRhDailyReportDO> list = getIotRhDailyReportPage(pageReqVO).getList();
+        Map<String, BigDecimal> result = new HashMap<>();
+        // 累计注气量
+        BigDecimal totalGasInjection = BigDecimal.ZERO;
+        // 累计氮气注气量
+        BigDecimal totalN2GasInjection = BigDecimal.ZERO;
+        // 累计天然气注气量
+        BigDecimal totalNaturalGasInjection = BigDecimal.ZERO;
+        BigDecimal totalWaterInjection = BigDecimal.ZERO;
+        BigDecimal totalPowerConsumption = BigDecimal.ZERO;
+        BigDecimal totalFuelConsumption = BigDecimal.ZERO;
+        double rate = 0.0;
+        Integer reportCount = 0;
+        if (CollUtil.isNotEmpty(list)) {
+            // 筛选出指定搜索条件下日报关联任务的工艺 类别 N2 或 天然气
+            Set<Long> filteredTaskIds = new HashSet<>();
+            list.forEach(report -> {
+                if (ObjUtil.isNotEmpty(report.getTaskId())) {
+                    filteredTaskIds.add(report.getTaskId());
+                }
+            });
+            // 查询日报对应的任务列表 获得 任务的施工工艺 N2(2) 或 天然气(15)
+            IotProjectTaskPageReqVO taskReqVO = new IotProjectTaskPageReqVO();
+            taskReqVO.setTaskIds(new ArrayList<>(filteredTaskIds));
+            List<IotProjectTaskDO> tasks = iotProjectTaskService.projectTasks(taskReqVO);
+            Map<Long, String> taskTechniquePair = new HashMap<>();
+            if (CollUtil.isNotEmpty(tasks)) {
+                tasks.forEach(task -> {
+                    if (StrUtil.isNotBlank(task.getTechnique())) {
+                        taskTechniquePair.put(task.getId(), task.getTechnique());
+                    }
+                });
+            }
+
+            for (IotRhDailyReportDO report : list) {
+                // 统计出状态为 LY 的项目部下的施工队伍的日报数量
+                // 20260604 设备利用率计算逻辑调整 分子 注气量或注水量>0 的日报数量
+                if (teamProjectIdPair.containsKey(report.getDeptId()) &&
+                        (report.getDailyGasInjection().compareTo(BigDecimal.ZERO)>0 || report.getDailyWaterInjection().compareTo(BigDecimal.ZERO)>0)) {
+                    ++reportCount;
+                }
+                BigDecimal dailyGasInjection = report.getDailyGasInjection();
+                BigDecimal dailyWaterInjection = report.getDailyWaterInjection();
+                BigDecimal powerConsumption = report.getDailyPowerUsage();
+                BigDecimal oilConsumption = report.getDailyOilUsage();
+                if (ObjUtil.isNotEmpty(dailyGasInjection)) {
+                    totalGasInjection = totalGasInjection.add(dailyGasInjection);
+                    if (taskTechniquePair.containsKey(report.getTaskId())) {
+                        String technique = taskTechniquePair.get(report.getTaskId());
+                        if ("2".equals(technique)) {
+                            // 注氮气
+                            totalN2GasInjection = totalN2GasInjection.add(dailyGasInjection);
+                        }
+                        if ("15".equals(technique)) {
+                            // 注天然气
+                            totalNaturalGasInjection = totalNaturalGasInjection.add(dailyGasInjection);
+                        }
+                    }
+                }
+                if (ObjUtil.isNotEmpty(dailyWaterInjection)) {
+                    totalWaterInjection = totalWaterInjection.add(dailyWaterInjection);
+                }
+                if (ObjUtil.isNotEmpty(powerConsumption)) {
+                    totalPowerConsumption = totalPowerConsumption.add(powerConsumption);
+                }
+                if (ObjUtil.isNotEmpty(oilConsumption)) {
+                    totalFuelConsumption = totalFuelConsumption.add(oilConsumption);
+                }
+            }
+            // 计算筛选时间范围内 指定部门的设备利用率
+            long daysCount = 0l;
+            if (ObjUtil.isNotEmpty(pageReqVO.getCreateTime()) && pageReqVO.getCreateTime().length >= 2) {
+                LocalDateTime start = pageReqVO.getCreateTime()[0];
+                LocalDateTime end = pageReqVO.getCreateTime()[1];
+                if (ObjUtil.isNotEmpty(start) && ObjUtil.isNotEmpty(end) && !end.isBefore(start)) {
+                    // 使用ChronoUnit.DAYS.between计算天数差,并+1包含首尾两天
+                    daysCount = ChronoUnit.DAYS.between(
+                            start.toLocalDate(),
+                            end.toLocalDate()
+                    ) + 1;
+                }
+            }
+            // 所有LY状态的项目部包含的队伍数量>0 并且 指定时间区间天数大于0
+            if (daysCount > 0 && teamProjectIdPair.size() > 0) {
+                // 指定部门(公司or项目部or队伍) 设备利用率 公式 reportCount/(currentTeamNum*daysCount)
+                // 计算设备利用率(处理除数为0的情况)
+                rate = new BigDecimal((double) reportCount / (teamProjectIdPair.size() * daysCount))
+                        .setScale(4, RoundingMode.HALF_UP)  // 保留4位小数,四舍五入
+                        .doubleValue();
+            }
+            // 汇总 指定搜索时间段内的 累计注气量 累计注水量 累计用电量 累计油耗
+            result.put("totalGasInjection", totalGasInjection);
+            // 区分出 累计注气量 中的 氮气/天然气 注气量
+            result.put("totalN2GasInjection", totalN2GasInjection);
+            result.put("totalNaturalGasInjection", totalNaturalGasInjection);
+
+            result.put("reportCount", new BigDecimal(reportCount));
+            result.put("teamDeptIds", new BigDecimal(teamProjectIdPair.size()));
+
+            result.put("totalWaterInjection", totalWaterInjection);
+            result.put("totalPowerConsumption", totalPowerConsumption);
+            result.put("totalFuelConsumption", totalFuelConsumption);
+            result.put("utilizationRate", BigDecimal.valueOf(rate));
+        }
+        return result;
+    }
+
     @Override
     public void updateIotRhDailyReport(IotRhDailyReportSaveReqVO updateReqVO) {
         // 校验存在

+ 17 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/service/iotrydailyreport/IotRyDailyReportService.java

@@ -6,6 +6,7 @@ import cn.iocoder.yudao.module.pms.controller.admin.iotrydailyreportdetail.vo.Io
 import cn.iocoder.yudao.module.pms.dal.dataobject.iotrydailyreport.IotRyDailyReportDO;
 
 import javax.validation.Valid;
+import java.math.BigDecimal;
 import java.time.LocalDateTime;
 import java.util.List;
 import java.util.Map;
@@ -214,4 +215,20 @@ public interface IotRyDailyReportService {
      * @return 组合钻井修井日报生产动态简报 列表
      */
     List<IotRyDailyReportDO> productionBriefs(IotRyDailyReportPageReqVO pageReqVO);
+
+    /**
+     * 日报列表
+     *
+     * @param reqVO taskId
+     * @return 日报列表
+     */
+    List<IotRyDailyReportDO> getDailyReports(IotRyDailyReportPageReqVO reqVO);
+
+    /**
+     * 日报汇总卡片
+     *
+     * @param reqVO taskId
+     * @return 日报列表
+     */
+    Map<String, BigDecimal> totalWorkload(IotRyDailyReportPageReqVO reqVO);
 }

+ 205 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/service/iotrydailyreport/IotRyDailyReportServiceImpl.java

@@ -1309,6 +1309,211 @@ public class IotRyDailyReportServiceImpl implements IotRyDailyReportService {
         return Collections.emptyList();
     }
 
+    @Override
+    public List<IotRyDailyReportDO> getDailyReports(IotRyDailyReportPageReqVO reqVO) {
+        List<IotRyDailyReportDO> dailyReports = iotRyDailyReportMapper.dailyReports(reqVO);
+        return CollUtil.isNotEmpty(dailyReports) ? dailyReports : Collections.emptyList();
+    }
+
+    @Override
+    public Map<String, BigDecimal> totalWorkload(IotRyDailyReportPageReqVO pageReqVO) {
+
+        // 时间查询区间内如果包含 未发生的时间段(今年 本季度) 则设置 结束时间为 当前日期
+        // 【调用公共方法】矫正未来时间区间
+        LocalDateTimeUtils.correctFutureTimeRange(pageReqVO.getCreateTime());
+
+        // 统计设备利用率
+        Long deptId = pageReqVO.getDeptId();
+        // 钻井或修井部门 队伍
+        List<Long> zjOrXjDeptIds = new ArrayList<>();
+        // 可用的部门id集合
+        Set<Long> availableDeptIds = new HashSet<>();
+        if (ObjUtil.isNotEmpty(deptId)) {
+            // 查询指定部门下所有子部门
+            Set<Long> childDeptIds = deptService.getChildDeptIdListFromCache(deptId);
+            Map<Long, DeptDO> allDeptPair = deptService.getDeptMap(childDeptIds);
+            // 过滤掉关闭的部门
+            if (CollUtil.isNotEmpty(allDeptPair)) {
+                allDeptPair.forEach((tempDeptId, dept) -> {
+                    if (0 == dept.getStatus()) {
+                        availableDeptIds.add(tempDeptId);
+                    }
+                });
+            }
+            // 钻井日报汇总 分母为 钻井施工队伍  修井日报汇总分母分母为修井施工队伍
+            // 1钻井  2修井
+            String projectClassification = pageReqVO.getProjectClassification();
+            // 查询钻井部门 修井 部门
+            IotDeptTypePageReqVO reqVO = new IotDeptTypePageReqVO();
+            if ("1".equals(projectClassification)) {
+                reqVO.setType("zj");
+            } else {
+                reqVO.setType("xj");
+            }
+            List<IotDeptTypeDO> deptTypes = iotDeptTypeMapper.selectList(reqVO);
+            if (CollUtil.isNotEmpty(deptTypes)) {
+                deptTypes.forEach(dept -> {
+                    zjOrXjDeptIds.add(dept.getDeptId());
+                });
+            }
+        }
+        // 取 availableDeptIds zjOrXjDeptIds 2个集合的交集 当前查询条件下 的钻井 或 修井 部门id集合
+        Set<Long> overlapDeptIds = Stream.of(availableDeptIds)
+                .filter(Objects::nonNull)
+                .flatMap(Set::stream)
+                .filter(tempDeptId -> CollUtil.isNotEmpty(zjOrXjDeptIds) && zjOrXjDeptIds.contains(tempDeptId))
+                .collect(Collectors.toSet());
+
+
+        // 统计设备利用率 查询非 dt zx 状态的日报
+        // 钻井:日报状态 过滤掉 ‘等停dt’    修井:日报状态过滤掉 ‘等停dt’、‘整修zx’
+        List<String> statuses = new ArrayList<>();
+        statuses.add("dt");
+        statuses.add("zx");
+        pageReqVO.setStatuses(statuses);
+        double rate = 0.0;
+        Integer reportCount = 0;
+        List<IotRyDailyReportDO> dailyReports = iotRyDailyReportMapper.dailyReports(pageReqVO);
+        if (CollUtil.isNotEmpty(dailyReports)) {
+            for (IotRyDailyReportDO dailyReport : dailyReports) {
+                if (overlapDeptIds.contains(dailyReport.getDeptId())) {
+                    ++reportCount;
+                }
+            }
+        }
+
+        // 计算筛选时间范围内 指定部门的设备利用率
+        long daysCount = 0l;
+        if (ObjUtil.isNotEmpty(pageReqVO.getCreateTime()) && pageReqVO.getCreateTime().length >= 2) {
+            LocalDateTime start = pageReqVO.getCreateTime()[0];
+            LocalDateTime end = pageReqVO.getCreateTime()[1];
+            if (ObjUtil.isNotEmpty(start) && ObjUtil.isNotEmpty(end) && !end.isBefore(start)) {
+                // 使用ChronoUnit.DAYS.between计算天数差,并+1包含首尾两天
+                daysCount = ChronoUnit.DAYS.between(
+                        start.toLocalDate(),
+                        end.toLocalDate()
+                ) + 1;
+            }
+        }
+
+        // 所有项目部包含的队伍数量>0 并且 指定时间区间天数大于0
+        if (daysCount > 0 && overlapDeptIds.size() > 0) {
+            // 当前项目部 设备利用率 公式 reportCount/(currentTeamNum*daysCount)
+            // 计算设备利用率(处理除数为0的情况)
+            rate = new BigDecimal((double) reportCount / (overlapDeptIds.size() * daysCount))
+                    .setScale(4, RoundingMode.HALF_UP)  // 保留4位小数,四舍五入
+                    .doubleValue();
+            System.out.println("瑞鹰设备利用率-分子:" + reportCount);
+            System.out.println("瑞鹰设备利用率-分母:" + overlapDeptIds.size());
+        }
+
+        // 查询指定部门 指定时间范围内的日报
+        List<IotRyDailyReportDO> list = getIotRyDailyReportPage(pageReqVO).getList();
+        Map<String, BigDecimal> result = new HashMap<>();
+        // 总进尺
+        BigDecimal totalFootage = BigDecimal.ZERO;
+        // 总用电量
+        BigDecimal totalPowerConsumption = BigDecimal.ZERO;
+        // 总油耗
+        BigDecimal totalFuelConsumption = BigDecimal.ZERO;
+        // 平均油耗
+        BigDecimal averageFuelConsumption = BigDecimal.ZERO;
+        // key队伍id      value施工井数
+        BigDecimal constructionWells = BigDecimal.ZERO;
+        // key队伍id      value完工井数
+        BigDecimal completedWells = BigDecimal.ZERO;
+        // key施工队伍id    value施工井数量
+        Map<Long, Integer> totalTasksPair = new HashMap<>();
+        // key施工队伍id    value完工井数量
+        Map<Long, Integer> completedTasksPair = new HashMap<>();
+        // 瑞鹰修井 施工井数 完工井数 统计
+        Set<Long> ids = new HashSet<>();
+        if (Objects.nonNull(pageReqVO.getDeptId())) {
+            ids = deptService.getChildDeptIdListFromCache(pageReqVO.getDeptId());
+            ids.add(pageReqVO.getDeptId());
+            pageReqVO.setDeptIds(ids);
+        }
+        if (ObjUtil.isNotEmpty(pageReqVO.getCreateTime())) {
+            List<IotRyDailyReportTaskCountVO> repairDeptTasks = countRepairTasksByDept(pageReqVO);
+            if (CollUtil.isNotEmpty(repairDeptTasks)) {
+                repairDeptTasks.forEach(task -> {
+                    totalTasksPair.put(task.getDeptId(), task.getTotalTaskCount());
+                    completedTasksPair.put(task.getDeptId(), task.getCompletedTaskCount());
+                });
+            }
+        }
+
+        if (CollUtil.isNotEmpty(list)) {
+            for (IotRyDailyReportDO report : list) {
+                BigDecimal dailyFootage = report.getDailyFootage();
+                BigDecimal powerConsumption = report.getDailyPowerUsage();
+                BigDecimal fuelConsumption = report.getDailyFuel();
+                if (ObjUtil.isNotEmpty(dailyFootage)) {
+                    totalFootage = totalFootage.add(dailyFootage);
+                }
+                if (ObjUtil.isNotEmpty(powerConsumption)) {
+                    totalPowerConsumption = totalPowerConsumption.add(powerConsumption);
+                }
+                if (ObjUtil.isNotEmpty(fuelConsumption)) {
+                    totalFuelConsumption = totalFuelConsumption.add(fuelConsumption);
+                }
+            }
+
+            // 施工井数
+            if (CollUtil.isNotEmpty(totalTasksPair)) {
+                for (Integer wellCount : totalTasksPair.values()) {
+                    constructionWells = constructionWells.add(new BigDecimal(wellCount));
+                }
+            }
+            // 完工井数
+            if (CollUtil.isNotEmpty(completedTasksPair)) {
+                for (Integer wellCount : completedTasksPair.values()) {
+                    completedWells = completedWells.add(new BigDecimal(wellCount));
+                }
+            }
+            // 累计用电量
+            result.put("totalPowerConsumption", totalPowerConsumption);
+            // 累计油耗
+            result.put("totalFuelConsumption", totalFuelConsumption);
+            // 平均油耗
+            if (ObjUtil.isNotEmpty(pageReqVO.getCreateTime())) {
+                LocalDateTime[] createTimes = pageReqVO.getCreateTime();
+                // 获取开始时间和结束时间
+                LocalDateTime startTime = createTimes[0];
+                LocalDateTime endTime = createTimes[1];
+                // 截断到日期(忽略时分秒)
+                LocalDate startDate = startTime.toLocalDate();
+                LocalDate endDate = endTime.toLocalDate();
+                // 计算天数:日期差 + 1(包含首尾两天)
+                long days = ChronoUnit.DAYS.between(startDate, endDate) + 1;
+                averageFuelConsumption = totalFuelConsumption.divide(new BigDecimal(days), 2, RoundingMode.HALF_UP);
+                result.put("averageFuelConsumption", averageFuelConsumption);
+            }
+
+            // 汇总 指定搜索时间段内的 总进尺  累计用电量 累计油耗
+            if ("1".equals(pageReqVO.getProjectClassification())) {
+                // 钻井日报
+                result.put("totalFootage", totalFootage);
+                // 钻井 设备利用率 分子
+                result.put("zjReportCount", new BigDecimal(reportCount));
+                // 钻井 设备利用率 分母
+                result.put("zjTeamDeptIds", new BigDecimal(overlapDeptIds.size()));
+            } else if ("2".equals(pageReqVO.getProjectClassification())) {
+                // 累计施工井数
+                result.put("constructionWells", constructionWells);
+                // 累计完工井数
+                result.put("completedWells", completedWells);
+                // 修井 设备利用率 分子
+                result.put("xjReportCount", new BigDecimal(reportCount));
+                // 修井 设备利用率 分母
+                result.put("xjTeamDeptIds", new BigDecimal(overlapDeptIds.size()));
+            }
+        }
+        // 设备利用率
+        result.put("utilizationRate", BigDecimal.valueOf(rate));
+        return result;
+    }
+
     private List<IotDeviceDO> devices() {
         // 查询 瑞鹰158l 所有存在设备的队伍
         // 查询 瑞鹰 下所有部门