package com.zhgd.xmgl.task; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.date.DatePattern; import cn.hutool.core.date.DateTime; import cn.hutool.core.date.DateUnit; import cn.hutool.core.date.DateUtil; import cn.hutool.core.util.NumberUtil; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.zhgd.xmgl.async.AsyncCommon; import com.zhgd.xmgl.modules.basicdata.entity.SystemUser; import com.zhgd.xmgl.modules.basicdata.service.ISystemUserService; import com.zhgd.xmgl.modules.project.constants.ProgressTaskConstant; import com.zhgd.xmgl.modules.project.entity.ProgressTask; import com.zhgd.xmgl.modules.project.entity.ProgressTaskAlarm; import com.zhgd.xmgl.modules.project.enums.ProgressAlarmTypeEnum; import com.zhgd.xmgl.modules.project.service.ProgressTaskAlarmService; import com.zhgd.xmgl.modules.project.service.ProgressTaskService; import lombok.extern.slf4j.Slf4j; import net.javacrumbs.shedlock.core.SchedulerLock; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import java.util.*; import java.util.stream.Collectors; /** * @author 邱平毅 * @ClassName ProgressTask * @date 2022/11/2 11:25 * @Version 1.0 * 甘特图任务调度 */ @Slf4j @Component public class ProgressAlarmTask { @Autowired ProgressTaskService progressTaskService; @Autowired ProgressTaskAlarmService progressTaskAlarmService; @Autowired AsyncCommon asyncCommon; @Autowired ISystemUserService systemUserService; /** * 每天0点5分处理报警数据 */ @SchedulerLock(name = "manageAlarmData", lockAtMostFor = 1000 * 60 * 60, lockAtLeastFor = 1000 * 60 * 5) @Scheduled(cron = "0 5 0 * * ?") public void manageAlarmData() { log.info("ProgressTask#manageAlarmData定时处理甘特图进度数据"); String today = DateUtil.today(); // 预计开始时间已过未开始、预计结束时间已过进行中任务 List alarmTaskList = progressTaskService.list(Wrappers.lambdaQuery(ProgressTask.class) .eq(ProgressTask::getIsOverdue, ProgressTaskConstant.NOT_OVERDUE) .eq(ProgressTask::getStatus, ProgressTaskConstant.NOT_STARTED).lt(ProgressTask::getStartDate, today) .or(wrapper -> wrapper.eq(ProgressTask::getStatus, ProgressTaskConstant.RUNNING).lt(ProgressTask::getFinishDate, today))); // 判断是否有逾期任务 if (CollUtil.isNotEmpty(alarmTaskList)) { List alarmList = new LinkedList<>(); // 根据状态分组 Map> statusTaskMap = alarmTaskList.stream().collect(Collectors.groupingBy(ProgressTask::getStatus)); statusTaskMap.forEach((status, taskList) -> { // 获取状态对应的预警信息 ProgressAlarmTypeEnum progressAlarmTypeEnum = ProgressAlarmTypeEnum.getInstanceByTaskStatus(status); if (progressAlarmTypeEnum == null) { log.error("ProgressTask#manageAlarmData定时处理甘特图进度数据,发生状态异常!当前状态:{}", status); return; } // 添加所有的违规信息 alarmList.addAll(taskList.stream().map(task -> new ProgressTaskAlarm(task.getId(), String.format(progressAlarmTypeEnum.getAlarmDetails() , DateUtil.format(progressAlarmTypeEnum.getField().apply(task), DatePattern.NORM_DATE_PATTERN)), progressAlarmTypeEnum.getId())).collect(Collectors.toList())); }); log.info("当前逾期数据:{}", alarmList); progressTaskAlarmService.saveBatch(alarmList); progressTaskService.updateIsOverdue(alarmTaskList.stream().map(ProgressTask::getId).collect(Collectors.toList())); } } /** * 每天0点对自动任务进行更新 */ @SchedulerLock(name = "autoTaskUpdate", lockAtMostFor = 1000 * 60 * 60, lockAtLeastFor = 1000 * 60 * 5) @Scheduled(cron = "0 0 0 * * ?") public void autoTaskUpdate() { log.info("ProgressTask#autoTaskUpdate每天7点对没有处理的逾期任务进行通知"); // 自动任务未完成列表 List autoTask = progressTaskService.autoNoFinishFinTaskList(); if (CollUtil.isNotEmpty(autoTask)) { log.info("ProgressTask#autoTaskUpdate自动任务列表:{}", autoTask); // 当前日期 DateTime currentDate = DateUtil.parse(DateUtil.today()); for (ProgressTask progressTask : autoTask) { // 设置未开始的任务为开始任务 if (Objects.equals(progressTask.getStatus(), ProgressTaskConstant.NOT_STARTED)) { progressTask.setStatus(ProgressTaskConstant.RUNNING); progressTask.setActualStartDate(currentDate); } // 实际相差 long betweenDay = currentDate.between(progressTask.getActualStartDate(), DateUnit.DAY); // 获取完成百分比 double ratio = NumberUtil.div(NumberUtil.mul(betweenDay, 100), progressTask.getDuration().doubleValue(), 2); progressTask.setProgressRatio(ratio); if (ratio == 100) { progressTask.setStatus(ProgressTaskConstant.FINISH); progressTask.setActualFinishDate(currentDate); } } progressTaskService.updateBatchById(autoTask); } } /** * 每天7点对没有处理的逾期任务进行通知 */ @SchedulerLock(name = "isOverdueDataNotice", lockAtMostFor = 1000 * 60 * 60, lockAtLeastFor = 1000 * 60 * 5) @Scheduled(cron = "0 0 7 * * ?") public void isOverdueDataNotice() { log.info("ProgressTask#isOverdueDataNotice每天7点对没有处理的逾期任务进行通知"); // 逾期任务列表 List overdueList = progressTaskService.list(Wrappers.lambdaQuery().eq(ProgressTask::getIsOverdue, ProgressTaskConstant.IS_OVERDUE).isNotNull(ProgressTask::getDutyUserId)); if (CollUtil.isNotEmpty(overdueList)) { Set userIdList = new HashSet<>(); Map userMsgMap = new LinkedHashMap<>(); for (ProgressTask progressTask : overdueList) { Long userId = progressTask.getDutyUserId(); userIdList.add(userId); userMsgMap.put(userId + "_" + progressTask.getId(), "任务:" + progressTask.getTaskName() + "目前已经逾期,请及时处理!"); } List userList = systemUserService.list(Wrappers.lambdaQuery().in(SystemUser::getUserId, userIdList)); asyncCommon.sendAppAndMqCustomKey("进度任务逾期通知", userMsgMap, "进度任务逾期通知", "/pages/projectEnd/projectIndex/projectIndex", userList); } } }