package com.ruoyi.task.service.impl; import com.ruoyi.task.api.enums.*; import com.ruoyi.task.domain.api.ITaskDomain; import com.ruoyi.task.domain.api.ITaskPlanDomain; import com.ruoyi.task.domain.model.Task; import com.ruoyi.task.domain.model.TaskPlan; import com.ruoyi.task.service.api.ITaskPlanService; import com.ruoyi.task.service.convert.TaskPlanDTOConvert; import com.ruoyi.task.service.dto.TaskPlanDTO; import com.ruoyi.task.service.dto.TaskPlanQueryDTO; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; import java.util.Objects; @Service public class TaskPlanServiceImpl implements ITaskPlanService { @Autowired private ITaskPlanDomain taskPlanDomain; @Autowired private ITaskDomain taskDomain; @Override public Long createNormalTimedTaskPlan(TaskPlanDTO taskPlanDTO, boolean create) { TaskPlan taskPlan = TaskPlanDTOConvert.toDomain(taskPlanDTO); // 校验PlanTypeEnum if (taskPlan.getPlanType() != null && taskPlan.getPlanType() == PlanTypeEnum.CYCLE) { throw new IllegalArgumentException("定时任务计划不能设置为周期类型"); } // 设置结束时间:开始时间 + 执行时长 if (taskPlan.getExecuteTime() != null && taskPlan.getDuration() != null) { taskPlan.setStartDate(taskPlan.getExecuteTime()); taskPlan.setEndDate(taskPlan.getExecuteTime()); } if(create){ TaskPlan result = taskPlanDomain.createTimedTaskPlan(taskPlan); // 创建对应的任务记录 createNormalTaskFromPlan(result); return result.getId(); }else { taskPlanDomain.updateTaskPlan(taskPlan); createNormalTaskFromPlan(taskPlan); return taskPlan.getId(); } } @Override public Long createCycleTaskPlan(TaskPlanDTO taskPlanDTO,boolean create) { TaskPlan taskPlan = TaskPlanDTOConvert.toDomain(taskPlanDTO); // 校验PlanTypeEnum if (taskPlan.getPlanType() != null && taskPlan.getPlanType() == PlanTypeEnum.TIMED) { throw new IllegalArgumentException("周期任务计划不能设置为定时类型"); } // 如果PlanTypeEnum为空,设置为周期类型 if (taskPlan.getPlanType() == null) { taskPlan.setPlanType(PlanTypeEnum.CYCLE); } if(create){ TaskPlan result = taskPlanDomain.createCycleTaskPlan(taskPlan); // 创建对应的任务记录 createNormalTaskFromPlan(result); return result.getId(); }else { taskPlanDomain.updateTaskPlan(taskPlan); createNormalTaskFromPlan(taskPlan); return taskPlan.getId(); } } /** * 根据任务计划创建任务记录 */ private void createNormalTaskFromPlan(TaskPlan taskPlan) { // 检查是否为周期任务计划 if (taskPlan.getPlanType() == PlanTypeEnum.CYCLE) { // 生成周期任务记录 generateNormalCycleTasks(taskPlan); } else { // 生成单次任务记录 generateNormalPlanTask(taskPlan); } } /** * 生成单次任务记录 */ private void generateNormalPlanTask(TaskPlan taskPlan) { Task task = new Task(); task.setTaskName(taskPlan.getPlanName() + "_任务"); task.setPlanId(taskPlan.getId()); task.setTaskCategory(TaskCategoryEnum.NORMAL); if(Objects.equals(taskPlan.getPlanType(), PlanTypeEnum.TIMED)){ task.setTaskType(TaskTypeEnum.TIMED); } if (Objects.equals(taskPlan.getPlanType(), PlanTypeEnum.CYCLE)) { task.setTaskType(TaskTypeEnum.CYCLE); } if (Objects.equals(taskPlan.getPlanType(), PlanTypeEnum.IMMEDIATELY)) { task.setTaskType(TaskTypeEnum.IMMEDIATELY); } task.setExecuteType(taskPlan.getExecuteType()); task.setRouteId(taskPlan.getRouteId()); task.setUavId(taskPlan.getUavId()); task.setStartTime(taskPlan.getExecuteTime()); // 设置结束时间:开始时间 + 执行时长 if (taskPlan.getExecuteTime() != null && taskPlan.getDuration() != null) { java.util.Calendar endTaskCalendar = java.util.Calendar.getInstance(); endTaskCalendar.setTime(taskPlan.getExecuteTime()); endTaskCalendar.add(java.util.Calendar.SECOND, taskPlan.getDuration()); task.setEndTime(endTaskCalendar.getTime()); } task.setStatus(StatusEnum.PENDING); // 待执行 task.setDescription("由任务计划自动创建"); // 创建任务 taskDomain.createTask(task); } /** * 生成周期任务记录 */ private void generateNormalCycleTasks(TaskPlan taskPlan) { java.util.Calendar calendar = java.util.Calendar.getInstance(); calendar.setTime(taskPlan.getStartDate()); java.util.Calendar endCalendar = java.util.Calendar.getInstance(); endCalendar.setTime(taskPlan.getEndDate()); if (taskPlan.getCycleType() == CycleTypeEnum.DAILY) { // 日周期:cycleValue 表示每几天执行一次 int dayInterval = 1; if (taskPlan.getCycleValue() != null && !taskPlan.getCycleValue().isEmpty()) { try { dayInterval = Integer.parseInt(taskPlan.getCycleValue().trim()); if (dayInterval < 1) dayInterval = 1; } catch (NumberFormatException e) { dayInterval = 1; } } while (!calendar.after(endCalendar)) { createNormalTaskForDate(taskPlan, calendar); calendar.add(java.util.Calendar.DAY_OF_YEAR, dayInterval); } } else { // 周周期和月周期:解析 cycleValue 为集合 java.util.Set cycleValues = new java.util.HashSet<>(); if (taskPlan.getCycleValue() != null && !taskPlan.getCycleValue().isEmpty()) { String[] values = taskPlan.getCycleValue().split(","); for (String value : values) { try { cycleValues.add(Integer.parseInt(value.trim())); } catch (NumberFormatException e) { // 忽略无效值 } } } while (!calendar.after(endCalendar)) { boolean shouldCreateTask = false; if (taskPlan.getCycleType() == CycleTypeEnum.WEEKLY) { int dayOfWeek = calendar.get(java.util.Calendar.DAY_OF_WEEK); shouldCreateTask = cycleValues.contains(dayOfWeek); } else if (taskPlan.getCycleType() == CycleTypeEnum.MONTHLY) { int dayOfMonth = calendar.get(java.util.Calendar.DAY_OF_MONTH); shouldCreateTask = cycleValues.contains(dayOfMonth); } if (shouldCreateTask) { createNormalTaskForDate(taskPlan, calendar); } calendar.add(java.util.Calendar.DAY_OF_YEAR, 1); } } } private void createNormalTaskForDate(TaskPlan taskPlan, java.util.Calendar calendar) { Task task = new Task(); task.setTaskName(taskPlan.getPlanName() + "_任务_" + formatDate(calendar.getTime())); task.setPlanId(taskPlan.getId()); task.setTaskCategory(TaskCategoryEnum.NORMAL); if(Objects.equals(taskPlan.getPlanType(), PlanTypeEnum.TIMED)){ task.setTaskType(TaskTypeEnum.TIMED); } if(Objects.equals(taskPlan.getPlanType(), PlanTypeEnum.CYCLE)){ task.setTaskType(TaskTypeEnum.CYCLE); } if(Objects.equals(taskPlan.getPlanType(), PlanTypeEnum.IMMEDIATELY)){ task.setTaskType(TaskTypeEnum.IMMEDIATELY); } task.setExecuteType(taskPlan.getExecuteType()); task.setRouteId(taskPlan.getRouteId()); task.setUavId(taskPlan.getUavId()); if (taskPlan.getExecuteTime() != null) { java.util.Calendar taskCalendar = java.util.Calendar.getInstance(); taskCalendar.setTime(calendar.getTime()); java.util.Calendar executeTimeCalendar = java.util.Calendar.getInstance(); executeTimeCalendar.setTime(taskPlan.getExecuteTime()); taskCalendar.set(java.util.Calendar.HOUR_OF_DAY, executeTimeCalendar.get(java.util.Calendar.HOUR_OF_DAY)); taskCalendar.set(java.util.Calendar.MINUTE, executeTimeCalendar.get(java.util.Calendar.MINUTE)); taskCalendar.set(java.util.Calendar.SECOND, executeTimeCalendar.get(java.util.Calendar.SECOND)); task.setStartTime(taskCalendar.getTime()); java.util.Calendar endTaskCalendar = (java.util.Calendar) taskCalendar.clone(); if (taskPlan.getDuration() != null) { endTaskCalendar.add(java.util.Calendar.SECOND, taskPlan.getDuration()); } else { endTaskCalendar.add(java.util.Calendar.SECOND, 3600); } task.setEndTime(endTaskCalendar.getTime()); } else { task.setStartTime(calendar.getTime()); task.setEndTime(calendar.getTime()); } task.setStatus(StatusEnum.PENDING); task.setDescription("由任务计划自动创建"); taskDomain.createTask(task); } /** * 格式化日期为字符串 */ private String formatDate(java.util.Date date) { java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyyMMdd"); return sdf.format(date); } @Override public TaskPlanDTO getTaskPlanById(Long planId) { TaskPlan taskPlan = taskPlanDomain.getTaskPlanById(planId); return TaskPlanDTOConvert.toDTO(taskPlan); } @Override public List getTaskPlanList(TaskPlanQueryDTO queryDTO) { // 如果传递了id,功能就等同于getTaskPlanById if (queryDTO.getId() != null) { TaskPlanDTO taskPlanDTO = getTaskPlanById(queryDTO.getId()); return taskPlanDTO != null ? java.util.Collections.singletonList(taskPlanDTO) : java.util.Collections.emptyList(); } // 创建TaskPlan对象作为查询条件 TaskPlan taskPlan = new TaskPlan(); taskPlan.setRouteId(queryDTO.getRouteId()); taskPlan.setUavId(queryDTO.getUavId()); taskPlan.setStatus(queryDTO.getStatus()); taskPlan.setPlanType(queryDTO.getPlanType()); taskPlan.setCycleType(queryDTO.getCycleType()); // 这里需要注意:TaskPlan类中没有airportCode和routeName字段, // 这些字段可能需要通过关联查询来实现过滤, // 但目前我们先按照现有的结构实现基本过滤 List taskPlans = taskPlanDomain.getTaskPlanList(taskPlan); // 过滤时间范围(只有当startDateStart和startDateEnd都传时才使用) if (queryDTO.getStartDateStart() != null && queryDTO.getStartDateEnd() != null) { java.util.Date startDateStart = queryDTO.getStartDateStart(); java.util.Date startDateEnd = queryDTO.getStartDateEnd(); taskPlans = taskPlans.stream() .filter(plan -> { java.util.Date planStartDate = plan.getStartDate(); return planStartDate != null && !planStartDate.before(startDateStart) && !planStartDate.after(startDateEnd); }) .collect(java.util.stream.Collectors.toList()); } return TaskPlanDTOConvert.toDTOList(taskPlans); } @Override public boolean updateTaskPlan(TaskPlanDTO taskPlanDTO) { // 先查询原始数据 TaskPlan existingTaskPlan = taskPlanDomain.getTaskPlanById(taskPlanDTO.getId()); if (existingTaskPlan == null) { throw new IllegalArgumentException("任务计划不存在"); } // 将传入的非空字段覆盖到原始数据 TaskPlan updateTaskPlan = TaskPlanDTOConvert.toDomain(taskPlanDTO); if (updateTaskPlan.getPlanName() != null) existingTaskPlan.setPlanName(updateTaskPlan.getPlanName()); if (updateTaskPlan.getPlanType() != null) existingTaskPlan.setPlanType(updateTaskPlan.getPlanType()); if (updateTaskPlan.getCycleType() != null) existingTaskPlan.setCycleType(updateTaskPlan.getCycleType()); if (updateTaskPlan.getCycleValue() != null) existingTaskPlan.setCycleValue(updateTaskPlan.getCycleValue()); if (updateTaskPlan.getExecuteType() != null) existingTaskPlan.setExecuteType(updateTaskPlan.getExecuteType()); if (updateTaskPlan.getExecuteTime() != null) existingTaskPlan.setExecuteTime(updateTaskPlan.getExecuteTime()); if (updateTaskPlan.getDuration() != null) existingTaskPlan.setDuration(updateTaskPlan.getDuration()); if (updateTaskPlan.getStartDate() != null) existingTaskPlan.setStartDate(updateTaskPlan.getStartDate()); if (updateTaskPlan.getEndDate() != null) existingTaskPlan.setEndDate(updateTaskPlan.getEndDate()); if (updateTaskPlan.getRouteId() != null) existingTaskPlan.setRouteId(updateTaskPlan.getRouteId()); if (updateTaskPlan.getUavId() != null) existingTaskPlan.setUavId(updateTaskPlan.getUavId()); if (updateTaskPlan.getStatus() != null) existingTaskPlan.setStatus(updateTaskPlan.getStatus()); if (updateTaskPlan.getDescription() != null) existingTaskPlan.setDescription(updateTaskPlan.getDescription()); if (updateTaskPlan.getRouteUrl() != null) existingTaskPlan.setRouteUrl(updateTaskPlan.getRouteUrl()); if (updateTaskPlan.getRemark() != null) existingTaskPlan.setRemark(updateTaskPlan.getRemark()); TaskPlan result = taskPlanDomain.updateTaskPlan(existingTaskPlan); if (result != null) { // 先删除该计划下的所有未执行任务 List tasks = taskDomain.getTaskByPlanId(result.getId()); for (Task task : tasks) { if (task.getStatus() == StatusEnum.PENDING) { taskDomain.deleteTask(task.getId()); } } } createNormalTaskFromPlan(existingTaskPlan); return result != null; } @Override public boolean deleteTaskPlan(Long planId) { // 先获取该计划下的所有任务 List tasks = taskDomain.getTaskByPlanId(planId); // 删除所有状态为待执行的任务 for (Task task : tasks) { if (task.getStatus() == StatusEnum.PENDING) { taskDomain.deleteTask(task.getId()); } } // 最后删除任务计划 return taskPlanDomain.deleteTaskPlan(planId); } }