|
@@ -0,0 +1,309 @@
|
|
|
|
|
+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.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.iotprojectinfo.IotProjectInfoService;
|
|
|
|
|
+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.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;
|
|
|
|
|
+
|
|
|
|
|
+/**
|
|
|
|
|
+ * 瑞鹰挂靠队伍 无设备队伍 生成 修井 日报
|
|
|
|
|
+ * 阿根廷 队伍 23:00 生成日报
|
|
|
|
|
+ */
|
|
|
|
|
+@Component
|
|
|
|
|
+@Slf4j
|
|
|
|
|
+public class CreateRyXjDailyReportOrderJob implements JobHandler {
|
|
|
|
|
+ @Resource
|
|
|
|
|
+ private IotProjectInfoService iotProjectInfoService;
|
|
|
|
|
+ @Resource
|
|
|
|
|
+ private IotRyDailyReportMapper iotRyDailyReportMapper;
|
|
|
|
|
+
|
|
|
|
|
+ @Autowired
|
|
|
|
|
+ private IotDeviceMapper iotDeviceMapper;
|
|
|
|
|
+ @Resource
|
|
|
|
|
+ private IotProjectTaskService iotProjectTaskService;
|
|
|
|
|
+ @Resource
|
|
|
|
|
+ private AdminUserApi adminUserApi;
|
|
|
|
|
+
|
|
|
|
|
+ @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("xj");
|
|
|
|
|
+ List<IotDeptTypeDO> deptTypes = iotDeptTypeMapper.selectList(deptTypeReqVO);
|
|
|
|
|
+ Set<Long> xjDeptIds = new HashSet<>();
|
|
|
|
|
+ // 挂靠 的部门id集合
|
|
|
|
|
+ Set<Long> affiliatedDeptIds = new HashSet<>();
|
|
|
|
|
+ AtomicReference<String> creator = new AtomicReference<>(StrUtil.EMPTY);
|
|
|
|
|
+ Long userId = 0l;
|
|
|
|
|
+ Map<Long, String> updaterPair = new HashMap<>();
|
|
|
|
|
+ Set<Long> arDeptIds = new HashSet<>();
|
|
|
|
|
+ if (CollUtil.isNotEmpty(deptTypes)) {
|
|
|
|
|
+ deptTypes.forEach(deptType -> {
|
|
|
|
|
+ xjDeptIds.add(deptType.getDeptId());
|
|
|
|
|
+ // 部分部门的日报需要由固定的人填写 RYMQC
|
|
|
|
|
+ if (StrUtil.isNotBlank(deptType.getCreator())) {
|
|
|
|
|
+ affiliatedDeptIds.add(deptType.getDeptId());
|
|
|
|
|
+ creator.set(deptType.getCreator());
|
|
|
|
|
+ }
|
|
|
|
|
+ // 瑞鹰 综合队 当天生成明天的日报
|
|
|
|
|
+ if (StrUtil.isNotBlank(deptType.getUpdater())) {
|
|
|
|
|
+ updaterPair.put(deptType.getDeptId(), deptType.getUpdater());
|
|
|
|
|
+ }
|
|
|
|
|
+ if ("ar".equals(deptType.getCategory())) {
|
|
|
|
|
+ arDeptIds.add(deptType.getDeptId());
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+ // 根据 用户账号 查询用户id 挂靠队伍 日报填报人
|
|
|
|
|
+ if (StrUtil.isNotBlank(creator.get())) {
|
|
|
|
|
+ List<AdminUserRespDTO> users = adminUserApi.getUserListByUsername(creator.get());
|
|
|
|
|
+ if (CollUtil.isNotEmpty(users)) {
|
|
|
|
|
+ AdminUserRespDTO user = users.get(0);
|
|
|
|
|
+ userId = user.getId();
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ // 查询瑞鹰下所有队伍
|
|
|
|
|
+ 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> noDeviceXjDeptIds = xjDeptIds.stream()
|
|
|
|
|
+ .filter(deptId -> !containsDeviceDeptIds.contains(deptId))
|
|
|
|
|
+ .collect(Collectors.toSet());
|
|
|
|
|
+
|
|
|
|
|
+ // 查询无设备修井队伍日报列表
|
|
|
|
|
+ IotRyDailyReportPageReqVO ryReqVO = new IotRyDailyReportPageReqVO();
|
|
|
|
|
+ ryReqVO.setDeptIds(noDeviceXjDeptIds);
|
|
|
|
|
+ ryReqVO.setProjectClassification("2");
|
|
|
|
|
+ List<IotRyDailyReportDO> ryDailyReports = iotRyDailyReportMapper.dailyReports(ryReqVO);
|
|
|
|
|
+
|
|
|
|
|
+ // 查询所有瑞鹰的项目任务 以‘部门-时间’ 为唯一键 当天创建时间 内没有生成过日报 就自动生成
|
|
|
|
|
+ LocalDateTime currentDate = LocalDateTime.now();
|
|
|
|
|
+ String currentFormatDateStr = LocalDateTimeUtil.format(currentDate, "yyyy-MM-dd");
|
|
|
|
|
+
|
|
|
|
|
+ // 查询所有瑞鹰的项目任务 以‘部门-时间’ 为唯一键 明天 创建时间 内没有生成过日报 就自动生成 新疆综合队
|
|
|
|
|
+ LocalDateTime tomorrow = currentDate.plusDays(1);
|
|
|
|
|
+ String tomorrowFormatDateStr = LocalDateTimeUtil.format(tomorrow, "yyyy-MM-dd");
|
|
|
|
|
+
|
|
|
|
|
+ // 前一天的日期
|
|
|
|
|
+ // 当天已经生成日报的修井队伍deptId集合
|
|
|
|
|
+ Set<Long> currentDayReportedDeptIds = new HashSet<>();
|
|
|
|
|
+ // 明天 已经生成日报的修井队伍 deptId 集合
|
|
|
|
|
+ Set<Long> tomorrowReportedDeptIds = 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) && !updaterPair.containsKey(report.getDeptId())) {
|
|
|
|
|
+ currentDayReportedDeptIds.add(report.getDeptId());
|
|
|
|
|
+ }
|
|
|
|
|
+ // 查询 新疆综合队 在明天有没有创建过日报
|
|
|
|
|
+ if (formatDateStr.equals(tomorrowFormatDateStr)) {
|
|
|
|
|
+ tomorrowReportedDeptIds.add(report.getDeptId());
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+ System.out.println("综合队明天的日报数量:" + tomorrowReportedDeptIds.size());
|
|
|
|
|
+ // 所有的部门id
|
|
|
|
|
+ Set<Long> reportedDeptIds = new HashSet<>();
|
|
|
|
|
+ // 今天生成日报部门id
|
|
|
|
|
+ Optional.ofNullable(currentDayReportedDeptIds)
|
|
|
|
|
+ .ifPresent(reportedDeptIds::addAll);
|
|
|
|
|
+ // 明天生成的日报部门id
|
|
|
|
|
+ Optional.ofNullable(tomorrowReportedDeptIds)
|
|
|
|
|
+ .ifPresent(reportedDeptIds::addAll);
|
|
|
|
|
+
|
|
|
|
|
+ // 如果当天的修井日报记录中不包含 无设备的修井队伍部门id 则生成修井队伍日报记录
|
|
|
|
|
+ Set<Long> tobeReportXjDeptIds = noDeviceXjDeptIds.stream()
|
|
|
|
|
+ .filter(deptId -> !reportedDeptIds.contains(deptId))
|
|
|
|
|
+ .filter(deptId -> arDeptIds.contains(deptId))
|
|
|
|
|
+ .collect(Collectors.toSet());
|
|
|
|
|
+
|
|
|
|
|
+ if (CollUtil.isNotEmpty(tobeReportXjDeptIds)) {
|
|
|
|
|
+ // 查询这些部门对象集合
|
|
|
|
|
+ Map<Long, DeptDO> deptMap = deptService.getDeptMap(tobeReportXjDeptIds);
|
|
|
|
|
+
|
|
|
|
|
+ // 查询这些部门所有的项目任务 筛选未完工的任务
|
|
|
|
|
+ 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 tobeReportXjDeptId : tobeReportXjDeptIds) {
|
|
|
|
|
+ IotRyDailyReportDO noDeviceReport = new IotRyDailyReportDO();
|
|
|
|
|
+ noDeviceReport.setDeptId(tobeReportXjDeptId);
|
|
|
|
|
+ noDeviceReport.setProjectClassification("2");
|
|
|
|
|
+ if (affiliatedDeptIds.contains(tobeReportXjDeptId)) {
|
|
|
|
|
+ // 挂靠队伍 煤层气 的日报
|
|
|
|
|
+ noDeviceReport.setCreator(String.valueOf(userId));
|
|
|
|
|
+ } else {
|
|
|
|
|
+ // 综合队等其它非挂靠修井队 综合队需要生成 明天 的日报
|
|
|
|
|
+ if (CollUtil.isNotEmpty(deptMap) && deptMap.containsKey(tobeReportXjDeptId)) {
|
|
|
|
|
+ DeptDO dept = deptMap.get(tobeReportXjDeptId);
|
|
|
|
|
+ if (ObjUtil.isNotEmpty(dept.getLeaderUserId())) {
|
|
|
|
|
+ noDeviceReport.setCreator(String.valueOf(dept.getLeaderUserId()));
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ // 如果是 新疆综合队 设置 createTime 为明天的时间
|
|
|
|
|
+ if (updaterPair.containsKey(tobeReportXjDeptId)) {
|
|
|
|
|
+ noDeviceReport.setCreateTime(tomorrow);
|
|
|
|
|
+ noDeviceReport.setUpdateTime(tomorrow);
|
|
|
|
|
+ }
|
|
|
|
|
+ // 设置日报的项目任务信息
|
|
|
|
|
+ if (CollUtil.isNotEmpty(taskDeptPair)) {
|
|
|
|
|
+ taskDeptPair.forEach((taskId, deptIds) -> {
|
|
|
|
|
+ if (deptIds.contains(tobeReportXjDeptId)) {
|
|
|
|
|
+ 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_XJ_DAILY_REPORT,
|
|
|
|
|
+ Long.valueOf(report.getCreator()), mobile);
|
|
|
|
|
+ }
|
|
|
|
|
+ } finally {
|
|
|
|
|
+ latch.countDown();
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ return "创建成功";
|
|
|
|
|
+ }
|
|
|
|
|
+}
|