Bladeren bron

Merge remote-tracking branch 'origin/master'

lipenghui 4 dagen geleden
bovenliggende
commit
3c5d4ae961

+ 11 - 54
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/iotopeationfill/IotOpeationFillController.java

@@ -362,9 +362,7 @@ public class IotOpeationFillController {
             Integer userId = allFillData.get(0).getUserId();
 
 
-            for (IotDeviceRunLogDO a:logDOList) {
-                System.out.println("设备数据-------------"+a);
-            }
+
             // 6. 批量保存日志(有则更新,无则插入)
             batchSaveLogs(logDOList);
 
@@ -409,9 +407,14 @@ public class IotOpeationFillController {
         Map<String, BigDecimal> unSumDataIndex = allFillData.stream()
                 .filter(fill -> 0 == fill.getIsSum() && fill.getDeviceCode() != null
                         && !fill.getDeviceCode().isEmpty())
+                .filter(fill -> {
+                    String content = String.valueOf(fill.getFillContent()).trim();
+                    // 排除空字符串和非数字(支持整数、小数,不支持文本)
+                    return !content.isEmpty() && content.matches("^[+-]?\\d+(\\.\\d+)?$");
+                })
                 .collect(Collectors.toMap(
                         fill -> fill.getDeviceId() + "_" + fill.getModelId(), // 构建索引键
-                        fill -> new BigDecimal(fill.getFillContent()), // 提前转换为BigDecimal
+                        fill -> new BigDecimal(String.valueOf(fill.getFillContent()).trim()), // 提前转换为BigDecimal
                         (v1, v2) -> v1.add(v2) // 同维度数据直接累加(根据业务调整,此处默认累加)
                 ));
 
@@ -539,14 +542,12 @@ public class IotOpeationFillController {
                 .map(fill -> {
                     IotDeviceRunLogDO deviceRunLogDO = new IotDeviceRunLogDO();
                     deviceRunLogDO.setDeviceId(fill.getDeviceId());
-                    System.out.println("deviceId----"+fill.getDeviceId());
                     deviceRunLogDO.setDeviceCode(fill.getDeviceCode());
                     deviceRunLogDO.setFillContent(fill.getFillContent());
                     deviceRunLogDO.setPointCode(fill.getModelAttr());
                     deviceRunLogDO.setDeptId(fill.getDeptId());
                     deviceRunLogDO.setCreateTime(LocalDateTime.of(fill.getCreateTime(), localTime));
                     deviceRunLogDO.setPointName(fill.getPointName());
-                    System.out.println("totalRunTime----"+fill.getTotalRunTime());
                     deviceRunLogDO.setTotalRunTime(fill.getTotalRunTime());
                     deviceRunLogDO.setIsSum(fill.getIsSum() != null ? fill.getIsSum() : 0);
                     return deviceRunLogDO;
@@ -629,18 +630,7 @@ public class IotOpeationFillController {
                         log -> log,
                         (v1, v2) -> v1 // 避免重复key(理论上不会有)
                 ));
-        System.out.println("=== existingLogMap 详细内容 ===");
-        existingLogMap.forEach((key, log) -> {
-            System.out.println("Key: " + key);
-            // 打印IotDeviceRunLogDO的属性(根据实际字段调整)
-            System.out.println("Value: " +
-                    "deviceId=" + log.getDeviceId() +
-                    ", pointName=" + log.getPointName() +
-                    ", createTime=" + log.getCreateTime() +
-                    ", value=" + log.getValue() // 补充你实际的字段
-            );
-            System.out.println("------------------------"); // 分隔符,方便阅读
-        });
+
 
         // 2. 拆分:待插入列表 + 待更新列表
         List<IotDeviceRunLogDO> insertList = new ArrayList<>();
@@ -664,52 +654,19 @@ public class IotOpeationFillController {
 
         // 3. 批量执行(MyBatis批量操作)
         if (!insertList.isEmpty()) {
-            System.out.println("执行了插入");
-            // 方式B:带索引遍历(方便定位第几个元素有问题)
-            System.out.println("===== insertList 详细元素(带索引) =====");
-            for (int i = 0; i < insertList.size(); i++) {
-                IotDeviceRunLogDO log = insertList.get(i);
-                System.out.printf("第 %d 个元素:deviceId=%s, pointName=%s, createTime=%s%n",
-                        i + 1,
-                        log.getDeviceId(),
-                        log.getPointName(),
-                        log.getCreateTime() // 若为Date类型,建议格式化:sdf.format(log.getCreateTime())
-                );
-            }
+
             TenantUtils.execute(1L, () -> {
                 iotOpeationFillService.batchInsertLogs(insertList); // 批量插入
             });
         }
         if (!updateList.isEmpty()) {
-            System.out.println("执行了更新");
-            // 方式B:带索引遍历(方便定位第几个元素有问题)
-            System.out.println("===== insertList 详细元素(带索引) =====");
-            for (int i = 0; i < updateList.size(); i++) {
-                IotDeviceRunLogDO log = updateList.get(i);
-                System.out.printf("第 %d 个元素:deviceId=%s, pointName=%s, createTime=%s%n",
-                        i + 1,
-                        log.getDeviceId(),
-                        log.getPointName(),
-                        log.getCreateTime() // 若为Date类型,建议格式化:sdf.format(log.getCreateTime())
-                );
-            }
+
             TenantUtils.execute(1L, () -> {
                 iotOpeationFillService.batchUpdateLogs(updateList); // 批量更新普通日志
             });
         }
         if (!updateSumList.isEmpty()) {
-            System.out.println("执行了累计更新");
-            // 方式B:带索引遍历(方便定位第几个元素有问题)
-            System.out.println("===== updateSumList 详细元素(带索引) =====");
-            for (int i = 0; i < updateSumList.size(); i++) {
-                IotDeviceRunLogDO log = updateSumList.get(i);
-                System.out.printf("第 %d 个元素:deviceId=%s, pointName=%s, createTime=%s%n",
-                        i + 1,
-                        log.getDeviceId(),
-                        log.getPointName(),
-                        log.getCreateTime() // 若为Date类型,建议格式化:sdf.format(log.getCreateTime())
-                );
-            }
+
             TenantUtils.execute(1L, () -> {
                 iotOpeationFillService.batchUpdateSumLogs(updateSumList); // 批量更新累计日志
             });

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

@@ -815,6 +815,112 @@ public class IotRdDailyReportController {
         return success(result);
     }
 
+    @GetMapping("/totalWorkload")
+    @Operation(summary = "瑞都日报 汇总 统计 卡片")
+    @PreAuthorize("@ss.hasPermission('pms:iot-rd-daily-report:query')")
+    public CommonResult<Map<String, BigDecimal>> totalWorkload(@Valid IotRdDailyReportPageReqVO pageReqVO) {
+        Map<String, BigDecimal> resultMap = new HashMap<>();
+        // 根据查询参数筛选出 符合条件 的记录id 再传入 分页查询
+        Set<Long> projectIds = new HashSet<>();
+        Set<Long> taskIds = new HashSet<>();
+        if (StrUtil.isNotBlank(pageReqVO.getContractName())) {
+            IotProjectInfoPageReqVO reqVO = new IotProjectInfoPageReqVO();
+            reqVO.setContractName(pageReqVO.getContractName());
+            List<IotProjectInfoDO> projects = iotProjectInfoService.getIotProjectInfos(reqVO);
+            if (CollUtil.isNotEmpty(projects)) {
+                projects.forEach(project -> {
+                    projectIds.add(project.getId());
+                });
+                pageReqVO.setProjectIds(projectIds);
+            }
+        }
+        if (StrUtil.isNotBlank(pageReqVO.getTaskName())) {
+            IotProjectTaskPageReqVO reqVO = new IotProjectTaskPageReqVO();
+            reqVO.setSearchKey(pageReqVO.getTaskName());
+            List<IotProjectTaskDO> tasks = iotProjectTaskService.projectTasks(reqVO);
+            if (CollUtil.isNotEmpty(tasks)) {
+                tasks.forEach(task -> {
+                    taskIds.add(task.getId());
+                });
+                pageReqVO.setTaskIds(taskIds);
+            }
+        }
+        List<IotRdDailyReportStatisticsRespVO> statistics = iotRdDailyReportService.totalWorkload(pageReqVO);
+        if (CollUtil.isNotEmpty(statistics)) {
+            final BigDecimal[] taici = {BigDecimal.ZERO};
+            statistics.forEach(stat -> {
+                // 循环遍历 获取 每个 维度 工作量的值
+                if ("cumulativeBridgePlug".equals(stat.getDeptName())) {
+                    resultMap.put("cumulativeBridgePlug", stat.getCumulativeBridgePlug());
+                }
+                if ("cumulativeRunCount".equals(stat.getDeptName())) {
+                    resultMap.put("cumulativeRunCount", stat.getCumulativeRunCount());
+                }
+                if ("cumulativeWorkingWell".equals(stat.getDeptName())) {
+                    resultMap.put("cumulativeWorkingWell", stat.getCumulativeWorkingWell());
+                }
+                if ("cumulativeHourCount".equals(stat.getDeptName())) {
+                    resultMap.put("cumulativeHourCount", stat.getCumulativeHourCount());
+                }
+                if ("cumulativeWaterVolume".equals(stat.getDeptName())) {
+                    resultMap.put("cumulativeWaterVolume", stat.getCumulativeWaterVolume());
+                }
+                if ("cumulativeWorkingLayers".equals(stat.getDeptName())) {
+                    resultMap.put("cumulativeWorkingLayers", stat.getCumulativeWorkingLayers());
+                }
+                if ("cumulativeMixSand".equals(stat.getDeptName())) {
+                    taici[0] = taici[0].add(stat.getCumulativeMixSand());
+                }
+                if ("cumulativePumpTrips".equals(stat.getDeptName())) {
+                    taici[0] = taici[0].add(stat.getCumulativePumpTrips());
+                }
+                resultMap.put("taici", taici[0]);
+                if ("cumulativeFuels".equals(stat.getDeptName())) {
+                    resultMap.put("cumulativeFuels", stat.getTotalDailyFuel());
+                }
+            });
+        }
+        return success(resultMap);
+    }
+
+    @GetMapping("/summaryStatistics")
+    @Operation(summary = "瑞都日报 汇总 统计")
+    @PreAuthorize("@ss.hasPermission('pms:iot-rd-daily-report:query')")
+    public CommonResult<Map<String, Object>> summaryStatistics(@Valid IotRdDailyReportPageReqVO pageReqVO) {
+        List<IotRdDailyReportStatisticsRespVO> result = new ArrayList<>();
+        Map<String, Object> resultMap = new HashMap<>();
+        // 根据查询参数筛选出 符合条件 的记录id 再传入 分页查询
+        Set<Long> projectIds = new HashSet<>();
+        Set<Long> taskIds = new HashSet<>();
+        if (StrUtil.isNotBlank(pageReqVO.getContractName())) {
+            IotProjectInfoPageReqVO reqVO = new IotProjectInfoPageReqVO();
+            reqVO.setContractName(pageReqVO.getContractName());
+            List<IotProjectInfoDO> projects = iotProjectInfoService.getIotProjectInfos(reqVO);
+            if (CollUtil.isNotEmpty(projects)) {
+                projects.forEach(project -> {
+                    projectIds.add(project.getId());
+                });
+                pageReqVO.setProjectIds(projectIds);
+            }
+        }
+        if (StrUtil.isNotBlank(pageReqVO.getTaskName())) {
+            IotProjectTaskPageReqVO reqVO = new IotProjectTaskPageReqVO();
+            reqVO.setSearchKey(pageReqVO.getTaskName());
+            List<IotProjectTaskDO> tasks = iotProjectTaskService.projectTasks(reqVO);
+            if (CollUtil.isNotEmpty(tasks)) {
+                tasks.forEach(task -> {
+                    taskIds.add(task.getId());
+                });
+                pageReqVO.setTaskIds(taskIds);
+            }
+        }
+        List<IotRdDailyReportStatisticsRespVO> statistics = iotRdDailyReportService.summaryStatistics(pageReqVO);
+        result.addAll(statistics);
+        resultMap.put("list", result);
+        resultMap.put("total", result.size());
+        return success(resultMap);
+    }
+
     @GetMapping("/teamReports")
     @Operation(summary = "根据井号查询瑞都日报列表 按照队伍分组统计工作量")
     @PreAuthorize("@ss.hasPermission('pms:iot-rd-daily-report:query')")
@@ -1971,7 +2077,7 @@ public class IotRdDailyReportController {
     @GetMapping("/polylineStatistics")
     @Operation(summary = "瑞都日报 统计")
     @PreAuthorize("@ss.hasPermission('pms:iot-rd-daily-report:query')")
-    public CommonResult<List<IotRdDailyReportStatisticsRespVO>> polylineStatistics(@Valid IotRdDailyReportPageReqVO pageReqVO) {
+    public CommonResult<List<IotRdDailyReportPolylineVO>> polylineStatistics(@Valid IotRdDailyReportPageReqVO pageReqVO) {
         // 根据查询参数筛选出 符合条件 的记录id 再传入 分页查询
         Set<Long> projectIds = new HashSet<>();
         Set<Long> taskIds = new HashSet<>();
@@ -1997,7 +2103,7 @@ public class IotRdDailyReportController {
                 pageReqVO.setTaskIds(taskIds);
             }
         }
-        List<IotRdDailyReportStatisticsRespVO> result = iotRdDailyReportService.statistics(pageReqVO);
+        List<IotRdDailyReportPolylineVO> result = iotRdDailyReportService.polylineStatistics(pageReqVO);
         return success(result);
     }
 

+ 35 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/iotrddailyreport/vo/IotRdDailyReportPolylineVO.java

@@ -52,4 +52,39 @@ public class IotRdDailyReportPolylineVO {
     @ExcelProperty("发生工作量所在月份")
     private String workloadMonth;
 
+    @Schema(description = "日报日期 yyyy-MM-dd", example = "1")
+    @ExcelProperty("日报日期 yyyy-MM-dd")
+    private String reportDate;
+
+    // 汇总统计 工作量
+    @Schema(description = "桥塞(个数)")
+    @ExcelProperty("桥塞(个数)")
+    private BigDecimal cumulativeBridgePlug;
+    @Schema(description = "趟数")
+    @ExcelProperty("趟数")
+    private BigDecimal cumulativeRunCount;
+    @Schema(description = "井数")
+    @ExcelProperty("井数")
+    private BigDecimal cumulativeWorkingWell;
+    @Schema(description = "小时H")
+    @ExcelProperty("小时H")
+    private BigDecimal cumulativeHourCount;
+    @Schema(description = "水方量(方)")
+    @ExcelProperty("水方量(方)")
+    private BigDecimal cumulativeWaterVolume;
+    @Schema(description = "段数  累计施工-层")
+    @ExcelProperty("段数  累计施工-层")
+    private BigDecimal cumulativeWorkingLayers;
+    @Schema(description = "台次 当日仪表/混砂")
+    @ExcelProperty("台次 当日仪表/混砂")
+    private BigDecimal cumulativeMixSand;
+    @Schema(description = "台次 当日泵车台次")
+    @ExcelProperty("台次 当日泵车台次")
+    private BigDecimal cumulativePumpTrips;
+    @Schema(description = "累计 台次")
+    @ExcelProperty("累计 台次")
+    private BigDecimal taici;
+    @Schema(description = "油耗L")
+    @ExcelProperty("油耗L")
+    private BigDecimal cumulativeFuels;
 }

+ 42 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/iotrddailyreport/vo/IotRdDailyReportStatisticsRespVO.java

@@ -22,6 +22,9 @@ public class IotRdDailyReportStatisticsRespVO {
     @ExcelProperty("项目部id")
     private Long deptId;
 
+    @Schema(description = "项目部id", example = "125")
+    private Long projectDeptId;
+
     @Schema(description = "项目部名称", example = "西南压裂项目部")
     @ExcelProperty("项目部名称")
     private String projectDeptName;
@@ -30,6 +33,16 @@ public class IotRdDailyReportStatisticsRespVO {
     @ExcelProperty("队伍名称")
     private String deptName;
 
+    @Schema(description = "队伍id", example = "125")
+    private Long teamId;
+
+    @Schema(description = "队伍名称", example = "HY-A1")
+    @ExcelProperty("队伍名称")
+    private String teamName;
+
+    @Schema(description = "部门类型(公司级1 项目部2 队伍3)", example = "1")
+    private String type;
+
     @Schema(description = "任务id", example = "15678")
     @ExcelProperty("任务id")
     private Long taskId;
@@ -70,7 +83,36 @@ public class IotRdDailyReportStatisticsRespVO {
     @ExcelProperty("油耗L")
     private BigDecimal totalDailyFuel;
 
+    @Schema(description = "排序", example = "1")
+    private Integer sort;
+
     @Schema(description = "工作量明细")
     @ExcelProperty("工作量明细")
     private List<IotRdDailyReportStatisticsItemVO> items;
+
+    // 汇总统计 工作量
+    @Schema(description = "桥塞(个数)")
+    @ExcelProperty("桥塞(个数)")
+    private BigDecimal cumulativeBridgePlug;
+    @Schema(description = "趟数")
+    @ExcelProperty("趟数")
+    private BigDecimal cumulativeRunCount;
+    @Schema(description = "井数")
+    @ExcelProperty("井数")
+    private BigDecimal cumulativeWorkingWell;
+    @Schema(description = "小时H")
+    @ExcelProperty("小时H")
+    private BigDecimal cumulativeHourCount;
+    @Schema(description = "水方量(方)")
+    @ExcelProperty("水方量(方)")
+    private BigDecimal cumulativeWaterVolume;
+    @Schema(description = "段数  累计施工-层")
+    @ExcelProperty("段数  累计施工-层")
+    private BigDecimal cumulativeWorkingLayers;
+    @Schema(description = "台次 当日仪表/混砂")
+    @ExcelProperty("台次 当日仪表/混砂")
+    private BigDecimal cumulativeMixSand;
+    @Schema(description = "台次 当日泵车台次")
+    @ExcelProperty("台次 当日泵车台次")
+    private BigDecimal cumulativePumpTrips;
 }

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

@@ -84,6 +84,22 @@ public interface IotRdDailyReportService {
      */
     List<IotRdDailyReportStatisticsRespVO> statistics(IotRdDailyReportPageReqVO pageReqVO);
 
+    /**
+     * 瑞都 日报 汇总统计
+     *
+     * @param pageReqVO 列表查询
+     * @return 瑞都日报汇总统计
+     */
+    List<IotRdDailyReportStatisticsRespVO> summaryStatistics(IotRdDailyReportPageReqVO pageReqVO);
+
+    /**
+     * 瑞都 日报 汇总统计 卡片
+     *
+     * @param pageReqVO 列表查询
+     * @return 瑞都日报汇总统计
+     */
+    List<IotRdDailyReportStatisticsRespVO> totalWorkload(IotRdDailyReportPageReqVO pageReqVO);
+
     /**
      * 瑞都 日报 按项目部统计 工作量折线图
      *

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

@@ -1,6 +1,8 @@
 package cn.iocoder.yudao.module.pms.service.iotrddailyreport;
 
 import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.date.DatePattern;
+import cn.hutool.core.date.LocalDateTimeUtil;
 import cn.hutool.core.util.ObjUtil;
 import cn.hutool.core.util.StrUtil;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
@@ -28,6 +30,7 @@ import cn.iocoder.yudao.module.pms.message.PmsMessage;
 import cn.iocoder.yudao.module.supplier.enums.common.SupplierAuditStatusEnum;
 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.controller.admin.dept.vo.dept.DeptListReqVO;
 import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO;
 import cn.iocoder.yudao.module.system.dal.dataobject.dict.DictDataDO;
 import cn.iocoder.yudao.module.system.dal.dataobject.permission.RoleDO;
@@ -764,29 +767,1048 @@ public class IotRdDailyReportServiceImpl implements IotRdDailyReportService {
         return result;
     }
 
+    @Override
+    public List<IotRdDailyReportStatisticsRespVO> summaryStatistics(IotRdDailyReportPageReqVO pageReqVO) {
+        List<IotRdDailyReportStatisticsRespVO> result = new ArrayList<>();
+        // 不分页统计所有数据
+        Set<Long> ids = new HashSet<>();
+        if (Objects.nonNull(pageReqVO.getDeptId())) {
+            ids = deptService.getChildDeptIdListFromCache(pageReqVO.getDeptId());
+            // 找到所有子部门对象集合
+            ids.add(pageReqVO.getDeptId());
+            pageReqVO.setDeptIds(ids);
+        }
+        // 检查contractName不为空但projectIds为空的情况
+        if (StrUtil.isNotBlank(pageReqVO.getContractName()) && (CollUtil.isEmpty(pageReqVO.getProjectIds()))) {
+            return new ArrayList<>();
+        }
+        // 检查taskName不为空但taskIds为空的情况
+        if (StrUtil.isNotBlank(pageReqVO.getTaskName()) && (CollUtil.isEmpty(pageReqVO.getTaskIds()))) {
+            return new ArrayList<>();
+        }
+        List<IotRdDailyReportDO> dailyReports = iotRdDailyReportMapper.dailyReports(pageReqVO);
+
+        // 默认显示所有项目部的汇总数据(新疆分公司也展示 下属各项目部的数据)
+        // 点击项目部 显示 下属队伍的数据
+        // 首先判断点击的部门是属于 公司 还是 队伍 如果没有点击任何部门 默认查询所有项目部数据
+        if (ObjUtil.isEmpty(pageReqVO.getDeptId())) {
+            result = statisticsByProjectDept(dailyReports, 163L, pageReqVO);
+        } else {
+            // 判断点击的组织树中的部门类型 类型(公司级1 项目部2 队伍3)
+            DeptDO selectedDept = deptService.getDept(pageReqVO.getDeptId());
+            if ("1".equals(selectedDept.getType())) {
+                // 以项目部为维度汇总数据
+                result = statisticsByProjectDept(dailyReports, pageReqVO.getDeptId(), pageReqVO);
+            } else if ("2".equals(selectedDept.getType())) {
+                // 以队伍为维度汇总数据
+                result = statisticsByProjectDepartment(dailyReports, pageReqVO.getDeptId());
+            } else if ("3".equals(selectedDept.getType())) {
+                // 显示单个队伍的汇总数据
+                result = statisticsByProjectDepartment(dailyReports, pageReqVO.getDeptId());
+            } else {
+                // 点击的部门没有类型 判断部门下的是否包含 项目部类型部门 新疆分公司
+                // 以项目部为维度汇总数据
+                result = statisticsByProjectDept(dailyReports, pageReqVO.getDeptId(), pageReqVO);
+            }
+        }
+        // 根据result集合内对象的 sort 属性正序排列 sort 类型为 integer 类型
+        if (CollUtil.isNotEmpty(result)) {
+            result.sort(Comparator.comparing(
+                    IotRdDailyReportStatisticsRespVO::getSort,
+                    Comparator.nullsLast(Comparator.naturalOrder())
+            ));
+        }
+        return result;
+    }
+
+    @Override
+    public List<IotRdDailyReportStatisticsRespVO> totalWorkload(IotRdDailyReportPageReqVO pageReqVO) {
+        List<IotRdDailyReportStatisticsRespVO> result = new ArrayList<>();
+        // 不分页统计所有数据
+        Set<Long> ids = new HashSet<>();
+        if (Objects.nonNull(pageReqVO.getDeptId())) {
+            ids = deptService.getChildDeptIdListFromCache(pageReqVO.getDeptId());
+            // 找到所有子部门对象集合
+            ids.add(pageReqVO.getDeptId());
+            pageReqVO.setDeptIds(ids);
+        }
+        // 检查contractName不为空但projectIds为空的情况
+        if (StrUtil.isNotBlank(pageReqVO.getContractName()) && (CollUtil.isEmpty(pageReqVO.getProjectIds()))) {
+            return new ArrayList<>();
+        }
+        // 检查taskName不为空但taskIds为空的情况
+        if (StrUtil.isNotBlank(pageReqVO.getTaskName()) && (CollUtil.isEmpty(pageReqVO.getTaskIds()))) {
+            return new ArrayList<>();
+        }
+
+        // key工作量标识   value累计 桥塞(个数)
+        Map<String, BigDecimal> cumulativeBridgePlugPair = new HashMap<>();
+        // key工作量标识   value累计 趟数
+        Map<String, BigDecimal> cumulativeRunCountPair = new HashMap<>();
+        // key工作量标识   value累计 井数
+        Map<String, BigDecimal> cumulativeWorkingWellPair = new HashMap<>();
+        // key工作量标识   value累计 小时H
+        Map<String, BigDecimal> cumulativeHourCountPair = new HashMap<>();
+        // key工作量标识   value累计 油耗
+        Map<String, BigDecimal> cumulativeFuelsPair = new HashMap<>();
+        // key工作量标识   value累计 水方量(方)
+        Map<String, BigDecimal> cumulativeWaterVolumePair = new HashMap<>();
+        // key工作量标识   value累计 段数 累计施工-层
+        Map<String, BigDecimal> cumulativeWorkingLayersPair = new HashMap<>();
+        // key工作量标识   value累计 台次 当日仪表/混砂
+        Map<String, BigDecimal> cumulativeMixSandPair = new HashMap<>();
+        // key工作量标识   value累计 台次 当日泵车台次
+        Map<String, BigDecimal> cumulativePumpTripsPair = new HashMap<>();
+
+        List<IotRdDailyReportDO> dailyReports = iotRdDailyReportMapper.dailyReports(pageReqVO);
+        // 累加所有日报的 工作量 数据 油耗 桥塞 趟数 井数...
+        if (CollUtil.isNotEmpty(dailyReports)) {
+            dailyReports.forEach(report -> {
+                BigDecimal dailyFuel = report.getDailyFuel();
+                dailyFuel = ObjUtil.isEmpty(dailyFuel) ? BigDecimal.ZERO : dailyFuel;
+                if (cumulativeFuelsPair.containsKey("cumulativeFuels")) {
+                    BigDecimal existTotalFuel = cumulativeFuelsPair.get("cumulativeFuels");
+                    BigDecimal tempTotalFuel = existTotalFuel.add(dailyFuel);
+                    cumulativeFuelsPair.put("cumulativeFuels", tempTotalFuel);
+                } else {
+                    cumulativeFuelsPair.put("cumulativeFuels", dailyFuel);
+                }
+                // 设置每个任务的工作量数据  单位相同的工作量值作合并处理
+                List<IotTaskAttrModelProperty> taskAttrs = report.getExtProperty();
+                // 暂存不同单位的工作量属性值
+                BigDecimal tempTotalBridgePlug = BigDecimal.ZERO;               // 桥塞(个数)
+                BigDecimal tempTotalRunCount = BigDecimal.ZERO;                 // 趟数
+                BigDecimal tempTotalCumulativeWorkingWell = BigDecimal.ZERO;    // 井数
+                BigDecimal tempTotalHourCount = BigDecimal.ZERO;                // 小时H
+                BigDecimal tempTotalWaterVolume = BigDecimal.ZERO;              // 水方量(方)
+                BigDecimal tempTotalPumpTrips = BigDecimal.ZERO;                // 泵车 台次
+                BigDecimal tempTotalCumulativeWorkingLayers = BigDecimal.ZERO;  // 段数 累计施工-层
+                BigDecimal tempTotalMixSand = BigDecimal.ZERO;                  // 台次 当日仪表/混砂
+                if (CollUtil.isNotEmpty(taskAttrs)) {
+                    for (IotTaskAttrModelProperty attr : taskAttrs) {
+                        String unit = attr.getUnit();   // 工作量单位
+                        String actualValueStr = attr.getActualValue();  // 工作量属性的实际值
+                        // 处理实际值:避免null或非数字字符串导致的异常
+                        BigDecimal actualValue = BigDecimal.ZERO;
+                        if (StrUtil.isNotBlank(actualValueStr)) {
+                            try {
+                                actualValue = new BigDecimal(actualValueStr);
+                            } catch (NumberFormatException e) {
+                                // 若字符串格式错误,默认按0处理(可根据业务调整)
+                                actualValue = BigDecimal.ZERO;
+                            }
+                        }
+                        if ("个数".equals(unit)) {
+                            // 钻可溶桥塞  钻复合桥塞
+                            tempTotalBridgePlug = tempTotalBridgePlug.add(actualValue);
+                            if (cumulativeBridgePlugPair.containsKey("cumulativeBridgePlug")) {
+                                BigDecimal tempBridgePlug = cumulativeBridgePlugPair.get("cumulativeBridgePlug");
+                                cumulativeBridgePlugPair.put("cumulativeBridgePlug", tempTotalBridgePlug.add(tempBridgePlug));
+                            } else {
+                                cumulativeBridgePlugPair.put("cumulativeBridgePlug", tempTotalBridgePlug);
+                            }
+                        }
+                        if ("趟数".equals(unit)) {
+                            tempTotalRunCount = tempTotalRunCount.add(actualValue);
+                            if (cumulativeRunCountPair.containsKey("cumulativeRunCount")) {
+                                BigDecimal tempRunCount = cumulativeRunCountPair.get("cumulativeRunCount");
+                                cumulativeRunCountPair.put("cumulativeRunCount", tempTotalRunCount.add(tempRunCount));
+                            } else {
+                                cumulativeRunCountPair.put("cumulativeRunCount", tempTotalRunCount);
+                            }
+                        }
+                        if ("小时".equals(unit)) {
+                            tempTotalHourCount = tempTotalHourCount.add(actualValue);
+                            if (cumulativeHourCountPair.containsKey("cumulativeHourCount")) {
+                                BigDecimal tempHourCount = cumulativeHourCountPair.get("cumulativeHourCount");
+                                cumulativeHourCountPair.put("cumulativeHourCount", tempTotalHourCount.add(tempHourCount));
+                            } else {
+                                cumulativeHourCountPair.put("cumulativeHourCount", tempTotalHourCount);
+                            }
+                        }
+                        if ("天数".equals(unit)) {
+                            // 将 actualValue 换算成 H
+                            BigDecimal hours = actualValue.multiply(new BigDecimal("24"));
+                            tempTotalHourCount = tempTotalHourCount.add(hours);
+                            if (cumulativeHourCountPair.containsKey("cumulativeHourCount")) {
+                                BigDecimal tempHourCount = cumulativeHourCountPair.get("cumulativeHourCount");
+                                cumulativeHourCountPair.put("cumulativeHourCount", tempTotalHourCount.add(tempHourCount));
+                            } else {
+                                cumulativeHourCountPair.put("cumulativeHourCount", tempTotalHourCount);
+                            }
+                        }
+                        if ("方".equals(unit)) {
+                            tempTotalWaterVolume = tempTotalWaterVolume.add(actualValue);
+                            if (cumulativeWaterVolumePair.containsKey("cumulativeWaterVolume")) {
+                                BigDecimal tempWaterVolume = cumulativeWaterVolumePair.get("cumulativeWaterVolume");
+                                cumulativeWaterVolumePair.put("cumulativeWaterVolume", tempTotalWaterVolume.add(tempWaterVolume));
+                            } else {
+                                cumulativeWaterVolumePair.put("cumulativeWaterVolume", tempTotalWaterVolume);
+                            }
+                        }
+                        if ("井数".equals(unit)) {
+                            tempTotalCumulativeWorkingWell = tempTotalCumulativeWorkingWell.add(actualValue);
+                            if (cumulativeWorkingWellPair.containsKey("cumulativeWorkingWell")) {
+                                BigDecimal tempWorkingWell = cumulativeWorkingWellPair.get("cumulativeWorkingWell");
+                                cumulativeWorkingWellPair.put("cumulativeWorkingWell", tempTotalCumulativeWorkingWell.add(tempWorkingWell));
+                            } else {
+                                cumulativeWorkingWellPair.put("cumulativeWorkingWell", tempTotalCumulativeWorkingWell);
+                            }
+                        }
+                        if ("段数".equals(unit)) {
+                            // 累计施工层
+                            tempTotalCumulativeWorkingLayers = tempTotalCumulativeWorkingLayers.add(actualValue);
+                            if (cumulativeWorkingLayersPair.containsKey("cumulativeWorkingLayers")) {
+                                BigDecimal tempWorkingLayer = cumulativeWorkingLayersPair.get("cumulativeWorkingLayers");
+                                cumulativeWorkingLayersPair.put("cumulativeWorkingLayers", tempTotalCumulativeWorkingLayers.add(tempWorkingLayer));
+                            } else {
+                                cumulativeWorkingLayersPair.put("cumulativeWorkingLayers", tempTotalCumulativeWorkingLayers);
+                            }
+                        }
+                        if ("台次".equals(unit) && "当日泵车台次".equals(attr.getName())) {
+                            tempTotalPumpTrips = tempTotalPumpTrips.add(actualValue);
+                            if (cumulativePumpTripsPair.containsKey("cumulativePumpTrips")) {
+                                BigDecimal tempPumpTrips = cumulativePumpTripsPair.get("cumulativePumpTrips");
+                                cumulativePumpTripsPair.put("cumulativePumpTrips", tempTotalPumpTrips.add(tempPumpTrips));
+                            } else {
+                                cumulativePumpTripsPair.put("cumulativePumpTrips", tempTotalPumpTrips);
+                            }
+                        }
+                        if ("台次".equals(unit) && ("当日仪表/混砂".equals(attr.getName())
+                                || "当日混砂".equals(attr.getName()) || "当日仪表".equals(attr.getName()))) {
+                            tempTotalMixSand = tempTotalMixSand.add(actualValue);
+                            if (cumulativeMixSandPair.containsKey("cumulativeMixSand")) {
+                                BigDecimal tempMixSand = cumulativeMixSandPair.get("cumulativeMixSand");
+                                cumulativeMixSandPair.put("cumulativeMixSand", tempTotalMixSand.add(tempMixSand));
+                            } else {
+                                cumulativeMixSandPair.put("cumulativeMixSand", tempTotalMixSand);
+                            }
+                        }
+                    }
+                }
+            });
+        }
+        if (CollUtil.isNotEmpty(cumulativeBridgePlugPair)) {
+            Collection<BigDecimal> cumulativeBridgePlugs = cumulativeBridgePlugPair.values();
+            Optional<BigDecimal> bridgePlugs = cumulativeBridgePlugs.stream().findAny();
+            BigDecimal bridgePlug = bridgePlugs.get();
+            IotRdDailyReportStatisticsRespVO bridgePlugResp = new IotRdDailyReportStatisticsRespVO();
+            bridgePlugResp.setCumulativeBridgePlug(bridgePlug);
+            bridgePlugResp.setDeptName("cumulativeBridgePlug");
+            result.add(bridgePlugResp);
+        }
+        if (CollUtil.isNotEmpty(cumulativeRunCountPair)) {
+            Collection<BigDecimal> cumulativeRunCounts = cumulativeRunCountPair.values();
+            Optional<BigDecimal> runCounts = cumulativeRunCounts.stream().findAny();
+            BigDecimal runCount = runCounts.get();
+            IotRdDailyReportStatisticsRespVO runCountResp = new IotRdDailyReportStatisticsRespVO();
+            runCountResp.setCumulativeRunCount(runCount);
+            runCountResp.setDeptName("cumulativeRunCount");
+            result.add(runCountResp);
+        }
+        if (CollUtil.isNotEmpty(cumulativeHourCountPair)) {
+            Collection<BigDecimal> cumulativeHourCounts = cumulativeHourCountPair.values();
+            Optional<BigDecimal> hourCounts = cumulativeHourCounts.stream().findAny();
+            BigDecimal hourCount = hourCounts.get();
+            IotRdDailyReportStatisticsRespVO hourCountResp = new IotRdDailyReportStatisticsRespVO();
+            hourCountResp.setCumulativeHourCount(hourCount);
+            hourCountResp.setDeptName("cumulativeHourCount");
+            result.add(hourCountResp);
+        }
+        if (CollUtil.isNotEmpty(cumulativeWaterVolumePair)) {
+            Collection<BigDecimal> cumulativeWaterVolumes = cumulativeWaterVolumePair.values();
+            Optional<BigDecimal> waterVolumes = cumulativeWaterVolumes.stream().findAny();
+            BigDecimal waterVolume = waterVolumes.get();
+            IotRdDailyReportStatisticsRespVO waterVolumeResp = new IotRdDailyReportStatisticsRespVO();
+            waterVolumeResp.setCumulativeWaterVolume(waterVolume);
+            waterVolumeResp.setDeptName("cumulativeWaterVolume");
+            result.add(waterVolumeResp);
+        }
+        if (CollUtil.isNotEmpty(cumulativeWorkingWellPair)) {
+            Collection<BigDecimal> cumulativeWorkingWells = cumulativeWorkingWellPair.values();
+            Optional<BigDecimal> workingWells = cumulativeWorkingWells.stream().findAny();
+            BigDecimal workingWell = workingWells.get();
+            IotRdDailyReportStatisticsRespVO workingWellResp = new IotRdDailyReportStatisticsRespVO();
+            workingWellResp.setCumulativeWorkingWell(workingWell);
+            workingWellResp.setDeptName("cumulativeWorkingWell");
+            result.add(workingWellResp);
+        }
+        if (CollUtil.isNotEmpty(cumulativeWorkingLayersPair)) {
+            Collection<BigDecimal> cumulativeWorkingLayers = cumulativeWorkingLayersPair.values();
+            Optional<BigDecimal> workingLayers = cumulativeWorkingLayers.stream().findAny();
+            BigDecimal workingLayer = workingLayers.get();
+            IotRdDailyReportStatisticsRespVO workingLayerResp = new IotRdDailyReportStatisticsRespVO();
+            workingLayerResp.setCumulativeWorkingLayers(workingLayer);
+            workingLayerResp.setDeptName("cumulativeWorkingLayers");
+            result.add(workingLayerResp);
+        }
+        if (CollUtil.isNotEmpty(cumulativePumpTripsPair)) {
+            Collection<BigDecimal> cumulativePumpTrips = cumulativePumpTripsPair.values();
+            Optional<BigDecimal> pumpTrips = cumulativePumpTrips.stream().findAny();
+            BigDecimal pumpTrip = pumpTrips.get();
+            IotRdDailyReportStatisticsRespVO pumpTripResp = new IotRdDailyReportStatisticsRespVO();
+            pumpTripResp.setCumulativePumpTrips(pumpTrip);
+            pumpTripResp.setDeptName("cumulativePumpTrips");
+            result.add(pumpTripResp);
+        }
+        if (CollUtil.isNotEmpty(cumulativeMixSandPair)) {
+            Collection<BigDecimal> cumulativeMixSands = cumulativeMixSandPair.values();
+            Optional<BigDecimal> mixSands = cumulativeMixSands.stream().findAny();
+            BigDecimal mixSand = mixSands.get();
+            IotRdDailyReportStatisticsRespVO mixSandResp = new IotRdDailyReportStatisticsRespVO();
+            mixSandResp.setCumulativeMixSand(mixSand);
+            mixSandResp.setDeptName("cumulativeMixSand");
+            result.add(mixSandResp);
+        }
+        if (CollUtil.isNotEmpty(cumulativeFuelsPair)) {
+            Collection<BigDecimal> cumulativeFuels = cumulativeFuelsPair.values();
+            Optional<BigDecimal> Fuels = cumulativeFuels.stream().findAny();
+            BigDecimal fuels = Fuels.get();
+            IotRdDailyReportStatisticsRespVO fuelsResp = new IotRdDailyReportStatisticsRespVO();
+            fuelsResp.setTotalDailyFuel(fuels);
+            fuelsResp.setDeptName("cumulativeFuels");
+            result.add(fuelsResp);
+        }
+        return result;
+    }
+
+    /**
+     * 按项目部维度 汇总 统计数据
+     * @param dailyReports 日报数据列表
+     * @param rootDeptId 根部门ID(如 163L为 瑞都 根部门,或其他公司级部门ID)
+     * @return 项目部维度统计结果列表
+     */
+    private List<IotRdDailyReportStatisticsRespVO> statisticsByProjectDept(List<IotRdDailyReportDO> dailyReports,
+                                                                           Long rootDeptId, IotRdDailyReportPageReqVO pageReqVO) {
+        List<IotRdDailyReportStatisticsRespVO> result = new ArrayList<>();
+
+        Set<Long> projectDeptIds = new HashSet<>();
+        // key项目部id    value项目部名称
+        Map<Long, DeptDO> projectDeptPair = new HashMap<>();
+        // key部门id   value部门parentId
+        Map<Long, Long> teamProjectIdPair = new HashMap<>();
+        // key队伍id    value队伍部门
+        Map<Long, DeptDO> teamDeptPair = new HashMap<>();
+
+        // key队伍id/项目部id   value累计 桥塞(个数)
+        Map<Long, BigDecimal> cumulativeBridgePlugPair = new HashMap<>();
+        // key队伍id/项目部id   value累计 趟数
+        Map<Long, BigDecimal> cumulativeRunCountPair = new HashMap<>();
+        // key队伍id/项目部id   value累计 井数
+        Map<Long, BigDecimal> cumulativeWorkingWellPair = new HashMap<>();
+        // key队伍id/项目部id   value累计 小时H
+        Map<Long, BigDecimal> cumulativeHourCountPair = new HashMap<>();
+        // key队伍id/项目部id   value累计 油耗
+        Map<Long, BigDecimal> cumulativeFuelsPair = new HashMap<>();
+        // key队伍id/项目部id   value累计 水方量(方)
+        Map<Long, BigDecimal> cumulativeWaterVolumePair = new HashMap<>();
+        // key队伍id/项目部id   value累计 段数 累计施工-层
+        Map<Long, BigDecimal> cumulativeWorkingLayersPair = new HashMap<>();
+        // key队伍id/项目部id   value累计 台次 当日仪表/混砂
+        Map<Long, BigDecimal> cumulativeMixSandPair = new HashMap<>();
+        // key队伍id/项目部id   value累计 台次 当日泵车台次
+        Map<Long, BigDecimal> cumulativePumpTripsPair = new HashMap<>();
+
+        // 队伍id 集合
+        Set<Long> teamIds = new HashSet<>();
+
+        // 以项目部为维度统计数据
+        // 找到所有项目部与队伍的对应关系
+        // 查询指定根部门下的所有子部门
+        Set<Long> allRhChildDeptIds = deptService.getChildDeptIdListFromCache(rootDeptId);
+        DeptListReqVO reqVO = new DeptListReqVO();
+        reqVO.setDeptIds(allRhChildDeptIds);
+        List<DeptDO> depts = deptService.getDeptList(reqVO);
+
+        // 构建项目部映射和父子部门关系 瑞都存在日报部门是项目部的情况
+        depts.forEach(dept -> {
+            if ("2".equals(dept.getType())) {
+                // 项目部
+                projectDeptIds.add(dept.getId());
+                projectDeptPair.put(dept.getId(), dept);
+            }
+            if ("3".equals(dept.getType())) {
+                // 队伍
+                teamIds.add(dept.getId());
+                teamDeptPair.put(dept.getId(), dept);
+            }
+            // 可能是项目部 也可能是队伍
+            teamProjectIdPair.put(dept.getId(), dept.getParentId());
+        });
+
+        // 累计计算各项 工作量
+        if (CollUtil.isNotEmpty(dailyReports)) {
+            dailyReports.forEach(report -> {
+                BigDecimal dailyFuel = report.getDailyFuel();
+                dailyFuel = ObjUtil.isEmpty(dailyFuel) ? BigDecimal.ZERO : dailyFuel;
+
+                if (ObjUtil.isNotEmpty(report.getDeptId()) && teamProjectIdPair.containsKey(report.getDeptId())) {
+                    // projectDeptId可能是项目部 也可能是项目的上级
+                    Long projectDeptId = 0l;
+                    if (teamDeptPair.containsKey(report.getDeptId())) {
+                        // 日报deptId如果是队伍 获取队伍的上级项目部
+                        projectDeptId = teamProjectIdPair.get(report.getDeptId());
+                    }
+                    if (projectDeptPair.containsKey(report.getDeptId())) {
+                        // 日报deptId如果是项目部 使用当前项目部
+                        projectDeptId = report.getDeptId();
+                    }
+                    if (ObjUtil.isNotEmpty(projectDeptId) && (projectDeptId > 0)) {
+                        if (cumulativeFuelsPair.containsKey(projectDeptId)) {
+                            BigDecimal existTotalFuel = cumulativeFuelsPair.get(projectDeptId);
+                            BigDecimal tempTotalFuel = existTotalFuel.add(dailyFuel);
+                            cumulativeFuelsPair.put(projectDeptId, tempTotalFuel);
+                        } else {
+                            cumulativeFuelsPair.put(projectDeptId, dailyFuel);
+                        }
+
+                        // 设置每个任务的工作量数据  单位相同的工作量值作合并处理
+                        List<IotTaskAttrModelProperty> taskAttrs = report.getExtProperty();
+                        // 暂存不同单位的工作量属性值
+                        BigDecimal tempTotalBridgePlug = BigDecimal.ZERO;               // 桥塞(个数)
+                        BigDecimal tempTotalRunCount = BigDecimal.ZERO;                 // 趟数
+                        BigDecimal tempTotalCumulativeWorkingWell = BigDecimal.ZERO;    // 井数
+                        BigDecimal tempTotalHourCount = BigDecimal.ZERO;                // 小时H
+                        BigDecimal tempTotalWaterVolume = BigDecimal.ZERO;              // 水方量(方)
+                        BigDecimal tempTotalPumpTrips = BigDecimal.ZERO;                // 泵车 台次
+                        BigDecimal tempTotalCumulativeWorkingLayers = BigDecimal.ZERO;  // 段数 累计施工-层
+                        BigDecimal tempTotalMixSand = BigDecimal.ZERO;                  // 台次 当日仪表/混砂
+                        if (CollUtil.isNotEmpty(taskAttrs)) {
+                            for (IotTaskAttrModelProperty attr : taskAttrs) {
+                                String unit = attr.getUnit();   // 工作量单位
+                                String actualValueStr = attr.getActualValue();  // 工作量属性的实际值
+                                // 处理实际值:避免null或非数字字符串导致的异常
+                                BigDecimal actualValue = BigDecimal.ZERO;
+                                if (StrUtil.isNotBlank(actualValueStr)) {  // 假设使用Hutool的StrUtil,或自行判断null/空
+                                    try {
+                                        actualValue = new BigDecimal(actualValueStr);
+                                    } catch (NumberFormatException e) {
+                                        // 若字符串格式错误,默认按0处理(可根据业务调整)
+                                        actualValue = BigDecimal.ZERO;
+                                    }
+                                }
+                                if ("个数".equals(unit)) {
+                                    // 钻可溶桥塞  钻复合桥塞
+                                    tempTotalBridgePlug = tempTotalBridgePlug.add(actualValue);
+                                    if (cumulativeBridgePlugPair.containsKey(projectDeptId)) {
+                                        BigDecimal tempBridgePlug = cumulativeBridgePlugPair.get(projectDeptId);
+                                        cumulativeBridgePlugPair.put(projectDeptId, tempTotalBridgePlug.add(tempBridgePlug));
+                                    } else {
+                                        cumulativeBridgePlugPair.put(projectDeptId, tempTotalBridgePlug);
+                                    }
+                                }
+                                if ("趟数".equals(unit)) {
+                                    tempTotalRunCount = tempTotalRunCount.add(actualValue);
+                                    if (cumulativeRunCountPair.containsKey(projectDeptId)) {
+                                        BigDecimal tempRunCount = cumulativeRunCountPair.get(projectDeptId);
+                                        cumulativeRunCountPair.put(projectDeptId, tempTotalRunCount.add(tempRunCount));
+                                    } else {
+                                        cumulativeRunCountPair.put(projectDeptId, tempTotalRunCount);
+                                    }
+                                }
+                                if ("小时".equals(unit)) {
+                                    tempTotalHourCount = tempTotalHourCount.add(actualValue);
+                                    if (cumulativeHourCountPair.containsKey(projectDeptId)) {
+                                        BigDecimal tempHourCount = cumulativeHourCountPair.get(projectDeptId);
+                                        cumulativeHourCountPair.put(projectDeptId, tempTotalHourCount.add(tempHourCount));
+                                    } else {
+                                        cumulativeHourCountPair.put(projectDeptId, tempTotalHourCount);
+                                    }
+                                }
+                                if ("天数".equals(unit)) {
+                                    // 将 actualValue 换算成 H
+                                    BigDecimal hours = actualValue.multiply(new BigDecimal("24"));
+                                    tempTotalHourCount = tempTotalHourCount.add(hours);
+                                    if (cumulativeHourCountPair.containsKey(projectDeptId)) {
+                                        BigDecimal tempHourCount = cumulativeHourCountPair.get(projectDeptId);
+                                        cumulativeHourCountPair.put(projectDeptId, tempTotalHourCount.add(tempHourCount));
+                                    } else {
+                                        cumulativeHourCountPair.put(projectDeptId, tempTotalHourCount);
+                                    }
+                                }
+                                if ("方".equals(unit)) {
+                                    tempTotalWaterVolume = tempTotalWaterVolume.add(actualValue);
+                                    if (cumulativeWaterVolumePair.containsKey(projectDeptId)) {
+                                        BigDecimal tempWaterVolume = cumulativeWaterVolumePair.get(projectDeptId);
+                                        cumulativeWaterVolumePair.put(projectDeptId, tempTotalWaterVolume.add(tempWaterVolume));
+                                    } else {
+                                        cumulativeWaterVolumePair.put(projectDeptId, tempTotalWaterVolume);
+                                    }
+                                }
+                                if ("井数".equals(unit)) {
+                                    tempTotalCumulativeWorkingWell = tempTotalCumulativeWorkingWell.add(actualValue);
+                                    if (cumulativeWorkingWellPair.containsKey(projectDeptId)) {
+                                        BigDecimal tempWorkingWell = cumulativeWorkingWellPair.get(projectDeptId);
+                                        cumulativeWorkingWellPair.put(projectDeptId, tempTotalCumulativeWorkingWell.add(tempWorkingWell));
+                                    } else {
+                                        cumulativeWorkingWellPair.put(projectDeptId, tempTotalCumulativeWorkingWell);
+                                    }
+                                }
+                                if ("段数".equals(unit)) {
+                                    // 累计施工层
+                                    tempTotalCumulativeWorkingLayers = tempTotalCumulativeWorkingLayers.add(actualValue);
+                                    if (cumulativeWorkingLayersPair.containsKey(projectDeptId)) {
+                                        BigDecimal tempWorkingLayer = cumulativeWorkingLayersPair.get(projectDeptId);
+                                        cumulativeWorkingLayersPair.put(projectDeptId, tempTotalCumulativeWorkingLayers.add(tempWorkingLayer));
+                                    } else {
+                                        cumulativeWorkingLayersPair.put(projectDeptId, tempTotalCumulativeWorkingLayers);
+                                    }
+                                }
+                                if ("台次".equals(unit) && "当日泵车台次".equals(attr.getName())) {
+                                    tempTotalPumpTrips = tempTotalPumpTrips.add(actualValue);
+                                    if (cumulativePumpTripsPair.containsKey(projectDeptId)) {
+                                        BigDecimal tempPumpTrips = cumulativePumpTripsPair.get(projectDeptId);
+                                        cumulativePumpTripsPair.put(projectDeptId, tempTotalPumpTrips.add(tempPumpTrips));
+                                    } else {
+                                        cumulativePumpTripsPair.put(projectDeptId, tempTotalPumpTrips);
+                                    }
+                                }
+                                if ("台次".equals(unit) && ("当日仪表/混砂".equals(attr.getName())
+                                        || "当日混砂".equals(attr.getName()) || "当日仪表".equals(attr.getName()))) {
+                                    tempTotalMixSand = tempTotalMixSand.add(actualValue);
+                                    if (cumulativeMixSandPair.containsKey(projectDeptId)) {
+                                        BigDecimal tempMixSand = cumulativeMixSandPair.get(projectDeptId);
+                                        cumulativeMixSandPair.put(projectDeptId, tempTotalMixSand.add(tempMixSand));
+                                    } else {
+                                        cumulativeMixSandPair.put(projectDeptId, tempTotalMixSand);
+                                    }
+                                }
+                            }
+                        }
+                        // 桥塞(个数)
+                        // 趟数
+                        // 井数
+                        // 小时H
+                        // 油耗L
+                        // 水方量(方)
+                        // 段数 累计施工-层
+                        // 台次 当日仪表/混砂
+                        // 台次 当日泵车台次
+                    }
+                }
+            });
+        }
+
+        // 生成返回的数据列表集合
+        projectDeptPair.forEach((deptId, dept) -> {
+            IotRdDailyReportStatisticsRespVO statistics = new IotRdDailyReportStatisticsRespVO();
+            statistics.setProjectDeptId(deptId);
+            statistics.setProjectDeptName(dept.getName());
+            statistics.setSort(dept.getSort());
+            statistics.setType("2");
+            statistics.setCumulativeBridgePlug(cumulativeBridgePlugPair.get(deptId));
+            statistics.setCumulativeRunCount(cumulativeRunCountPair.get(deptId));
+            statistics.setCumulativeWorkingWell(cumulativeWorkingWellPair.get(deptId));
+            statistics.setCumulativeHourCount(cumulativeHourCountPair.get(deptId));
+            statistics.setCumulativeWaterVolume(cumulativeWaterVolumePair.get(deptId));
+            statistics.setCumulativeWorkingLayers(cumulativeWorkingLayersPair.get(deptId));
+            statistics.setCumulativeMixSand(cumulativeMixSandPair.get(deptId));
+            statistics.setCumulativePumpTrips(cumulativePumpTripsPair.get(deptId));
+            statistics.setTotalDailyFuel(cumulativeFuelsPair.get(deptId));
+            result.add(statistics);
+        });
+
+        return result;
+    }
+
+    /**
+     * 按 队伍 维度统计 汇总 数据
+     * @param dailyReports 日报数据列表
+     * @param deptId 项目部ID 或 队伍id
+     * @return 队伍 维度统计结果列表
+     */
+    private List<IotRdDailyReportStatisticsRespVO> statisticsByProjectDepartment(List<IotRdDailyReportDO> dailyReports, Long deptId) {
+        List<IotRdDailyReportStatisticsRespVO> result = new ArrayList<>();
+
+        Set<Long> projectDeptIds = new HashSet<>();
+        // key项目部id    value项目部名称
+        Map<Long, DeptDO> projectDeptPair = new HashMap<>();
+        // key队伍id    value队伍名称
+        Map<Long, DeptDO> teamDeptPair = new HashMap<>();
+        // key部门id   value部门parentId
+        Map<Long, Long> teamProjectIdPair = new HashMap<>();
+
+        // key队伍id/项目部id   value累计 桥塞(个数)
+        Map<Long, BigDecimal> cumulativeBridgePlugPair = new HashMap<>();
+        // key队伍id/项目部id   value累计 趟数
+        Map<Long, BigDecimal> cumulativeRunCountPair = new HashMap<>();
+        // key队伍id/项目部id   value累计 井数
+        Map<Long, BigDecimal> cumulativeWorkingWellPair = new HashMap<>();
+        // key队伍id/项目部id   value累计 小时H
+        Map<Long, BigDecimal> cumulativeHourCountPair = new HashMap<>();
+        // key队伍id/项目部id   value累计 油耗
+        Map<Long, BigDecimal> cumulativeFuelsPair = new HashMap<>();
+        // key队伍id/项目部id   value累计 水方量(方)
+        Map<Long, BigDecimal> cumulativeWaterVolumePair = new HashMap<>();
+        // key队伍id/项目部id   value累计 段数 累计施工-层
+        Map<Long, BigDecimal> cumulativeWorkingLayersPair = new HashMap<>();
+        // key队伍id/项目部id   value累计 台次 当日仪表/混砂
+        Map<Long, BigDecimal> cumulativeMixSandPair = new HashMap<>();
+        // key队伍id/项目部id   value累计 台次 当日泵车台次
+        Map<Long, BigDecimal> cumulativePumpTripsPair = new HashMap<>();
+
+        // 以 队伍 为维度统计数据
+        // 找到所有项目部与队伍的对应关系
+        // 查询指定根部门下的所有子部门
+        Set<Long> allRhChildDeptIds = deptService.getChildDeptIdListFromCache(deptId);
+        DeptListReqVO reqVO = new DeptListReqVO();
+        // 查询某支队伍 或 所属项目部的信息
+        allRhChildDeptIds.add(deptId);
+        reqVO.setDeptIds(allRhChildDeptIds);
+        List<DeptDO> depts = deptService.getDeptList(reqVO);
+
+        // 构建项目部映射和父子部门关系
+        depts.forEach(dept -> {
+            if ("3".equals(dept.getType())) {
+                // 队伍
+                projectDeptIds.add(dept.getId());
+                teamDeptPair.put(dept.getId(), dept);
+            }
+            if ("2".equals(dept.getType())) {
+                // 项目部
+                projectDeptPair.put(dept.getId(), dept);
+            }
+            teamProjectIdPair.put(dept.getId(), dept.getParentId());
+        });
+
+        // 因为有的日报是挂在项目部下 所以 点击某个项目部最好是同时展示 项目部和队伍的数据
+
+        // 累计计算 工作量
+        if (CollUtil.isNotEmpty(dailyReports)) {
+            dailyReports.forEach(report -> {
+                BigDecimal dailyFuel = report.getDailyFuel();
+                dailyFuel = ObjUtil.isEmpty(dailyFuel) ? BigDecimal.ZERO : dailyFuel;
+                if (ObjUtil.isNotEmpty(report.getDeptId()) && teamProjectIdPair.containsKey(report.getDeptId())) {
+                    // projectDeptId可能是项目部 也可能是项目的上级
+                    Long detailDeptId = 0l;
+                    if (teamDeptPair.containsKey(report.getDeptId())) {
+                        // 日报deptId如果是队伍 获取队伍的上级项目部
+                        detailDeptId = teamProjectIdPair.get(report.getDeptId());
+                    }
+                    if (projectDeptPair.containsKey(report.getDeptId())) {
+                        // 日报deptId如果是项目部 使用当前项目部
+                        detailDeptId = report.getDeptId();
+                    }
+                    if (ObjUtil.isNotEmpty(detailDeptId) && (detailDeptId > 0)) {
+                        if (cumulativeFuelsPair.containsKey(detailDeptId)) {
+                            BigDecimal existTotalFuel = cumulativeFuelsPair.get(detailDeptId);
+                            BigDecimal tempTotalFuel = existTotalFuel.add(dailyFuel);
+                            cumulativeFuelsPair.put(detailDeptId, tempTotalFuel);
+                        } else {
+                            cumulativeFuelsPair.put(detailDeptId, dailyFuel);
+                        }
+
+                        // 设置每个任务的工作量数据  单位相同的工作量值作合并处理
+                        List<IotTaskAttrModelProperty> taskAttrs = report.getExtProperty();
+                        // 暂存不同单位的工作量属性值
+                        BigDecimal tempTotalBridgePlug = BigDecimal.ZERO;               // 桥塞(个数)
+                        BigDecimal tempTotalRunCount = BigDecimal.ZERO;                 // 趟数
+                        BigDecimal tempTotalCumulativeWorkingWell = BigDecimal.ZERO;    // 井数
+                        BigDecimal tempTotalHourCount = BigDecimal.ZERO;                // 小时H
+                        BigDecimal tempTotalWaterVolume = BigDecimal.ZERO;              // 水方量(方)
+                        BigDecimal tempTotalPumpTrips = BigDecimal.ZERO;                // 泵车 台次
+                        BigDecimal tempTotalCumulativeWorkingLayers = BigDecimal.ZERO;  // 段数 累计施工-层
+                        BigDecimal tempTotalMixSand = BigDecimal.ZERO;                  // 台次 当日仪表/混砂
+                        if (CollUtil.isNotEmpty(taskAttrs)) {
+                            for (IotTaskAttrModelProperty attr : taskAttrs) {
+                                String unit = attr.getUnit();   // 工作量单位
+                                String actualValueStr = attr.getActualValue();  // 工作量属性的实际值
+                                // 处理实际值:避免null或非数字字符串导致的异常
+                                BigDecimal actualValue = BigDecimal.ZERO;
+                                if (StrUtil.isNotBlank(actualValueStr)) {
+                                    try {
+                                        actualValue = new BigDecimal(actualValueStr);
+                                    } catch (NumberFormatException e) {
+                                        // 若字符串格式错误,默认按0处理(可根据业务调整)
+                                        actualValue = BigDecimal.ZERO;
+                                    }
+                                }
+                                if ("个数".equals(unit)) {
+                                    // 钻可溶桥塞  钻复合桥塞
+                                    tempTotalBridgePlug = tempTotalBridgePlug.add(actualValue);
+                                    if (cumulativeBridgePlugPair.containsKey(detailDeptId)) {
+                                        BigDecimal tempBridgePlug = cumulativeBridgePlugPair.get(detailDeptId);
+                                        cumulativeBridgePlugPair.put(detailDeptId, tempTotalBridgePlug.add(tempBridgePlug));
+                                    } else {
+                                        cumulativeBridgePlugPair.put(detailDeptId, tempTotalBridgePlug);
+                                    }
+                                }
+                                if ("趟数".equals(unit)) {
+                                    tempTotalRunCount = tempTotalRunCount.add(actualValue);
+                                    if (cumulativeRunCountPair.containsKey(detailDeptId)) {
+                                        BigDecimal tempRunCount = cumulativeRunCountPair.get(detailDeptId);
+                                        cumulativeRunCountPair.put(detailDeptId, tempTotalRunCount.add(tempRunCount));
+                                    } else {
+                                        cumulativeRunCountPair.put(detailDeptId, tempTotalRunCount);
+                                    }
+                                }
+                                if ("小时".equals(unit)) {
+                                    tempTotalHourCount = tempTotalHourCount.add(actualValue);
+                                    if (cumulativeHourCountPair.containsKey(detailDeptId)) {
+                                        BigDecimal tempHourCount = cumulativeHourCountPair.get(detailDeptId);
+                                        cumulativeHourCountPair.put(detailDeptId, tempTotalHourCount.add(tempHourCount));
+                                    } else {
+                                        cumulativeHourCountPair.put(detailDeptId, tempTotalHourCount);
+                                    }
+                                }
+                                if ("天数".equals(unit)) {
+                                    // 将 actualValue 换算成 H
+                                    BigDecimal hours = actualValue.multiply(new BigDecimal("24"));
+                                    tempTotalHourCount = tempTotalHourCount.add(hours);
+                                    if (cumulativeHourCountPair.containsKey(detailDeptId)) {
+                                        BigDecimal tempHourCount = cumulativeHourCountPair.get(detailDeptId);
+                                        cumulativeHourCountPair.put(detailDeptId, tempTotalHourCount.add(tempHourCount));
+                                    } else {
+                                        cumulativeHourCountPair.put(detailDeptId, tempTotalHourCount);
+                                    }
+                                }
+                                if ("方".equals(unit)) {
+                                    tempTotalWaterVolume = tempTotalWaterVolume.add(actualValue);
+                                    if (cumulativeWaterVolumePair.containsKey(detailDeptId)) {
+                                        BigDecimal tempWaterVolume = cumulativeWaterVolumePair.get(detailDeptId);
+                                        cumulativeWaterVolumePair.put(detailDeptId, tempTotalWaterVolume.add(tempWaterVolume));
+                                    } else {
+                                        cumulativeWaterVolumePair.put(detailDeptId, tempTotalWaterVolume);
+                                    }
+                                }
+                                if ("井数".equals(unit)) {
+                                    tempTotalCumulativeWorkingWell = tempTotalCumulativeWorkingWell.add(actualValue);
+                                    if (cumulativeWorkingWellPair.containsKey(detailDeptId)) {
+                                        BigDecimal tempWorkingWell = cumulativeWorkingWellPair.get(detailDeptId);
+                                        cumulativeWorkingWellPair.put(detailDeptId, tempTotalCumulativeWorkingWell.add(tempWorkingWell));
+                                    } else {
+                                        cumulativeWorkingWellPair.put(detailDeptId, tempTotalCumulativeWorkingWell);
+                                    }
+                                }
+                                if ("段数".equals(unit)) {
+                                    // 累计施工层
+                                    tempTotalCumulativeWorkingLayers = tempTotalCumulativeWorkingLayers.add(actualValue);
+                                    if (cumulativeWorkingLayersPair.containsKey(detailDeptId)) {
+                                        BigDecimal tempWorkingLayer = cumulativeWorkingLayersPair.get(detailDeptId);
+                                        cumulativeWorkingLayersPair.put(detailDeptId, tempTotalCumulativeWorkingLayers.add(tempWorkingLayer));
+                                    } else {
+                                        cumulativeWorkingLayersPair.put(detailDeptId, tempTotalCumulativeWorkingLayers);
+                                    }
+                                }
+                                if ("台次".equals(unit) && "当日泵车台次".equals(attr.getName())) {
+                                    tempTotalPumpTrips = tempTotalPumpTrips.add(actualValue);
+                                    if (cumulativePumpTripsPair.containsKey(detailDeptId)) {
+                                        BigDecimal tempPumpTrips = cumulativePumpTripsPair.get(detailDeptId);
+                                        cumulativePumpTripsPair.put(detailDeptId, tempTotalPumpTrips.add(tempPumpTrips));
+                                    } else {
+                                        cumulativePumpTripsPair.put(detailDeptId, tempTotalPumpTrips);
+                                    }
+                                }
+                                if ("台次".equals(unit) && ("当日仪表/混砂".equals(attr.getName())
+                                        || "当日混砂".equals(attr.getName()) || "当日仪表".equals(attr.getName()))) {
+                                    tempTotalMixSand = tempTotalMixSand.add(actualValue);
+                                    if (cumulativeMixSandPair.containsKey(detailDeptId)) {
+                                        BigDecimal tempMixSand = cumulativeMixSandPair.get(detailDeptId);
+                                        cumulativeMixSandPair.put(detailDeptId, tempTotalMixSand.add(tempMixSand));
+                                    } else {
+                                        cumulativeMixSandPair.put(detailDeptId, tempTotalMixSand);
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            });
+        }
+
+        // 生成返回的数据列表集合
+        teamDeptPair.forEach((teamDeptId, dept) -> {
+            IotRdDailyReportStatisticsRespVO statistics = new IotRdDailyReportStatisticsRespVO();
+            statistics.setTeamId(teamDeptId);
+            statistics.setTeamName(dept.getName());
+            statistics.setSort(dept.getSort());
+            if (teamDeptPair.containsKey(teamDeptId)) {
+                statistics.setType("3");    // 最好是 项目部小队同时展示 因为有的瑞都日报挂在了项目部下
+            }
+            if (projectDeptPair.containsKey(teamDeptId)) {
+                statistics.setSort(0);
+                statistics.setType("2");
+            }
+            statistics.setCumulativeBridgePlug(cumulativeBridgePlugPair.get(teamDeptId));
+            statistics.setCumulativeRunCount(cumulativeRunCountPair.get(teamDeptId));
+            statistics.setCumulativeWorkingWell(cumulativeWorkingWellPair.get(teamDeptId));
+            statistics.setCumulativeHourCount(cumulativeHourCountPair.get(teamDeptId));
+            statistics.setCumulativeWaterVolume(cumulativeWaterVolumePair.get(teamDeptId));
+            statistics.setCumulativeWorkingLayers(cumulativeWorkingLayersPair.get(teamDeptId));
+            statistics.setCumulativeMixSand(cumulativeMixSandPair.get(teamDeptId));
+            statistics.setCumulativePumpTrips(cumulativePumpTripsPair.get(teamDeptId));
+            statistics.setTotalDailyFuel(cumulativeFuelsPair.get(teamDeptId));
+            result.add(statistics);
+        });
+
+        return result;
+    }
+
     @Override
     public List<IotRdDailyReportPolylineVO> polylineStatistics(IotRdDailyReportPageReqVO pageReqVO) {
         List<IotRdDailyReportPolylineVO> result = new ArrayList<>();
-        // 默认查询当年工作量
+        // 查询折线趋势图必须 传递时间参数
         if (ObjUtil.isEmpty(pageReqVO.getCreateTime())) {
             throw exception(IOT_DAILY_REPORT_TIME_NOT_EXISTS);
         }
+        Set<Long> ids = new HashSet<>();
+        if (Objects.nonNull(pageReqVO.getDeptId())) {
+            ids = deptService.getChildDeptIdListFromCache(pageReqVO.getDeptId());
+            // 找到所有子部门对象集合
+            ids.add(pageReqVO.getDeptId());
+            pageReqVO.setDeptIds(ids);
+        }
+        // 检查contractName不为空但projectIds为空的情况
+        if (StrUtil.isNotBlank(pageReqVO.getContractName()) && (CollUtil.isEmpty(pageReqVO.getProjectIds()))) {
+            return new ArrayList<>();
+        }
+        // 检查taskName不为空但taskIds为空的情况
+        if (StrUtil.isNotBlank(pageReqVO.getTaskName()) && (CollUtil.isEmpty(pageReqVO.getTaskIds()))) {
+            return new ArrayList<>();
+        }
         // 筛选审核通过的数据
-        pageReqVO.setAuditStatus(20);
+        // pageReqVO.setAuditStatus(20);
         List<IotRdDailyReportDO> dailyReports = iotRdDailyReportMapper.dailyReports(pageReqVO);
         if (CollUtil.isNotEmpty(dailyReports)) {
-            // 设置 小队 任务已经完成的工作量集合 (按照不同的单位统计任务的不同工作量)
-            // key任务井id      value队伍工作量数据
-            Map<Long, BigDecimal> bridgePlugPair = new HashMap<>();
-            Map<Long, BigDecimal> runCountPair = new HashMap<>();
-            Map<Long, BigDecimal> cumulativeWorkingWellPair = new HashMap<>();
-            Map<Long, BigDecimal> hourCountPair = new HashMap<>();
-            Map<Long, BigDecimal> waterVolumePair = new HashMap<>();
-            Map<Long, BigDecimal> pumpTripsPair = new HashMap<>();
-            Map<Long, BigDecimal> cumulativeWorkingLayersPair = new HashMap<>();
-            Map<Long, BigDecimal> mixSandPair = new HashMap<>();
+            Long rootDeptId = 163l;
+            if (ObjUtil.isEmpty(pageReqVO.getDeptId())) {
+                pageReqVO.setDeptId(rootDeptId);
+            }
+            result = polylineStatisticsByProjectDept(dailyReports, pageReqVO.getDeptId(), pageReqVO.getCreateTime());
+        }
+        return result;
+    }
+
+    /**
+     * 按项 日期 维度统计 折线 工作量 数据
+     * @param dailyReports 日报数据列表
+     * @param rootDeptId 部门ID(如163L为瑞恒根部门,或其他项目部 ID)
+     * @return
+     */
+    private List<IotRdDailyReportPolylineVO> polylineStatisticsByProjectDept(List<IotRdDailyReportDO> dailyReports,
+                                                                             Long rootDeptId, LocalDateTime[] createTimes) {
+        List<IotRdDailyReportPolylineVO> result = new ArrayList<>();
+        // 按照日期维度统计数据
+        Set<Long> projectDeptIds = new HashSet<>();
+        // key项目部id    value项目部名称
+        Map<Long, DeptDO> projectDeptPair = new HashMap<>();
+        // key部门id   value部门parentId
+        Map<Long, Long> teamProjectIdPair = new HashMap<>();
+
+        // 按照日期维度统计各工作量数据
+        // key日期yyyy-MM-dd   value 累计 桥塞(个数)
+        Map<String, BigDecimal> dateBridgePlugPair = new HashMap<>();
+        // key日期yyyy-MM-dd   value 累计 趟数
+        Map<String, BigDecimal> dateRunCountPair = new HashMap<>();
+        // key日期yyyy-MM-dd   value 累计 井数
+        Map<String, BigDecimal> dateWorkingWellPair = new HashMap<>();
+        // key日期yyyy-MM-dd   value 累计 小时H
+        Map<String, BigDecimal> dateHourCountPair = new HashMap<>();
+        // key日期yyyy-MM-dd   value 累计 水方量(方)
+        Map<String, BigDecimal> dateWaterVolumePair = new HashMap<>();
+        // key日期yyyy-MM-dd   value 累计 台次 泵车
+        Map<String, BigDecimal> datePumpTripsPair = new HashMap<>();
+        // key日期yyyy-MM-dd  value 累计 段数 累计施工-层
+        Map<String, BigDecimal> dateWorkingLayersPair = new HashMap<>();
+        // key日期yyyy-MM-dd  value 累计 台次 当日仪表/混砂
+        Map<String, BigDecimal> dateMixSandPair = new HashMap<>();
+        // key日期yyyy-MM-dd  value 累计 油耗
+        Map<String, BigDecimal> dateFuelsPair = new HashMap<>();
+
+        // 以项目部为维度统计数据
+        // 找到所有项目部与队伍的对应关系
+        // 查询指定根部门下的所有子部门
+        Set<Long> allRhChildDeptIds = deptService.getChildDeptIdListFromCache(rootDeptId);
+        DeptListReqVO reqVO = new DeptListReqVO();
+        reqVO.setDeptIds(allRhChildDeptIds);
+        List<DeptDO> depts = deptService.getDeptList(reqVO);
 
-            dailyReports.forEach(report -> {});
+        // 构建项目部映射和父子部门关系
+        depts.forEach(dept -> {
+            if ("2".equals(dept.getType())) {
+                projectDeptIds.add(dept.getId());
+                projectDeptPair.put(dept.getId(), dept);
+            }
+            teamProjectIdPair.put(dept.getId(), dept.getParentId());
+        });
+
+        // 累计计算各项指标
+        if (CollUtil.isNotEmpty(dailyReports)) {
+            dailyReports.forEach(report -> {
+                BigDecimal dailyFuel = report.getDailyFuel();
+                dailyFuel = ObjUtil.isEmpty(dailyFuel) ? BigDecimal.ZERO : dailyFuel;
+
+                // 按照日期维度统计各 工作量数据 累计用电量 累计油耗 累计注气量 累计注水量
+                LocalDateTime reportLocalDate = report.getCreateTime();
+                // 将日期格式转换成 字符串
+                String reportDateStr = LocalDateTimeUtil.format(reportLocalDate, DatePattern.NORM_DATE_PATTERN);
+                if (dateFuelsPair.containsKey(reportDateStr)) {
+                    BigDecimal existTotalFuel = dateFuelsPair.get(reportDateStr);
+                    BigDecimal tempTotalFuel = existTotalFuel.add(dailyFuel);
+                    dateFuelsPair.put(reportDateStr, tempTotalFuel);
+                } else {
+                    dateFuelsPair.put(reportDateStr, dailyFuel);
+                }
+
+                // 设置每个任务的工作量数据  单位相同的工作量值作合并处理
+                List<IotTaskAttrModelProperty> taskAttrs = report.getExtProperty();
+                // 暂存不同单位的工作量属性值
+                BigDecimal tempTotalBridgePlug = BigDecimal.ZERO;               // 桥塞(个数)
+                BigDecimal tempTotalRunCount = BigDecimal.ZERO;                 // 趟数
+                BigDecimal tempTotalCumulativeWorkingWell = BigDecimal.ZERO;    // 井数
+                BigDecimal tempTotalHourCount = BigDecimal.ZERO;                // 小时H
+                BigDecimal tempTotalWaterVolume = BigDecimal.ZERO;              // 水方量(方)
+                BigDecimal tempTotalPumpTrips = BigDecimal.ZERO;                // 泵车 台次
+                BigDecimal tempTotalCumulativeWorkingLayers = BigDecimal.ZERO;  // 段数 累计施工-层
+                BigDecimal tempTotalMixSand = BigDecimal.ZERO;                  // 台次 当日仪表/混砂
+
+                if (CollUtil.isNotEmpty(taskAttrs)) {
+                    for (IotTaskAttrModelProperty attr : taskAttrs) {
+                        String unit = attr.getUnit();   // 工作量单位
+                        String actualValueStr = attr.getActualValue();  // 工作量属性的实际值
+                        // 处理实际值:避免null或非数字字符串导致的异常
+                        BigDecimal actualValue = BigDecimal.ZERO;
+                        if (StrUtil.isNotBlank(actualValueStr)) {  // 假设使用Hutool的StrUtil,或自行判断null/空
+                            try {
+                                actualValue = new BigDecimal(actualValueStr);
+                            } catch (NumberFormatException e) {
+                                // 若字符串格式错误,默认按0处理(可根据业务调整)
+                                actualValue = BigDecimal.ZERO;
+                            }
+                        }
+                        if ("个数".equals(unit)) {
+                            // 钻可溶桥塞  钻复合桥塞
+                            tempTotalBridgePlug = tempTotalBridgePlug.add(actualValue);
+                            if (dateBridgePlugPair.containsKey(reportDateStr)) {
+                                BigDecimal tempBridgePlug = dateBridgePlugPair.get(reportDateStr);
+                                dateBridgePlugPair.put(reportDateStr, tempTotalBridgePlug.add(tempBridgePlug));
+                            } else {
+                                dateBridgePlugPair.put(reportDateStr, tempTotalBridgePlug);
+                            }
+                        }
+                        if ("趟数".equals(unit)) {
+                            tempTotalRunCount = tempTotalRunCount.add(actualValue);
+                            if (dateRunCountPair.containsKey(reportDateStr)) {
+                                BigDecimal tempRunCount = dateRunCountPair.get(reportDateStr);
+                                dateRunCountPair.put(reportDateStr, tempTotalRunCount.add(tempRunCount));
+                            } else {
+                                dateRunCountPair.put(reportDateStr, tempTotalRunCount);
+                            }
+                        }
+                        if ("小时".equals(unit)) {
+                            tempTotalHourCount = tempTotalHourCount.add(actualValue);
+                            if (dateHourCountPair.containsKey(reportDateStr)) {
+                                BigDecimal tempHourCount = dateHourCountPair.get(reportDateStr);
+                                dateHourCountPair.put(reportDateStr, tempTotalHourCount.add(tempHourCount));
+                            } else {
+                                dateHourCountPair.put(reportDateStr, tempTotalHourCount);
+                            }
+                        }
+                        if ("天数".equals(unit)) {
+                            // 将 actualValue 换算成 H
+                            BigDecimal hours = actualValue.multiply(new BigDecimal("24"));
+                            tempTotalHourCount = tempTotalHourCount.add(hours);
+                            if (dateHourCountPair.containsKey(reportDateStr)) {
+                                BigDecimal tempHourCount = dateHourCountPair.get(reportDateStr);
+                                dateHourCountPair.put(reportDateStr, tempTotalHourCount.add(tempHourCount));
+                            } else {
+                                dateHourCountPair.put(reportDateStr, tempTotalHourCount);
+                            }
+                        }
+                        if ("方".equals(unit)) {
+                            tempTotalWaterVolume = tempTotalWaterVolume.add(actualValue);
+                            if (dateWaterVolumePair.containsKey(reportDateStr)) {
+                                BigDecimal tempWaterVolume = dateWaterVolumePair.get(reportDateStr);
+                                dateWaterVolumePair.put(reportDateStr, tempTotalWaterVolume.add(tempWaterVolume));
+                            } else {
+                                dateWaterVolumePair.put(reportDateStr, tempTotalWaterVolume);
+                            }
+                        }
+                        if ("井数".equals(unit)) {
+                            tempTotalCumulativeWorkingWell = tempTotalCumulativeWorkingWell.add(actualValue);
+                            if (dateWorkingWellPair.containsKey(reportDateStr)) {
+                                BigDecimal tempWorkingWell = dateWorkingWellPair.get(reportDateStr);
+                                dateWorkingWellPair.put(reportDateStr, tempTotalCumulativeWorkingWell.add(tempWorkingWell));
+                            } else {
+                                dateWorkingWellPair.put(reportDateStr, tempTotalCumulativeWorkingWell);
+                            }
+                        }
+                        if ("段数".equals(unit)) {
+                            // 累计施工层
+                            tempTotalCumulativeWorkingLayers = tempTotalCumulativeWorkingLayers.add(actualValue);
+                            if (dateWorkingLayersPair.containsKey(reportDateStr)) {
+                                BigDecimal tempWorkingLayer = dateWorkingLayersPair.get(reportDateStr);
+                                dateWorkingLayersPair.put(reportDateStr, tempTotalCumulativeWorkingLayers.add(tempWorkingLayer));
+                            } else {
+                                dateWorkingLayersPair.put(reportDateStr, tempTotalCumulativeWorkingLayers);
+                            }
+                        }
+                        if ("台次".equals(unit) && "当日泵车台次".equals(attr.getName())) {
+                            tempTotalPumpTrips = tempTotalPumpTrips.add(actualValue);
+                            if (datePumpTripsPair.containsKey(reportDateStr)) {
+                                BigDecimal tempPumpTrips = datePumpTripsPair.get(reportDateStr);
+                                datePumpTripsPair.put(reportDateStr, tempTotalPumpTrips.add(tempPumpTrips));
+                            } else {
+                                datePumpTripsPair.put(reportDateStr, tempTotalPumpTrips);
+                            }
+                        }
+                        if ("台次".equals(unit) && ("当日仪表/混砂".equals(attr.getName())
+                                || "当日混砂".equals(attr.getName()) || "当日仪表".equals(attr.getName()))) {
+                            tempTotalMixSand = tempTotalMixSand.add(actualValue);
+                            if (dateMixSandPair.containsKey(reportDateStr)) {
+                                BigDecimal tempMixSand = dateMixSandPair.get(reportDateStr);
+                                dateMixSandPair.put(reportDateStr, tempTotalMixSand.add(tempMixSand));
+                            } else {
+                                dateMixSandPair.put(reportDateStr, tempTotalMixSand);
+                            }
+                        }
+                    }
+                }
+            });
+        }
+
+        // 新增:日期字符串集合
+        List<String> dateRangeList = new ArrayList<>();
+
+        if (createTimes.length >= 2) {
+            LocalDate startDate = createTimes[0].toLocalDate();
+            LocalDate endDate = createTimes[1].toLocalDate();
+            // 生成从起始日期到结束日期的所有日期
+            for (LocalDate date = startDate;
+                 !date.isAfter(endDate);  // 使用 isAfter 而不是 <= 判断
+                 date = date.plusDays(1)) {
+                dateRangeList.add(date.format(DateTimeFormatter.ofPattern(DatePattern.NORM_DATE_PATTERN)));
+            }
+        }
+
+        if (CollUtil.isNotEmpty(dateRangeList)) {
+            dateRangeList.forEach(date -> {
+                IotRdDailyReportPolylineVO statistics = new IotRdDailyReportPolylineVO();
+                statistics.setReportDate(date);
+                statistics.setCumulativeBridgePlug(dateBridgePlugPair.get(date));
+                statistics.setCumulativeRunCount(dateRunCountPair.get(date));
+                statistics.setCumulativeWorkingWell(dateWorkingWellPair.get(date));
+                statistics.setCumulativeHourCount(dateHourCountPair.get(date));
+                statistics.setCumulativeFuels(dateFuelsPair.get(date));
+                statistics.setCumulativeWaterVolume(dateWaterVolumePair.get(date));
+                statistics.setCumulativeWorkingLayers(dateWorkingLayersPair.get(date));
+                BigDecimal taici = BigDecimal.ZERO;
+                // 合并 仪表混砂 泵车 的台次
+                if (CollUtil.isNotEmpty(dateMixSandPair)) {
+                    BigDecimal mixSand = dateMixSandPair.get(date);
+                    mixSand = ObjUtil.isNotEmpty(mixSand) ? mixSand : BigDecimal.ZERO;
+                    taici = taici.add(mixSand);
+                }
+                if (CollUtil.isNotEmpty(datePumpTripsPair)) {
+                    BigDecimal pumpTrips = datePumpTripsPair.get(date);
+                    pumpTrips = ObjUtil.isNotEmpty(pumpTrips) ? pumpTrips : BigDecimal.ZERO;
+                    taici = taici.add(pumpTrips);
+                }
+                statistics.setCumulativeMixSand(dateMixSandPair.get(date));
+                statistics.setCumulativePumpTrips(datePumpTripsPair.get(date));
+                statistics.setTaici(taici);
+                result.add(statistics);
+            });
         }
         return result;
     }

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

@@ -108,6 +108,7 @@ public class IotRyDailyReportServiceImpl implements IotRyDailyReportService {
 
     @Override
     public Long createIotRyDailyReport(IotRyDailyReportSaveReqVO createReqVO) {
+        System.out.println("新增日报方法开始:");
         // 插入
         IotRyDailyReportDO iotRyDailyReport = BeanUtils.toBean(createReqVO, IotRyDailyReportDO.class);
         LocalDateTime reportDate = createReqVO.getFillOrderCreateTime();
@@ -224,10 +225,11 @@ public class IotRyDailyReportServiceImpl implements IotRyDailyReportService {
         }
         // 生成消息提醒 到 项目部审批人员 站内信 钉钉
         Long deptId = createReqVO.getDeptId();
-        DeptDO dept = deptService.getDept(deptId);
-        Long parentId = dept.getParentId();
-        if (ObjUtil.isNotEmpty(parentId)) {
-            DataPermissionUtils.executeIgnore(() -> {
+        DataPermissionUtils.executeIgnore(() -> {
+            DeptDO dept = deptService.getDept(deptId);
+            System.out.println("当前查询到的部门是NULL:" + deptId);
+            Long parentId = dept.getParentId();
+            if (ObjUtil.isNotEmpty(parentId)) {
                 DeptDO projectDept = deptService.getDept(parentId);
                 // 当前部门的上级部门如果 不是项目部 再向上找一级 煤层气 项目
                 if (!"2".equals(projectDept.getType())) {
@@ -311,8 +313,8 @@ public class IotRyDailyReportServiceImpl implements IotRyDailyReportService {
                         }
                     }
                 }
-            });
-        }
+            }
+        });
         // 返回
         return iotRyDailyReport.getId();
     }