浏览代码

pms 瑞鹰 日报 汇总统计

zhangcl 2 天之前
父节点
当前提交
f2165ab9a7

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

@@ -12,10 +12,7 @@ import cn.iocoder.yudao.framework.datapermission.core.util.DataPermissionUtils;
 import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
 import cn.iocoder.yudao.module.pms.controller.admin.iotprojectinfo.vo.IotProjectInfoPageReqVO;
 import cn.iocoder.yudao.module.pms.controller.admin.iotprojecttask.vo.IotProjectTaskPageReqVO;
-import cn.iocoder.yudao.module.pms.controller.admin.iotrydailyreport.vo.IotRyDailyReportPageReqVO;
-import cn.iocoder.yudao.module.pms.controller.admin.iotrydailyreport.vo.IotRyDailyReportRespVO;
-import cn.iocoder.yudao.module.pms.controller.admin.iotrydailyreport.vo.IotRyDailyReportSaveReqVO;
-import cn.iocoder.yudao.module.pms.controller.admin.iotrydailyreport.vo.IotRyDailyReportTaskCountVO;
+import cn.iocoder.yudao.module.pms.controller.admin.iotrydailyreport.vo.*;
 import cn.iocoder.yudao.module.pms.dal.dataobject.iotprojectinfo.IotProjectInfoDO;
 import cn.iocoder.yudao.module.pms.dal.dataobject.iotprojecttask.IotProjectTaskDO;
 import cn.iocoder.yudao.module.pms.dal.dataobject.iotprojecttaskattrs.IotTaskAttrModelProperty;
@@ -129,6 +126,41 @@ public class IotRyDailyReportController {
         return success(new PageResult<>(buildRyDailyReports(pageResult.getList()), pageResult.getTotal()));
     }
 
