ソースを参照

pms 瑞鹰日报 自动生成无设备队伍的钻井日报

zhangcl 6 時間 前
コミット
66afb1c632

+ 2 - 2
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/job/dailyreport/CreateRyDailyReportOrderJob.java

@@ -46,7 +46,7 @@ import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.
 import static cn.iocoder.yudao.module.pms.framework.config.MultiThreadConfiguration.PMS_THREAD_POOL_TASK_EXECUTOR;
 
 /**
- * 瑞鹰挂靠队伍 生成日报
+ * 瑞鹰挂靠队伍 无设备队伍 生成 修井 日报
  */
 @Component
 @Slf4j
@@ -81,7 +81,7 @@ public class CreateRyDailyReportOrderJob implements JobHandler {
 
         // 查询瑞鹰下所有部门 筛选出 修井 队伍(不包含任何设备的队伍)
         IotDeptTypePageReqVO deptTypeReqVO = new IotDeptTypePageReqVO();
-        // 查询 钻井 修井 类型的部门 综合队 层气项目
+        // 查询 修井 类型的部门 综合队 层气项目
         deptTypeReqVO.setType("xj");
         List<IotDeptTypeDO> deptTypes = iotDeptTypeMapper.selectList(deptTypeReqVO);
         Set<Long> xjDeptIds = new HashSet<>();

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

@@ -0,0 +1,305 @@
+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.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.depttype.vo.IotDeptTypePageReqVO;
+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.iotrddailyreport.vo.IotRdDailyReportPageReqVO;
+import cn.iocoder.yudao.module.pms.controller.admin.iotrydailyreport.vo.IotRyDailyReportPageReqVO;
+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.depttype.IotDeptTypeDO;
+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.iotrydailyreport.IotRyDailyReportDO;
+import cn.iocoder.yudao.module.pms.dal.mysql.IotDeviceMapper;
+import cn.iocoder.yudao.module.pms.dal.mysql.depttype.IotDeptTypeMapper;
+import cn.iocoder.yudao.module.pms.dal.mysql.iotrydailyreport.IotRyDailyReportMapper;
+import cn.iocoder.yudao.module.pms.message.PmsMessage;
+import cn.iocoder.yudao.module.pms.service.iotmainworkorderbom.IotMainWorkOrderBomService;
+import cn.iocoder.yudao.module.pms.service.iotprojectinfo.IotProjectInfoService;
+import cn.iocoder.yudao.module.pms.service.iotprojecttask.IotProjectTaskService;
+import cn.iocoder.yudao.module.pms.service.iotrydailyreport.IotRyDailyReportService;
+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.service.dept.DeptService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+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.concurrent.atomic.AtomicReference;
+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;
+
+/**
+ * 瑞鹰挂靠队伍 无设备队伍 生成 钻井 日报
+ */
+@Component
+@Slf4j
+public class CreateRyZjDailyReportOrderJob implements JobHandler {
+    @Resource
+    private IotProjectInfoService iotProjectInfoService;
+    @Resource
+    private IotRyDailyReportMapper iotRyDailyReportMapper;
+    @Autowired
+    private IotRyDailyReportService iotRyDailyReportService;
+
+    @Autowired
+    private IotDeviceMapper iotDeviceMapper;
+    @Resource
+    private IotProjectTaskService iotProjectTaskService;
+    @Resource
+    private AdminUserApi adminUserApi;
+    @Resource
+    private IotMainWorkOrderBomService iotMainWorkOrderBomService;
+    @Resource
+    private IotDeptTypeMapper iotDeptTypeMapper;
+    @Resource(name = PMS_THREAD_POOL_TASK_EXECUTOR)
+    private ThreadPoolTaskExecutor pmsThreadPoolTaskExecutor;
+    @Resource
+    private PmsMessage pmsMessage;
+    @Resource
+    private DeptService deptService;
+
+    @Override
+    @TenantIgnore
+    public String execute(String param) throws Exception {
+
+        // 查询瑞鹰下所有部门 筛选出 钻井 队伍(不包含任何设备的队伍)
+        IotDeptTypePageReqVO deptTypeReqVO = new IotDeptTypePageReqVO();
+        // 查询 钻井 类型的部门
+        deptTypeReqVO.setType("zj");
+        List<IotDeptTypeDO> deptTypes = iotDeptTypeMapper.selectList(deptTypeReqVO);
+        Set<Long> zjDeptIds = new HashSet<>();
+        // 无设备 的部门id集合
+        Set<Long> affiliatedDeptIds = new HashSet<>();
+        // key部门id      value日报填报人id
+        Map<Long, Long> affiliatedDeptIdUserIdPair = new HashMap<>();
+        AtomicReference<String> creator = new AtomicReference<>(StrUtil.EMPTY);
+        Set<String> usernames = new HashSet<>();
+        // key用户username  value用户userId
+        Map<String, Long> usernameIdPair = new HashMap<>();
+        // key部门deptId  value用户username
+        Map<Long, String> deptUsernamePair = new HashMap<>();
+        // key部门deptId  value用户userId
+        Map<Long, Long> deptUserIdPair = new HashMap<>();
+        Long userId = 0l;
+        if (CollUtil.isNotEmpty(deptTypes)) {
+            deptTypes.forEach(deptType -> {
+                zjDeptIds.add(deptType.getDeptId());
+                // 部分部门的日报需要由固定的人填写 RYMQC
+                if (StrUtil.isNotBlank(deptType.getCreator())) {
+                    affiliatedDeptIds.add(deptType.getDeptId());
+                    // creator.set(deptType.getCreator());
+                    usernames.add(deptType.getCreator());
+                    deptUsernamePair.put(deptType.getDeptId(), deptType.getCreator());
+                }
+            });
+            // 根据 用户账号 查询用户id 无设备队伍 日报填报人
+            if (CollUtil.isNotEmpty(usernames)) {
+                List<AdminUserRespDTO> users = adminUserApi.getUserListByUsernames(usernames);
+                if (CollUtil.isNotEmpty(users)) {
+                    users.forEach(user -> {
+                        usernameIdPair.put(user.getUsername(), user.getId());
+                    });
+                    // AdminUserRespDTO user = users.get(0);
+                    // userId = user.getId();
+                    // 设置部门与用户id对应关系
+                    deptUsernamePair.forEach((deptId, username) -> {
+                        if (usernameIdPair.containsKey(username)) {
+                            Long tempUserId = usernameIdPair.get(username);
+                            deptUserIdPair.put(deptId, tempUserId);
+                        } else {
+                            log.warn("用户名:{} 未找到对应的用户ID,部门ID:{}", username, deptId);
+                        }
+                    });
+                }
+            }
+        }
+        // 查询瑞鹰下所有队伍
+        Set<Long> ryTeamDeptIds = new HashSet<>();
+        // 查询瑞鹰所有 队伍 项目部
+        Set<Long> ryChildDeptIds = deptService.getChildDeptIdListFromCache(158l);
+        List<DeptDO> depts =deptService.getDeptList(ryChildDeptIds);
+        if (CollUtil.isNotEmpty(depts)) {
+            depts.forEach(dept -> {
+                if ("3".equals(dept.getType())) {
+                    ryTeamDeptIds.add(dept.getId());
+                }
+            });
+        }
+        // 查询瑞鹰所有队伍关联的设备 筛选出不包含任何设备的队伍
+        IotDevicePageReqVO reqVO = new IotDevicePageReqVO();
+        reqVO.setDeptIds(new ArrayList<>(ryTeamDeptIds));
+        List<IotDeviceDO> devices = iotDeviceMapper.selectListAlone(reqVO);
+        // 包含设备的部门id集合
+        Set<Long> containsDeviceDeptIds = new HashSet<>();
+        if (CollUtil.isNotEmpty(devices)) {
+            devices.forEach(device -> {
+                containsDeviceDeptIds.add(device.getDeptId());
+            });
+        }
+        // 不包含任何设备的队伍id集合
+        Set<Long> noDeviceZjDeptIds = zjDeptIds.stream()
+                .filter(deptId -> !containsDeviceDeptIds.contains(deptId))
+                .collect(Collectors.toSet());
+
+        // 查询 无设备 钻井 队伍 日报列表
+        IotRyDailyReportPageReqVO ryReqVO = new IotRyDailyReportPageReqVO();
+        ryReqVO.setDeptIds(noDeviceZjDeptIds);
+        ryReqVO.setProjectClassification("1");
+        List<IotRyDailyReportDO> ryDailyReports = iotRyDailyReportMapper.dailyReports(ryReqVO);
+
+        // 查询所有瑞鹰的项目任务 以‘部门-时间’ 为唯一键 当天创建时间 内没有生成过日报 就自动生成
+        IotRdDailyReportPageReqVO pageReqVO = new IotRdDailyReportPageReqVO();
+        LocalDateTime currentDate = LocalDateTime.now();
+        String currentFormatDateStr = LocalDateTimeUtil.format(currentDate, "yyyy-MM-dd");
+        // 前一天的日期
+        LocalDateTime yesterday = currentDate.minusDays(1);
+        // 当天已经生成日报的钻井队伍deptId集合
+        Set<Long> currentDayReportedDeptIds = new HashSet<>();
+        if (CollUtil.isNotEmpty(ryDailyReports)) {
+            ryDailyReports.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> tobeReportZjDeptIds = noDeviceZjDeptIds.stream()
+                .filter(deptId -> !currentDayReportedDeptIds.contains(deptId))
+                .collect(Collectors.toSet());
+
+        if (CollUtil.isNotEmpty(tobeReportZjDeptIds)) {
+            // 查询这些部门对象集合
+            Map<Long, DeptDO> deptMap = deptService.getDeptMap(tobeReportZjDeptIds);
+
+            // 查询这些部门所有的项目任务 筛选未完工的任务
+            IotProjectTaskPageReqVO taskReqVO = new IotProjectTaskPageReqVO();
+            taskReqVO.setCompanyId(158l);
+            taskReqVO.setJobFlag("Y");
+            List<IotProjectTaskDO> tasks = iotProjectTaskService.projectTasks(taskReqVO);
+            Map<Long, Set<Long>> taskDeptPair = new HashMap<>();
+            // key任务id   value项目id
+            Map<Long, Long> taskProjectPair = new HashMap<>();
+            // key任务id   value井号
+            Map<Long, String> taskWellNamePair = new HashMap<>();
+            Set<Long> projectIds = new HashSet<>();
+            if (CollUtil.isNotEmpty(tasks)) {
+                tasks.forEach(task -> {
+                    taskDeptPair.put(task.getId(), task.getDeptIds());
+                    projectIds.add(task.getProjectId());
+                    taskProjectPair.put(task.getId(), task.getProjectId());
+                    taskWellNamePair.put(task.getId(), task.getWellName());
+                });
+            }
+            Map<Long, IotProjectInfoDO> projectPair = new HashMap<>();
+            if (CollUtil.isNotEmpty(projectIds)) {
+                IotProjectInfoPageReqVO projectReqVO = new IotProjectInfoPageReqVO();
+                projectReqVO.setProjectIds(new ArrayList<>(projectIds));
+                List<IotProjectInfoDO> projects = iotProjectInfoService.getIotProjectInfos(projectReqVO);
+                if (CollUtil.isNotEmpty(projects)) {
+                    projects.forEach(project -> {
+                        projectPair.put(project.getId(), project);
+                    });
+                }
+            }
+
+            List<IotRyDailyReportDO> tobeAddedReports = new ArrayList<>();
+            for (Long tobeReportZjDeptId : tobeReportZjDeptIds) {
+                IotRyDailyReportDO noDeviceReport = new IotRyDailyReportDO();
+                noDeviceReport.setDeptId(tobeReportZjDeptId);
+                noDeviceReport.setProjectClassification("1");
+                if (affiliatedDeptIds.contains(tobeReportZjDeptId)) {
+                    // 无设备队伍 的日报
+                    if (deptUserIdPair.containsKey(tobeReportZjDeptId)) {
+                        noDeviceReport.setCreator(String.valueOf(deptUserIdPair.get(tobeReportZjDeptId)));
+                    }
+                } else {
+                    // 综合队等其它挂靠修井队
+                    if (CollUtil.isNotEmpty(deptMap) && deptMap.containsKey(tobeReportZjDeptId)) {
+                        DeptDO dept = deptMap.get(tobeReportZjDeptId);
+                        if (ObjUtil.isNotEmpty(dept.getLeaderUserId())) {
+                            noDeviceReport.setCreator(String.valueOf(dept.getLeaderUserId()));
+                        }
+                    }
+                }
+                // 设置日报的项目任务信息
+                if (CollUtil.isNotEmpty(taskDeptPair)) {
+                    taskDeptPair.forEach((taskId, deptIds) -> {
+                        if (deptIds.contains(tobeReportZjDeptId)) {
+                            noDeviceReport.setTaskId(taskId);
+                            // 设置任务对应的项目信息
+                            if (taskProjectPair.containsKey(taskId)) {
+                                noDeviceReport.setProjectId(taskProjectPair.get(taskId));
+                            }
+                        }
+                    });
+                }
+                tobeAddedReports.add(noDeviceReport);
+            }
+
+            if (CollUtil.isNotEmpty(tobeAddedReports)) {
+                iotRyDailyReportMapper.insertBatch(tobeAddedReports);
+
+                // 异步发送消息提醒 钉钉 站内信
+                // 查询所有日报的创建人 userId 集合
+                Set<Long> userIds = new HashSet<>(convertList(tobeAddedReports, report -> Long.valueOf(report.getCreator())));
+                Map<Long, AdminUserRespDTO> users = adminUserApi.getUserMap(userIds);
+                // 建立日报与 用户手机号的 对应关系
+                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();
+                    Long taskId = report.getTaskId();
+                    if (ObjUtil.isNotEmpty(taskId)) {
+                        String wellName = taskWellNamePair.get(taskId);
+                        msgTitle = StrUtil.join("-", msgTitle, wellName);
+                    }
+                    String finalMsgTitle = msgTitle;
+                    pmsThreadPoolTaskExecutor.execute(() -> {
+                        try {
+                            if (reportMobilePair.containsKey(report.getId())) {
+                                String mobile = reportMobilePair.get(report.getId());
+                                pmsMessage.sendMessage(report.getId(), finalMsgTitle, PmsConstants.RY_DAILY_REPORT,
+                                        Long.valueOf(report.getCreator()), mobile);
+                            }
+                        } finally {
+                            latch.countDown();
+                        }
+                    });
+                });
+
+            }
+        }
+        return "创建成功";
+    }
+}

