diff --git a/viewsh-module-ops/viewsh-module-ops-biz/src/main/java/com/viewsh/module/ops/core/lifecycle/OrderLifecycleManager.java b/viewsh-module-ops/viewsh-module-ops-biz/src/main/java/com/viewsh/module/ops/core/lifecycle/OrderLifecycleManager.java index cbce021..14049b5 100644 --- a/viewsh-module-ops/viewsh-module-ops-biz/src/main/java/com/viewsh/module/ops/core/lifecycle/OrderLifecycleManager.java +++ b/viewsh-module-ops/viewsh-module-ops-biz/src/main/java/com/viewsh/module/ops/core/lifecycle/OrderLifecycleManager.java @@ -166,6 +166,25 @@ public interface OrderLifecycleManager { */ void cancelOrder(Long orderId, Long operatorId, OperatorTypeEnum operatorType, String reason); + /** + * 强制完成工单(跳过状态规则校验,走完整责任链) + *

+ * 适用于系统自动结单等场景:告警自动解除时工单可能处于任何非终态 + * (QUEUED / DISPATCHED / CONFIRMED / ARRIVED / PAUSED), + * 需要直接跳转到 COMPLETED,同时确保队列清理和事件发布。 + *

+ * 与直接调用 {@code OrderStateMachine.forceTransition()} 的区别: + * 本方法走完整责任链(状态转换 → 队列同步 → 事件发布), + * 避免队列脏数据和 Redis 状态不一致。 + * + * @param orderId 工单ID + * @param operatorId 操作人ID + * @param operatorType 操作人类型 + * @param remark 完成备注 + * @return 转换结果 + */ + OrderTransitionResult forceComplete(Long orderId, Long operatorId, OperatorTypeEnum operatorType, String remark); + // ==================== 查询方法 ==================== /** diff --git a/viewsh-module-ops/viewsh-module-ops-biz/src/main/java/com/viewsh/module/ops/core/lifecycle/OrderLifecycleManagerImpl.java b/viewsh-module-ops/viewsh-module-ops-biz/src/main/java/com/viewsh/module/ops/core/lifecycle/OrderLifecycleManagerImpl.java index e91d099..d593d05 100644 --- a/viewsh-module-ops/viewsh-module-ops-biz/src/main/java/com/viewsh/module/ops/core/lifecycle/OrderLifecycleManagerImpl.java +++ b/viewsh-module-ops/viewsh-module-ops-biz/src/main/java/com/viewsh/module/ops/core/lifecycle/OrderLifecycleManagerImpl.java @@ -346,6 +346,32 @@ public class OrderLifecycleManagerImpl implements OrderLifecycleManager { .build()); } + @Override + @Transactional(rollbackFor = Exception.class) + public OrderTransitionResult forceComplete(Long orderId, Long operatorId, + OperatorTypeEnum operatorType, String remark) { + log.info("强制完成工单: orderId={}, operatorId={}, operatorType={}, remark={}", + orderId, operatorId, operatorType, remark); + + OpsOrderDO order = opsOrderMapper.selectById(orderId); + if (order == null) { + log.warn("强制完成工单失败,工单不存在: orderId={}", orderId); + return OrderTransitionResult.fail(orderId, "工单不存在"); + } + + OrderTransitionRequest request = OrderTransitionRequest.builder() + .orderId(orderId) + .targetStatus(WorkOrderStatusEnum.COMPLETED) + .operatorType(operatorType != null ? operatorType : OperatorTypeEnum.SYSTEM) + .operatorId(operatorId) + .reason(remark) + .assigneeId(order.getAssigneeId()) + .forced(true) + .build(); + + return transition(request); + } + // ==================== 查询方法 ==================== @Override diff --git a/viewsh-module-ops/viewsh-module-ops-biz/src/main/java/com/viewsh/module/ops/core/lifecycle/handler/StateTransitionHandler.java b/viewsh-module-ops/viewsh-module-ops-biz/src/main/java/com/viewsh/module/ops/core/lifecycle/handler/StateTransitionHandler.java index b4bdaab..be75a49 100644 --- a/viewsh-module-ops/viewsh-module-ops-biz/src/main/java/com/viewsh/module/ops/core/lifecycle/handler/StateTransitionHandler.java +++ b/viewsh-module-ops/viewsh-module-ops-biz/src/main/java/com/viewsh/module/ops/core/lifecycle/handler/StateTransitionHandler.java @@ -38,13 +38,19 @@ public class StateTransitionHandler extends TransitionHandler { // 通过状态机执行状态转换 try { - orderStateMachine.transition( - order, - targetStatus, - request.getOperatorType() != null ? request.getOperatorType() : OperatorTypeEnum.SYSTEM, - request.getOperatorId(), - request.getReason() - ); + OperatorTypeEnum operatorType = request.getOperatorType() != null + ? request.getOperatorType() : OperatorTypeEnum.SYSTEM; + + if (Boolean.TRUE.equals(request.getForced())) { + // 强制转换:跳过状态规则校验(用于系统自动结单等场景) + orderStateMachine.forceTransition( + order, targetStatus, operatorType, + request.getOperatorId(), request.getReason()); + } else { + orderStateMachine.transition( + order, targetStatus, operatorType, + request.getOperatorId(), request.getReason()); + } // 更新上下文中的状态 context.setNewStatus(targetStatus); diff --git a/viewsh-module-ops/viewsh-module-ops-biz/src/main/java/com/viewsh/module/ops/core/lifecycle/model/OrderTransitionRequest.java b/viewsh-module-ops/viewsh-module-ops-biz/src/main/java/com/viewsh/module/ops/core/lifecycle/model/OrderTransitionRequest.java index 688d590..d578d4f 100644 --- a/viewsh-module-ops/viewsh-module-ops-biz/src/main/java/com/viewsh/module/ops/core/lifecycle/model/OrderTransitionRequest.java +++ b/viewsh-module-ops/viewsh-module-ops-biz/src/main/java/com/viewsh/module/ops/core/lifecycle/model/OrderTransitionRequest.java @@ -91,6 +91,14 @@ public class OrderTransitionRequest { */ private PriorityEnum priority; + /** + * 是否强制转换(跳过状态规则校验) + *

+ * 适用于系统自动结单等场景:告警自动解除时工单可能处于任何非终态, + * 需要直接跳转到 COMPLETED / CANCELLED,不经过中间状态。 + */ + private Boolean forced; + /** * 扩展信息(可选) *