maven
2025-09-25 83f457a2128e6964b829a76a347b9f000218e14e
src/main/java/com/ruoyi/inspectiontask/service/impl/TimingTaskServiceImpl.java
@@ -19,6 +19,7 @@
import org.springframework.transaction.annotation.Transactional;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;
@@ -76,7 +77,7 @@
        // 4. 批量查询用户信息
        Map<Long, String> userNickNameMap = new HashMap<>();
        if (!userIds.isEmpty()) {
            List<SysUser> users = sysUserMapper.selectUserByIds((List<Long>) userIds);
            List<SysUser> users = sysUserMapper.selectUserByIds((new ArrayList<>(userIds)));
            users.forEach(user -> userNickNameMap.put(user.getUserId(), user.getNickName()));
        }
@@ -93,13 +94,13 @@
            // 设置巡检人昵称列表
            if (StringUtils.isNotBlank(task.getInspectorIds())) {
                List<String> inspectorNickNames = Arrays.stream(task.getInspectorIds().split(","))
                        .filter(StringUtils::isNotBlank)
                        .map(idStr -> {
                            Long id = Long.valueOf(idStr);
                            return userNickNameMap.getOrDefault(id, "未知用户");
                        })
                        .toList();
                List<String> inspectorNickNames = new ArrayList<>();
                for (String idStr : task.getInspectorIds().split(",")) {
                    if (StringUtils.isNotBlank(idStr)) {
                        Long id = Long.valueOf(idStr);
                        inspectorNickNames.add(userNickNameMap.getOrDefault(id, "未知用户"));
                    }
                }
                dto.setInspector(inspectorNickNames);
            }
