Эх сурвалжийг харах

Merge remote-tracking branch 'origin/master'

Zimo 7 цаг өмнө
parent
commit
f72f3359fd

+ 29 - 19
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/app/IotAppController.java

@@ -1,36 +1,34 @@
 package cn.iocoder.yudao.module.pms.controller.admin.app;
 
+import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
+import cn.iocoder.yudao.framework.common.pojo.CommonResult;
+import cn.iocoder.yudao.framework.common.pojo.PageParam;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
+import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
 import cn.iocoder.yudao.module.pms.controller.admin.app.vo.IotAppPageReqVO;
 import cn.iocoder.yudao.module.pms.controller.admin.app.vo.IotAppRespVO;
 import cn.iocoder.yudao.module.pms.controller.admin.app.vo.IotAppSaveReqVO;
+import cn.iocoder.yudao.module.pms.controller.admin.app.vo.IotWgtRespVO;
 import cn.iocoder.yudao.module.pms.dal.dataobject.app.IotAppDO;
 import cn.iocoder.yudao.module.pms.service.app.IotAppService;
-import org.springframework.web.bind.annotation.*;
-import javax.annotation.Resource;
-import org.springframework.validation.annotation.Validated;
-import org.springframework.security.access.prepost.PreAuthorize;
-import io.swagger.v3.oas.annotations.tags.Tag;
-import io.swagger.v3.oas.annotations.Parameter;
 import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
 
+import javax.annotation.Resource;
 import javax.annotation.security.PermitAll;
-import javax.validation.constraints.*;
-import javax.validation.*;
-import javax.servlet.http.*;
-import java.util.*;
+import javax.servlet.http.HttpServletResponse;
+import javax.validation.Valid;
 import java.io.IOException;
+import java.util.List;
 
-import cn.iocoder.yudao.framework.common.pojo.PageParam;
-import cn.iocoder.yudao.framework.common.pojo.PageResult;
-import cn.iocoder.yudao.framework.common.pojo.CommonResult;
-import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
+import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
 
-import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
-
-import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
-import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.*;
-
 
 @Tag(name = "管理后台 - app版本更新")
 @RestController
@@ -102,4 +100,16 @@ public class IotAppController {
         IotAppDO aNew = iotAppService.getNew();
         return success(BeanUtils.toBean(aNew, IotAppRespVO.class));
     }
+
+    @GetMapping("/newWgt")
+    @Operation(summary = "获取最新app版本信息 wgt app内更新")
+    @PermitAll
+    public CommonResult<IotWgtRespVO> getNewIotWgtRespVO() {
+        IotAppDO aNew = iotAppService.getNew();
+        IotWgtRespVO wgt = new IotWgtRespVO();
+        wgt.setWgtUrl(aNew.getUrl());
+        wgt.setVersion(aNew.getAppVersion());
+        wgt.setForce(true);
+        return success(wgt);
+    }
 }

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

