Browse Source

pms 5#国日报 定时任务

zhangcl 2 tuần trước cách đây
mục cha
commit
3b6b629b05

+ 15 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/iotfivedailyreport/IotFiveDailyReportController.java

@@ -1,5 +1,6 @@
 package cn.iocoder.yudao.module.pms.controller.admin.iotfivedailyreport;
 
+import cn.hutool.core.collection.CollUtil;
 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;
@@ -22,6 +23,7 @@ import javax.annotation.Resource;
 import javax.servlet.http.HttpServletResponse;
 import javax.validation.Valid;
 import java.io.IOException;
+import java.util.Collections;
 import java.util.List;
 
 import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
@@ -77,6 +79,19 @@ public class IotFiveDailyReportController {
         return success(BeanUtils.toBean(pageResult, IotFiveDailyReportRespVO.class));
     }
 
+    /**
+     * 设置日报的关联信息 部门(施工队伍) 项目 任务 带班干部 日报填报人
+     * @param reports
+     * @return
+     */
+    private List<IotFiveDailyReportRespVO> buildDailyReportList(List<IotFiveDailyReportDO> reports) {
+        if (CollUtil.isEmpty(reports)) {
+            return Collections.emptyList();
+        }
+
+        return BeanUtils.toBean(reports, IotFiveDailyReportRespVO.class);
+    }
+
     @GetMapping("/export-excel")
     @Operation(summary = "导出5#国日报 Excel")
     @PreAuthorize("@ss.hasPermission('pms:iot-five-daily-report:export')")

+ 5 - 1
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/dal/dataobject/iotfivedailyreport/IotFiveDailyReportDO.java

@@ -2,13 +2,16 @@ package cn.iocoder.yudao.module.pms.dal.dataobject.iotfivedailyreport;
 
 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
 import com.baomidou.mybatisplus.annotation.KeySequence;
+import com.baomidou.mybatisplus.annotation.TableField;
 import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
 import lombok.*;
 
 import java.math.BigDecimal;
 import java.time.LocalDateTime;
 import java.time.LocalTime;
+import java.util.Set;
 
 /**
  * 5#国日报 DO
@@ -73,7 +76,8 @@ public class IotFiveDailyReportDO extends BaseDO {
     /**
      * 施工设备([123,233])
      */
-    private String deviceIds;
+    @TableField(typeHandler = JacksonTypeHandler.class)
+    private Set<Long> deviceIds;
     /**
      * 设备名称
      */

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

