feat(ops): 工单创建发布事件(事件驱动调度) & 工单完成自动下一个任务
This commit is contained in:
@@ -8,6 +8,7 @@ import com.viewsh.module.ops.dal.mysql.workorder.OpsOrderMapper;
|
||||
import com.viewsh.module.ops.enums.OperatorTypeEnum;
|
||||
import com.viewsh.module.ops.enums.WorkOrderStatusEnum;
|
||||
import com.viewsh.module.ops.environment.integration.dto.CleanOrderCompleteEventDTO;
|
||||
import com.viewsh.module.ops.environment.service.cleanorder.CleanOrderService;
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.rocketmq.spring.annotation.ConsumeMode;
|
||||
@@ -68,6 +69,9 @@ public class CleanOrderCompleteEventHandler implements RocketMQListener<String>
|
||||
@Resource
|
||||
private OrderLifecycleManager orderLifecycleManager;
|
||||
|
||||
@Resource
|
||||
private CleanOrderService cleanOrderService;
|
||||
|
||||
@Override
|
||||
public void onMessage(String message) {
|
||||
try {
|
||||
@@ -142,8 +146,13 @@ public class CleanOrderCompleteEventHandler implements RocketMQListener<String>
|
||||
// 6. 清除 Redis 缓存(设备当前工单)
|
||||
clearDeviceCurrentOrder(event.getDeviceId());
|
||||
|
||||
log.info("[CleanOrderCompleteEventHandler] 工单完成成功: eventId={}, orderId={}, duration={}ms",
|
||||
event.getEventId(), event.getOrderId(),
|
||||
// 7. 自动调度下一个任务(优先恢复被中断的任务)
|
||||
if (order.getAssigneeId() != null) {
|
||||
cleanOrderService.autoDispatchNextOrder(event.getOrderId(), order.getAssigneeId());
|
||||
}
|
||||
|
||||
log.info("[CleanOrderCompleteEventHandler] 工单完成成功: eventId={}, orderId={}, assigneeId={}, duration={}ms",
|
||||
event.getEventId(), event.getOrderId(), order.getAssigneeId(),
|
||||
event.getTriggerData() != null ? event.getTriggerData().get("durationMs") : "N/A");
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
package com.viewsh.module.ops.environment.integration.listener;
|
||||
|
||||
import com.viewsh.module.ops.core.dispatch.DispatchEngine;
|
||||
import com.viewsh.module.ops.core.dispatch.model.OrderDispatchContext;
|
||||
import com.viewsh.module.ops.core.event.OrderCreatedEvent;
|
||||
import com.viewsh.module.ops.dal.dataobject.workorder.OpsOrderDO;
|
||||
import com.viewsh.module.ops.dal.mysql.workorder.OpsOrderMapper;
|
||||
import com.viewsh.module.ops.enums.PriorityEnum;
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.context.event.EventListener;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.event.TransactionPhase;
|
||||
import org.springframework.transaction.event.TransactionalEventListener;
|
||||
|
||||
/**
|
||||
* 工单创建事件监听器
|
||||
* <p>
|
||||
* 监听工单创建事件,自动触发调度流程
|
||||
* <p>
|
||||
* 职责:
|
||||
* - 工单创建后自动调用调度引擎进行派单
|
||||
* - 支持 P0 紧急任务的打断逻辑(通过 CleanerPriorityScheduleStrategy)
|
||||
*
|
||||
* @author AI
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class OrderCreatedEventListener {
|
||||
|
||||
@Resource
|
||||
private DispatchEngine dispatchEngine;
|
||||
|
||||
@Resource
|
||||
private OpsOrderMapper opsOrderMapper;
|
||||
|
||||
/**
|
||||
* 监听工单创建事件,触发自动调度
|
||||
* <p>
|
||||
* 使用 @TransactionalEventListener 确保在事务提交后才执行调度
|
||||
* 这样可以避免调度失败导致工单创建回滚
|
||||
*/
|
||||
@org.springframework.transaction.event.TransactionalEventListener(
|
||||
phase = TransactionPhase.AFTER_COMMIT
|
||||
)
|
||||
public void onOrderCreated(OrderCreatedEvent event) {
|
||||
try {
|
||||
log.info("[OrderCreatedEventListener] 收到工单创建事件: orderId={}, orderType={}, priority={}",
|
||||
event.getOrderId(), event.getOrderType(), event.getPriority());
|
||||
|
||||
// 只处理保洁工单
|
||||
if (!"CLEAN".equals(event.getOrderType())) {
|
||||
log.debug("[OrderCreatedEventListener] 跳过非保洁工单: orderType={}", event.getOrderType());
|
||||
return;
|
||||
}
|
||||
|
||||
// 查询工单信息
|
||||
OpsOrderDO order = opsOrderMapper.selectById(event.getOrderId());
|
||||
if (order == null) {
|
||||
log.warn("[OrderCreatedEventListener] 工单不存在,无法调度: orderId={}", event.getOrderId());
|
||||
return;
|
||||
}
|
||||
|
||||
// 构建调度上下文
|
||||
OrderDispatchContext context = OrderDispatchContext.builder()
|
||||
.orderId(order.getId())
|
||||
.orderCode(order.getOrderCode())
|
||||
.orderTitle(order.getTitle())
|
||||
.businessType(order.getOrderType())
|
||||
.areaId(event.getAreaId() != null ? event.getAreaId() : order.getAreaId())
|
||||
.priority(PriorityEnum.fromPriority(event.getPriority()))
|
||||
.build();
|
||||
|
||||
// 使用调度引擎执行调度(包含 P0 打断逻辑)
|
||||
var result = dispatchEngine.dispatch(context);
|
||||
|
||||
if (result.isSuccess()) {
|
||||
log.info("[OrderCreatedEventListener] 自动调度成功: orderId={}, assigneeId={}, path={}",
|
||||
event.getOrderId(), result.getAssigneeId(), result.getPath());
|
||||
} else {
|
||||
log.warn("[OrderCreatedEventListener] 自动调度失败: orderId={}, reason={}",
|
||||
event.getOrderId(), result.getMessage());
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
// 调度失败不应影响工单创建
|
||||
log.error("[OrderCreatedEventListener] 自动调度异常: orderId={}", event.getOrderId(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,8 @@ import com.viewsh.module.ops.api.queue.OrderQueueService;
|
||||
import com.viewsh.module.ops.core.dispatch.DispatchEngine;
|
||||
import com.viewsh.module.ops.core.dispatch.model.DispatchResult;
|
||||
import com.viewsh.module.ops.core.dispatch.model.OrderDispatchContext;
|
||||
import com.viewsh.module.ops.core.event.OrderCreatedEvent;
|
||||
import com.viewsh.module.ops.core.event.OrderEventPublisher;
|
||||
import com.viewsh.module.ops.core.lifecycle.OrderLifecycleManager;
|
||||
import com.viewsh.module.ops.core.lifecycle.model.OrderTransitionRequest;
|
||||
import com.viewsh.module.ops.dal.dataobject.workorder.OpsOrderDO;
|
||||
@@ -64,11 +66,11 @@ public class CleanOrderServiceImpl implements CleanOrderService {
|
||||
@Resource
|
||||
private OrderQueueService orderQueueService;
|
||||
|
||||
@Resource
|
||||
private CleanerAreaAssignStrategy cleanerAreaAssignStrategy;
|
||||
|
||||
@Resource
|
||||
private CleanerStatusService cleanerStatusService;
|
||||
// @Resource
|
||||
// private CleanerAreaAssignStrategy cleanerAreaAssignStrategy;
|
||||
//
|
||||
// @Resource
|
||||
// private CleanerStatusService cleanerStatusService;
|
||||
|
||||
@Resource
|
||||
private DispatchEngine dispatchEngine;
|
||||
@@ -79,6 +81,9 @@ public class CleanOrderServiceImpl implements CleanOrderService {
|
||||
@Resource
|
||||
private CleanOrderEventHandler cleanOrderEventHandler;
|
||||
|
||||
@Resource
|
||||
private OrderEventPublisher orderEventPublisher;
|
||||
|
||||
// ==================== 工单创建 ====================
|
||||
|
||||
@Override
|
||||
@@ -100,8 +105,17 @@ public class CleanOrderServiceImpl implements CleanOrderService {
|
||||
log.info("创建自动保洁工单成功: orderId={}, expectedDuration={}分钟",
|
||||
orderId, createReq.getExpectedDuration());
|
||||
|
||||
// 3. 调度引擎分配
|
||||
autoAssignOrder(orderId, createReq.getAreaId(), PriorityEnum.fromPriority(createReq.getPriority()));
|
||||
// 3. 发布工单创建事件,由 OrderCreatedEventListener 触发调度
|
||||
OrderCreatedEvent event = OrderCreatedEvent.builder()
|
||||
.orderId(orderId)
|
||||
.orderType("CLEAN")
|
||||
.areaId(createReq.getAreaId())
|
||||
.priority(PriorityEnum.fromPriority(createReq.getPriority()).getPriority())
|
||||
.createTime(java.time.LocalDateTime.now())
|
||||
.build()
|
||||
.addPayload("isAuto", true)
|
||||
.addPayload("expectedDuration", createReq.getExpectedDuration());
|
||||
orderEventPublisher.publishOrderCreated(event);
|
||||
|
||||
return orderId;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user