+    @GetMapping("/statistics")
+    @Operation(summary = "获得瑞鹰日报汇总统计")
+    @PreAuthorize("@ss.hasPermission('pms:iot-ry-daily-report:query')")
+    public CommonResult<List<IotRyDailyReportStatisticsRespVO>> statistics(@Valid IotRyDailyReportPageReqVO pageReqVO) {
+        List<IotRyDailyReportStatisticsRespVO> result = new ArrayList<>();
+        // 根据查询参数筛选出 符合条件 的记录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<IotRyDailyReportStatisticsRespVO> statistics = iotRyDailyReportService.statistics(pageReqVO);
+        result.addAll(statistics);
+        return success(result);
+    }
+
     /**
      * 瑞恒日报分页 设置关联查询信息
      * @param reports
@@ -309,6 +341,21 @@ public class IotRyDailyReportController {
         BigDecimal totalPowerConsumption = BigDecimal.ZERO;
         // 总油耗
         BigDecimal totalFuelConsumption = 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<>();
+        List<IotRyDailyReportTaskCountVO> repairDeptTasks = iotRyDailyReportService.countRepairTasksByDept();
+        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();
@@ -323,18 +370,35 @@ public class IotRyDailyReportController {
                 if (ObjUtil.isNotEmpty(fuelConsumption)) {
                     totalFuelConsumption = totalFuelConsumption.add(fuelConsumption);
                 }
-
             }
             // 汇总 指定搜索时间段内的 总进尺  累计用电量 累计油耗
             if ("1".equals(pageReqVO.getProjectClassification())) {
                 // 钻井日报
                 result.put("totalFootage", totalFootage);
             } else if ("2".equals(pageReqVO.getProjectClassification())) {
-                // 修井日报
+                // 修井日报 总施工井数 完工井数 取日报记录中的最大值
                 result.put("totalFootage", totalFootage);
             }
+            // 施工井数
+            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);
+            // 累计施工井数
+            result.put("constructionWells", constructionWells);
+            // 累计完工井数
+            result.put("completedWells", completedWells);
         }
         return success(result);
     }

+ 71 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/iotrydailyreport/vo/IotRyDailyReportStatisticsRespVO.java

@@ -0,0 +1,71 @@
+package cn.iocoder.yudao.module.pms.controller.admin.iotrydailyreport.vo;
+
+import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
+import com.alibaba.excel.annotation.ExcelProperty;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+@Schema(description = "管理后台 - 瑞鹰日报 汇总统计 Response VO")
+@Data
+@ExcelIgnoreUnannotated
+public class IotRyDailyReportStatisticsRespVO {
+
+    @Schema(description = "主键id", requiredMode = Schema.RequiredMode.REQUIRED, example = "13853")
+    @ExcelProperty("主键id")
+    private Long id;
+
+    @Schema(description = "项目部id", example = "125")
+    @ExcelProperty("项目部id")
+    private Long projectDeptId;
+
+    @Schema(description = "队伍id", example = "125")
+    @ExcelProperty("队伍id")
+    private Long teamId;
+
+    @Schema(description = "项目部名称", example = "新疆项目部")
+    @ExcelProperty("项目部名称")
+    private String projectDeptName;
+
+    @Schema(description = "队伍名称", example = "小修20队")
+    @ExcelProperty("队伍名称")
+    private String teamName;
+
+    @Schema(description = "任务id", example = "15678")
+    @ExcelProperty("任务id")
+    private Long taskId;
+
+    @Schema(description = "排序", example = "1")
+    @ExcelProperty("排序")
+    private Integer sort;
+
+    @Schema(description = "部门类型(公司级1 项目部2 队伍3)", example = "1")
+    @ExcelProperty("部门类型(公司级1 项目部2 队伍3)")
+    private String type;
+
+    @Schema(description = "累计进尺(m)")
+    @ExcelProperty("累计进尺(m)")
+    private BigDecimal cumulativeFootage = BigDecimal.ZERO;
+
+    @Schema(description = "累计施工井数")
+    @ExcelProperty("累计施工井数")
+    private Integer cumulativeConstructWells = 0;
+
+    @Schema(description = "累计完工井数")
+    @ExcelProperty("累计完工井数")
+    private Integer cumulativeCompletedWells = 0;
+
+    @Schema(description = "累计用电量(kWh)")
+    @ExcelProperty("累计用电量(kWh)")
+    private BigDecimal cumulativePowerConsumption = BigDecimal.ZERO;
+
+    @Schema(description = "累计油耗(吨)")
+    @ExcelProperty("累计油耗(吨)")
+    private BigDecimal cumulativeFuelConsumption = BigDecimal.ZERO;
+
+    @Schema(description = "运行时效")
+    @ExcelProperty("运行时效")
+    private BigDecimal transitTime = BigDecimal.ZERO;
+
+}

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

@@ -600,7 +600,7 @@ public class IotRhDailyReportServiceImpl implements IotRhDailyReportService {
                         BigDecimal tempCapacity = cumulativeCapacityPair.get(teamDeptId);
                         if (tempCapacity.compareTo(BigDecimal.ZERO) > 0) {
                             // 指定队伍的累计运行时效
-                            BigDecimal tempTransitTime = cumulativeGasInjection.divide(tempCapacity);
+                            BigDecimal tempTransitTime = cumulativeGasInjection.divide(tempCapacity, 4, RoundingMode.HALF_UP);
                             cumulativeTransitTimePair.put(teamDeptId, tempTransitTime);
                         }
                     }

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

@@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.pms.service.iotrydailyreport;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.module.pms.controller.admin.iotrydailyreport.vo.IotRyDailyReportPageReqVO;
 import cn.iocoder.yudao.module.pms.controller.admin.iotrydailyreport.vo.IotRyDailyReportSaveReqVO;
+import cn.iocoder.yudao.module.pms.controller.admin.iotrydailyreport.vo.IotRyDailyReportStatisticsRespVO;
 import cn.iocoder.yudao.module.pms.controller.admin.iotrydailyreport.vo.IotRyDailyReportTaskCountVO;
 import cn.iocoder.yudao.module.pms.dal.dataobject.iotrydailyreport.IotRyDailyReportDO;
 
@@ -112,4 +113,12 @@ public interface IotRyDailyReportService {
      * @return 按部门统计任务数量
      */
     List<IotRyDailyReportTaskCountVO> countDateRigTasksByDepartment();