@@ -0,0 +1,217 @@
+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.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.iotfivedailyreport.vo.IotFiveDailyReportPageReqVO;
+import cn.iocoder.yudao.module.pms.controller.admin.iotprojecttask.vo.IotProjectTaskPageReqVO;
+import cn.iocoder.yudao.module.pms.dal.dataobject.iotfivedailyreport.IotFiveDailyReportDO;
+import cn.iocoder.yudao.module.pms.dal.dataobject.iotprojecttask.IotProjectTaskDO;
+import cn.iocoder.yudao.module.pms.message.PmsMessage;
+import cn.iocoder.yudao.module.pms.service.iotfivedailyreport.IotFiveDailyReportService;
+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.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.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.util.*;
+import java.util.concurrent.CountDownLatch;
+
+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;
+
+/**
+ * 5#国日报 生成定时任务
+ */
+@Component
+@Slf4j
+public class CreateFiveDailyReportOrderJob implements JobHandler {
+    @Autowired
+    private IotFiveDailyReportService iotFiveDailyReportService;
+
+    @Resource
+    private IotProjectTaskService iotProjectTaskService;
+    @Resource
+    private AdminUserApi adminUserApi;
+
+    @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 {
+
+        // 查询所有瑞都的项目任务 以‘井号-时间’ 为唯一键 当天创建时间 内没有生成过日报 就自动生成
+        IotFiveDailyReportPageReqVO pageReqVO = new IotFiveDailyReportPageReqVO();
+        PageResult<IotFiveDailyReportDO> dailyReportsPage = iotFiveDailyReportService.getIotFiveDailyReportPage(pageReqVO);
+        List<IotFiveDailyReportDO> dailyReports = dailyReportsPage.getList();
+
+        LocalDateTime currentDate = LocalDateTime.now();
+        String currentFormatDateStr = LocalDateTimeUtil.format(currentDate, "yyyy-MM-dd");
+        // 次日的日期
+        LocalDateTime nextDay = currentDate.plusDays(1);
+        // 需要生成日报的 任务(井号) 集合
+        Set<Long> taskIds = new HashSet<>();
+        if (CollUtil.isNotEmpty(dailyReports)) {
+            dailyReports.forEach(report -> {
+                // 查询当天生成的日报
+                LocalDateTime createDate = report.getCreateTime();
+                String formatDateStr = LocalDateTimeUtil.format(createDate, "yyyy-MM-dd");
+                if (formatDateStr.equals(currentFormatDateStr)) {
+                    taskIds.add(report.getTaskId());
+                }
+            });
+        }
+        
+        // 查询 5#公司 相关的项目任务 根据每个任务的填报人进行工单生成和推送
+        IotProjectTaskPageReqVO taskReqVO = new IotProjectTaskPageReqVO();
+        taskReqVO.setCompanyId(388l);
+        taskReqVO.setJobFlag("Y");
+        List<IotProjectTaskDO> tasks = iotProjectTaskService.projectTasks(taskReqVO);
+        List<IotProjectTaskDO> qualifiedTasks = new ArrayList<>();
+        // 未施工完成的任务id集合
+        Set<Long> unfinishedTaskIds = new HashSet<>();
+        if (CollUtil.isNotEmpty(tasks)) {
+            tasks.forEach(task -> {
+                qualifiedTasks.add(task);
+                // 生成所有所有未施工完成的任务id集合
+                unfinishedTaskIds.add(task.getId());
+            });
+        }
+
+        Set<Long> userIds = new HashSet<>();
+        List<IotFiveDailyReportDO> reports = new ArrayList<>();
+        Map<Long, Long> taskSubmitterPair = new HashMap<>();
+        // key任务id  value施工队伍id
+        Map<Long, Long> taskTeamIdPair = new HashMap<>();
+        Set<Long> teamDepartmentIds = new HashSet<>();
+        if (CollUtil.isNotEmpty(qualifiedTasks)) {
+            qualifiedTasks.forEach(task -> {
+                // 查询当前任务的 工单填报人
+                Set<Long> submitterIds = task.getSubmitter();
+                Set<Long> teamDeptIds = task.getDeptIds();
+                if (CollUtil.isNotEmpty(submitterIds)) {
+                    // 查询工单填报人所在部门
+                    userIds.addAll(submitterIds);
+                    taskSubmitterPair.put(task.getId(), new ArrayList<>(submitterIds).get(0));
+                }
+                if (CollUtil.isNotEmpty(teamDeptIds)) {
+                    taskTeamIdPair.put(task.getId(), new ArrayList<>(teamDeptIds).get(0));
+                    teamDepartmentIds.addAll(teamDeptIds);
+                }
+            });
+            // 查询所有任务配置的工单填报人的信息
+            Map<Long, AdminUserRespDTO> users = adminUserApi.getUserMap(userIds);
+            Set<Long> deptIds = new HashSet<>();
+            if (CollUtil.isNotEmpty(users)) {
+                // 统一查询所有用户所属的部门信息
+                users.forEach((userId, user) -> {
+                    deptIds.add(user.getDeptId());
+                });
+            }
+            // 查询所有任务施工队伍的 deptId
+            Map<Long, DeptDO> deptPair = deptService.getDeptMap(teamDepartmentIds);
+            // 以任务为维度 生成 5#国 日报 部门为任务配置的工单填报人对应的部门
+            qualifiedTasks.forEach(task -> {
+                if (!taskIds.contains(task.getId()) && CollUtil.isNotEmpty(task.getSubmitter())) {
+                    // 生成当天的日报
+                    IotFiveDailyReportDO report = new IotFiveDailyReportDO();
+                    if (taskSubmitterPair.containsKey(task.getId())) {
+                        Long userId = taskSubmitterPair.get(task.getId());
+                        if (users.containsKey(userId)) {
+                            AdminUserRespDTO user = users.get(userId);
+                            // 取任务施工队伍的 deptId
+                            if (taskTeamIdPair.containsKey(task.getId())) {
+                                report.setDeptId(taskTeamIdPair.get(task.getId()));
+                            } else {
+                                report.setDeptId(user.getDeptId());
+                            }
+                            // 根据用户部门名称 生成日报标题
+                            if (deptPair.containsKey(report.getDeptId())) {
+                                DeptDO dept = deptPair.get(report.getDeptId());
+                                String deptName = dept.getName();
+                                String[] multiLangDeptNames = deptName.split("~~");
+                                report.setReportName(multiLangDeptNames[0] + "/" + currentFormatDateStr + "日报填报" );
+                            }
+                        }
+                    }
+
+                    // 修改开始:创建专门用于日报的日期时间,将时分秒固定为08:00:00
+                    // 将日期部分保持不变,时间部分设置为08:00:00
+                    LocalDate currentLocalDate = currentDate.toLocalDate();
+                    LocalDate nextLocalDate = nextDay.toLocalDate();
+
+                    LocalDateTime dailyReportStartTime = LocalDateTime.of(currentLocalDate, LocalTime.of(8, 0, 0));
+                    LocalDateTime dailyReportEndTime = LocalDateTime.of(nextLocalDate, LocalTime.of(8, 0, 0));
+
+                    report.setProjectId(task.getProjectId());
+                    report.setTaskId(task.getId());
+                    report.setDeviceIds(task.getDeviceIds());
+                    report.setStartTime(LocalTime.of(8, 0, 0));
+                    report.setEndTime(LocalTime.of(8, 0, 0));
+                    report.setConstructionStartDate(dailyReportStartTime);
+                    report.setConstructionEndDate(dailyReportEndTime);
+                    Set<Long> submitters = task.getSubmitter();
+                    report.setCreator(String.valueOf(new ArrayList<>(submitters).get(0)));
+                    report.setCreateTime(LocalDateTime.now());
+                    reports.add(report);
+                }
+            });
+        }
+        if (CollUtil.isNotEmpty(reports)) {
+            iotFiveDailyReportService.batchAddDailyReports(reports);
+        }
+
+        // 向日报 填报人 发送 站内信 钉钉消息
+        if (CollUtil.isNotEmpty(reports)) {
+            List<IotFiveDailyReportDO> msgReports = new ArrayList<>();
+            // 如果日报是平台井 只发送主井任务
+            reports.forEach(report -> {
+                msgReports.add(report);
+            });
+            // 先查询所有 日报填报人的手机号
+            Set<Long> personIds = new HashSet<>(convertList(msgReports, report -> Long.valueOf(report.getCreator())));
+            Map<Long, AdminUserRespDTO> users = adminUserApi.getUserMap(personIds);
+            // 建立日报与 用户手机号的 对应关系
+            Map<Long, String> orderMobilePair = new HashMap<>();
+            msgReports.forEach(report -> {
+                if (users.containsKey(Long.valueOf(report.getCreator()))) {
+                    AdminUserRespDTO user = users.get(Long.valueOf(report.getCreator()));
+                    orderMobilePair.put(report.getId(), user.getMobile());
+                }
+            });
+            // 异步多线程发送 站内信 钉钉 消息
+            msgReports.forEach(order -> {
+                CountDownLatch latch = new CountDownLatch(msgReports.size());
+                pmsThreadPoolTaskExecutor.execute(() -> {
+                    try {
+                        if (orderMobilePair.containsKey(order.getId())) {
+                            String mobile = orderMobilePair.get(order.getId());
+                            pmsMessage.sendMessage(order.getId(), order.getReportName(), PmsConstants.DAILY_REPORT,
+                                    Long.valueOf(order.getCreator()), mobile);
+                        }
+                    } finally {
+                        latch.countDown();
+                    }
+                });
+            });
+        }
+        return "创建成功";
+    }
+}

