ソースを参照

pms 生成5#国定时任务逻辑调整 每个部门固定生成日报 不管有没有创建任务。

zhangcl 1 日 前
コミット
ac408fe185

+ 161 - 6
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/job/dailyreport/CreateFiveDailyReportOrderJob.java

@@ -1,8 +1,7 @@
 package cn.iocoder.yudao.module.pms.job.dailyreport;
 
 import cn.hutool.core.collection.CollUtil;
-import cn.hutool.core.date.LocalDateTimeUtil;
-import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.common.pojo.PageParam;
 import cn.iocoder.yudao.framework.quartz.core.handler.JobHandler;
 import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore;
 import cn.iocoder.yudao.module.pms.constant.PmsConstants;
@@ -15,6 +14,7 @@ import cn.iocoder.yudao.module.pms.service.iotfivedailyreport.IotFiveDailyReport
 import cn.iocoder.yudao.module.pms.service.iotprojecttask.IotProjectTaskService;
 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.service.dept.DeptService;
 import lombok.extern.slf4j.Slf4j;
@@ -27,9 +27,9 @@ import java.time.LocalDate;
 import java.time.LocalDateTime;
 import java.time.LocalTime;
 import java.util.*;
-import java.util.concurrent.CountDownLatch;
+import java.util.function.Function;
+import java.util.stream.Collectors;
 
-import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
 import static cn.iocoder.yudao.module.pms.framework.config.MultiThreadConfiguration.PMS_THREAD_POOL_TASK_EXECUTOR;
 
 /**
@@ -53,7 +53,7 @@ public class CreateFiveDailyReportOrderJob implements JobHandler {
     @Resource
     private DeptService deptService;
 
-    @Override
+    /* @Override
     @TenantIgnore
     public String execute(String param) throws Exception {
 
@@ -78,7 +78,24 @@ public class CreateFiveDailyReportOrderJob implements JobHandler {
                 }
             });
         }
-        
+
+        // 查询5#国所有的 施工队伍 key部门id   value部门名称
+        Map<Long, String> teamPair = new HashMap<>();
+        Set<Long> allFiveChildDeptIds = deptService.getChildDeptIdListFromCache(388l);
+        if (CollUtil.isNotEmpty(allFiveChildDeptIds)) {
+            DeptListReqVO reqVO = new DeptListReqVO();
+            reqVO.setDeptIds(allFiveChildDeptIds);
+            List<DeptDO> fiveDepartments = deptService.getDeptList(reqVO);
+            if (CollUtil.isNotEmpty(fiveDepartments)) {
+                fiveDepartments.forEach(dept -> {
+                    if ("3".equals(dept.getType())) {
+                        // 组装队伍集合
+                        teamPair.put(dept.getId(), dept.getName());
+                    }
+                });
+            }
+        }
+
         // 查询 5#公司 相关的项目任务 根据每个任务的填报人进行工单生成和推送
         IotProjectTaskPageReqVO taskReqVO = new IotProjectTaskPageReqVO();
         taskReqVO.setCompanyId(388l);
@@ -213,5 +230,143 @@ public class CreateFiveDailyReportOrderJob implements JobHandler {
             });
         }
         return "创建成功";
+    } */
+
+    @Override
+    @TenantIgnore
+    public String execute(String param) throws Exception {
+        LocalDate today = LocalDate.now();
+        IotFiveDailyReportPageReqVO reqVO = new IotFiveDailyReportPageReqVO();
+        reqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
+        // 1. 当天已有日报的去重集合
+        List<IotFiveDailyReportDO> allReports = iotFiveDailyReportService
+                .getIotFiveDailyReportPage(reqVO).getList();
+        Set<Long> existedTaskIds = new HashSet<>();
+        Set<Long> existedEmptyDeptIds = new HashSet<>();
+        for (IotFiveDailyReportDO report : allReports) {
+            if (report.getCreateTime().toLocalDate().equals(today)) {
+                if (report.getTaskId() != null) {
+                    existedTaskIds.add(report.getTaskId());
+                } else {
+                    existedEmptyDeptIds.add(report.getDeptId());
+                }
+            }
+        }
+
+        // 2. 获取所有施工队伍部门(type=3)并构建部门信息映射
+        Set<Long> childDeptIds = deptService.getChildDeptIdListFromCache(388L);
+        List<DeptDO> deptList = deptService.getDeptList(new DeptListReqVO().setDeptIds(childDeptIds));
+        Map<Long, DeptDO> deptMap = deptList.stream()
+                .filter(d -> "3".equals(d.getType()))
+                .collect(Collectors.toMap(DeptDO::getId, Function.identity()));
+
+        // 3. 查询所有非完工任务,构建 deptId → 任务列表 映射
+        IotProjectTaskPageReqVO taskReq = new IotProjectTaskPageReqVO();
+        taskReq.setCompanyId(388L);
+        taskReq.setJobFlag("Y");
+        List<IotProjectTaskDO> allTasks = iotProjectTaskService.projectTasks(taskReq);
+        Map<Long, List<IotProjectTaskDO>> deptTasksMap = new HashMap<>();
+        for (IotProjectTaskDO task : allTasks) {
+            if (CollUtil.isNotEmpty(task.getDeptIds())) {
+                for (Long deptId : task.getDeptIds()) {
+                    deptTasksMap.computeIfAbsent(deptId, k -> new ArrayList<>()).add(task);
+                }
+            }
+        }
+
+        // 4. 收集所有需要查询的用户ID(提前统一查询,避免循环内调用)
+        Set<Long> allUserIds = new HashSet<>();
+        for (IotProjectTaskDO task : allTasks) {
+            if (CollUtil.isNotEmpty(task.getResponsiblePerson())) {
+                allUserIds.addAll(task.getResponsiblePerson());
+            }
+        }
+        deptMap.values().forEach(d -> {
+            if (d.getLeaderUserId() != null) allUserIds.add(d.getLeaderUserId());
+        });
+        Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(allUserIds);
+
+        // 5. 按部门生成日报
+        List<IotFiveDailyReportDO> newReports = new ArrayList<>();
+        for (Map.Entry<Long, DeptDO> entry : deptMap.entrySet()) {
+            Long deptId = entry.getKey();
+            DeptDO dept = entry.getValue();
+            List<IotProjectTaskDO> deptTasks = deptTasksMap.getOrDefault(deptId, Collections.emptyList());
+
+            if (CollUtil.isNotEmpty(deptTasks)) {
+                // 有任务 → 为每个未生成日报的任务创建日报
+                for (IotProjectTaskDO task : deptTasks) {
+                    if (!existedTaskIds.contains(task.getId()) && CollUtil.isNotEmpty(task.getResponsiblePerson())) {
+                        Long creatorId = new ArrayList<>(task.getResponsiblePerson()).get(0);
+                        newReports.add(buildReportWithTask(dept, task, creatorId, today));
+                    }
+                }
+            } else {
+                // 无任务 → 为该部门生成一份空日报(当天只生成一次)
+                if (!existedEmptyDeptIds.contains(deptId)) {
+                    Long creatorId = dept.getLeaderUserId();
+                    newReports.add(buildEmptyReport(dept, creatorId, today));
+                }
+            }
+        }
+
+        // 6. 批量保存
+        if (CollUtil.isNotEmpty(newReports)) {
+            iotFiveDailyReportService.batchAddDailyReports(newReports);
+        }
+
+        // 7. 异步发送消息(仅对有填报人的日报)
+        if (CollUtil.isNotEmpty(newReports)) {
+            Set<Long> creatorIds = newReports.stream()
+                    .map(r -> {
+                        try { return Long.valueOf(r.getCreator()); } catch (Exception e) { return null; }
+                    })
+                    .filter(Objects::nonNull)
+                    .collect(Collectors.toSet());
+            Map<Long, AdminUserRespDTO> creatorUserMap = adminUserApi.getUserMap(creatorIds);
+            for (IotFiveDailyReportDO report : newReports) {
+                Long creatorId = Long.valueOf(report.getCreator());
+                AdminUserRespDTO user = creatorUserMap.get(creatorId);
+                if (user != null && user.getMobile() != null) {
+                    pmsThreadPoolTaskExecutor.execute(() ->
+                            pmsMessage.sendMessage(report.getId(), report.getReportName(),
+                                    PmsConstants.DAILY_REPORT, creatorId, user.getMobile()));
+                }
+            }
+        }
+        return "创建成功";
+    }
+
+    // 创建关联任务的日报
+    private IotFiveDailyReportDO buildReportWithTask(DeptDO dept, IotProjectTaskDO task, Long creatorId, LocalDate today) {
+        IotFiveDailyReportDO report = new IotFiveDailyReportDO();
+        report.setDeptId(dept.getId());
+        report.setProjectId(task.getProjectId());
+        report.setTaskId(task.getId());
+        report.setDeviceIds(task.getDeviceIds());
+        report.setCreator(String.valueOf(creatorId));
+        fillCommonFields(report, dept, today);
+        return report;
     }