@@ -145,21 +146,22 @@
    private LocalDateTime calculateFirstExecutionTime(TimingTask task) {
        // 根据频率类型和详情计算首次执行时间
        return switch (task.getFrequencyType()) {
            case "DAILY" ->
                    // 如果是每天执行,计算今天或明天的具体时间
                    calculateDailyFirstExecution(task.getFrequencyDetail());
            case "WEEKLY" ->
                    // 如果是每周执行,计算下周的具体星期几
                    calculateWeeklyFirstExecution(task.getFrequencyDetail());
            case "MONTHLY" ->
                    // 如果是每月执行,计算下个月的具体日期
                    calculateMonthlyFirstExecution(task.getFrequencyDetail());
            case "QUARTERLY" ->
                    // 自定义频率,如每小时、每30分钟等
                    calculateCustomFirstExecution(task.getFrequencyDetail());
            default -> throw new IllegalArgumentException("不支持的频率类型: " + task.getFrequencyType());
        };
        String frequencyType = task.getFrequencyType();
        if ("DAILY".equals(frequencyType)) {
            // 如果是每天执行,计算今天或明天的具体时间
            return calculateDailyFirstExecution(task.getFrequencyDetail());
        } else if ("WEEKLY".equals(frequencyType)) {
            // 如果是每周执行,计算下周的具体星期几
            return calculateWeeklyFirstExecution(task.getFrequencyDetail());
        } else if ("MONTHLY".equals(frequencyType)) {
            // 如果是每月执行,计算下个月的具体日期
            return calculateMonthlyFirstExecution(task.getFrequencyDetail());
        } else if ("QUARTERLY".equals(frequencyType)) {
            // 自定义频率,如每小时、每30分钟等
            return calculateCustomFirstExecution(task.getFrequencyDetail());
        } else {
            throw new IllegalArgumentException("不支持的频率类型: " + task.getFrequencyType());
        }
    }
    private LocalDateTime calculateDailyFirstExecution(String frequencyDetail) {
@@ -172,12 +174,107 @@
        return now.isBefore(todayExecution) ? todayExecution : todayExecution.plusDays(1);
    }
    // 映射星期简写与DayOfWeek
    private static final Map<String, DayOfWeek> WEEK_DAY_MAP = new HashMap<>();
    static {
        WEEK_DAY_MAP.put("MON", DayOfWeek.MONDAY);
        WEEK_DAY_MAP.put("TUE", DayOfWeek.TUESDAY);
        WEEK_DAY_MAP.put("WED", DayOfWeek.WEDNESDAY);
        WEEK_DAY_MAP.put("THU", DayOfWeek.THURSDAY);
        WEEK_DAY_MAP.put("FRI", DayOfWeek.FRIDAY);
        WEEK_DAY_MAP.put("SAT", DayOfWeek.SATURDAY);
        WEEK_DAY_MAP.put("SUN", DayOfWeek.SUNDAY);
    }
    private LocalDateTime calculateWeeklyFirstExecution(String frequencyDetail) {
        return null;
        // 解析输入参数
        String[] parts = frequencyDetail.split(",");
        if (parts.length != 2) {
            throw new IllegalArgumentException("参数格式错误,应为'MON,13:43'格式");
        }
        String weekDayStr = parts[0].trim();
        String timeStr = parts[1].trim();
        // 获取对应的星期几
        DayOfWeek targetDay = WEEK_DAY_MAP.get(weekDayStr);
        if (targetDay == null) {
            throw new IllegalArgumentException("无效的星期简写: " + weekDayStr);
        }
        // 解析时间
        LocalTime targetTime = LocalTime.parse(timeStr, DateTimeFormatter.ofPattern("HH:mm"));
        // 获取当前时间
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime targetDateTime = now.with(targetDay).with(targetTime);
        // 如果计算出的时间在当前时间之前,则加一周
        if (targetDateTime.isBefore(now)) {
            targetDateTime = targetDateTime.plusWeeks(1);
        }
        return targetDateTime;
    }
    private LocalDateTime calculateMonthlyFirstExecution(String frequencyDetail) {
        return null;
        // 解析输入参数
        String[] parts = frequencyDetail.split(",");
        if (parts.length != 2) {
            throw new IllegalArgumentException("参数格式错误,应为'03,17:00'格式");
        }
        String dayStr = parts[0].trim();
        String timeStr = parts[1].trim();
        // 解析日期
        int dayOfMonth;
        try {
            dayOfMonth = Integer.parseInt(dayStr);
        } catch (NumberFormatException e) {
            throw new IllegalArgumentException("无效的日期格式: " + dayStr, e);
        }
        // 验证日期有效性(1-31之间)
        if (dayOfMonth < 1 || dayOfMonth > 31) {
            throw new IllegalArgumentException("日期必须在1-31之间: " + dayOfMonth);
        }
        // 解析时间
        LocalTime targetTime;
        try {
            targetTime = LocalTime.parse(timeStr, DateTimeFormatter.ofPattern("HH:mm"));
        } catch (DateTimeException e) {
            throw new IllegalArgumentException("无效的时间格式: " + timeStr, e);
        }
        // 获取当前时间
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime targetDateTime = now.withDayOfMonth(dayOfMonth).with(targetTime);
        // 检查日期是否被自动调整(如31日在小月会被调整)
        boolean isDateAdjusted = targetDateTime.getDayOfMonth() != dayOfMonth;
        // 如果目标时间在当前时间之前,或者日期被系统自动调整了
        if (targetDateTime.isBefore(now) || isDateAdjusted) {
            // 计算下个月的日期
            LocalDateTime nextMonth = now.plusMonths(1);
            // 尝试设置下个月的目标日期
            LocalDateTime nextMonthTarget = nextMonth.withDayOfMonth(dayOfMonth).with(targetTime);
            // 如果下个月的日期也被调整了,就用下个月的最后一天
            if (nextMonthTarget.getDayOfMonth() != dayOfMonth) {
                // 正确获取下个月的最后一天(修复isLeapYear调用问题)
                int lastDayOfMonth = nextMonth.getMonth().length(
                        Year.of(nextMonth.getYear()).isLeap()
                );
                nextMonthTarget = nextMonth.withDayOfMonth(lastDayOfMonth).with(targetTime);
            }
            targetDateTime = nextMonthTarget;
        }
        return targetDateTime;
    }
    private LocalDateTime calculateCustomFirstExecution(String frequencyDetail) {
@@ -214,13 +311,18 @@
                                                     String frequencyDetail,
                                                     LocalDateTime currentTime) {
        try {
            return switch (frequencyType) {
                case "DAILY" -> calculateDailyNextTime(frequencyDetail, currentTime);
                case "WEEKLY" -> calculateWeeklyNextTime(frequencyDetail, currentTime);
                case "MONTHLY" -> calculateMonthlyNextTime(frequencyDetail, currentTime);
                case "QUARTERLY" -> calculateQuarterlyNextTime(frequencyDetail, currentTime);
                default -> throw new IllegalArgumentException("不支持的频率类型: " + frequencyType);
            };
            switch (frequencyType) {
                case "DAILY":
                    return calculateDailyNextTime(frequencyDetail, currentTime);
                case "WEEKLY":
                    return calculateWeeklyNextTime(frequencyDetail, currentTime);
                case "MONTHLY":
                    return calculateMonthlyNextTime(frequencyDetail, currentTime);
                case "QUARTERLY":
                    return calculateQuarterlyNextTime(frequencyDetail, currentTime);
                default:
                    throw new IllegalArgumentException("不支持的频率类型: " + frequencyType);
            }
        } catch (Exception e) {
            throw new RuntimeException("计算下次执行时间失败: " + e.getMessage(), e);
        }