gongchunyi
2 天以前 6bab142343375e744e46f2042aa3b0fedea70b06
src/main/java/com/ruoyi/inspectiontask/service/impl/TimingTaskServiceImpl.java
@@ -1,8 +1,10 @@
package com.ruoyi.inspectiontask.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.bean.BeanUtils;
import com.ruoyi.inspectiontask.dto.TimingTaskDto;
@@ -13,12 +15,12 @@
import com.ruoyi.project.system.domain.SysUser;
import com.ruoyi.project.system.mapper.SysUserMapper;
import lombok.extern.slf4j.Slf4j;
import org.quartz.SchedulerException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;
@@ -46,7 +48,12 @@
    @Override
    public IPage<TimingTaskDto> selectTimingTaskList(Page<TimingTask> page, TimingTask timingTask) {
        // 1. 先分页查询定时任务数据
        IPage<TimingTask> taskPage = timingTaskMapper.selectPage(page, null);
        // 构建查询条件
        LambdaQueryWrapper<TimingTask> queryWrapper = new LambdaQueryWrapper<>();
        if (StringUtils.isNotBlank(timingTask.getTaskName())) {
            queryWrapper.like(TimingTask::getTaskName, timingTask.getTaskName());
        }
        IPage<TimingTask> taskPage = timingTaskMapper.selectPage(page, queryWrapper);
        // 2. 如果没有数据,直接返回空分页
        if (taskPage.getRecords().isEmpty()) {
@@ -65,6 +72,7 @@
        // 收集巡检人ID(多个ID以逗号分隔)
        taskPage.getRecords().forEach(task -> {
            task.setDateStr(task.getCreateTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
            if (StringUtils.isNotBlank(task.getInspectorIds())) {
                Arrays.stream(task.getInspectorIds().split(","))
                        .filter(StringUtils::isNotBlank)
@@ -73,10 +81,17 @@
            }
        });
        // 收集验收入ID
        taskPage.getRecords().forEach(task -> {
            if (task.getInspectionAcceptorId() != null) {
                userIds.add(task.getInspectionAcceptorId());
            }
        });
        // 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()));
        }
@@ -103,6 +118,11 @@
                dto.setInspector(inspectorNickNames);
            }
            // 设置验收人昵称
            if (task.getInspectionAcceptorId() != null) {
                dto.setInspectionAcceptor(userNickNameMap.getOrDefault(task.getInspectionAcceptorId(), "未知用户"));
            }
            return dto;
        }).collect(Collectors.toList());
