浏览代码

pms 瑞恒日报 统计未填报数据

zhangcl 3 天之前
父节点
当前提交
bd83948634

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

@@ -137,6 +137,14 @@ public class IotRhDailyReportController {
         return success(statistics);
     }
 
+    @GetMapping("/rhUnReportDetails")
+    @Operation(summary = "按照日期查询瑞恒日报统计数据 未填报队伍明细")
+    @PreAuthorize("@ss.hasPermission('pms:iot-rh-daily-report:query')")
+    public CommonResult<List<IotRhDailyReportStatisticsVO>> rhUnReportDetails(@Valid IotRhDailyReportPageReqVO pageReqVO) {
+        List<IotRhDailyReportStatisticsVO> statistics = iotRhDailyReportService.rhUnReportedDetails(pageReqVO);
+        return success(statistics);
+    }
+
     @GetMapping("/dailyReportSummary")
     @Operation(summary = "瑞恒日报汇总")
     @PreAuthorize("@ss.hasPermission('pms:iot-rh-daily-report:query')")

+ 5 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/iotrhdailyreport/vo/IotRhDailyReportStatisticsVO.java

@@ -12,4 +12,9 @@ public class IotRhDailyReportStatisticsVO {
     @Schema(description = "已填报 未填报 小队 数量")
     private long count;
 
+    @Schema(description = "队伍名称")
+    private String deptNames;
+
+    @Schema(description = "日期 2025-01-01")
+    private String reportDate;
 }

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