+
+    /**
+     * 瑞鹰日报汇总统计
+     *
+     * @param pageReqVO 列表查询
+     * @return 瑞恒日报汇总统计
+     */
+    List<IotRyDailyReportStatisticsRespVO> statistics(IotRyDailyReportPageReqVO pageReqVO);
 }

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

@@ -3,20 +3,25 @@ package cn.iocoder.yudao.module.pms.service.iotrydailyreport;
 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.common.util.object.BeanUtils;
 import cn.iocoder.yudao.module.pms.controller.admin.iotdevicecategorytemplateattrs.vo.IotDeviceProperty;
 import cn.iocoder.yudao.module.pms.controller.admin.iotprojecttask.vo.IotProjectTaskPageReqVO;
 import cn.iocoder.yudao.module.pms.controller.admin.iotrydailyreport.vo.IotRyDailyReportPageReqVO;
 import cn.iocoder.yudao.module.pms.controller.admin.iotrydailyreport.vo.IotRyDailyReportSaveReqVO;
+import cn.iocoder.yudao.module.pms.controller.admin.iotrydailyreport.vo.IotRyDailyReportStatisticsRespVO;
 import cn.iocoder.yudao.module.pms.controller.admin.iotrydailyreport.vo.IotRyDailyReportTaskCountVO;
 import cn.iocoder.yudao.module.pms.controller.admin.vo.IotDevicePageReqVO;
 import cn.iocoder.yudao.module.pms.dal.dataobject.IotDeviceDO;
 import cn.iocoder.yudao.module.pms.dal.dataobject.iotprojecttask.IotProjectTaskDO;
+import cn.iocoder.yudao.module.pms.dal.dataobject.iotprojecttaskattrs.IotTaskAttrModelProperty;
 import cn.iocoder.yudao.module.pms.dal.dataobject.iotrydailyreport.IotRyDailyReportDO;
 import cn.iocoder.yudao.module.pms.dal.mysql.IotDeviceMapper;
 import cn.iocoder.yudao.module.pms.dal.mysql.iotprojecttask.IotProjectTaskMapper;
 import cn.iocoder.yudao.module.pms.dal.mysql.iotrydailyreport.IotRyDailyReportMapper;
+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.DictTypeDO;
 import cn.iocoder.yudao.module.system.service.dept.DeptService;
 import cn.iocoder.yudao.module.system.service.dict.DictTypeService;
@@ -28,11 +33,13 @@ import org.springframework.validation.annotation.Validated;
 import javax.annotation.Resource;
 import java.lang.reflect.Type;
 import java.math.BigDecimal;
+import java.math.RoundingMode;
 import java.time.LocalDateTime;
 import java.util.*;
 import java.util.concurrent.atomic.AtomicReference;
 
 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
+import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
 import static cn.iocoder.yudao.module.pms.enums.ErrorCodeConstant.*;
 
 
@@ -288,4 +295,391 @@ public class IotRyDailyReportServiceImpl implements IotRyDailyReportService {
         return iotRyDailyReportMapper.countDateRigTasksByDepartment();
     }
 