+ 4 - 2
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/service/IotDeviceServiceImpl.java

@@ -705,14 +705,16 @@ public class IotDeviceServiceImpl implements IotDeviceService {
         if (CollUtil.isEmpty(reqVO.getDeviceIds()) && CollUtil.isEmpty(reqVO.getDeptIds())) {
             throw new ServiceException(IOT_DEPT_NOT_SELECTED);
         }
+        // 需要查询的公司id
+        Long deptId = reqVO.getDeptId();
         List<IotDeviceDO> rdDevices = new ArrayList<>();
-        if (CollUtil.isNotEmpty(reqVO.getDeptIds())) {
+        if (CollUtil.isNotEmpty(reqVO.getDeptIds()) && ObjUtil.isNotEmpty(deptId)) {
             // 查询选择的部门 选择的部门所属的公司 属于 瑞都 163l 则查询所有瑞都下的设备
             // 但是 所选队伍 下的所有设备 需要显示在列表最上面
             List<Long> deptIds = reqVO.getDeptIds();
             Long randomDeptId = deptIds.get(0);
             // 查询 瑞都下的所有 部门
-            Set<Long> childDeptIds = deptService.getChildDeptIdListFromCache(163l);
+            Set<Long> childDeptIds = deptService.getChildDeptIdListFromCache(deptId);
             if (childDeptIds.contains(randomDeptId)) {
                 // 施工队伍 属于 瑞都 163l 则查询所有瑞都下的设备
                 reqVO.setDeptIds(new ArrayList<>(childDeptIds));

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

@@ -6,6 +6,7 @@ import cn.iocoder.yudao.module.pms.controller.admin.iotfivedailyreport.vo.IotFiv
 import cn.iocoder.yudao.module.pms.dal.dataobject.iotfivedailyreport.IotFiveDailyReportDO;
 
 import javax.validation.Valid;
+import java.util.List;
 
 /**
  * 5#国日报 Service 接口
@@ -52,4 +53,10 @@ public interface IotFiveDailyReportService {
      */
     PageResult<IotFiveDailyReportDO> getIotFiveDailyReportPage(IotFiveDailyReportPageReqVO pageReqVO);
 
+    /**
+     * 批量 新增日报工单
+     *
+     * @param
+     */
+    void batchAddDailyReports(List<IotFiveDailyReportDO> reports);
 }

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

@@ -10,6 +10,7 @@ import org.springframework.stereotype.Service;
 import org.springframework.validation.annotation.Validated;
 
 import javax.annotation.Resource;
+import java.util.List;
 
 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
 import static cn.iocoder.yudao.module.pms.enums.ErrorCodeConstant.IOT_FIVE_DAILY_REPORT_NOT_EXISTS;
@@ -68,4 +69,9 @@ public class IotFiveDailyReportServiceImpl implements IotFiveDailyReportService
         return iotFiveDailyReportMapper.selectPage(pageReqVO);
     }
 
+    @Override
+    public void batchAddDailyReports(List<IotFiveDailyReportDO> reports) {
+        iotFiveDailyReportMapper.insertBatch(reports);
+    }
+
 }