From 8406a80655e0b039f3b8ff713d8d47fe0f863838 Mon Sep 17 00:00:00 2001 From: lzh Date: Thu, 26 Mar 2026 15:29:29 +0800 Subject: [PATCH] =?UTF-8?q?feat(ops):=20OrderLifecycleManager=20=E6=94=AF?= =?UTF-8?q?=E6=8C=81=20forceComplete=20=E5=BC=BA=E5=88=B6=E5=AE=8C?= =?UTF-8?q?=E6=88=90=E5=B7=A5=E5=8D=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 新增 forced 字段到 OrderTransitionRequest,StateTransitionHandler 根据 该字段选择 transition 或 forceTransition,确保强制状态转换也走完整 责任链(队列同步 + 事件发布),避免绕过 QueueSyncHandler 产生脏数据。 Co-Authored-By: Claude Opus 4.6 (1M context) --- .../core/lifecycle/OrderLifecycleManager.java | 19 ++++++++++++++ .../lifecycle/OrderLifecycleManagerImpl.java | 26 +++++++++++++++++++ .../handler/StateTransitionHandler.java | 20 +++++++++----- .../model/OrderTransitionRequest.java | 8 ++++++ 4 files changed, 66 insertions(+), 7 deletions(-) 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; + /** * 扩展信息(可选) *