@@ -1258,6 +1258,8 @@ public class IotRdDailyReportController {
         Map<Long, BigDecimal> groupIdMixSandPair = new HashMap<>();
         // 已经完工的任务id集合
         Set<Long> finishedTaskIds = new HashSet<>();
+        // key日报id   value生产动态明细
+        Map<Long, List<IotRdDailyReportDetailRespVO>> reportDetailsPair = new HashMap<>();
 
         DataPermissionUtils.executeIgnore(() -> {
             IotProjectTaskPageReqVO taskReqVO = new IotProjectTaskPageReqVO();
@@ -1511,11 +1513,72 @@ public class IotRdDailyReportController {
             // relatedWellReqVO.setPlatformWell(2);
             List<IotRdDailyReportDO> relatedWellReports = iotRdDailyReportService.dailyReports(relatedWellReqVO);
 
+            // key日报id  value平台井platformGroup
+            Map<Long, String> platformWellPair = new HashMap<>();
+
+            // 查询每个日报的生产动态明细 平台井查询 主井 的生产动态明细
+            IotRdDailyReportDetailPageReqVO detailReqVO = new IotRdDailyReportDetailPageReqVO();
+            detailReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
+            detailReqVO.setReportIds(convertList(relatedWellReports, IotRdDailyReportDO::getId));
+            PageResult<IotRdDailyReportDetailDO> reportDetailsPage = iotRdDailyReportDetailMapper.selectPage(detailReqVO);
+            List<IotRdDailyReportDetailDO> reportDetails = reportDetailsPage.getList();
+            if (CollUtil.isNotEmpty(reportDetails)) {
+                // 设置每个日报的生产动态明细
+                reportDetails.forEach(detail -> {
+                    if (reportDetailsPair.containsKey(detail.getReportId())) {
+                        List<IotRdDailyReportDetailRespVO> tempDetails = reportDetailsPair.get(detail.getReportId());
+                        tempDetails.add(BeanUtils.toBean(detail, IotRdDailyReportDetailRespVO.class));
+                        reportDetailsPair.put(detail.getReportId(), tempDetails);
+                    } else {
+                        List<IotRdDailyReportDetailRespVO> tempDetails = new ArrayList<>();
+                        tempDetails.add(BeanUtils.toBean(detail, IotRdDailyReportDetailRespVO.class));
+                        reportDetailsPair.put(detail.getReportId(), tempDetails);
+                    }
+                });
+            }
+
             // 按照日报创建时间倒序排列
             if (CollUtil.isNotEmpty(relatedWellReports)) {
                 relatedWellReports = relatedWellReports.stream()
                         .sorted(Comparator.comparing(IotRdDailyReportDO::getCreateTime).reversed())
                         .collect(Collectors.toList());
+                // 筛选 平台井 类型的日报
+                platformWellPair = relatedWellReports.stream()
+                        .collect(Collectors.toMap(
+                                IotRdDailyReportDO::getId,        // key:日报ID
+                                IotRdDailyReportDO::getPlatformGroup, // value:platformGroup
+                                (oldValue, newValue) -> oldValue  // 重复key时保留旧值(避免重复ID报错)
+                        ));
+            }
+            // 组装没有关联生产动态明细的 日报
+            // 1. 按 platformGroup 分组,存储每组的明细列表
+            Map<String, List<IotRdDailyReportDetailRespVO>> platformGroupDetailsMap = new HashMap<>();
+            // 2. 把已有明细的日报,按 platformGroup 汇总明细
+            if (CollUtil.isNotEmpty(platformWellPair) && CollUtil.isNotEmpty(reportDetailsPair)) {
+                platformWellPair.forEach((reportId, platformGroup) -> {
+                    List<IotRdDailyReportDetailRespVO> details = reportDetailsPair.get(reportId);
+                    if (CollUtil.isNotEmpty(details)) {
+                        platformGroupDetailsMap
+                                .computeIfAbsent(platformGroup, k -> new ArrayList<>())
+                                .addAll(details);
+                    }
+                });
+            }
+            // 3. 给没有明细的日报,赋值同平台组的明细(实现共享)
+            for (IotRdDailyReportDO report : reports) {
+                Long reportId = report.getId();
+                String platformGroup = platformWellPair.get(reportId);
+
+                // 如果当前日报没有明细 && 同组有共享明细 → 赋值
+                if (!reportDetailsPair.containsKey(reportId)
+                        && StrUtil.isNotBlank(platformGroup)
+                        && platformGroupDetailsMap.containsKey(platformGroup)) {
+
+                    List<IotRdDailyReportDetailRespVO> sharedDetails = platformGroupDetailsMap.get(platformGroup);
+                    if (CollUtil.isNotEmpty(sharedDetails)) {
+                        reportDetailsPair.put(reportId, sharedDetails);
+                    }
+                }
             }
 
             if (CollUtil.isNotEmpty(tasks)) {
@@ -1735,6 +1798,8 @@ public class IotRdDailyReportController {
             if (ObjUtil.isNotEmpty(reportVO.getCreateTime())) {
                 reportVO.setCreateTimeStr(LocalDateTimeUtil.format(reportVO.getCreateTime(), DatePattern.NORM_DATE_PATTERN));
             }
+            // 生产动态明细
+            findAndThen(reportDetailsPair, reportVO.getId(), details -> reportVO.setReportDetails(details));
             // 部门信息 任务中关联的施工队伍
             findAndThen(taskTeamsPair, reportVO.getTaskId(), deptNames -> reportVO.setDeptName(deptNames));
             // 日报关联的项目信息
@@ -1847,6 +1912,8 @@ public class IotRdDailyReportController {
         Map<Long, BigDecimal> groupIdMixSandPair = new HashMap<>();
         // 已经完工的任务id集合
         Set<Long> finishedTaskIds = new HashSet<>();
+        // key日报id   value生产动态明细
+        Map<Long, List<IotRdDailyReportDetailRespVO>> reportDetailsPair = new HashMap<>();
 
         DataPermissionUtils.executeIgnore(() -> {
             IotProjectTaskPageReqVO taskReqVO = new IotProjectTaskPageReqVO();
@@ -2103,11 +2170,72 @@ public class IotRdDailyReportController {
             // relatedWellReqVO.setPlatformWell(2);
             List<IotRdDailyReportDO> relatedWellReports = iotRdDailyReportService.dailyReports(relatedWellReqVO);
 
+            // key日报id  value平台井platformGroup
+            Map<Long, String> platformWellPair = new HashMap<>();
+
+            // 查询每个日报的生产动态明细 平台井查询 主井 的生产动态明细
+            IotRdDailyReportDetailPageReqVO detailReqVO = new IotRdDailyReportDetailPageReqVO();
+            detailReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
+            detailReqVO.setReportIds(convertList(relatedWellReports, IotRdDailyReportDO::getId));
+            PageResult<IotRdDailyReportDetailDO> reportDetailsPage = iotRdDailyReportDetailMapper.selectPage(detailReqVO);
+            List<IotRdDailyReportDetailDO> reportDetails = reportDetailsPage.getList();
+            if (CollUtil.isNotEmpty(reportDetails)) {
+                // 设置每个日报的生产动态明细
+                reportDetails.forEach(detail -> {
+                    if (reportDetailsPair.containsKey(detail.getReportId())) {
+                        List<IotRdDailyReportDetailRespVO> tempDetails = reportDetailsPair.get(detail.getReportId());
+                        tempDetails.add(BeanUtils.toBean(detail, IotRdDailyReportDetailRespVO.class));
+                        reportDetailsPair.put(detail.getReportId(), tempDetails);
+                    } else {
+                        List<IotRdDailyReportDetailRespVO> tempDetails = new ArrayList<>();
+                        tempDetails.add(BeanUtils.toBean(detail, IotRdDailyReportDetailRespVO.class));
+                        reportDetailsPair.put(detail.getReportId(), tempDetails);
+                    }
+                });
+            }
+
             // 按照日报创建时间倒序排列
             if (CollUtil.isNotEmpty(relatedWellReports)) {
                 relatedWellReports = relatedWellReports.stream()
                         .sorted(Comparator.comparing(IotRdDailyReportDO::getCreateTime).reversed())
                         .collect(Collectors.toList());
+                // 筛选 平台井 类型的日报
+                platformWellPair = relatedWellReports.stream()
+                        .collect(Collectors.toMap(
+                                IotRdDailyReportDO::getId,        // key:日报ID
+                                IotRdDailyReportDO::getPlatformGroup, // value:platformGroup
+                                (oldValue, newValue) -> oldValue  // 重复key时保留旧值(避免重复ID报错)
+                        ));
+            }
+            // 组装没有关联生产动态明细的 日报
+            // 1. 按 platformGroup 分组,存储每组的明细列表
+            Map<String, List<IotRdDailyReportDetailRespVO>> platformGroupDetailsMap = new HashMap<>();
+            // 2. 把已有明细的日报,按 platformGroup 汇总明细
+            if (CollUtil.isNotEmpty(platformWellPair) && CollUtil.isNotEmpty(reportDetailsPair)) {
+                platformWellPair.forEach((reportId, platformGroup) -> {
+                    List<IotRdDailyReportDetailRespVO> details = reportDetailsPair.get(reportId);
+                    if (CollUtil.isNotEmpty(details)) {
+                        platformGroupDetailsMap
+                                .computeIfAbsent(platformGroup, k -> new ArrayList<>())
+                                .addAll(details);
+                    }
+                });
+            }
+            // 3. 给没有明细的日报,赋值同平台组的明细(实现共享)
+            for (IotRdDailyReportDO report : reports) {
+                Long reportId = report.getId();
+                String platformGroup = platformWellPair.get(reportId);
+
+                // 如果当前日报没有明细 && 同组有共享明细 → 赋值
+                if (!reportDetailsPair.containsKey(reportId)
+                        && StrUtil.isNotBlank(platformGroup)
+                        && platformGroupDetailsMap.containsKey(platformGroup)) {
+
+                    List<IotRdDailyReportDetailRespVO> sharedDetails = platformGroupDetailsMap.get(platformGroup);
+                    if (CollUtil.isNotEmpty(sharedDetails)) {
+                        reportDetailsPair.put(reportId, sharedDetails);
+                    }
+                }
             }
 
             if (CollUtil.isNotEmpty(tasks)) {
@@ -2321,6 +2449,8 @@ public class IotRdDailyReportController {
             if (ObjUtil.isNotEmpty(reportVO.getCreateTime())) {
                 reportVO.setCreateTimeStr(LocalDateTimeUtil.format(reportVO.getCreateTime(), DatePattern.NORM_DATE_PATTERN));
             }
+            // 生产动态明细
+            findAndThen(reportDetailsPair, reportVO.getId(), details -> reportVO.setReportDetails(details));
             // 施工状态 导出使用
             if (StrUtil.isNotBlank(reportVO.getRdStatus())) {
                 if (constructStatusPair.containsKey(reportVO.getRdStatus())) {

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

@@ -723,6 +723,8 @@ public class IotRhDailyReportController {
         // 搬迁安装天数
         Map<Long, BigDecimal> relocationDaysPair = new HashMap<>();
 
+        // key部门id    value 部门相关日报列表
+        Map<Long, List<IotRhDailyReportDO>> deptReportsPair = new HashMap<>();
         // key队伍id   value 队伍当年累计注气量
         Map<Long, BigDecimal> yearGasInjectionPair = new HashMap<>();
         // key队伍id   value 队伍当年累计注水量
@@ -734,13 +736,16 @@ public class IotRhDailyReportController {
 
         // key任务井id    value 井累计注气量
         Map<Long, BigDecimal> wellGasInjectionPair = new HashMap<>();
-        // key任务井id    value 井累计注水量
+        // key任务井id    value 井相关日报列表
+        Map<Long, List<IotRhDailyReportDO>> wellReportsPair = new HashMap<>();
+        // key日报id    value 井累计注水量
         Map<Long, BigDecimal> wellWaterInjectionPair = new HashMap<>();
         // key任务井id    value 井累计用电量
         Map<Long, BigDecimal> wellPowerPair = new HashMap<>();
         // key任务井id    value 井累计油耗
         Map<Long, BigDecimal> wellFuelPair = new HashMap<>();
 
+        // 井累计 注气量 日报当天日期及之前所有日报累计注气量之和
         // 查询所有井日报数据
         IotRhDailyReportPageReqVO currentTaskReqVO = new IotRhDailyReportPageReqVO();
         currentTaskReqVO.setTaskIds(convertList(reports, IotRhDailyReportDO::getTaskId));
@@ -748,21 +753,31 @@ public class IotRhDailyReportController {
         if (CollUtil.isNotEmpty(taskDailyReports)) {
             taskDailyReports.forEach(report -> {
                 // 注气量
-                if (wellGasInjectionPair.containsKey(report.getTaskId())) {
+                /* if (wellGasInjectionPair.containsKey(report.getTaskId())) {
                     BigDecimal tempGasInjection = wellGasInjectionPair.get(report.getTaskId());
                     BigDecimal tempResult = tempGasInjection.add(report.getDailyGasInjection());
                     wellGasInjectionPair.put(report.getTaskId(), tempResult);
                 } else {
                     wellGasInjectionPair.put(report.getTaskId(), report.getDailyGasInjection());
+                } */
+                // 井相关的所有日报列表
+                if (wellReportsPair.containsKey(report.getTaskId())) {
+                    List<IotRhDailyReportDO> tempReports = wellReportsPair.get(report.getTaskId());
+                    tempReports.add(report);
+                    wellReportsPair.put(report.getTaskId(), tempReports);
+                } else {
+                    List<IotRhDailyReportDO> tempReports = new ArrayList<>();
+                    tempReports.add(report);
+                    wellReportsPair.put(report.getTaskId(), tempReports);
                 }
                 // 注水量
-                if (wellWaterInjectionPair.containsKey(report.getTaskId())) {
+                /* if (wellWaterInjectionPair.containsKey(report.getTaskId())) {
                     BigDecimal tempWaterInjection = wellWaterInjectionPair.get(report.getTaskId());
                     BigDecimal tempResult = tempWaterInjection.add(report.getDailyWaterInjection());
                     wellWaterInjectionPair.put(report.getTaskId(), tempResult);
                 } else {
                     wellWaterInjectionPair.put(report.getTaskId(), report.getDailyWaterInjection());
-                }
+                } */
                 // 电量
                 if (wellPowerPair.containsKey(report.getTaskId())) {
                     BigDecimal tempPower = wellPowerPair.get(report.getTaskId());
@@ -782,6 +797,41 @@ public class IotRhDailyReportController {
             });
         }
 
+        // 基于 wellReportsPair 计算每个日报的截止到创建时间的累计注气量
+        Map<Long, BigDecimal> reportCumulativeGasMap = new HashMap<>();
+        if (CollUtil.isNotEmpty(wellReportsPair)) {
+            for (Map.Entry<Long, List<IotRhDailyReportDO>> entry : wellReportsPair.entrySet()) {
+                List<IotRhDailyReportDO> reportList = entry.getValue();
+                // 按 createTime 升序排序(确保时间顺序)
+                reportList.sort(Comparator.comparing(IotRhDailyReportDO::getCreateTime));
+                BigDecimal cumulativeSum = BigDecimal.ZERO;
+                // 累计注水量
+                BigDecimal cumulativeSumWater = BigDecimal.ZERO;
+                // 累计用电量
+                BigDecimal cumulativeSumPower = BigDecimal.ZERO;
+                // 累计油耗
+                BigDecimal cumulativeSumFuel = BigDecimal.ZERO;
+                for (IotRhDailyReportDO report : reportList) {
+                    // 累加当前日报的注气量
+                    cumulativeSum = cumulativeSum.add(Optional.ofNullable(report.getDailyGasInjection()).orElse(BigDecimal.ZERO));
+                    // 存入 map,key=日报ID,value=截止到当前日报的累计注气量
+                    reportCumulativeGasMap.put(report.getId(), cumulativeSum);
+                    // 累计注水量
+                    cumulativeSumWater = cumulativeSumWater.add(Optional.ofNullable(report.getDailyWaterInjection()).orElse(BigDecimal.ZERO));
+                    // 存入 map,key=日报ID,value=截止到当前日报的累计注水量
+                    wellWaterInjectionPair.put(report.getId(), cumulativeSumWater);
+                    // 累计用电量
+                    cumulativeSumPower = cumulativeSumPower.add(Optional.ofNullable(report.getDailyPowerUsage()).orElse(BigDecimal.ZERO));
+                    // 存入 map,key=日报ID,value=截止到当前日报的累计用电量
+                    wellPowerPair.put(report.getId(), cumulativeSumPower);
+                    // 累计油耗
+                    cumulativeSumFuel = cumulativeSumFuel.add(Optional.ofNullable(report.getDailyOilUsage()).orElse(BigDecimal.ZERO));
+                    // 存入 map,key=日报ID,value=截止到当前日报的累计油耗
+                    wellFuelPair.put(report.getId(), cumulativeSumFuel);
+                }
+            }
+        }
+
         // 根据传递的时间筛选获取要查询的 yyyy
         if (ObjUtil.isNotEmpty(pageReqVO.getCreateTime())) {
             // 只有传递了 时间查询条件 才会查询 当年累计的工作量数据
@@ -795,39 +845,74 @@ public class IotRhDailyReportController {
                 List<IotRhDailyReportDO> dailyReports = iotRhDailyReportMapper.dailyReports(reqVO);
                 if (CollUtil.isNotEmpty(dailyReports)) {
                     dailyReports.forEach(report -> {
+                        // 组装每个部门的日报列表
+                        if (deptReportsPair.containsKey(report.getDeptId())) {
+                            List<IotRhDailyReportDO> tempReports = deptReportsPair.get(report.getDeptId());
+                            tempReports.add(report);
+                            deptReportsPair.put(report.getDeptId(), tempReports);
+                        } else {
+                            List<IotRhDailyReportDO> tempReports = new ArrayList<>();
+                            tempReports.add(report);
+                            deptReportsPair.put(report.getDeptId(), tempReports);
+                        }
                         // 注气量
-                        if (yearGasInjectionPair.containsKey(report.getDeptId())) {
+                        /* if (yearGasInjectionPair.containsKey(report.getDeptId())) {
                             BigDecimal tempGasInjection = yearGasInjectionPair.get(report.getDeptId());
                             BigDecimal tempResult = tempGasInjection.add(report.getDailyGasInjection());
                             yearGasInjectionPair.put(report.getDeptId(), tempResult);
                         } else {
                             yearGasInjectionPair.put(report.getDeptId(), report.getDailyGasInjection());
-                        }
+                        } */
                         // 注水量
-                        if (yearWaterInjectionPair.containsKey(report.getDeptId())) {
+                        /* if (yearWaterInjectionPair.containsKey(report.getDeptId())) {
                             BigDecimal tempWaterInjection = yearWaterInjectionPair.get(report.getDeptId());
                             BigDecimal tempResult = tempWaterInjection.add(report.getDailyWaterInjection());
                             yearWaterInjectionPair.put(report.getDeptId(), tempResult);
                         } else {
                             yearWaterInjectionPair.put(report.getDeptId(), report.getDailyWaterInjection());
-                        }
+                        } */
                         // 电量
-                        if (yearPowerPair.containsKey(report.getDeptId())) {
+                        /* if (yearPowerPair.containsKey(report.getDeptId())) {
                             BigDecimal tempPower = yearPowerPair.get(report.getDeptId());
                             BigDecimal tempResult = tempPower.add(report.getDailyPowerUsage());
                             yearPowerPair.put(report.getDeptId(), tempResult);
                         } else {
                             yearPowerPair.put(report.getDeptId(), report.getDailyPowerUsage());
-                        }
+                        } */
                         // 油耗
-                        if (yearFuelPair.containsKey(report.getDeptId())) {
+                        /* if (yearFuelPair.containsKey(report.getDeptId())) {
                             BigDecimal tempFuel = yearFuelPair.get(report.getDeptId());
                             BigDecimal tempResult = tempFuel.add(report.getDailyOilUsage());
                             yearFuelPair.put(report.getDeptId(), tempResult);
                         } else {
                             yearFuelPair.put(report.getDeptId(), report.getDailyOilUsage());
-                        }
+                        } */
                     });
+
+                    // 2. 对每个部门的日报列表按 createTime 排序,计算滚动累计
+                    for (Map.Entry<Long, List<IotRhDailyReportDO>> entry : deptReportsPair.entrySet()) {
+                        List<IotRhDailyReportDO> deptReports = entry.getValue();
+                        deptReports.sort(Comparator.comparing(IotRhDailyReportDO::getCreateTime));
+                        // 累计注气量
+                        BigDecimal cumGas = BigDecimal.ZERO;
+                        // 累计注水量
+                        BigDecimal cumWater = BigDecimal.ZERO;
+                        // 累计用电量
+                        BigDecimal cumPower = BigDecimal.ZERO;
+                        // 累计油耗
+                        BigDecimal cumFuel = BigDecimal.ZERO;
+                        for (IotRhDailyReportDO report : deptReports) {
+                            cumGas = cumGas.add(Optional.ofNullable(report.getDailyGasInjection()).orElse(BigDecimal.ZERO));
+                            cumWater = cumWater.add(Optional.ofNullable(report.getDailyWaterInjection()).orElse(BigDecimal.ZERO));
+                            cumPower = cumPower.add(Optional.ofNullable(report.getDailyPowerUsage()).orElse(BigDecimal.ZERO));
+                            cumFuel = cumFuel.add(Optional.ofNullable(report.getDailyOilUsage()).orElse(BigDecimal.ZERO));
+                            // 存入以日报ID为键的Map
+                            yearGasInjectionPair.put(report.getId(), cumGas);
+                            yearWaterInjectionPair.put(report.getId(), cumWater);
+                            yearPowerPair.put(report.getId(), cumPower);
+                            yearFuelPair.put(report.getId(), cumFuel);
+                        }
+                    }
                 }
             }
         }
@@ -961,41 +1046,41 @@ public class IotRhDailyReportController {
             // 2.1 拼接项目部信息
             findAndThen(projectDeptNamePair, reportVO.getDeptId(), projectDeptName -> reportVO.setProjectDeptName(projectDeptName));
             // 队伍当年累计注气量
-            findAndThen(yearGasInjectionPair, reportVO.getDeptId(), gasInjection -> {
+            findAndThen(yearGasInjectionPair, reportVO.getId(), gasInjection -> {
                 // 转换单位为 万方
                 BigDecimal gasInjectionWanFang = gasInjection
                         .divide(BigDecimal.valueOf(10000), 4, RoundingMode.HALF_UP);
                 reportVO.setYearTotalGasInjection(gasInjectionWanFang);
             });
             // 队伍当年累计注水量
-            findAndThen(yearWaterInjectionPair, reportVO.getDeptId(), waterInjection -> reportVO.setYearTotalWaterInjection(waterInjection));
+            findAndThen(yearWaterInjectionPair, reportVO.getId(), waterInjection -> reportVO.setYearTotalWaterInjection(waterInjection));
             // 队伍当年累计用电量
-            findAndThen(yearPowerPair, reportVO.getDeptId(), power -> {
+            findAndThen(yearPowerPair, reportVO.getId(), power -> {
                 // 换算单位为 MWh
                 BigDecimal powerW = power
                         .divide(BigDecimal.valueOf(1000), 2, RoundingMode.HALF_UP);
                 reportVO.setYearTotalPower(powerW);
             });
             // 队伍当年累计油耗
-            findAndThen(yearFuelPair, reportVO.getDeptId(), fuel -> reportVO.setYearTotalFuel(fuel));
+            findAndThen(yearFuelPair, reportVO.getId(), fuel -> reportVO.setYearTotalFuel(fuel));
             // 井当年累计注气量
-            findAndThen(wellGasInjectionPair, reportVO.getTaskId(), gasInjection -> {
+            findAndThen(reportCumulativeGasMap, reportVO.getId(), gasInjection -> {
                 // 转换单位为 万方
                 BigDecimal gasInjectionWanFang = gasInjection
                         .divide(BigDecimal.valueOf(10000), 4, RoundingMode.HALF_UP);
                 reportVO.setWellTotalGasInjection(gasInjectionWanFang);
             });
             // 井当年累计注水量
-            findAndThen(wellWaterInjectionPair, reportVO.getTaskId(), waterInjection -> reportVO.setWellTotalWaterInjection(waterInjection));
+            findAndThen(wellWaterInjectionPair, reportVO.getId(), waterInjection -> reportVO.setWellTotalWaterInjection(waterInjection));
             // 井当年累计用电量
-            findAndThen(wellPowerPair, reportVO.getTaskId(), power -> {
+            findAndThen(wellPowerPair, reportVO.getId(), power -> {
                 // 换算单位为 MWh
                 BigDecimal powerW = power
                         .divide(BigDecimal.valueOf(1000), 2, RoundingMode.HALF_UP);
                 reportVO.setWellTotalPower(powerW);
             });
             // 井当年累计油耗
-            findAndThen(wellFuelPair, reportVO.getTaskId(), fuel -> reportVO.setWellTotalFuel(fuel));
+            findAndThen(wellFuelPair, reportVO.getId(), fuel -> reportVO.setWellTotalFuel(fuel));
             // 2.2 日报关联的项目信息
             findAndThen(projectPair, reportVO.getProjectId(), contractName -> reportVO.setContractName(contractName));
             // 2.3 日报关联的任务井号
@@ -1401,10 +1486,10 @@ public class IotRhDailyReportController {
                 reportVO.setDailyPowerUsage(powerW);
             }
 
-            // 转换当日油耗 原始单位 方 转换成 万方
+            // 转换当日注气量 原始单位 方 转换成 万方
             if (reportVO.getDailyGasInjection().compareTo(BigDecimal.ZERO) > 0) {
                 BigDecimal gasW = reportVO.getDailyGasInjection()
-                        .divide(BigDecimal.valueOf(10000), 2, RoundingMode.HALF_UP);
+                        .divide(BigDecimal.valueOf(10000), 4, RoundingMode.HALF_UP);
                 reportVO.setDailyGasInjection(gasW);
             }
 
@@ -1416,7 +1501,7 @@ public class IotRhDailyReportController {
             // 小组内累计注气量 精确到单位 万方
             findAndThen(groupIdGasInjectionPair, reportVO.getId(), gasInjection -> {
                 BigDecimal gasInjectionWanFang = gasInjection
-                        .divide(BigDecimal.valueOf(10000), 2, RoundingMode.HALF_UP);
+                        .divide(BigDecimal.valueOf(10000), 4, RoundingMode.HALF_UP);
                 reportVO.setGroupIdGasInjection(gasInjectionWanFang);
             });
             // 小组内累计注水量
@@ -1848,10 +1933,10 @@ public class IotRhDailyReportController {
                 reportVO.setDailyPowerUsage(powerW);
             }
 
-            // 转换当日油耗 原始单位 方 转换成 万方
+            // 转换当日注气量 原始单位 方 转换成 万方
             if (reportVO.getDailyGasInjection().compareTo(BigDecimal.ZERO) > 0) {
                 BigDecimal gasW = reportVO.getDailyGasInjection()
-                        .divide(BigDecimal.valueOf(10000), 2, RoundingMode.HALF_UP);
+                        .divide(BigDecimal.valueOf(10000), 4, RoundingMode.HALF_UP);
                 reportVO.setDailyGasInjection(gasW);
             }
 
@@ -1863,7 +1948,7 @@ public class IotRhDailyReportController {
             // 小组内累计注气量
             findAndThen(groupIdGasInjectionPair, reportVO.getId(), gasInjection -> {
                 BigDecimal gasInjectionWanFang = gasInjection
-                        .divide(BigDecimal.valueOf(10000), 2, RoundingMode.HALF_UP);
+                        .divide(BigDecimal.valueOf(10000), 4, RoundingMode.HALF_UP);
                 reportVO.setGroupIdGasInjection(gasInjectionWanFang);
             });
             // 小组内累计注水量

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

@@ -1076,6 +1076,8 @@ public class IotRyDailyReportController {
         Map<Long, BigDecimal> groupIdZjNoProductTimePair = new HashMap<>();
         // key小组最后1条记录id    value 小计平均运行时效
         Map<Long, BigDecimal> groupIdTransTimePair = new HashMap<>();
+        // key日报id   value生产动态明细
+        Map<Long, List<IotRyDailyReportDetailRespVO>> reportDetailsPair = new HashMap<>();
 
         // 查询 当前分页 所有部门 任务井 日报数据 小计工作量
         IotRyDailyReportPageReqVO currentTaskReqVO = new IotRyDailyReportPageReqVO();
@@ -1244,6 +1246,27 @@ public class IotRyDailyReportController {
             });
         }
 
+        // 查询每个日报的生产动态明细
+        IotRyDailyReportDetailPageReqVO detailReqVO = new IotRyDailyReportDetailPageReqVO();
+        detailReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
+        detailReqVO.setReportIds(convertList(reports, IotRyDailyReportDO::getId));
+        PageResult<IotRyDailyReportDetailDO> reportDetailsPage = iotRyDailyReportDetailMapper.selectPage(detailReqVO);
+        List<IotRyDailyReportDetailDO> reportDetails = reportDetailsPage.getList();
+        if (CollUtil.isNotEmpty(reportDetails)) {
+            // 设置每个日报的生产动态明细
+            reportDetails.forEach(detail -> {
+                if (reportDetailsPair.containsKey(detail.getReportId())) {
+                    List<IotRyDailyReportDetailRespVO> tempDetails = reportDetailsPair.get(detail.getReportId());
+                    tempDetails.add(BeanUtils.toBean(detail, IotRyDailyReportDetailRespVO.class));
+                    reportDetailsPair.put(detail.getReportId(), tempDetails);
+                } else {
+                    List<IotRyDailyReportDetailRespVO> tempDetails = new ArrayList<>();
+                    tempDetails.add(BeanUtils.toBean(detail, IotRyDailyReportDetailRespVO.class));
+                    reportDetailsPair.put(detail.getReportId(), tempDetails);
+                }
+            });
+        }
+
         DataPermissionUtils.executeIgnore(() -> {
             // 查询日报关联的项目信息
             IotProjectInfoPageReqVO reqVO = new IotProjectInfoPageReqVO();
@@ -1360,6 +1383,29 @@ public class IotRyDailyReportController {
                 reportVO.setDailyFuel(fuel);
             }
 
+            // 生产动态明细
+            findAndThen(reportDetailsPair, reportVO.getId(), details -> {
+                // 每个日报的明细 根据 reportDate+startTime 正序排列
+                details.sort(Comparator.comparing(
+                                // 处理 reportDate 为空的情况
+                                (IotRyDailyReportDetailRespVO detail) -> {
+                                    if (detail.getReportDate() == null) {
+                                        return null; // null 值会排在前面
+                                    }
+                                    return detail.getReportDate().toLocalDate();
+                                },
+                                // 自定义 null 值比较器:null 排在非 null 前面
+                                Comparator.nullsFirst(Comparator.naturalOrder())
+                        )
+                        .thenComparing(
+                                // 处理 startTime 为空的情况
+                                IotRyDailyReportDetailRespVO::getStartTime,
+                                // 自定义 null 值比较器:null 排在非 null 前面
+                                Comparator.nullsFirst(Comparator.naturalOrder())
+                        ));
+                reportVO.setReportDetails(details);
+            });
+
             // 小组内最后1条记录标识
             findAndThen(groupIdFootagePair, reportVO.getId(), footage -> reportVO.setLastGroupIdFlag(true));
             // 小组内累计进尺
@@ -1490,6 +1536,8 @@ public class IotRyDailyReportController {
         Map<Long, BigDecimal> groupIdZjNoProductTimePair = new HashMap<>();
         // key小组最后1条记录id    value 小计平均运行时效
         Map<Long, BigDecimal> groupIdTransTimePair = new HashMap<>();
+        // key日报id   value生产动态明细
+        Map<Long, List<IotRyDailyReportDetailRespVO>> reportDetailsPair = new HashMap<>();
 
         // 查询 当前分页 所有部门 任务井 日报数据 小计工作量
         IotRyDailyReportPageReqVO currentTaskReqVO = new IotRyDailyReportPageReqVO();
@@ -1658,6 +1706,27 @@ public class IotRyDailyReportController {
             });
         }
 
+        // 查询每个日报的生产动态明细
+        IotRyDailyReportDetailPageReqVO detailReqVO = new IotRyDailyReportDetailPageReqVO();
+        detailReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
+        detailReqVO.setReportIds(convertList(reports, IotRyDailyReportDO::getId));
+        PageResult<IotRyDailyReportDetailDO> reportDetailsPage = iotRyDailyReportDetailMapper.selectPage(detailReqVO);
+        List<IotRyDailyReportDetailDO> reportDetails = reportDetailsPage.getList();
+        if (CollUtil.isNotEmpty(reportDetails)) {
+            // 设置每个日报的生产动态明细
+            reportDetails.forEach(detail -> {
+                if (reportDetailsPair.containsKey(detail.getReportId())) {
+                    List<IotRyDailyReportDetailRespVO> tempDetails = reportDetailsPair.get(detail.getReportId());
+                    tempDetails.add(BeanUtils.toBean(detail, IotRyDailyReportDetailRespVO.class));
+                    reportDetailsPair.put(detail.getReportId(), tempDetails);
+                } else {
+                    List<IotRyDailyReportDetailRespVO> tempDetails = new ArrayList<>();
+                    tempDetails.add(BeanUtils.toBean(detail, IotRyDailyReportDetailRespVO.class));
+                    reportDetailsPair.put(detail.getReportId(), tempDetails);
+                }
+            });
+        }
+
         DataPermissionUtils.executeIgnore(() -> {
             // 查询日报关联的项目信息
             IotProjectInfoPageReqVO reqVO = new IotProjectInfoPageReqVO();
@@ -1760,6 +1829,29 @@ public class IotRyDailyReportController {
                 reportVO.setDailyFuel(fuel);
             }
 
+            // 生产动态明细
+            findAndThen(reportDetailsPair, reportVO.getId(), details -> {
+                // 每个日报的明细 根据 reportDate+startTime 正序排列
+                details.sort(Comparator.comparing(
+                                // 处理 reportDate 为空的情况
+                                (IotRyDailyReportDetailRespVO detail) -> {
+                                    if (detail.getReportDate() == null) {
+                                        return null; // null 值会排在前面
+                                    }
+                                    return detail.getReportDate().toLocalDate();
+                                },
+                                // 自定义 null 值比较器:null 排在非 null 前面
+                                Comparator.nullsFirst(Comparator.naturalOrder())
+                        )
+                        .thenComparing(
+                                // 处理 startTime 为空的情况
+                                IotRyDailyReportDetailRespVO::getStartTime,
+                                // 自定义 null 值比较器:null 排在非 null 前面
+                                Comparator.nullsFirst(Comparator.naturalOrder())
+                        ));
+                reportVO.setReportDetails(details);
+            });
+
             // 小组内最后1条记录标识
             findAndThen(groupIdFootagePair, reportVO.getId(), footage -> reportVO.setLastGroupIdFlag(true));
             // 小组内累计进尺