+    @Override
+    public List<IotRyDailyReportStatisticsRespVO> statistics(IotRyDailyReportPageReqVO pageReqVO) {
+        List<IotRyDailyReportStatisticsRespVO> result = new ArrayList<>();
+        // 不分页统计所有数据
+        pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
+        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<>();
+        }
+        PageResult<IotRyDailyReportDO> page = iotRyDailyReportMapper.selectPage(pageReqVO);
+        List<IotRyDailyReportDO> dailyReports = page.getList();
+
+        // 默认显示所有项目部的汇总数据
+        // 点击项目部 显示 下属队伍的数据
+        // 首先判断点击的部门是属于 公司 还是 队伍 如果没有点击任何部门 默认查询所有项目部数据
+        if (ObjUtil.isEmpty(pageReqVO.getDeptId())) {
+            result = statisticsByProjectDept(pageReqVO, dailyReports, 158L);
+        } else {
+            // 判断点击的组织树中的部门类型 类型(公司级1 项目部2 队伍3)
+            DeptDO selectedDept = deptService.getDept(pageReqVO.getDeptId());
+            if ("1".equals(selectedDept.getType())) {
+                // 以项目部为维度汇总数据
+                result = statisticsByProjectDept(pageReqVO, dailyReports, pageReqVO.getDeptId());
+            } else if ("2".equals(selectedDept.getType())) {
+                // 以队伍为维度汇总数据
+                result = statisticsByProjectDepartment(pageReqVO, dailyReports, pageReqVO.getDeptId());
+            } else if ("3".equals(selectedDept.getType())) {
+                // 显示单个队伍的汇总数据
+                result = statisticsByProjectDepartment(pageReqVO, dailyReports, pageReqVO.getDeptId());
+            } else {
+                // 点击的部门没有类型 判断部门下的是否包含 项目部类型部门 新疆分公司
+                // 以项目部为维度汇总数据
+                result = statisticsByProjectDept(pageReqVO, dailyReports, pageReqVO.getDeptId());
+            }
+        }
+        // 根据result集合内对象的 sort 属性正序排列 sort 类型为 integer 类型
+        if (CollUtil.isNotEmpty(result)) {
+            result.sort(Comparator.comparing(
+                    IotRyDailyReportStatisticsRespVO::getSort,
+                    Comparator.nullsLast(Comparator.naturalOrder())
+            ));
+        }
+        return result;
+    }
+
+    /**
+     * 按项目部维度统计数据
+     * @param pageReqVO 日报查询对象
+     * @param dailyReports 日报数据列表
+     * @param rootDeptId 根部门ID(如158L为 瑞鹰 根部门,或其他公司级部门ID)
+     * @return 项目部维度统计结果列表  钻井 修井
+     */
+    private List<IotRyDailyReportStatisticsRespVO> statisticsByProjectDept(IotRyDailyReportPageReqVO pageReqVO,
+                                                                           List<IotRyDailyReportDO> dailyReports, Long rootDeptId) {
+        List<IotRyDailyReportStatisticsRespVO> 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/项目部id   value累计进尺
+        Map<Long, BigDecimal> cumulativeFootagePair = new HashMap<>();
+        // key队伍id/项目部id   value累计用电
+        Map<Long, BigDecimal> cumulativePowerConsumptionPair = new HashMap<>();
+        // key队伍id/项目部id   value累计油耗
+        Map<Long, BigDecimal> cumulativeFuelConsumptionPair = new HashMap<>();
+        // key队伍id/项目部id   value对应项目部的施工井数
+        Map<Long, Integer> cumulativeConstructWellsPair = new HashMap<>();
+        // key队伍id/项目部id   value对应项目部的完工井数
+        Map<Long, Integer> cumulativeCompletedWellsPair = new HashMap<>();
+        // key队伍id/项目部id   value生产时间(H)
+        Map<Long, BigDecimal> cumulativeProductTimePair = new HashMap<>();
+        // key队伍id/项目部id   value额定生产时间(H)
+        Map<Long, BigDecimal> cumulativeRatedTimePair = new HashMap<>();
+        // key队伍id/项目部id   value累计运行时效   累计注气量/累计产能
+        Map<Long, BigDecimal> cumulativeTransitTimePair = new HashMap<>();
+
+        // 以项目部为维度统计数据
+        // 找到所有项目部与队伍的对应关系
+        // 查询指定根部门下的所有子部门
+        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);
+            }
+            teamProjectIdPair.put(dept.getId(), dept.getParentId());
+        });
+
+        // key施工队伍id    value施工井数量
+        Map<Long, Integer> totalTasksPair = new HashMap<>();
+        // key施工队伍id    value完工井数量
+        Map<Long, Integer> completedTasksPair = new HashMap<>();
+        // key任务id   value额定生产时间
+        Map<Long, BigDecimal> taskRatedProductionTimePair = new HashMap<>();
+        if ("2".equals(pageReqVO.getProjectClassification())) {
+            // 查询修井 累计施工井数 累计完工井数
+            List<IotRyDailyReportTaskCountVO> repairDeptTasks = iotRyDailyReportMapper.countRepairTasksByDept();
+            if (CollUtil.isNotEmpty(repairDeptTasks)) {
+                repairDeptTasks.forEach(task -> {
+                    totalTasksPair.put(task.getDeptId(), task.getTotalTaskCount());
+                    completedTasksPair.put(task.getDeptId(), task.getCompletedTaskCount());
+                });
+
+            }
+            // 计算 运行时效 累计生产时间/累计额定生产时间
+            // 查询日报关联的任务信息
+            IotProjectTaskPageReqVO taskReqVO = new IotProjectTaskPageReqVO();
+            taskReqVO.setTaskIds(convertList(dailyReports, IotRyDailyReportDO::getTaskId));
+            List<IotProjectTaskDO> tasks = iotProjectTaskMapper.selectList(taskReqVO);
+            if (CollUtil.isNotEmpty(tasks)) {
+                tasks.forEach(task -> {
+                    if (CollUtil.isNotEmpty(task.getExtProperty())) {
+                        List<IotTaskAttrModelProperty> taskAttrs = task.getExtProperty();
+                        if (CollUtil.isNotEmpty(taskAttrs)) {
+                            // 找到 额定生产时间 属性 对应的值
+                            taskAttrs.forEach(attr -> {
+                                if ("额定生产时间".equals(attr.getName()) && StrUtil.isNotBlank(attr.getActualValue())) {
+                                    taskRatedProductionTimePair.put(task.getId(), new BigDecimal(attr.getActualValue()));
+                                }
+                            });
+                        }
+                    }
+                });
+            }
+        }
+
+        // 累计计算各项指标
+        if (CollUtil.isNotEmpty(dailyReports)) {
+            dailyReports.forEach(report -> {
+                if (ObjUtil.isNotEmpty(report.getDeptId()) && teamProjectIdPair.containsKey(report.getDeptId())) {
+                    Long projectDeptId = teamProjectIdPair.get(report.getDeptId());
+                    if (ObjUtil.isNotEmpty(projectDeptId) && projectDeptPair.containsKey(projectDeptId)) {
+                        // 累计进尺
+                        cumulativeFootagePair.merge(projectDeptId, report.getDailyFootage(), BigDecimal::add);
+                        // 累计用电量
+                        cumulativePowerConsumptionPair.merge(projectDeptId, report.getDailyPowerUsage(), BigDecimal::add);
+                        // 累计油耗
+                        cumulativeFuelConsumptionPair.merge(projectDeptId, report.getDailyFuel(), BigDecimal::add);
+                        // 统计各项目部的 累计施工井数 累计完工井数 取每个井任务的最大值 而不是累加
+                        /* if (totalTasksPair.containsKey(report.getDeptId())) {
+                            Integer tempCount = totalTasksPair.get(report.getDeptId());
+                            cumulativeConstructWellsPair.merge(projectDeptId, tempCount, Integer::sum);
+                        }
+                        if (completedTasksPair.containsKey(report.getDeptId())) {
+                            Integer tempCompleteCount = completedTasksPair.get(report.getDeptId());
+                            cumulativeCompletedWellsPair.merge(projectDeptId, tempCompleteCount, Integer::sum);
+                        } */
+                        // 额定生产时间
+                        if (taskRatedProductionTimePair.containsKey(report.getTaskId())) {
+                            BigDecimal ratedTime = taskRatedProductionTimePair.get(report.getTaskId());
+                            cumulativeRatedTimePair.merge(projectDeptId, ratedTime, BigDecimal::add);
+                        }
+                        // 生产时间
+                        cumulativeProductTimePair.merge(projectDeptId, report.getProductionTime(), BigDecimal::add);
+                    }
+                }
+            });
+            // 筛选每个队伍对应的项目部 设置每个项目部的 累计施工井数 累计完工井数 totalTasksPair   completedTasksPair
+            if (CollUtil.isNotEmpty(totalTasksPair)) {
+                totalTasksPair.forEach((teamDeptId, taskCount) -> {
+                    if (teamProjectIdPair.containsKey(teamDeptId)) {
+                        // 项目部id
+                        Long projectDeptId = teamProjectIdPair.get(teamDeptId);
+                        cumulativeConstructWellsPair.merge(projectDeptId, taskCount, Integer::sum);
+                    }
+                });
+            }
+            if (CollUtil.isNotEmpty(completedTasksPair)) {
+                completedTasksPair.forEach((teamDeptId, taskCount) -> {
+                    if (teamProjectIdPair.containsKey(teamDeptId)) {
+                        // 项目部id
+                        Long projectDeptId = teamProjectIdPair.get(teamDeptId);
+                        cumulativeCompletedWellsPair.merge(projectDeptId, taskCount, Integer::sum);
+                    }
+                });
+            }
+
+            // 计算项目部对应的 运行时效
+            if (CollUtil.isNotEmpty(cumulativeProductTimePair) && CollUtil.isNotEmpty(cumulativeRatedTimePair)) {
+                cumulativeProductTimePair.forEach((projectDeptId, productionTime) -> {
+                    if (cumulativeRatedTimePair.containsKey(projectDeptId)) {
+                        BigDecimal tempRatedTime = cumulativeRatedTimePair.get(projectDeptId);
+                        if (tempRatedTime.compareTo(BigDecimal.ZERO) > 0) {
+                            // 指定项目部的 累计额定生产时间
+                            BigDecimal tempTransitTime = productionTime.divide(tempRatedTime, 4, RoundingMode.HALF_UP);
+                            cumulativeTransitTimePair.put(projectDeptId, tempTransitTime);
+                        } else {
+                            cumulativeTransitTimePair.put(projectDeptId, BigDecimal.ZERO);
+                        }
+                    }
+                });
+            }
+        }
+
+        // 生成返回的数据列表集合
+        projectDeptPair.forEach((deptId, dept) -> {
+            IotRyDailyReportStatisticsRespVO statistics = new IotRyDailyReportStatisticsRespVO();
+            statistics.setProjectDeptId(deptId);
+            statistics.setProjectDeptName(dept.getName());
+            statistics.setSort(dept.getSort());
+            statistics.setType("2");
+            statistics.setCumulativeFootage(cumulativeFootagePair.get(deptId));
+            statistics.setCumulativeConstructWells(cumulativeConstructWellsPair.get(deptId));
+            statistics.setCumulativeCompletedWells(cumulativeCompletedWellsPair.get(deptId));
+            statistics.setCumulativePowerConsumption(cumulativePowerConsumptionPair.get(deptId));
+            statistics.setCumulativeFuelConsumption(cumulativeFuelConsumptionPair.get(deptId));
+            statistics.setTransitTime(cumulativeTransitTimePair.get(deptId));
+            result.add(statistics);
+        });
+
+        return result;
+    }
+
+    /**
+     * 按 队伍 维度统计数据
+     * @param pageReqVO 日报数据请求对象
+     * @param dailyReports 日报数据列表
+     * @param deptId 项目部ID 或 队伍id(塔河项目部 HY-A1)
+     * @return 队伍 维度统计结果列表
+     */
+    private List<IotRyDailyReportStatisticsRespVO> statisticsByProjectDepartment(IotRyDailyReportPageReqVO pageReqVO,
+                                                                                 List<IotRyDailyReportDO> dailyReports, Long deptId) {
+        List<IotRyDailyReportStatisticsRespVO> 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> cumulativeFootagePair = new HashMap<>();
+        // key队伍id   value累计用电
+        Map<Long, BigDecimal> cumulativePowerConsumptionPair = new HashMap<>();
+        // key队伍id/项目部id   value累计油耗
+        Map<Long, BigDecimal> cumulativeFuelConsumptionPair = new HashMap<>();
+        // key队伍id/项目部id   value对应项目部的施工井数
+        Map<Long, Integer> cumulativeConstructWellsPair = new HashMap<>();
+        // key队伍id/项目部id   value对应项目部的完工井数
+        Map<Long, Integer> cumulativeCompletedWellsPair = new HashMap<>();
+        // key队伍id/项目部id   value生产时间(H)
+        Map<Long, BigDecimal> cumulativeProductTimePair = new HashMap<>();
+        // key队伍id/项目部id   value额定生产时间(H)
+        Map<Long, BigDecimal> cumulativeRatedTimePair = new HashMap<>();
+        // key队伍id   value累计运行时效   累计注气量/累计产能
+        Map<Long, BigDecimal> cumulativeTransitTimePair = 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);
+            }
+            teamProjectIdPair.put(dept.getId(), dept.getParentId());
+        });
+
+        // key施工队伍id    value施工井数量
+        Map<Long, Integer> totalTasksPair = new HashMap<>();
+        // key施工队伍id    value完工井数量
+        Map<Long, Integer> completedTasksPair = new HashMap<>();
+        // key任务id   value额定生产时间
+        Map<Long, BigDecimal> taskRatedProductionTimePair = new HashMap<>();
+        if ("2".equals(pageReqVO.getProjectClassification())) {
+            // 查询修井 累计施工井数 累计完工井数
+            List<IotRyDailyReportTaskCountVO> repairDeptTasks = iotRyDailyReportMapper.countRepairTasksByDept();
+            if (CollUtil.isNotEmpty(repairDeptTasks)) {
+                repairDeptTasks.forEach(task -> {
+                    totalTasksPair.put(task.getDeptId(), task.getTotalTaskCount());
+                    completedTasksPair.put(task.getDeptId(), task.getCompletedTaskCount());
+                });
+
+            }
+            // 计算 运行时效 累计生产时间/累计额定生产时间
+            // 查询日报关联的任务信息
+            IotProjectTaskPageReqVO taskReqVO = new IotProjectTaskPageReqVO();
+            taskReqVO.setTaskIds(convertList(dailyReports, IotRyDailyReportDO::getTaskId));
+            List<IotProjectTaskDO> tasks = iotProjectTaskMapper.selectList(taskReqVO);
+            if (CollUtil.isNotEmpty(tasks)) {
+                tasks.forEach(task -> {
+                    if (CollUtil.isNotEmpty(task.getExtProperty())) {
+                        List<IotTaskAttrModelProperty> taskAttrs = task.getExtProperty();
+                        if (CollUtil.isNotEmpty(taskAttrs)) {
+                            // 找到 额定生产时间 属性 对应的值
+                            taskAttrs.forEach(attr -> {
+                                if ("额定生产时间".equals(attr.getName()) && StrUtil.isNotBlank(attr.getActualValue())) {
+                                    taskRatedProductionTimePair.put(task.getId(), new BigDecimal(attr.getActualValue()));
+                                }
+                            });
+                        }
+                    }
+                });
+            }
+        }
+
+        // 累计计算各项指标
+        if (CollUtil.isNotEmpty(dailyReports)) {
+            dailyReports.forEach(report -> {
+                if (ObjUtil.isNotEmpty(report.getDeptId())) {
+                    // 累计进尺
+                    cumulativeFootagePair.merge(report.getDeptId(), report.getDailyFootage(), BigDecimal::add);
+                    // 累计油耗
+                    cumulativeFuelConsumptionPair.merge(report.getDeptId(), report.getDailyFuel(), BigDecimal::add);
+                    // 累计用电量
+                    cumulativePowerConsumptionPair.merge(report.getDeptId(), report.getDailyPowerUsage(), BigDecimal::add);
+                    // 统计各项目部的 累计施工井数 累计完工井数
+                    /* if (totalTasksPair.containsKey(report.getDeptId())) {
+                        Integer tempCount = totalTasksPair.get(report.getDeptId());
+                        cumulativeConstructWellsPair.put(report.getDeptId(), tempCount);
+                    }
+                    if (completedTasksPair.containsKey(report.getDeptId())) {
+                        Integer tempCompleteCount = completedTasksPair.get(report.getDeptId());
+                        cumulativeCompletedWellsPair.put(report.getDeptId(), tempCompleteCount);
+                    } */
+                    // 额定生产时间
+                    if (taskRatedProductionTimePair.containsKey(report.getTaskId())) {
+                        BigDecimal ratedTime = taskRatedProductionTimePair.get(report.getTaskId());
+                        cumulativeRatedTimePair.merge(report.getDeptId(), ratedTime, BigDecimal::add);
+                    }
+                    // 生产时间
+                    cumulativeProductTimePair.merge(report.getDeptId(), report.getProductionTime(), BigDecimal::add);
+                }
+            });
+            // 根据 累计注气量 累计产能 计算指定队伍下的平均产能
+            if (CollUtil.isNotEmpty(cumulativeProductTimePair) && CollUtil.isNotEmpty(cumulativeRatedTimePair)) {
+                cumulativeProductTimePair.forEach((teamDeptId, productionTime) -> {
+                    if (cumulativeRatedTimePair.containsKey(teamDeptId)) {
+                        BigDecimal tempRatedTime = cumulativeRatedTimePair.get(teamDeptId);
+                        if (tempRatedTime.compareTo(BigDecimal.ZERO) > 0) {
+                            // 指定队伍的累计运行时效
+                            BigDecimal tempTransitTime = productionTime.divide(tempRatedTime, 4, RoundingMode.HALF_UP);
+                            cumulativeTransitTimePair.put(teamDeptId, tempTransitTime);
+                        }
+                    }
+                });
+            }
+        }
+
+        // 生成返回的数据列表集合
+        teamDeptPair.forEach((teamDeptId, dept) -> {
+            IotRyDailyReportStatisticsRespVO statistics = new IotRyDailyReportStatisticsRespVO();
+            statistics.setTeamId(teamDeptId);
+            statistics.setTeamName(dept.getName());
+            statistics.setSort(dept.getSort());
+            statistics.setType("3");
+            statistics.setCumulativeFootage(cumulativeFootagePair.get(teamDeptId));
+            statistics.setCumulativeConstructWells(totalTasksPair.get(teamDeptId));
+            statistics.setCumulativeCompletedWells(completedTasksPair.get(teamDeptId));
+            statistics.setCumulativePowerConsumption(cumulativePowerConsumptionPair.get(teamDeptId));
+            statistics.setCumulativeFuelConsumption(cumulativeFuelConsumptionPair.get(teamDeptId));
+            statistics.setTransitTime(cumulativeTransitTimePair.get(teamDeptId));
+            result.add(statistics);
+        });
+
+        return result;
+    }
+
 }