|
@@ -1,8 +1,7 @@
|
|
|
package cn.iocoder.yudao.module.pms.job.dailyreport;
|
|
package cn.iocoder.yudao.module.pms.job.dailyreport;
|
|
|
|
|
|
|
|
import cn.hutool.core.collection.CollUtil;
|
|
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.quartz.core.handler.JobHandler;
|
|
|
import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore;
|
|
import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore;
|
|
|
import cn.iocoder.yudao.module.pms.constant.PmsConstants;
|
|
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.pms.service.iotprojecttask.IotProjectTaskService;
|
|
|
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
|
|
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.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.dal.dataobject.dept.DeptDO;
|
|
|
import cn.iocoder.yudao.module.system.service.dept.DeptService;
|
|
import cn.iocoder.yudao.module.system.service.dept.DeptService;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
import lombok.extern.slf4j.Slf4j;
|
|
@@ -27,9 +27,9 @@ import java.time.LocalDate;
|
|
|
import java.time.LocalDateTime;
|
|
import java.time.LocalDateTime;
|
|
|
import java.time.LocalTime;
|
|
import java.time.LocalTime;
|
|
|
import java.util.*;
|
|
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;
|
|
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
|
|
@Resource
|
|
|
private DeptService deptService;
|
|
private DeptService deptService;
|
|
|
|
|
|
|
|
- @Override
|
|
|
|
|
|
|
+ /* @Override
|
|
|
@TenantIgnore
|
|
@TenantIgnore
|
|
|
public String execute(String param) throws Exception {
|
|
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#公司 相关的项目任务 根据每个任务的填报人进行工单生成和推送
|
|
// 查询 5#公司 相关的项目任务 根据每个任务的填报人进行工单生成和推送
|
|
|
IotProjectTaskPageReqVO taskReqVO = new IotProjectTaskPageReqVO();
|
|
IotProjectTaskPageReqVO taskReqVO = new IotProjectTaskPageReqVO();
|
|
|
taskReqVO.setCompanyId(388l);
|
|
taskReqVO.setCompanyId(388l);
|
|
@@ -213,5 +230,143 @@ public class CreateFiveDailyReportOrderJob implements JobHandler {
|
|
|
});
|
|
});
|
|
|
}
|
|
}
|
|
|
return "创建成功";
|
|
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());
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
}
|
|
}
|