diff --git a/viewsh-module-ops/viewsh-module-environment-biz/src/main/java/com/viewsh/module/ops/environment/service/manual/CleanOrderBusinessStrategy.java b/viewsh-module-ops/viewsh-module-environment-biz/src/main/java/com/viewsh/module/ops/environment/service/manual/CleanOrderBusinessStrategy.java index f90e2ee..74e5aa3 100644 --- a/viewsh-module-ops/viewsh-module-environment-biz/src/main/java/com/viewsh/module/ops/environment/service/manual/CleanOrderBusinessStrategy.java +++ b/viewsh-module-ops/viewsh-module-environment-biz/src/main/java/com/viewsh/module/ops/environment/service/manual/CleanOrderBusinessStrategy.java @@ -36,6 +36,12 @@ public class CleanOrderBusinessStrategy implements OrderBusinessStrategy { return WorkOrderTypeEnum.CLEAN.getType().equals(businessType); } + @Override + public boolean isAssigneeIdle(DispatchOrderCommand cmd, OpsOrderDO order) { + BadgeDeviceStatusDTO badge = badgeDeviceStatusService.getBadgeStatus(cmd.getAssigneeId()); + return badge != null && !badge.isBusy(); + } + @Override public void validateDispatch(DispatchOrderCommand cmd, OpsOrderDO order) { if (cmd.getAssigneeId() == null) { diff --git a/viewsh-module-ops/viewsh-module-ops-biz/src/main/java/com/viewsh/module/ops/core/manual/ManualOrderActionFacade.java b/viewsh-module-ops/viewsh-module-ops-biz/src/main/java/com/viewsh/module/ops/core/manual/ManualOrderActionFacade.java index 8b71bd6..c02168c 100644 --- a/viewsh-module-ops/viewsh-module-ops-biz/src/main/java/com/viewsh/module/ops/core/manual/ManualOrderActionFacade.java +++ b/viewsh-module-ops/viewsh-module-ops-biz/src/main/java/com/viewsh/module/ops/core/manual/ManualOrderActionFacade.java @@ -68,10 +68,14 @@ public class ManualOrderActionFacade { OrderBusinessStrategy strategy = resolveStrategy(cmd.getBusinessType()); strategy.validateDispatch(cmd, order); - // 3. 状态变更 + // 3. 判断执行人是否空闲,决定目标状态 + boolean idle = strategy.isAssigneeIdle(cmd, order); + WorkOrderStatusEnum targetStatus = idle ? WorkOrderStatusEnum.DISPATCHED : WorkOrderStatusEnum.QUEUED; + + // 4. 状态变更 OrderTransitionRequest request = OrderTransitionRequest.builder() .orderId(cmd.getOrderId()) - .targetStatus(WorkOrderStatusEnum.DISPATCHED) + .targetStatus(targetStatus) .assigneeId(cmd.getAssigneeId()) .assigneeName(cmd.getAssigneeName()) .assigneePhone(cmd.getAssigneePhone()) @@ -85,18 +89,19 @@ public class ManualOrderActionFacade { throw new IllegalStateException("手动派单失败: " + result.getMessage()); } - // 4. 更新主表执行人(只更新 assignee 字段,避免覆盖状态机已写入的 status) + // 5. 更新主表执行人(只更新 assignee 字段,避免覆盖状态机已写入的 status) OpsOrderDO assigneeUpdate = new OpsOrderDO(); assigneeUpdate.setId(cmd.getOrderId()); assigneeUpdate.setAssigneeId(cmd.getAssigneeId()); assigneeUpdate.setAssigneeName(cmd.getAssigneeName()); opsOrderMapper.updateById(assigneeUpdate); - // 5. 条线后置 + // 6. 条线后置 // 注:业务日志由生命周期事件 → 条线 EventListener 统一记录,此处不重复写 strategy.afterDispatch(cmd, order); - log.info("[ManualOrderActionFacade] 手动派单完成: orderId={}, assigneeId={}", cmd.getOrderId(), cmd.getAssigneeId()); + log.info("[ManualOrderActionFacade] 手动派单完成: orderId={}, assigneeId={}, targetStatus={}", + cmd.getOrderId(), cmd.getAssigneeId(), targetStatus); } // ==================== 手动升级优先级 ==================== diff --git a/viewsh-module-ops/viewsh-module-ops-biz/src/main/java/com/viewsh/module/ops/core/manual/strategy/OrderBusinessStrategy.java b/viewsh-module-ops/viewsh-module-ops-biz/src/main/java/com/viewsh/module/ops/core/manual/strategy/OrderBusinessStrategy.java index 4b6b603..5a27ddd 100644 --- a/viewsh-module-ops/viewsh-module-ops-biz/src/main/java/com/viewsh/module/ops/core/manual/strategy/OrderBusinessStrategy.java +++ b/viewsh-module-ops/viewsh-module-ops-biz/src/main/java/com/viewsh/module/ops/core/manual/strategy/OrderBusinessStrategy.java @@ -20,6 +20,20 @@ public interface OrderBusinessStrategy { */ boolean supports(String businessType); + // ==================== 派单决策 ==================== + + /** + * 判断执行人是否空闲,决定手动派单的目标状态。 + *
+ * 空闲返回 true → DISPATCHED(直接派发); + * 忙碌返回 false → QUEUED(入队等待)。 + *
+ * 默认返回 true(直接派发),条线按需覆写。 + */ + default boolean isAssigneeIdle(DispatchOrderCommand cmd, OpsOrderDO order) { + return true; + } + // ==================== 前置校验 ==================== default void validateDispatch(DispatchOrderCommand cmd, OpsOrderDO order) {} diff --git a/viewsh-module-ops/viewsh-module-security-biz/src/main/java/com/viewsh/module/ops/security/service/manual/SecurityOrderBusinessStrategy.java b/viewsh-module-ops/viewsh-module-security-biz/src/main/java/com/viewsh/module/ops/security/service/manual/SecurityOrderBusinessStrategy.java index 68c7dd5..fdb2375 100644 --- a/viewsh-module-ops/viewsh-module-security-biz/src/main/java/com/viewsh/module/ops/security/service/manual/SecurityOrderBusinessStrategy.java +++ b/viewsh-module-ops/viewsh-module-security-biz/src/main/java/com/viewsh/module/ops/security/service/manual/SecurityOrderBusinessStrategy.java @@ -8,13 +8,11 @@ import com.viewsh.module.ops.enums.WorkOrderStatusEnum; import com.viewsh.module.ops.enums.WorkOrderTypeEnum; import com.viewsh.module.ops.security.dal.dataobject.area.OpsAreaSecurityUserDO; import com.viewsh.module.ops.security.dal.mysql.area.OpsAreaSecurityUserMapper; +import com.viewsh.module.ops.service.dispatch.UserDispatchStatusService; import jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; -import static com.viewsh.framework.common.exception.util.ServiceExceptionUtil.exception; -import static com.viewsh.module.ops.enums.ErrorCodeConstants.SECURITY_ASSIGNEE_NOT_BOUND_TO_AREA; - /** * 安保条线策略 *
@@ -32,11 +30,19 @@ public class SecurityOrderBusinessStrategy implements OrderBusinessStrategy { @Resource private OrderQueueService orderQueueService; + @Resource + private UserDispatchStatusService userDispatchStatusService; + @Override public boolean supports(String businessType) { return WorkOrderTypeEnum.SECURITY.getType().equals(businessType); } + @Override + public boolean isAssigneeIdle(DispatchOrderCommand cmd, OpsOrderDO order) { + return userDispatchStatusService.isIdle(cmd.getAssigneeId()); + } + @Override public void validateDispatch(DispatchOrderCommand cmd, OpsOrderDO order) { // 尝试从区域绑定记录回填姓名(不做区域限制,允许跨区域派单)