From 60cb1ba8f34fa25a367864671014ae7df74de636 Mon Sep 17 00:00:00 2001 From: chiguyong Date: Tue, 24 Mar 2026 00:11:57 +0800 Subject: [PATCH] feat: add maintenance plan and task services --- .../mdm/service/MaintenancePlanService.java | 14 ++ .../mdm/service/MaintenanceTaskService.java | 21 ++ .../impl/MaintenancePlanServiceImpl.java | 130 ++++++++++++ .../impl/MaintenanceTaskServiceImpl.java | 200 ++++++++++++++++++ 4 files changed, 365 insertions(+) create mode 100644 module-mdm/src/main/java/com/ether/pms/mdm/service/MaintenancePlanService.java create mode 100644 module-mdm/src/main/java/com/ether/pms/mdm/service/MaintenanceTaskService.java create mode 100644 module-mdm/src/main/java/com/ether/pms/mdm/service/impl/MaintenancePlanServiceImpl.java create mode 100644 module-mdm/src/main/java/com/ether/pms/mdm/service/impl/MaintenanceTaskServiceImpl.java diff --git a/module-mdm/src/main/java/com/ether/pms/mdm/service/MaintenancePlanService.java b/module-mdm/src/main/java/com/ether/pms/mdm/service/MaintenancePlanService.java new file mode 100644 index 0000000..f5d4126 --- /dev/null +++ b/module-mdm/src/main/java/com/ether/pms/mdm/service/MaintenancePlanService.java @@ -0,0 +1,14 @@ +package com.ether.pms.mdm.service; + +import com.ether.pms.mdm.entity.MaintenancePlan; +import java.util.List; +import java.util.UUID; + +public interface MaintenancePlanService { + MaintenancePlan createPlan(MaintenancePlan plan); + MaintenancePlan updatePlan(UUID id, MaintenancePlan plan); + void deactivatePlan(UUID id); + MaintenancePlan getPlanById(UUID id); + List getActivePlansByProject(UUID projectId); + List getPlansByTriggerType(MaintenancePlan.TriggerType triggerType); +} \ No newline at end of file diff --git a/module-mdm/src/main/java/com/ether/pms/mdm/service/MaintenanceTaskService.java b/module-mdm/src/main/java/com/ether/pms/mdm/service/MaintenanceTaskService.java new file mode 100644 index 0000000..138122d --- /dev/null +++ b/module-mdm/src/main/java/com/ether/pms/mdm/service/MaintenanceTaskService.java @@ -0,0 +1,21 @@ +package com.ether.pms.mdm.service; + +import com.ether.pms.mdm.entity.MaintenancePlan; +import com.ether.pms.mdm.entity.MaintenanceTask; +import java.math.BigDecimal; +import java.util.List; +import java.util.UUID; + +public interface MaintenanceTaskService { + MaintenanceTask getTaskById(UUID id); + List getTasksByAssignee(UUID assignee); + List getTasksByStatus(UUID projectId, MaintenanceTask.Status status); + List getTasksByEquipment(UUID equipmentId); + List getOverdueTasks(); + MaintenanceTask createTask(MaintenanceTask task); + MaintenanceTask acceptTask(UUID taskId, UUID userId); + MaintenanceTask startTask(UUID taskId); + MaintenanceTask completeTask(UUID taskId, BigDecimal laborHours, BigDecimal materialsCost, String remarks); + void cancelTask(UUID taskId); + List generateTasksFromPlan(MaintenancePlan plan); +} \ No newline at end of file diff --git a/module-mdm/src/main/java/com/ether/pms/mdm/service/impl/MaintenancePlanServiceImpl.java b/module-mdm/src/main/java/com/ether/pms/mdm/service/impl/MaintenancePlanServiceImpl.java new file mode 100644 index 0000000..cb59de2 --- /dev/null +++ b/module-mdm/src/main/java/com/ether/pms/mdm/service/impl/MaintenancePlanServiceImpl.java @@ -0,0 +1,130 @@ +package com.ether.pms.mdm.service.impl; + +import com.ether.pms.common.BusinessException; +import com.ether.pms.common.ErrorCode; +import com.ether.pms.mdm.entity.MaintenancePlan; +import com.ether.pms.mdm.repository.MaintenancePlanRepository; +import com.ether.pms.mdm.service.MaintenancePlanService; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.List; +import java.util.UUID; + +@Service +@RequiredArgsConstructor +public class MaintenancePlanServiceImpl implements MaintenancePlanService { + + private final MaintenancePlanRepository maintenancePlanRepository; + private static final DateTimeFormatter CODE_FORMATTER = DateTimeFormatter.ofPattern("yyyyMMddHHmmss"); + + @Override + @Transactional + public MaintenancePlan createPlan(MaintenancePlan plan) { + // 生成计划编码 MP + 时间戳 + String planCode = generatePlanCode(); + plan.setPlanCode(planCode); + + // 设置默认状态为ACTIVE + if (plan.getStatus() == null) { + plan.setStatus(MaintenancePlan.Status.ACTIVE); + } + + return maintenancePlanRepository.save(plan); + } + + @Override + @Transactional + public MaintenancePlan updatePlan(UUID id, MaintenancePlan plan) { + MaintenancePlan existing = getPlanById(id); + + // 状态转换校验:只有ACTIVE状态才能更新 + if (existing.getStatus() != MaintenancePlan.Status.ACTIVE) { + throw new BusinessException(6001, "只有ACTIVE状态的计划才能更新"); + } + + // 更新字段 + if (plan.getPlanName() != null) { + existing.setPlanName(plan.getPlanName()); + } + if (plan.getEquipmentType() != null) { + existing.setEquipmentType(plan.getEquipmentType()); + } + if (plan.getTriggerType() != null) { + existing.setTriggerType(plan.getTriggerType()); + } + if (plan.getTriggerValue() != null) { + existing.setTriggerValue(plan.getTriggerValue()); + } + if (plan.getTriggerUnit() != null) { + existing.setTriggerUnit(plan.getTriggerUnit()); + } + if (plan.getMaintenanceItems() != null) { + existing.setMaintenanceItems(plan.getMaintenanceItems()); + } + if (plan.getEstimatedDuration() != null) { + existing.setEstimatedDuration(plan.getEstimatedDuration()); + } + if (plan.getAssignedTo() != null) { + existing.setAssignedTo(plan.getAssignedTo()); + } + if (plan.getSlaResponseHours() != null) { + existing.setSlaResponseHours(plan.getSlaResponseHours()); + } + if (plan.getSlaCompleteHours() != null) { + existing.setSlaCompleteHours(plan.getSlaCompleteHours()); + } + + return maintenancePlanRepository.save(existing); + } + + @Override + @Transactional + public void deactivatePlan(UUID id) { + MaintenancePlan plan = getPlanById(id); + + // 状态转换校验:只有ACTIVE状态才能停用 + if (plan.getStatus() != MaintenancePlan.Status.ACTIVE) { + throw new BusinessException(6002, "只有ACTIVE状态的计划才能停用"); + } + + plan.setStatus(MaintenancePlan.Status.INACTIVE); + maintenancePlanRepository.save(plan); + } + + @Override + public MaintenancePlan getPlanById(UUID id) { + return maintenancePlanRepository.findById(id) + .orElseThrow(() -> new BusinessException(ErrorCode.NOT_FOUND, "维保计划不存在")); + } + + @Override + public List getActivePlansByProject(UUID projectId) { + return maintenancePlanRepository.findByProjectIdAndStatus(projectId, MaintenancePlan.Status.ACTIVE); + } + + @Override + public List getPlansByTriggerType(MaintenancePlan.TriggerType triggerType) { + return maintenancePlanRepository.findByTriggerType(triggerType); + } + + /** + * 生成计划编码:MP + yyyyMMddHHmmss + */ + private String generatePlanCode() { + String timestamp = LocalDateTime.now().format(CODE_FORMATTER); + String planCode = "MP" + timestamp; + + // 确保编码唯一 + int suffix = 1; + while (maintenancePlanRepository.existsByPlanCode(planCode)) { + planCode = "MP" + timestamp + "_" + suffix; + suffix++; + } + + return planCode; + } +} \ No newline at end of file diff --git a/module-mdm/src/main/java/com/ether/pms/mdm/service/impl/MaintenanceTaskServiceImpl.java b/module-mdm/src/main/java/com/ether/pms/mdm/service/impl/MaintenanceTaskServiceImpl.java new file mode 100644 index 0000000..2676fd1 --- /dev/null +++ b/module-mdm/src/main/java/com/ether/pms/mdm/service/impl/MaintenanceTaskServiceImpl.java @@ -0,0 +1,200 @@ +package com.ether.pms.mdm.service.impl; + +import com.ether.pms.common.BusinessException; +import com.ether.pms.mdm.entity.MaintenancePlan; +import com.ether.pms.mdm.entity.MaintenanceTask; +import com.ether.pms.mdm.repository.MaintenanceTaskRepository; +import com.ether.pms.mdm.service.MaintenanceTaskService; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.math.BigDecimal; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.UUID; + +@Service +@RequiredArgsConstructor +public class MaintenanceTaskServiceImpl implements MaintenanceTaskService { + + private final MaintenanceTaskRepository maintenanceTaskRepository; + private static final DateTimeFormatter CODE_FORMATTER = DateTimeFormatter.ofPattern("yyyyMMddHHmmss"); + + @Override + public MaintenanceTask getTaskById(UUID id) { + return maintenanceTaskRepository.findById(id) + .orElseThrow(() -> new BusinessException(6003, "维保任务不存在")); + } + + @Override + public List getTasksByAssignee(UUID assignee) { + return maintenanceTaskRepository.findByAssignedToAndStatus(assignee, MaintenanceTask.Status.PENDING); + } + + @Override + public List getTasksByStatus(UUID projectId, MaintenanceTask.Status status) { + return maintenanceTaskRepository.findByProjectIdAndStatus(projectId, status); + } + + @Override + public List getTasksByEquipment(UUID equipmentId) { + return maintenanceTaskRepository.findByEquipmentIdAndStatusNot(equipmentId, MaintenanceTask.Status.CANCELLED); + } + + @Override + public List getOverdueTasks() { + return maintenanceTaskRepository.findOverdueTasks(LocalDateTime.now()); + } + + @Override + @Transactional + public MaintenanceTask createTask(MaintenanceTask task) { + // 生成任务编码 MT + 时间戳 + String taskCode = generateTaskCode(); + task.setTaskCode(taskCode); + + // 设置默认状态为PENDING + if (task.getStatus() == null) { + task.setStatus(MaintenanceTask.Status.PENDING); + } + + // 设置默认任务类型为预防性维护 + if (task.getTaskType() == null) { + task.setTaskType(MaintenanceTask.TaskType.PREVENTIVE); + } + + return maintenanceTaskRepository.save(task); + } + + @Override + @Transactional + public MaintenanceTask acceptTask(UUID taskId, UUID userId) { + MaintenanceTask task = getTaskById(taskId); + + // 状态校验:只有PENDING状态才能接受 + if (task.getStatus() != MaintenanceTask.Status.PENDING) { + throw new BusinessException(6004, "只有PENDING状态的任务才能接受"); + } + + task.setStatus(MaintenanceTask.Status.ACCEPTED); + task.setAssignedTo(userId); + + return maintenanceTaskRepository.save(task); + } + + @Override + @Transactional + public MaintenanceTask startTask(UUID taskId) { + MaintenanceTask task = getTaskById(taskId); + + // 状态校验:只有ACCEPTED状态才能开始执行 + if (task.getStatus() != MaintenanceTask.Status.ACCEPTED) { + throw new BusinessException(6005, "只有ACCEPTED状态的任务才能开始执行"); + } + + task.setStatus(MaintenanceTask.Status.IN_PROGRESS); + task.setActualStartDate(LocalDateTime.now()); + + return maintenanceTaskRepository.save(task); + } + + @Override + @Transactional + public MaintenanceTask completeTask(UUID taskId, BigDecimal laborHours, BigDecimal materialsCost, String remarks) { + MaintenanceTask task = getTaskById(taskId); + + // 状态校验:只有IN_PROGRESS状态才能完成 + if (task.getStatus() != MaintenanceTask.Status.IN_PROGRESS) { + throw new BusinessException(6006, "只有IN_PROGRESS状态的任务才能完成"); + } + + task.setStatus(MaintenanceTask.Status.COMPLETED); + task.setActualEndDate(LocalDateTime.now()); + + if (laborHours != null) { + task.setLaborHours(laborHours); + } + if (materialsCost != null) { + task.setMaterialsCost(materialsCost); + } + if (remarks != null) { + task.setRemarks(remarks); + } + + return maintenanceTaskRepository.save(task); + } + + @Override + @Transactional + public void cancelTask(UUID taskId) { + MaintenanceTask task = getTaskById(taskId); + + // 状态校验:PENDING、ACCEPTED、IN_PROGRESS状态都可以取消 + List cancellableStatuses = Arrays.asList( + MaintenanceTask.Status.PENDING, + MaintenanceTask.Status.ACCEPTED, + MaintenanceTask.Status.IN_PROGRESS + ); + + if (!cancellableStatuses.contains(task.getStatus())) { + throw new BusinessException(6007, "只有PENDING、ACCEPTED或IN_PROGRESS状态的任务才能取消"); + } + + task.setStatus(MaintenanceTask.Status.CANCELLED); + maintenanceTaskRepository.save(task); + } + + @Override + @Transactional + public List generateTasksFromPlan(MaintenancePlan plan) { + List generatedTasks = new ArrayList<>(); + + // 根据触发类型生成相应数量的任务 + int taskCount = 1; // 默认生成1个任务 + if (plan.getTriggerValue() != null && plan.getTriggerValue() > 0) { + taskCount = plan.getTriggerValue(); + } + + for (int i = 0; i < taskCount; i++) { + MaintenanceTask task = new MaintenanceTask(); + task.setProjectId(plan.getProjectId()); + task.setPlanId(plan.getId()); + task.setTriggerType(plan.getTriggerType()); + task.setMaintenanceItems(plan.getMaintenanceItems()); + task.setAssignedTo(plan.getAssignedTo()); + task.setStatus(MaintenanceTask.Status.PENDING); + task.setTaskType(MaintenanceTask.TaskType.PREVENTIVE); + + // 设置计划执行时间(如果有) + if (plan.getEstimatedDuration() != null) { + task.setScheduledDate(LocalDateTime.now().plusDays(i * (long) plan.getEstimatedDuration())); + } + + MaintenanceTask savedTask = createTask(task); + generatedTasks.add(savedTask); + } + + return generatedTasks; + } + + /** + * 生成任务编码:MT + yyyyMMddHHmmss + */ + private String generateTaskCode() { + String timestamp = LocalDateTime.now().format(CODE_FORMATTER); + String taskCode = "MT" + timestamp; + + // 确保编码唯一 + int suffix = 1; + while (maintenanceTaskRepository.existsByTaskCode(taskCode)) { + taskCode = "MT" + timestamp + "_" + suffix; + suffix++; + } + + return taskCode; + } +} \ No newline at end of file