package com.ruoyi.safe.service.impl;
|
|
import com.ruoyi.common.utils.StringUtils;
|
import com.ruoyi.safe.mapper.SafeFacilityInspectionMapper;
|
import com.ruoyi.safe.mapper.SafeFacilityInspectionTaskMapper;
|
import com.ruoyi.safe.pojo.SafeFacilityInspection;
|
import com.ruoyi.safe.pojo.SafeFacilityInspectionTask;
|
import org.quartz.DisallowConcurrentExecution;
|
import org.quartz.Job;
|
import org.quartz.JobDataMap;
|
import org.quartz.JobExecutionContext;
|
import org.quartz.JobExecutionException;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.stereotype.Component;
|
|
import java.io.Serializable;
|
import java.time.DayOfWeek;
|
import java.time.LocalDateTime;
|
import java.time.LocalTime;
|
import java.time.YearMonth;
|
import java.time.format.DateTimeFormatter;
|
import java.util.HashSet;
|
import java.util.Set;
|
|
@Component
|
@DisallowConcurrentExecution
|
public class SafeFacilityInspectionTaskJob implements Job, Serializable {
|
|
private static final long serialVersionUID = 1L;
|
private static final DateTimeFormatter CODE_FORMATTER = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
|
|
@Autowired
|
private SafeFacilityInspectionTaskMapper safeFacilityInspectionTaskMapper;
|
@Autowired
|
private SafeFacilityInspectionMapper safeFacilityInspectionMapper;
|
|
@Override
|
public void execute(JobExecutionContext context) throws JobExecutionException {
|
JobDataMap jobDataMap = context.getJobDetail().getJobDataMap();
|
Long taskId = jobDataMap.getLong("taskId");
|
|
try {
|
SafeFacilityInspectionTask task = safeFacilityInspectionTaskMapper.selectById(taskId);
|
if (task == null || Integer.valueOf(0).equals(task.getIsEnabled())) {
|
return;
|
}
|
|
LocalDateTime executionTime = LocalDateTime.now();
|
SafeFacilityInspection inspection = createFacilityInspection(task, executionTime);
|
safeFacilityInspectionMapper.insert(inspection);
|
|
task.setLastExecutionTime(executionTime);
|
task.setNextExecutionTime(calculateNextExecutionTime(
|
task.getFrequencyType(),
|
task.getFrequencyDetail(),
|
executionTime
|
));
|
safeFacilityInspectionTaskMapper.updateById(task);
|
} catch (Exception e) {
|
throw new JobExecutionException(e);
|
}
|
}
|
|
private SafeFacilityInspection createFacilityInspection(SafeFacilityInspectionTask task, LocalDateTime executionTime) {
|
SafeFacilityInspection inspection = new SafeFacilityInspection();
|
inspection.setScheduleTaskId(task.getId());
|
inspection.setInspectionCode("SSXJ-" + executionTime.format(CODE_FORMATTER) + "-" + task.getId());
|
inspection.setFacilityId(task.getFacilityId());
|
inspection.setInspectionType("定期巡检");
|
inspection.setInspectionProject(task.getInspectionProject());
|
inspection.setPlanTime(task.getNextExecutionTime() != null ? task.getNextExecutionTime() : executionTime);
|
inspection.setInspectorId(task.getInspectorId());
|
inspection.setCheckDesc(buildCheckDesc(task));
|
inspection.setStatus("待巡检");
|
inspection.setCreateUser(task.getCreateUser());
|
inspection.setUpdateUser(task.getCreateUser());
|
inspection.setCreateTime(executionTime);
|
inspection.setUpdateTime(executionTime);
|
inspection.setTenantId(task.getTenantId());
|
inspection.setDeptId(task.getDeptId());
|
return inspection;
|
}
|
|
private String buildCheckDesc(SafeFacilityInspectionTask task) {
|
String desc = "自动生成自定时任务ID: " + task.getId();
|
if (StringUtils.isNotBlank(task.getRemark())) {
|
desc = desc + ";" + task.getRemark();
|
}
|
return desc;
|
}
|
|
private LocalDateTime calculateNextExecutionTime(String frequencyType,
|
String frequencyDetail,
|
LocalDateTime currentTime) {
|
return switch (frequencyType) {
|
case "DAILY" -> calculateDailyNextTime(frequencyDetail, currentTime);
|
case "WEEKLY" -> calculateWeeklyNextTime(frequencyDetail, currentTime);
|
case "MONTHLY" -> calculateMonthlyNextTime(frequencyDetail, currentTime);
|
default -> throw new IllegalArgumentException("不支持的频率类型: " + frequencyType);
|
};
|
}
|
|
private LocalDateTime calculateDailyNextTime(String timeStr, LocalDateTime current) {
|
LocalTime executionTime = LocalTime.parse(timeStr);
|
LocalDateTime nextTime = LocalDateTime.of(current.toLocalDate(), executionTime);
|
return current.isBefore(nextTime) ? nextTime : nextTime.plusDays(1);
|
}
|
|
private LocalDateTime calculateWeeklyNextTime(String detail, LocalDateTime current) {
|
String[] parts = detail.split(",");
|
LocalTime time = LocalTime.parse(parts[1].trim());
|
Set<DayOfWeek> targetDays = parseDayOfWeeks(parts[0]);
|
|
LocalDateTime nextTime = current;
|
while (true) {
|
nextTime = nextTime.plusDays(1);
|
if (targetDays.contains(nextTime.getDayOfWeek())) {
|
return LocalDateTime.of(nextTime.toLocalDate(), time);
|
}
|
if (nextTime.isAfter(current.plusYears(1))) {
|
throw new RuntimeException("无法找到下次执行时间");
|
}
|
}
|
}
|
|
private LocalDateTime calculateMonthlyNextTime(String detail, LocalDateTime current) {
|
String[] parts = detail.split(",");
|
int dayOfMonth = Integer.parseInt(parts[0].trim());
|
LocalTime time = LocalTime.parse(parts[1].trim());
|
YearMonth currentMonth = YearMonth.from(current);
|
for (int i = 0; i < 24; i++) {
|
YearMonth targetMonth = currentMonth.plusMonths(i);
|
if (dayOfMonth > targetMonth.lengthOfMonth()) {
|
continue;
|
}
|
LocalDateTime candidate = LocalDateTime.of(
|
targetMonth.getYear(),
|
targetMonth.getMonthValue(),
|
dayOfMonth,
|
time.getHour(),
|
time.getMinute()
|
);
|
if (current.isBefore(candidate)) {
|
return candidate;
|
}
|
}
|
throw new IllegalArgumentException("无法计算下次执行时间");
|
}
|
|
private Set<DayOfWeek> parseDayOfWeeks(String dayOfWeekStr) {
|
Set<DayOfWeek> days = new HashSet<>();
|
String[] dayStrs = dayOfWeekStr.split("\\|");
|
|
for (String dayStr : dayStrs) {
|
switch (dayStr.trim()) {
|
case "MON" -> days.add(DayOfWeek.MONDAY);
|
case "TUE" -> days.add(DayOfWeek.TUESDAY);
|
case "WED" -> days.add(DayOfWeek.WEDNESDAY);
|
case "THU" -> days.add(DayOfWeek.THURSDAY);
|
case "FRI" -> days.add(DayOfWeek.FRIDAY);
|
case "SAT" -> days.add(DayOfWeek.SATURDAY);
|
case "SUN" -> days.add(DayOfWeek.SUNDAY);
|
default -> throw new IllegalArgumentException("无效的星期几: " + dayStr);
|
}
|
}
|
|
return days;
|
}
|
}
|