@@ -114,36 +134,65 @@
    @Override
    @Transactional
    public int addOrEditTimingTask(TimingTaskDto timingTaskDto) throws SchedulerException {
    public int addOrEditTimingTask(TimingTaskDto timingTaskDto) {
        TimingTask timingTask = new TimingTask();
        BeanUtils.copyProperties(timingTaskDto, timingTask);
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        LocalDate localDate = LocalDate.now();
        // 设置创建人信息和默认值
        if (StringUtils.isNotEmpty(timingTaskDto.getDateStr())) {
            localDate = LocalDate.parse(timingTaskDto.getDateStr(), formatter);
        }
        LocalTime currentTime = LocalTime.now();
        LocalDateTime localDateTime = LocalDateTime.of(localDate, currentTime);
        timingTask.setCreateTime(localDateTime);
        if (Objects.isNull(timingTaskDto.getId())) {
            timingTask.setRegistrationDate(LocalDate.now());
            timingTask.setActive(true);
            // 计算首次执行时间
            LocalDateTime firstExecutionTime = calculateFirstExecutionTime(timingTask);
            timingTask.setNextExecutionTime(firstExecutionTime);
            int result = timingTaskMapper.insert(timingTask);
            if (result > 0) {
                // 新增成功后添加到调度器
                timingTaskScheduler.scheduleTimingTask(timingTask);
            // 新增成功后且启用状态才添加到调度器
            if (result > 0 && Integer.valueOf(1).equals(timingTask.getIsActive())) {
                try {
                    timingTaskScheduler.scheduleTimingTask(timingTask);
                } catch (Exception e) {
                    log.error("添加巡检任务失败 : {}", e.getMessage(), e);
                    throw new ServiceException("添加巡检任务失败");
                }
            }
            return result;
        } else {
            // 编辑时,保存旧的状态
            TimingTask oldTask = timingTaskMapper.selectById(timingTaskDto.getId());
            Integer oldIsActive = oldTask != null ? oldTask.getIsActive() : 0;
            Integer newIsActive = timingTask.getIsActive();
            int result = timingTaskMapper.updateById(timingTask);
            if (result > 0) {
                // 更新成功后重新调度任务
                timingTaskScheduler.rescheduleTimingTask(timingTask);
                // 从启用变为停用,移除任务
                if (Integer.valueOf(1).equals(oldIsActive)
                        && !Integer.valueOf(1).equals(newIsActive)) {
                    timingTaskScheduler.unscheduleTimingTask(timingTask.getId());
                }
                // 从停用变为启用,添加任务
                else if (!Integer.valueOf(1).equals(oldIsActive)
                        && Integer.valueOf(1).equals(newIsActive)) {
                    // 计算首次执行时间
                    LocalDateTime firstExecutionTime = calculateFirstExecutionTime(timingTask);
                    timingTask.setNextExecutionTime(firstExecutionTime);
                    try {
                        timingTaskScheduler.scheduleTimingTask(timingTask);
                    } catch (Exception e) {
                        log.error("添加巡检任务失败 : {}", e.getMessage(), e);
                        throw new ServiceException("添加巡检任务失败");
                    }
                }
            }
            return result;
        }
    }
    private LocalDateTime calculateFirstExecutionTime(TimingTask task) {
    public LocalDateTime calculateFirstExecutionTime(TimingTask task) {
        // 根据频率类型和详情计算首次执行时间
        String frequencyType = task.getFrequencyType();
        if ("DAILY".equals(frequencyType)) {
@@ -173,12 +222,108 @@
        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) {
@@ -330,14 +475,29 @@
        for (String dayStr : dayStrs) {
            switch (dayStr) {
                case "MON": days.add(DayOfWeek.MONDAY); break;
                case "TUE": days.add(DayOfWeek.TUESDAY); break;
                case "WED": days.add(DayOfWeek.WEDNESDAY); break;
                case "THU": days.add(DayOfWeek.THURSDAY); break;
                case "FRI": days.add(DayOfWeek.FRIDAY); break;
                case "SAT": days.add(DayOfWeek.SATURDAY); break;
                case "SUN": days.add(DayOfWeek.SUNDAY); break;
                default: throw new IllegalArgumentException("无效的星期几: " + dayStr);
                case "MON":
                    days.add(DayOfWeek.MONDAY);
                    break;
                case "TUE":
                    days.add(DayOfWeek.TUESDAY);
                    break;
                case "WED":
                    days.add(DayOfWeek.WEDNESDAY);
                    break;
                case "THU":
                    days.add(DayOfWeek.THURSDAY);
                    break;
                case "FRI":
                    days.add(DayOfWeek.FRIDAY);
                    break;
                case "SAT":
                    days.add(DayOfWeek.SATURDAY);
                    break;
                case "SUN":
                    days.add(DayOfWeek.SUNDAY);
                    break;
                default:
                    throw new IllegalArgumentException("无效的星期几: " + dayStr);
            }
        }
@@ -345,10 +505,15 @@
    }
    @Override
    public int delByIds(Long[] ids) {
        return timingTaskMapper.deleteBatchIds(Arrays.asList(ids));
        int i = timingTaskMapper.deleteBatchIds(Arrays.asList(ids));
        if (i > 0) {
            for (Long id : ids) {
                timingTaskScheduler.unscheduleTimingTask(id);
            }
        }
        return i;
    }
}