@@ -65,6 +65,14 @@ public interface IotRhDailyReportService {
      */
     List<IotRhDailyReportStatisticsVO> rhDailyReportStatistics(IotRhDailyReportPageReqVO pageReqVO);
 
+    /**
+     * 按照日期查询瑞恒日报统计数据 未填报队伍明细
+     *
+     * @param pageReqVO 查询参数
+     * @return 未填报队伍明细
+     */
+    List<IotRhDailyReportStatisticsVO> rhUnReportedDetails(IotRhDailyReportPageReqVO pageReqVO);
+
     /**
      * 查询任务的实际进度
      *

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

@@ -40,9 +40,11 @@ import java.math.BigDecimal;
 import java.math.RoundingMode;
 import java.time.LocalDate;
 import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
 import java.time.temporal.ChronoUnit;
 import java.util.*;
 import java.util.concurrent.atomic.AtomicReference;
+import java.util.stream.Collectors;
 
 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
 import static cn.iocoder.yudao.module.pms.enums.ErrorCodeConstant.*;
@@ -373,12 +375,7 @@ public class IotRhDailyReportServiceImpl implements IotRhDailyReportService {
         List<IotRhDailyReportStatisticsVO> results = new ArrayList<>();
         // 查询 瑞恒157l 所有存在设备的队伍
         // 查询瑞恒下所有部门
-        Set<Long> ids = new HashSet<>();
-        ids = deptService.getChildDeptIdListFromCache(157l);
-        ids.add(reqVO.getDeptId());
-        // 查询ids下包含的所有设备 设备对应的部门就是 小队全集
-        IotDevicePageReqVO deviceReqVO = new IotDevicePageReqVO();
-        List<IotDeviceDO> devices = iotDeviceMapper.selectSimpleList(deviceReqVO, ids);
+        List<IotDeviceDO> devices = devices();
         // 所有需要填报日报的 瑞恒 队伍集合
         Set<Long> deptIds = new HashSet<>();
         if (CollUtil.isNotEmpty(devices)){
@@ -420,6 +417,142 @@ public class IotRhDailyReportServiceImpl implements IotRhDailyReportService {
         return results;
     }
 
+    @Override
+    public List<IotRhDailyReportStatisticsVO> rhUnReportedDetails(IotRhDailyReportPageReqVO reqVO) {
+        // 查询所有未填报日报的队伍名称 HY-A1,HY-A2...
+        // 首先必须传递了日期范围
+        if (reqVO.getCreateTime().length == 0) {
+            // 必须传递时间区间参数
+            throw exception(IOT_DAILY_REPORT_TIME_NOT_EXISTS);
+        }
+        List<IotRhDailyReportStatisticsVO> results = new ArrayList<>();
+        List<IotDeviceDO> devices = devices();
+        // 所有需要填报日报的 瑞恒 队伍集合
+        Set<Long> deptIds = new HashSet<>();
+        List<String> reportDates = new ArrayList<>();
+        if (CollUtil.isNotEmpty(devices)){
+            devices.forEach(device -> {
+                deptIds.add(device.getDeptId());
+            });
+            // 根据指定的时间区间 计算出天数
+            LocalDateTime[] createTimes = reqVO.getCreateTime();
+            // 获取开始时间和结束时间
+            LocalDateTime startTime = createTimes[0];
+            LocalDateTime endTime = createTimes[1];
+            // 截断到日期(忽略时分秒)
+            LocalDate startDate = startTime.toLocalDate();
+            LocalDate endDate = endTime.toLocalDate();
+            // 将时间区间拆分成具体的每天 计算每天未填报日报的队伍明细
+            Set<LocalDate> dateSet = new HashSet<>();
+            LocalDate currentDate = startDate;
+            // 循环添加从开始日期到结束日期的所有日期(包含两端)
+            while (!currentDate.isAfter(endDate)) {
+                dateSet.add(currentDate);
+                currentDate = currentDate.plusDays(1); // 日期加1天
+            }
+            // 转换为字符串格式的日期集合(如:2025-10-06)
+            reportDates = dateSet.stream()
+                    .map(date -> date.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")))
+                    .collect(Collectors.toList());
+            // 比如有20个队伍 某个时间区间D内 必须有20*D份日报 时间区间最好是1天
+            // 查询出指定时间区间内 已经填写的日报数量
+            List<IotRhDailyReportDO> dailyReports = iotRhDailyReportMapper.dailyReports(reqVO);
+            // 已经填报的队伍名称集合
+            Map<String, List<String>> reportedDeptNames = new HashMap<>();
+            // 未填报的队伍名称集合
+            Map<String, List<String>> unReportedDeptNames = new HashMap<>();
+            // 查询所有部门信息
+            Map<Long, DeptDO> allDepts = deptService.getDeptMap(deptIds);
+            // 过滤后的所有部门信息
+            Map<Long, DeptDO> filteredDepts = new HashMap<>();
+            // 过滤掉部门中的 ‘项目部’
+            if (CollUtil.isNotEmpty(allDepts)) {
+                allDepts.forEach((deptId, dept) -> {
+                    if (!dept.getName().contains("项目部") && !dept.getName().contains("瑞恒兴域")
+                            && !dept.getName().contains("基地") && !dept.getName().contains("服务部")) {
+                        filteredDepts.put(deptId, dept);
+                    }
+                });
+            }
+            if (CollUtil.isNotEmpty(dailyReports)) {
+                // 组装每天填写的日报集合 从而统计出每天未填写日报的队伍
+                dailyReports.forEach(report -> {
+                    Long tempDeptId = report.getDeptId();
+                    if (filteredDepts.containsKey(tempDeptId)) {
+                        String deptName = filteredDepts.get(tempDeptId).getName();
+                        LocalDateTime createTime = report.getCreateTime();
+                        LocalDate tempDate = createTime.toLocalDate();
+                        String tempReportDate = tempDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
+                        if (reportedDeptNames.containsKey(tempReportDate)) {
+                            List<String> tempDeptNames = reportedDeptNames.get(tempReportDate);
+                            tempDeptNames.add(deptName);
+                            reportedDeptNames.put(tempReportDate, tempDeptNames);
+                        } else {
+                            List<String> tempDeptNames = new ArrayList<>();
+                            tempDeptNames.add(deptName);
+                            reportedDeptNames.put(tempReportDate, tempDeptNames);
+                        }
+                    }
+                });
+            }
+            // 遍历所有时间区间的日期 组装每个日期中 未填写日报的队伍名称集合
+            if (CollUtil.isNotEmpty(reportDates)) {
+                reportDates.forEach(dateStr -> {
+                    // 对时间区间内每个日期 都经过已经填报日报的过滤
+                    if (reportedDeptNames.containsKey(dateStr)) {
+                        List<String> tempReportedDeptNames = reportedDeptNames.get(dateStr);
+                        filteredDepts.forEach((deptId, dept) -> {
+                            if (!tempReportedDeptNames.contains(dept.getName())) {
+                                if (unReportedDeptNames.containsKey(dateStr)) {
+                                    List<String> tempDeptNames = unReportedDeptNames.get(dateStr);
+                                    tempDeptNames.add(dept.getName());
+                                    unReportedDeptNames.put(dateStr, tempDeptNames);
+                                } else {
+                                    List<String> tempDeptNames = new ArrayList<>();
+                                    tempDeptNames.add(dept.getName());
+                                    unReportedDeptNames.put(dateStr, tempDeptNames);
+                                }
+                            }
+                        });
+                    } else {
+                        // 当天没有任何队伍填写日报
+                        filteredDepts.forEach((deptId, dept) -> {
+                            List<String> tempDeptNames = new ArrayList<>();
+                            tempDeptNames.add(dept.getName());
+                            unReportedDeptNames.put(dateStr, tempDeptNames);
+                        });
+                    }
+                });
+            }
+            // 将集合中的未填报日报的队伍集合转换成 逗号 分隔的字符串
+            if (CollUtil.isNotEmpty(unReportedDeptNames)) {
+                unReportedDeptNames.forEach((reportDate, deptList) -> {
+                    IotRhDailyReportStatisticsVO dailyReportVO = new IotRhDailyReportStatisticsVO();
+                    dailyReportVO.setReportDate(reportDate);
+                    dailyReportVO.setDeptNames(deptList.stream().collect(Collectors.joining(",")));
+                    results.add(dailyReportVO);
+                });
+                // 使用Comparator进行排序
+                results.sort(Comparator
+                        .comparing(IotRhDailyReportStatisticsVO::getReportDate,
+                                Comparator.nullsLast(Comparator.reverseOrder())));
+            }
+        }
+        return results;
+    }
+
+    private List<IotDeviceDO> devices() {
+        // 查询 瑞恒157l 所有存在设备的队伍
+        // 查询瑞恒下所有部门
+        Set<Long> ids = new HashSet<>();
+        ids = deptService.getChildDeptIdListFromCache(157l);
+        ids.add(157l);
+        // 查询ids下包含的所有设备 设备对应的部门就是 小队全集
+        IotDevicePageReqVO deviceReqVO = new IotDevicePageReqVO();
+        List<IotDeviceDO> devices = iotDeviceMapper.selectSimpleList(deviceReqVO, ids);
+        return devices;
+    }
+
     @Override
     public List<IotRhDailyReportDO> taskActualProgress(IotRhDailyReportPageReqVO reqVO) {
         if (ObjUtil.isEmpty(reqVO.getTaskId())) {