+ 9 - 4
yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/user/AdminUserApi.java

@@ -4,10 +4,7 @@ import cn.iocoder.yudao.framework.common.pojo.Pms;
 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
 import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
 
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
 
 /**
  * Admin 用户 API 接口
@@ -80,6 +77,14 @@ public interface AdminUserApi {
      */
     List<AdminUserRespDTO> getUserListByUsername(String username);
 
+    /**
+     * 获得用户列表,基于 用户账号 集合
+     *
+     * @param usernames 用户账号
+     * @return 用户列表
+     */
+    List<AdminUserRespDTO> getUserListByUsernames(Set<String> usernames);
+
     /**
      * 校验用户是否有效。如下情况,视为无效:
      * 1. 用户编号不存在

+ 6 - 0
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/user/AdminUserApiImpl.java

@@ -135,6 +135,12 @@ public class AdminUserApiImpl implements AdminUserApi {
         return BeanUtils.toBean(users, AdminUserRespDTO.class);
     }
 
+    @Override
+    public List<AdminUserRespDTO> getUserListByUsernames(Set<String> usernames) {
+        List<AdminUserDO> users = userService.getUsers(usernames);
+        return BeanUtils.toBean(users, AdminUserRespDTO.class);
+    }
+
     @Override
     public void validateUserList(Collection<Long> ids) {
         userService.validateUserList(ids);

+ 4 - 0
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserPageReqVO.java

@@ -9,6 +9,7 @@ import lombok.NoArgsConstructor;
 import org.springframework.format.annotation.DateTimeFormat;
 
 import java.time.LocalDateTime;
+import java.util.Collection;
 import java.util.List;
 
 import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@@ -53,4 +54,7 @@ public class UserPageReqVO extends PageParam {
 
     @Schema(description = "用户编号集合", example = "[102,123]")
     private List<Long> userIds;
+
+    @Schema(description = "用户账号集合", example = "['张三','李四']")
+    private Collection<String> usernames;
 }

+ 1 - 0
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/user/AdminUserMapper.java

@@ -41,6 +41,7 @@ public interface AdminUserMapper extends BaseMapperX<AdminUserDO> {
     default List<AdminUserDO> selectList(UserPageReqVO reqVO) {
         return selectList(new LambdaQueryWrapperX<AdminUserDO>()
                 .likeIfPresent(AdminUserDO::getUsername, reqVO.getUsername())
+                .inIfPresent(AdminUserDO::getUsername, reqVO.getUsernames())
                 .likeIfPresent(AdminUserDO::getNickname, reqVO.getNickname())
                 .likeIfPresent(AdminUserDO::getMobile, reqVO.getMobile())
                 .eqIfPresent(AdminUserDO::getStatus, reqVO.getStatus())

+ 9 - 4
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserService.java

@@ -15,10 +15,7 @@ import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
 
 import javax.validation.Valid;
 import java.io.InputStream;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
 
 /**
  * 后台用户 Service 接口
@@ -229,6 +226,14 @@ public interface AdminUserService {
 
     List<AdminUserDO> selectListByDept(Long deptId);
 
+    /**
+     * 获得用户信息列表
+     *
+     * @param usernames 列表条件
+     * @return 用户列表
+     */
+    List<AdminUserDO> getUsers(Set<String> usernames);
+
     /**
      * 获得用户简单信息列表
      *

+ 7 - 0
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserServiceImpl.java

@@ -641,6 +641,13 @@ public class AdminUserServiceImpl implements AdminUserService {
         return userMapper.selectListByDept(deptId);
     }
 
+    @Override
+    public List<AdminUserDO> getUsers(Set<String> usernames) {
+        UserPageReqVO reqVO = new UserPageReqVO();
+        reqVO.setUsernames(usernames);
+        return userMapper.selectList(reqVO);
+    }
+
     @Override
     public List<AdminUserDO> getSimpleUserList(UserPageReqVO reqVO) {
         return userMapper.selectSimpleList(getDeptCondition(reqVO.getDeptId(), reqVO.getDeptIds()));