+
+    // 创建无任务的空日报
+    private IotFiveDailyReportDO buildEmptyReport(DeptDO dept, Long creatorId, LocalDate today) {
+        IotFiveDailyReportDO report = new IotFiveDailyReportDO();
+        report.setDeptId(dept.getId());
+        report.setCreator(creatorId != null ? String.valueOf(creatorId) : "0");
+        fillCommonFields(report, dept, today);
+        return report;
+    }
+
+    // 填充公共字段
+    private void fillCommonFields(IotFiveDailyReportDO report, DeptDO dept, LocalDate today) {
+        String deptName = dept.getName().split("~~")[0];
+        report.setReportName(deptName + "/" + today + "日报填报");
+        report.setStartTime(LocalTime.of(8, 0, 0));
+        report.setEndTime(LocalTime.of(8, 0, 0));
+        report.setConstructionStartDate(LocalDateTime.of(today, LocalTime.of(8, 0, 0)));
+        report.setConstructionEndDate(LocalDateTime.of(today.plusDays(1), LocalTime.of(8, 0, 0)));
+        report.setCreateTime(LocalDateTime.now());
+    }
+
 }

+ 3 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/service/iotfivedailyreport/IotFiveDailyReportServiceImpl.java

@@ -97,11 +97,14 @@ public class IotFiveDailyReportServiceImpl implements IotFiveDailyReportService
             if (ObjUtil.isNotEmpty(task)) {
                 task.setStatus(updateReqVO.getFiveStatus());
                 task.setRdStatus(updateReqVO.getFiveStatus());
+                Set<Long> deviceIds = task.getDeviceIds();
                 int num = iotProjectTaskMapper.updateById(task);
                 // 有可能重新选择任务井 根据taskId 查询相关的项目 projectId 重新赋值
                 updateObj.setProjectId(task.getProjectId());
+                updateObj.setDeviceIds(deviceIds);
             }
         }
+        // 查询当前日报关联的任务 带入任务关联的 设备id列表
 
         iotFiveDailyReportMapper.updateById(updateObj);
         // 将生产异常情况 (npt 工程质量 > 0) 发送到拥有 生产异常通知 角色的人员