| | |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | |
| | | import java.time.*; |
| | | import java.time.format.DateTimeFormatter; |
| | | import java.util.*; |
| | | import java.util.stream.Collectors; |
| | | |
| | |
| | | // 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())); |
| | | } |
| | | |
| | |
| | | |
| | | // 设置巡检人昵称列表 |
| | | 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); |
| | | } |
| | | |
| | |
| | | |
| | | 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) { |
| | |
| | | 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) { |
| | |
| | | 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); |
| | | } |