Răsfoiți Sursa

pms 瑞鹰项目启动设备整改 定时任务生成日报

zhangcl 23 ore în urmă
părinte
comite
fcacf591fe

+ 7 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/iotryimprovedailyreport/vo/IotRyImproveDailyReportPageReqVO.java

@@ -9,6 +9,7 @@ import org.springframework.format.annotation.DateTimeFormat;
 
 import java.math.BigDecimal;
 import java.time.LocalDateTime;
+import java.util.Collection;
 
 import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
 
@@ -236,4 +237,10 @@ public class IotRyImproveDailyReportPageReqVO extends PageParam {
     @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
     private LocalDateTime[] createTime;
 
+    /**
+     * 扩展字段
+     */
+    @Schema(description = "部门id集合")
+    private Collection<Long> deptIds;
+
 }

+ 196 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/job/dailyreport/CreateRyImproveDailyReportOrderJob.java

@@ -0,0 +1,196 @@
+package cn.iocoder.yudao.module.pms.job.dailyreport;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.date.LocalDateTimeUtil;
+import cn.hutool.core.util.ObjUtil;
+import cn.hutool.core.util.StrUtil;
+import cn.iocoder.yudao.framework.common.pojo.PageParam;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+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;
+import cn.iocoder.yudao.module.pms.controller.admin.iotryimprovedailyreport.vo.IotRyImproveDailyReportPageReqVO;
+import cn.iocoder.yudao.module.pms.dal.dataobject.iotryimprovedailyreport.IotRyImproveDailyReportDO;
+import cn.iocoder.yudao.module.pms.dal.mysql.iotryimprovedailyreport.IotRyImproveDailyReportMapper;
+import cn.iocoder.yudao.module.pms.message.PmsMessage;
+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.dal.dataobject.dept.DeptDO;
+import cn.iocoder.yudao.module.system.dal.dataobject.dict.DictDataDO;
+import cn.iocoder.yudao.module.system.dal.dataobject.permission.RoleDO;
+import cn.iocoder.yudao.module.system.dal.dataobject.permission.UserRoleDO;
+import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
+import cn.iocoder.yudao.module.system.dal.mysql.permission.UserRoleMapper;
+import cn.iocoder.yudao.module.system.service.dept.DeptService;
+import cn.iocoder.yudao.module.system.service.dict.DictDataService;
+import cn.iocoder.yudao.module.system.service.permission.RoleService;
+import cn.iocoder.yudao.module.system.service.user.AdminUserService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+import java.time.LocalDateTime;
+import java.util.*;
+import java.util.concurrent.CountDownLatch;
+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;
+
+/**
+ * 瑞鹰 项目启动设备整改 日报定时任务
+ * 每天 22:00 生成日报
+ */
+@Component
+@Slf4j
+public class CreateRyImproveDailyReportOrderJob implements JobHandler {
+    @Resource
+    private AdminUserApi adminUserApi;
+
+    @Resource(name = PMS_THREAD_POOL_TASK_EXECUTOR)
+    private ThreadPoolTaskExecutor pmsThreadPoolTaskExecutor;
+    @Resource
+    private PmsMessage pmsMessage;
+    @Resource
+    private DeptService deptService;
+
+    @Resource
+    private DictDataService dictDataService;
+    @Resource
+    private AdminUserService adminUserService;
+    @Resource
+    private RoleService roleService;
+    @Resource
+    private UserRoleMapper userRoleMapper;
+    @Resource
+    private IotRyImproveDailyReportMapper iotRyImproveDailyReportMapper;
+
+    @Override
+    @TenantIgnore
+    public String execute(String param) throws Exception {
+        // 查询数据字典中 需要生成 瑞鹰项目启动设备整改 日报的部门
+        // 筛选部门下具有 角色 '项目启动设备整改RY' 的 人员 设置为 日报的创建人
+        // 修井 施工状态 字典数据
+        Set<Long> departmentIds = new HashSet<>();
+        List<DictDataDO> improveReportDeptDictData = dictDataService.getDictDataListByDictType("rq_iot_improve_report_dept");
+        if (CollUtil.isNotEmpty(improveReportDeptDictData)) {
+            improveReportDeptDictData.forEach(data -> {
+                departmentIds.add(Long.valueOf(data.getValue()));
+            });
+        }
+
+        if (CollUtil.isNotEmpty(departmentIds)) {
+            Set<Long> projectDeptIds = new HashSet<>();
+            projectDeptIds.addAll(departmentIds);
+            List<AdminUserDO> receivedMsgUsers = adminUserService.getUserListByDeptIds(projectDeptIds);
+            Set<Long> userIds = new HashSet<>();
+            if (CollUtil.isNotEmpty(receivedMsgUsers)) {
+                receivedMsgUsers.forEach(user -> {
+                    userIds.add(user.getId());
+                });
+            }
+            RoleDO role = roleService.getRoleByCode("项目部日报审批RY");
+            if (ObjUtil.isNotEmpty(role)) {
+                Set<Long> roleIds = new HashSet<>();
+                roleIds.add(role.getId());
+                List<UserRoleDO> userRoles = userRoleMapper.selectListByRoleIds(roleIds);
+                if (CollUtil.isNotEmpty(userRoles)) {
+                    // 提取有审批角色的所有用户ID(去重+空值过滤)
+                    Set<Long> roleUserIds = userRoles.stream()
+                            .map(UserRoleDO::getUserId)
+                            .filter(Objects::nonNull) // 过滤空userId
+                            .collect(Collectors.toSet());
+                    // 计算两个集合的交集,得到最终目标用户ID
+                    Set<Long> targetUserIds = userIds.stream()
+                            .filter(roleUserIds::contains)
+                            .collect(Collectors.toSet());
+                    // 从 targetUserIds 随机选择1个用户作为日报的 创建人
+                    List<Long> targetUserIdList = new ArrayList<>(targetUserIds);
+                    if (CollUtil.isNotEmpty(targetUserIdList)) {
+                        Long creatorId = targetUserIdList.get(0);
+                        // 当天已经生成 瑞鹰项目启动设备整改 日报的队伍deptId集合
+                        Set<Long> currentDayReportedDeptIds = new HashSet<>();
+                        // 查询所有 '瑞鹰项目启动设备整改日报' 以‘部门-时间’ 为唯一键 当天创建时间 内没有生成过日报
+                        LocalDateTime currentDate = LocalDateTime.now();
+                        String currentFormatDateStr = LocalDateTimeUtil.format(currentDate, "yyyy-MM-dd");
+                        IotRyImproveDailyReportPageReqVO ryReqVO = new IotRyImproveDailyReportPageReqVO();
+                        ryReqVO.setDeptIds(departmentIds);
+                        ryReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
+                        PageResult<IotRyImproveDailyReportDO> pageReports = iotRyImproveDailyReportMapper.selectPage(ryReqVO);
+                        if (ObjUtil.isNotEmpty(pageReports)) {
+                            List<IotRyImproveDailyReportDO> improveDailyReports = pageReports.getList();
+                            if (CollUtil.isNotEmpty(improveDailyReports)) {
+                                improveDailyReports.forEach(report -> {
+                                    // 查询当天生成的日报
+                                    LocalDateTime createDate = report.getCreateTime();
+                                    String formatDateStr = LocalDateTimeUtil.format(createDate, "yyyy-MM-dd");
+                                    if (formatDateStr.equals(currentFormatDateStr)) {
+                                        currentDayReportedDeptIds.add(report.getDeptId());
+                                    }
+                                });
+                            }
+                        }
+                        // 如果当天的 瑞鹰项目启动设备整改 日报记录中不包含 数据字典中配置的部门id 则生成队伍日报记录
+                        Set<Long> tobeReportDeptIds = departmentIds.stream()
+                                .filter(deptId -> !currentDayReportedDeptIds.contains(deptId))
+                                .collect(Collectors.toSet());
+                        List<IotRyImproveDailyReportDO> tobeAddedReports = new ArrayList<>();
+                        if (CollUtil.isNotEmpty(tobeReportDeptIds)) {
+                            // 查询这些部门对象集合
+                            Map<Long, DeptDO> deptMap = deptService.getDeptMap(tobeReportDeptIds);
+                            for (Long tobeReportDeptId : tobeReportDeptIds) {
+                                IotRyImproveDailyReportDO improveReport = new IotRyImproveDailyReportDO();
+                                improveReport.setDeptId(tobeReportDeptId);
+                                improveReport.setStatus(0);
+                                improveReport.setAuditStatus(0);
+                                improveReport.setCreateTime(LocalDateTime.now());
+                                improveReport.setCreator(creatorId.toString());
+                                tobeAddedReports.add(improveReport);
+                            }
+                            if (CollUtil.isNotEmpty(tobeAddedReports)) {
+                                iotRyImproveDailyReportMapper.insertBatch(tobeAddedReports);
+
+                                // 异步发送消息提醒 钉钉 站内信
+                                // 查询所有日报的创建人 userId 集合
+                                Set<Long> msgUserIds = new HashSet<>(convertList(tobeAddedReports, report -> Long.valueOf(report.getCreator())));
+                                Map<Long, AdminUserRespDTO> users = adminUserApi.getUserMap(msgUserIds);
+                                // 建立日报与 用户手机号的 对应关系
+                                Map<Long, String> reportMobilePair = new HashMap<>();
+                                tobeAddedReports.forEach(report -> {
+                                    if (users.containsKey(Long.valueOf(report.getCreator()))) {
+                                        AdminUserRespDTO user = users.get(Long.valueOf(report.getCreator()));
+                                        reportMobilePair.put(report.getId(), user.getMobile());
+                                    }
+                                });
+                                // 异步多线程发送 站内信 钉钉 消息
+                                tobeAddedReports.forEach(report -> {
+                                    CountDownLatch latch = new CountDownLatch(tobeAddedReports.size());
+                                    // deptMap 部门集合   taskWellNamePair任务集合
+                                    Long deptId = report.getDeptId();
+                                    DeptDO dept = deptMap.get(deptId);
+                                    String msgTitle = dept.getName();
+                                    String finalMsgTitle = msgTitle;
+                                    pmsThreadPoolTaskExecutor.execute(() -> {
+                                        try {
+                                            // 用户 没有维护 手机号 也可以发送站内信消息
+                                            String mobile = StrUtil.EMPTY;
+                                            if (reportMobilePair.containsKey(report.getId())) {
+                                                mobile = reportMobilePair.get(report.getId());
+                                            }
+                                            pmsMessage.sendMessage(report.getId(), finalMsgTitle, PmsConstants.RY_XJ_DAILY_REPORT,
+                                                    Long.valueOf(report.getCreator()), mobile);
+                                        } finally {
+                                            latch.countDown();
+                                        }
+                                    });
+                                });
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        return "创建成功";
+    }
+}