| | |
| | | package com.ruoyi.device.service.impl; |
| | | |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import com.ruoyi.common.utils.bean.BeanUtils; |
| | | import com.ruoyi.device.mapper.MaintenanceTaskMapper; |
| | | import com.ruoyi.device.mapper.MaintenanceItemMapper; |
| | | import com.ruoyi.device.mapper.MaintenanceTaskItemMapper; |
| | | import com.ruoyi.device.pojo.MaintenanceItem; |
| | | import com.ruoyi.device.pojo.MaintenanceTask; |
| | | import com.ruoyi.device.pojo.MaintenanceTaskItem; |
| | | import com.ruoyi.device.service.MaintenanceTaskService; |
| | | import com.ruoyi.framework.web.domain.AjaxResult; |
| | | import com.ruoyi.inspectiontask.pojo.TimingTask; |
| | | import com.ruoyi.inspectiontask.service.impl.TimingTaskServiceImpl; |
| | | import com.ruoyi.project.system.domain.SysUser; |
| | | import com.ruoyi.project.system.mapper.SysUserMapper; |
| | | import lombok.RequiredArgsConstructor; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | |
| | | import java.time.LocalDateTime; |
| | | import java.util.*; |
| | | import java.util.ArrayList; |
| | | import java.util.Collections; |
| | | import java.util.HashMap; |
| | | import java.util.HashSet; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import java.util.Objects; |
| | | import java.util.Set; |
| | | import java.util.stream.Collectors; |
| | | |
| | | /** |
| | | * @author :yys |
| | |
| | | */ |
| | | @Service |
| | | @Slf4j |
| | | @RequiredArgsConstructor |
| | | public class MaintenanceTaskServiceImpl extends ServiceImpl<MaintenanceTaskMapper, MaintenanceTask> implements MaintenanceTaskService { |
| | | |
| | | @Autowired |
| | | private MaintenanceTaskMapper maintenanceTaskMapper; |
| | | |
| | | @Autowired |
| | | private SysUserMapper sysUserMapper; |
| | | |
| | | @Autowired |
| | | private TimingTaskServiceImpl timingTaskService; |
| | | |
| | | @Autowired |
| | | private MaintenanceTaskScheduler maintenanceTaskScheduler; |
| | | private final MaintenanceTaskMapper maintenanceTaskMapper; |
| | | private final MaintenanceItemMapper maintenanceItemMapper; |
| | | private final MaintenanceTaskItemMapper maintenanceTaskItemMapper; |
| | | private final SysUserMapper sysUserMapper; |
| | | private final TimingTaskServiceImpl timingTaskService; |
| | | private final MaintenanceTaskScheduler maintenanceTaskScheduler; |
| | | |
| | | @Override |
| | | public AjaxResult listPage(Page page, MaintenanceTask maintenanceTask) { |
| | | Page<MaintenanceTask> taskPage = maintenanceTaskMapper.selectPage(page, null); |
| | | LambdaQueryWrapper<MaintenanceTask> queryWrapper = new LambdaQueryWrapper<>(); |
| | | queryWrapper.orderByDesc(MaintenanceTask::getId); |
| | | Page<MaintenanceTask> taskPage = maintenanceTaskMapper.selectPage(page, queryWrapper); |
| | | // 2. 如果没有数据,直接返回空分页 |
| | | if (taskPage.getRecords().isEmpty()) { |
| | | return AjaxResult.success(taskPage); |
| | |
| | | task.setRegistrant(userNickNameMap.getOrDefault(task.getRegistrantId(), "未知用户")); |
| | | } |
| | | }); |
| | | taskPage.getRecords().forEach(this::fillTaskItems); |
| | | return AjaxResult.success(taskPage); |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public AjaxResult add(MaintenanceTask maintenanceTask) { |
| | | maintenanceTask.setActive(true); |
| | | List<MaintenanceItem> selectedItems = getSelectedItems(maintenanceTask.getMaintenanceItemIds(), null, maintenanceTask.getTaskId(), maintenanceTask.getFrequencyType()); |
| | | List<MaintenanceTaskItem> customItems = normalizeCustomItems(maintenanceTask.getCustomItems()); |
| | | if (selectedItems == null || selectedItems.size() + customItems.size() == 0) |
| | | return AjaxResult.error("请选择至少一个有效的保养项目"); |
| | | // 计算首次执行时间 |
| | | TimingTask task = new TimingTask(); |
| | | task.setFrequencyType(maintenanceTask.getFrequencyType()); |
| | |
| | | maintenanceTask.setNextExecutionTime(firstExecutionTime); |
| | | int insert = maintenanceTaskMapper.insert(maintenanceTask); |
| | | if (insert > 0) { |
| | | maintenanceTaskScheduler.scheduleMaintenanceTask(maintenanceTask); |
| | | saveTaskItems(maintenanceTask, selectedItems, customItems); |
| | | // 只有当 isActive 为 1 时才添加到定时任务调度器 |
| | | if (maintenanceTask.getIsActive() != null && maintenanceTask.getIsActive() == 1) { |
| | | maintenanceTaskScheduler.scheduleMaintenanceTask(maintenanceTask); |
| | | } |
| | | } |
| | | return AjaxResult.success("添加成功"); |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public AjaxResult updateByMaintenanceTaskId(MaintenanceTask maintenanceTask) { |
| | | MaintenanceTask maintenanceTask1 = maintenanceTaskMapper.selectById(maintenanceTask.getId()); |
| | | if (maintenanceTask1 == null) { |
| | | return AjaxResult.warn("没有此数据"); |
| | | } |
| | | List<MaintenanceItem> selectedItems = getSelectedItems(maintenanceTask.getMaintenanceItemIds(), maintenanceTask1.getId(), maintenanceTask.getTaskId(), maintenanceTask.getFrequencyType()); |
| | | List<MaintenanceTaskItem> customItems = normalizeCustomItems(maintenanceTask.getCustomItems()); |
| | | if (selectedItems == null || selectedItems.size() + customItems.size() == 0) |
| | | return AjaxResult.error("请选择至少一个有效的保养项目"); |
| | | |
| | | // 保存旧的 isActive 状态 |
| | | Integer oldIsActive = maintenanceTask1.getIsActive(); |
| | | Integer newIsActive = maintenanceTask.getIsActive(); |
| | | |
| | | BeanUtils.copyProperties(maintenanceTask, maintenanceTask1); |
| | | int update = maintenanceTaskMapper.updateById(maintenanceTask1); |
| | | if (update > 0) { |
| | | maintenanceTaskScheduler.rescheduleMaintenanceTask(maintenanceTask1); |
| | | maintenanceTaskItemMapper.delete(new LambdaQueryWrapper<MaintenanceTaskItem>() |
| | | .eq(MaintenanceTaskItem::getMaintenanceTaskId, maintenanceTask1.getId())); |
| | | saveTaskItems(maintenanceTask1, selectedItems, customItems); |
| | | // 处理 isActive 状态变化 |
| | | if (newIsActive != null && newIsActive == 1) { |
| | | // 新状态为启用:添加到定时任务调度器 |
| | | if (oldIsActive == null || oldIsActive != 1) { |
| | | // 从未启用变为启用,添加到调度器 |
| | | maintenanceTaskScheduler.scheduleMaintenanceTask(maintenanceTask1); |
| | | } else { |
| | | // 已经启用,更新调度器中的任务 |
| | | maintenanceTaskScheduler.rescheduleMaintenanceTask(maintenanceTask1); |
| | | } |
| | | } else { |
| | | // 新状态为停用:从定时任务调度器中移除 |
| | | if (oldIsActive != null && oldIsActive == 1) { |
| | | maintenanceTaskScheduler.unscheduleMaintenanceTask(maintenanceTask1.getId()); |
| | | } |
| | | } |
| | | } |
| | | return AjaxResult.success("更新成功"); |
| | | } |
| | | |
| | | @Override |
| | | public AjaxResult delete(List<Long> ids) { |
| | | // 先从定时任务调度器中移除所有待删除的任务 |
| | | ids.forEach(id -> { |
| | | try { |
| | | maintenanceTaskScheduler.unscheduleMaintenanceTask(id); |
| | | } catch (Exception e) { |
| | | log.error("删除定时任务调度失败, id: {}", id, e); |
| | | } |
| | | }); |
| | | |
| | | // 再从数据库中删除记录 |
| | | int delete = maintenanceTaskMapper.deleteBatchIds(ids); |
| | | if (delete > 0) { |
| | | ids.forEach(id -> { |
| | | maintenanceTaskScheduler.unscheduleMaintenanceTask(id); |
| | | }); |
| | | maintenanceTaskItemMapper.delete(new LambdaQueryWrapper<MaintenanceTaskItem>() |
| | | .in(MaintenanceTaskItem::getMaintenanceTaskId, ids)); |
| | | } |
| | | return AjaxResult.success("删除成功"); |
| | | if (delete > 0) { |
| | | return AjaxResult.success("删除成功"); |
| | | } |
| | | return AjaxResult.error("删除失败"); |
| | | } |
| | | |
| | | private List<MaintenanceTaskItem> normalizeCustomItems(List<MaintenanceTaskItem> customItems) { |
| | | if (customItems == null) return new ArrayList<>(); |
| | | return customItems.stream().filter(Objects::nonNull) |
| | | .filter(item -> item.getItemProject() != null && !item.getItemProject().trim().isEmpty() |
| | | && item.getItemName() != null && !item.getItemName().trim().isEmpty()) |
| | | .peek(item -> { |
| | | item.setItemProject(item.getItemProject().trim()); |
| | | item.setItemName(item.getItemName().trim()); |
| | | }) |
| | | .toList(); |
| | | } |
| | | |
| | | private List<MaintenanceItem> getSelectedItems(List<Long> ids, Long taskId, Long deviceId, String frequencyType) { |
| | | if (deviceId == null || !List.of("DAILY", "WEEKLY", "MONTHLY", "QUARTERLY").contains(frequencyType) |
| | | || (ids != null && new HashSet<>(ids).size() != ids.size())) return null; |
| | | if (ids == null || ids.isEmpty()) return new ArrayList<>(); |
| | | List<MaintenanceItem> items = maintenanceItemMapper.selectList(new LambdaQueryWrapper<MaintenanceItem>() |
| | | .in(MaintenanceItem::getId, ids)); |
| | | if (items.size() != ids.size()) return null; |
| | | if (items.stream().anyMatch(item -> (item.getDeviceLedgerId() != null && !deviceId.equals(item.getDeviceLedgerId())) |
| | | || !(frequencyType.equals(item.getFrequencyType()) || "ALL".equals(item.getFrequencyType())))) |
| | | return null; |
| | | Map<Long, MaintenanceItem> itemMap = new HashMap<>(); |
| | | items.forEach(item -> itemMap.put(item.getId(), item)); |
| | | Set<Long> existingIds = taskId == null ? Collections.emptySet() : maintenanceTaskItemMapper.selectList( |
| | | new LambdaQueryWrapper<MaintenanceTaskItem>() |
| | | .eq(MaintenanceTaskItem::getMaintenanceTaskId, taskId)) |
| | | .stream().map(MaintenanceTaskItem::getMaintenanceItemId).collect(Collectors.toSet()); |
| | | if (items.stream().anyMatch(item -> (item.getDeleted() != null && item.getDeleted() == 1 |
| | | || item.getIsActive() == null || item.getIsActive() != 1) |
| | | && !existingIds.contains(item.getId()))) return null; |
| | | List<MaintenanceItem> sorted = new ArrayList<>(); |
| | | ids.forEach(id -> sorted.add(itemMap.get(id))); |
| | | return sorted; |
| | | } |
| | | |
| | | private void saveTaskItems(MaintenanceTask task, List<MaintenanceItem> selectedItems, List<MaintenanceTaskItem> customItems) { |
| | | for (int i = 0; i < selectedItems.size(); i++) { |
| | | MaintenanceItem source = selectedItems.get(i); |
| | | MaintenanceTaskItem link = new MaintenanceTaskItem(); |
| | | link.setMaintenanceTaskId(task.getId()); |
| | | link.setMaintenanceItemId(source.getId()); |
| | | link.setItemProject(source.getItemProject()); |
| | | link.setItemName(source.getItemName()); |
| | | link.setSortNum(i); |
| | | link.setTenantId(task.getTenantId()); |
| | | link.setDeptId(task.getDeptId()); |
| | | maintenanceTaskItemMapper.insert(link); |
| | | } |
| | | for (int i = 0; i < customItems.size(); i++) { |
| | | MaintenanceTaskItem link = new MaintenanceTaskItem(); |
| | | link.setMaintenanceTaskId(task.getId()); |
| | | link.setMaintenanceItemId(null); |
| | | link.setItemProject(customItems.get(i).getItemProject()); |
| | | link.setItemName(customItems.get(i).getItemName()); |
| | | link.setSortNum(selectedItems.size() + i); |
| | | link.setTenantId(task.getTenantId()); |
| | | link.setDeptId(task.getDeptId()); |
| | | maintenanceTaskItemMapper.insert(link); |
| | | } |
| | | task.setMaintenanceItems(maintenanceTaskItemMapper.selectList(new LambdaQueryWrapper<MaintenanceTaskItem>() |
| | | .eq(MaintenanceTaskItem::getMaintenanceTaskId, task.getId()) |
| | | .orderByAsc(MaintenanceTaskItem::getSortNum))); |
| | | task.setMaintenanceItemIds(task.getMaintenanceItems().stream() |
| | | .map(MaintenanceTaskItem::getMaintenanceItemId).filter(Objects::nonNull).collect(Collectors.toList())); |
| | | } |
| | | |
| | | private void fillTaskItems(MaintenanceTask task) { |
| | | List<MaintenanceTaskItem> items = maintenanceTaskItemMapper.selectList(new LambdaQueryWrapper<MaintenanceTaskItem>() |
| | | .eq(MaintenanceTaskItem::getMaintenanceTaskId, task.getId()) |
| | | .orderByAsc(MaintenanceTaskItem::getSortNum)); |
| | | task.setMaintenanceItems(items); |
| | | task.setMaintenanceItemIds(items.stream().map(MaintenanceTaskItem::getMaintenanceItemId).filter(Objects::nonNull) |
| | | .collect(Collectors.toList())); |
| | | } |
| | | } |