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.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.time.LocalDateTime; 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 * @date : 2025/12/22 14:57 */ @Service @Slf4j @RequiredArgsConstructor public class MaintenanceTaskServiceImpl extends ServiceImpl implements MaintenanceTaskService { 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) { LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.orderByDesc(MaintenanceTask::getId); Page taskPage = maintenanceTaskMapper.selectPage(page, queryWrapper); // 2. 如果没有数据,直接返回空分页 if (taskPage.getRecords().isEmpty()) { return AjaxResult.success(taskPage); } // 3. 收集所有需要查询的用户ID Set userIds = new HashSet<>(); // 收集登记人ID taskPage.getRecords().forEach(task -> { if (task.getRegistrantId() != null) { userIds.add(task.getRegistrantId()); } }); // 4. 批量查询用户信息 Map userNickNameMap = new HashMap<>(); if (!userIds.isEmpty()) { List users = sysUserMapper.selectUserByIds((new ArrayList<>(userIds))); users.forEach(user -> userNickNameMap.put(user.getUserId(), user.getNickName())); } taskPage.getRecords().forEach(task -> { // 设置登记人昵称 if (task.getRegistrantId() != null) { 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) { List selectedItems = getSelectedItems(maintenanceTask.getMaintenanceItemIds(), null, maintenanceTask.getTaskId(), maintenanceTask.getFrequencyType()); List customItems = normalizeCustomItems(maintenanceTask.getCustomItems()); if (selectedItems == null || selectedItems.size() + customItems.size() == 0) return AjaxResult.error("请选择至少一个有效的保养项目"); // 计算首次执行时间 TimingTask task = new TimingTask(); task.setFrequencyType(maintenanceTask.getFrequencyType()); task.setFrequencyDetail(maintenanceTask.getFrequencyDetail()); LocalDateTime firstExecutionTime = timingTaskService.calculateFirstExecutionTime(task); maintenanceTask.setNextExecutionTime(firstExecutionTime); int insert = maintenanceTaskMapper.insert(maintenanceTask); if (insert > 0) { 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 selectedItems = getSelectedItems(maintenanceTask.getMaintenanceItemIds(), maintenanceTask1.getId(), maintenanceTask.getTaskId(), maintenanceTask.getFrequencyType()); List 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) { maintenanceTaskItemMapper.delete(new LambdaQueryWrapper() .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 ids) { // 先从定时任务调度器中移除所有待删除的任务 ids.forEach(id -> { try { maintenanceTaskScheduler.unscheduleMaintenanceTask(id); } catch (Exception e) { log.error("删除定时任务调度失败, id: {}", id, e); } }); // 再从数据库中删除记录 int delete = maintenanceTaskMapper.deleteBatchIds(ids); if (delete > 0) { maintenanceTaskItemMapper.delete(new LambdaQueryWrapper() .in(MaintenanceTaskItem::getMaintenanceTaskId, ids)); } if (delete > 0) { return AjaxResult.success("删除成功"); } return AjaxResult.error("删除失败"); } private List normalizeCustomItems(List 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 getSelectedItems(List 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 items = maintenanceItemMapper.selectList(new LambdaQueryWrapper() .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 itemMap = new HashMap<>(); items.forEach(item -> itemMap.put(item.getId(), item)); Set existingIds = taskId == null ? Collections.emptySet() : maintenanceTaskItemMapper.selectList( new LambdaQueryWrapper() .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 sorted = new ArrayList<>(); ids.forEach(id -> sorted.add(itemMap.get(id))); return sorted; } private void saveTaskItems(MaintenanceTask task, List selectedItems, List 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() .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 items = maintenanceTaskItemMapper.selectList(new LambdaQueryWrapper() .eq(MaintenanceTaskItem::getMaintenanceTaskId, task.getId()) .orderByAsc(MaintenanceTaskItem::getSortNum)); task.setMaintenanceItems(items); task.setMaintenanceItemIds(items.stream().map(MaintenanceTaskItem::getMaintenanceItemId).filter(Objects::nonNull) .collect(Collectors.toList())); } }