refactor(ops): 简化工单Handler,移除冗余业务逻辑
- CleanOrderCreateEventHandler: 移除直接RPC调用,合并重复日志 - CleanOrderConfirmEventHandler: 移除TTS调用和日志记录 - CleanOrderArriveEventHandler: 移除设备缓存更新和日志记录 - CleanOrderCompleteEventHandler: 移除业务日志和自动调度调用 Handler只负责消息幂等性和状态转换,业务逻辑移至EventListener Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -8,9 +8,6 @@ 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.CleanOrderArriveEventDTO;
|
||||
import com.viewsh.module.ops.infrastructure.log.enumeration.EventDomain;
|
||||
import com.viewsh.module.ops.infrastructure.log.recorder.EventLogRecord;
|
||||
import com.viewsh.module.ops.infrastructure.log.recorder.EventLogRecorder;
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.rocketmq.spring.annotation.ConsumeMode;
|
||||
@@ -28,9 +25,30 @@ import java.util.concurrent.TimeUnit;
|
||||
* <p>
|
||||
* 订阅 IoT 模块发布的保洁工单到岗事件
|
||||
* <p>
|
||||
* RocketMQ 配置:
|
||||
* - Topic: ops-order-arrive
|
||||
* - ConsumerGroup: ops-clean-order-arrive-group
|
||||
* 调用链路:
|
||||
* <pre>
|
||||
* IoT 发布 RocketMQ 消息 (ops-order-arrive)
|
||||
* ↓
|
||||
* CleanOrderArriveEventHandler.onMessage()
|
||||
* - 幂等性检查
|
||||
* - 状态检查
|
||||
* ↓
|
||||
* orderLifecycleManager.transition(ARRIVED) [@Transactional]
|
||||
* - 更新工单状态
|
||||
* - 发布 OrderStateChangedEvent
|
||||
* ↓
|
||||
* 事务提交
|
||||
* ↓
|
||||
* CleanOrderEventListener.handleArrived() [@Async, AFTER_COMMIT]
|
||||
* - 记录到岗时间到扩展表
|
||||
* - 更新设备工单关联信息(areaId, beaconMac)
|
||||
* - 记录业务日志
|
||||
* </pre>
|
||||
* <p>
|
||||
* 设计说明:
|
||||
* - Handler 只负责消息接收和状态转换
|
||||
* - 业务日志、设备缓存更新由 CleanOrderEventListener 在事务提交后处理
|
||||
* - BadgeDeviceStatusServiceImpl 在 BEFORE_COMMIT 阶段跳过 ARRIVED(由 Listener 处理完整信息)
|
||||
*
|
||||
* @author AI
|
||||
*/
|
||||
@@ -54,16 +72,6 @@ public class CleanOrderArriveEventHandler implements RocketMQListener<String> {
|
||||
*/
|
||||
private static final int DEDUP_TTL_SECONDS = 300;
|
||||
|
||||
/**
|
||||
* 设备当前工单缓存 Key 模式
|
||||
*/
|
||||
private static final String ORDER_CACHE_KEY_PATTERN = "ops:clean:device:order:%s";
|
||||
|
||||
/**
|
||||
* 工单缓存 TTL(秒)
|
||||
*/
|
||||
private static final int ORDER_CACHE_TTL_SECONDS = 3600;
|
||||
|
||||
@Resource
|
||||
private ObjectMapper objectMapper;
|
||||
|
||||
@@ -76,9 +84,6 @@ public class CleanOrderArriveEventHandler implements RocketMQListener<String> {
|
||||
@Resource
|
||||
private OrderLifecycleManager orderLifecycleManager;
|
||||
|
||||
@Resource
|
||||
private EventLogRecorder eventLogRecorder;
|
||||
|
||||
@Override
|
||||
public void onMessage(String message) {
|
||||
try {
|
||||
@@ -126,12 +131,7 @@ public class CleanOrderArriveEventHandler implements RocketMQListener<String> {
|
||||
return;
|
||||
}
|
||||
|
||||
// 3. 更新工单的设备信息(扩展字段)
|
||||
order.setAssigneeDeviceId(event.getDeviceId());
|
||||
order.setAssigneeDeviceKey(event.getDeviceKey());
|
||||
opsOrderMapper.updateById(order);
|
||||
|
||||
// 4. 构建状态转换请求
|
||||
// 3. 构建状态转换请求(包含完整信息,供 Listener 使用)
|
||||
Map<String, Object> payload = new HashMap<>();
|
||||
payload.put("deviceId", event.getDeviceId());
|
||||
payload.put("deviceKey", event.getDeviceKey());
|
||||
@@ -148,87 +148,11 @@ public class CleanOrderArriveEventHandler implements RocketMQListener<String> {
|
||||
.reason("蓝牙信标自动到岗确认")
|
||||
.payload(payload)
|
||||
.build();
|
||||
|
||||
// 5. 通过生命周期管理器执行状态转换(DISPATCHED/CONFIRMED -> ARRIVED)
|
||||
// 4. 执行状态转换
|
||||
// 注意:业务日志和设备缓存更新由 CleanOrderEventListener 在 AFTER_COMMIT 阶段处理
|
||||
orderLifecycleManager.transition(request);
|
||||
|
||||
// 6. 记录业务日志
|
||||
recordOrderArrivedLog(event, request);
|
||||
|
||||
// 7. 更新 Redis 缓存(设备当前工单)
|
||||
cacheDeviceCurrentOrder(event);
|
||||
|
||||
log.info("[CleanOrderArriveEventHandler] 工单到岗成功: eventId={}, orderId={}, deviceId={}",
|
||||
event.getEventId(), event.getOrderId(), event.getDeviceId());
|
||||
}
|
||||
|
||||
/**
|
||||
* 缓存设备当前工单
|
||||
* <p>
|
||||
* 供 IoT 模块的规则处理器查询
|
||||
*/
|
||||
private void cacheDeviceCurrentOrder(CleanOrderArriveEventDTO event) {
|
||||
try {
|
||||
String cacheKey = String.format(ORDER_CACHE_KEY_PATTERN, event.getDeviceId());
|
||||
|
||||
// 构建缓存数据
|
||||
StringBuilder cacheData = new StringBuilder();
|
||||
cacheData.append("{");
|
||||
cacheData.append("\"orderId\":").append(event.getOrderId()).append(",");
|
||||
cacheData.append("\"status\":\"").append(WorkOrderStatusEnum.ARRIVED.getStatus()).append("\",");
|
||||
cacheData.append("\"areaId\":").append(event.getAreaId());
|
||||
|
||||
// 如果有信标 MAC,也缓存
|
||||
if (event.getTriggerData() != null && event.getTriggerData().containsKey("beaconMac")) {
|
||||
cacheData.append(",\"beaconMac\":\"").append(event.getTriggerData().get("beaconMac")).append("\"");
|
||||
}
|
||||
|
||||
cacheData.append("}");
|
||||
|
||||
// 写入 Redis
|
||||
stringRedisTemplate.opsForValue().set(
|
||||
cacheKey,
|
||||
cacheData.toString(),
|
||||
ORDER_CACHE_TTL_SECONDS,
|
||||
TimeUnit.SECONDS
|
||||
);
|
||||
|
||||
log.debug("[CleanOrderArriveEventHandler] 设备工单缓存已更新: deviceId={}, orderId={}",
|
||||
event.getDeviceId(), event.getOrderId());
|
||||
} catch (Exception e) {
|
||||
log.error("[CleanOrderArriveEventHandler] 设备工单缓存更新失败: deviceId={}", event.getDeviceId(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 记录工单到岗业务日志
|
||||
*/
|
||||
private void recordOrderArrivedLog(CleanOrderArriveEventDTO event, OrderTransitionRequest request) {
|
||||
try {
|
||||
// 构建扩展信息
|
||||
Map<String, Object> extra = new HashMap<>();
|
||||
extra.put("eventId", event.getEventId());
|
||||
extra.put("triggerSource", event.getTriggerSource());
|
||||
extra.put("areaId", event.getAreaId());
|
||||
if (event.getTriggerData() != null) {
|
||||
extra.putAll(event.getTriggerData());
|
||||
}
|
||||
|
||||
// 记录日志
|
||||
eventLogRecorder.record(EventLogRecord.builder()
|
||||
.module("clean")
|
||||
.domain(EventDomain.BEACON)
|
||||
.eventType("ORDER_ARRIVED")
|
||||
.message(String.format("蓝牙信标自动到岗确认 [设备:%s, 区域:%d]",
|
||||
event.getDeviceKey(), event.getAreaId()))
|
||||
.targetId(event.getOrderId())
|
||||
.targetType("order")
|
||||
.deviceId(event.getDeviceId())
|
||||
.payload(extra)
|
||||
.build());
|
||||
|
||||
} catch (Exception e) {
|
||||
log.warn("[CleanOrderArriveEventHandler] 记录业务日志失败: orderId={}", event.getOrderId(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,10 +8,6 @@ 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 com.viewsh.module.ops.infrastructure.log.enumeration.EventDomain;
|
||||
import com.viewsh.module.ops.infrastructure.log.recorder.EventLogRecord;
|
||||
import com.viewsh.module.ops.infrastructure.log.recorder.EventLogRecorder;
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.rocketmq.spring.annotation.ConsumeMode;
|
||||
@@ -29,9 +25,36 @@ import java.util.concurrent.TimeUnit;
|
||||
* <p>
|
||||
* 订阅 IoT 模块发布的保洁工单完成事件
|
||||
* <p>
|
||||
* RocketMQ 配置:
|
||||
* - Topic: ops-order-complete
|
||||
* - ConsumerGroup: ops-clean-order-complete-group
|
||||
* 调用链路:
|
||||
* <pre>
|
||||
* IoT 发布 RocketMQ 消息 (ops-order-complete)
|
||||
* ↓
|
||||
* CleanOrderCompleteEventHandler.onMessage()
|
||||
* - 幂等性检查
|
||||
* - 状态检查
|
||||
* ↓
|
||||
* orderLifecycleManager.transition(COMPLETED) [@Transactional]
|
||||
* - 更新工单状态
|
||||
* - 发布 OrderStateChangedEvent
|
||||
* ↓
|
||||
* 事务提交
|
||||
* ↓
|
||||
* BadgeDeviceStatusEventListener.onOrderStateChanged() [BEFORE_COMMIT]
|
||||
* - 清除设备工单关联
|
||||
* - 检查等待任务,决定设备状态 (BUSY/IDLE)
|
||||
* ↓
|
||||
* CleanOrderEventListener.handleCompleted() [AFTER_COMMIT]
|
||||
* - 记录完成时间到扩展表
|
||||
* - 记录业务日志
|
||||
* CleanOrderEventListener.onOrderCompleted() [AFTER_COMMIT]
|
||||
* - 自动调度下一个任务
|
||||
* - 发送完成通知
|
||||
* </pre>
|
||||
* <p>
|
||||
* 设计说明:
|
||||
* - Handler 只负责消息接收和状态转换
|
||||
* - 设备状态由 BadgeDeviceStatusEventListener 在 BEFORE_COMMIT 阶段处理
|
||||
* - 业务日志、自动调度由 CleanOrderEventListener 在 AFTER_COMMIT 阶段处理
|
||||
*
|
||||
* @author AI
|
||||
*/
|
||||
@@ -55,11 +78,6 @@ public class CleanOrderCompleteEventHandler implements RocketMQListener<String>
|
||||
*/
|
||||
private static final int DEDUP_TTL_SECONDS = 300;
|
||||
|
||||
/**
|
||||
* 设备当前工单缓存 Key 模式
|
||||
*/
|
||||
private static final String ORDER_CACHE_KEY_PATTERN = "ops:clean:device:order:%s";
|
||||
|
||||
@Resource
|
||||
private ObjectMapper objectMapper;
|
||||
|
||||
@@ -72,11 +90,6 @@ public class CleanOrderCompleteEventHandler implements RocketMQListener<String>
|
||||
@Resource
|
||||
private OrderLifecycleManager orderLifecycleManager;
|
||||
|
||||
@Resource
|
||||
private CleanOrderService cleanOrderService;
|
||||
|
||||
@Resource
|
||||
private EventLogRecorder eventLogRecorder;
|
||||
|
||||
@Override
|
||||
public void onMessage(String message) {
|
||||
@@ -146,23 +159,12 @@ public class CleanOrderCompleteEventHandler implements RocketMQListener<String>
|
||||
.payload(payload)
|
||||
.build();
|
||||
|
||||
// 5. 通过生命周期管理器执行状态转换(ARRIVED -> COMPLETED)
|
||||
orderLifecycleManager.completeOrder(event.getOrderId(), null, remark);
|
||||
// 5. 执行状态转换
|
||||
// 注意:设备状态、业务日志、自动调度由事件监听器处理
|
||||
orderLifecycleManager.transition(request);
|
||||
|
||||
// 6. 记录业务日志
|
||||
recordOrderCompletedLog(event, order, remark);
|
||||
|
||||
// 7. 清除 Redis 缓存(设备当前工单)
|
||||
clearDeviceCurrentOrder(event.getDeviceId());
|
||||
|
||||
// 8. 自动调度下一个任务(优先恢复被中断的任务)
|
||||
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");
|
||||
log.info("[CleanOrderCompleteEventHandler] 工单完成成功: eventId={}, orderId={}",
|
||||
event.getEventId(), event.getOrderId());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -183,62 +185,4 @@ public class CleanOrderCompleteEventHandler implements RocketMQListener<String>
|
||||
return remark.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 清除设备当前工单缓存
|
||||
*/
|
||||
private void clearDeviceCurrentOrder(Long deviceId) {
|
||||
try {
|
||||
String cacheKey = String.format(ORDER_CACHE_KEY_PATTERN, deviceId);
|
||||
stringRedisTemplate.delete(cacheKey);
|
||||
|
||||
log.debug("[CleanOrderCompleteEventHandler] 设备工单缓存已清除: deviceId={}", deviceId);
|
||||
} catch (Exception e) {
|
||||
log.error("[CleanOrderCompleteEventHandler] 设备工单缓存清除失败: deviceId={}", deviceId, e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 记录工单完成业务日志
|
||||
*/
|
||||
private void recordOrderCompletedLog(CleanOrderCompleteEventDTO event, OpsOrderDO order, String remark) {
|
||||
try {
|
||||
// 构建扩展信息
|
||||
Map<String, Object> extra = new HashMap<>();
|
||||
extra.put("eventId", event.getEventId());
|
||||
extra.put("triggerSource", event.getTriggerSource());
|
||||
extra.put("areaId", event.getAreaId());
|
||||
extra.put("completionReason", event.getTriggerData() != null ?
|
||||
event.getTriggerData().get("completionReason") : "SIGNAL_LOSS_TIMEOUT");
|
||||
if (event.getTriggerData() != null) {
|
||||
extra.putAll(event.getTriggerData());
|
||||
}
|
||||
|
||||
// 计算作业时长(分钟)
|
||||
String durationInfo = "";
|
||||
if (event.getTriggerData() != null && event.getTriggerData().containsKey("durationMs")) {
|
||||
Object durationMs = event.getTriggerData().get("durationMs");
|
||||
if (durationMs != null) {
|
||||
long durationMinutes = ((Number) durationMs).longValue() / 60000;
|
||||
durationInfo = String.format(",作业时长: %d分钟", durationMinutes);
|
||||
extra.put("durationMinutes", durationMinutes);
|
||||
}
|
||||
}
|
||||
|
||||
// 记录日志
|
||||
eventLogRecorder.record(EventLogRecord.builder()
|
||||
.module("clean")
|
||||
.domain(EventDomain.BEACON)
|
||||
.eventType("ORDER_COMPLETED")
|
||||
.message("信号丢失超时自动完成 [设备:" + event.getDeviceKey() + durationInfo + "]")
|
||||
.targetId(event.getOrderId())
|
||||
.targetType("order")
|
||||
.deviceId(event.getDeviceId())
|
||||
.personId(order.getAssigneeId())
|
||||
.payload(extra)
|
||||
.build());
|
||||
|
||||
} catch (Exception e) {
|
||||
log.warn("[CleanOrderCompleteEventHandler] 记录业务日志失败: orderId={}", event.getOrderId(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,15 +2,12 @@ package com.viewsh.module.ops.environment.integration.consumer;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.viewsh.module.ops.core.lifecycle.OrderLifecycleManager;
|
||||
import com.viewsh.module.ops.environment.service.voice.VoiceBroadcastService;
|
||||
import com.viewsh.module.ops.core.lifecycle.model.OrderTransitionRequest;
|
||||
import com.viewsh.module.ops.dal.dataobject.workorder.OpsOrderDO;
|
||||
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.CleanOrderConfirmEventDTO;
|
||||
import com.viewsh.module.ops.infrastructure.log.enumeration.EventDomain;
|
||||
import com.viewsh.module.ops.infrastructure.log.recorder.EventLogRecorder;
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.rocketmq.spring.annotation.ConsumeMode;
|
||||
@@ -25,6 +22,30 @@ import java.util.concurrent.TimeUnit;
|
||||
* 保洁工单确认事件消费者
|
||||
* <p>
|
||||
* 订阅 IoT 模块发布的工单确认事件(如:工牌按键确认)
|
||||
* <p>
|
||||
* 调用链路:
|
||||
* <pre>
|
||||
* IoT 发布 RocketMQ 消息 (ops-order-confirm)
|
||||
* ↓
|
||||
* CleanOrderConfirmEventHandler.onMessage()
|
||||
* - 幂等性检查
|
||||
* - 状态检查
|
||||
* ↓
|
||||
* orderLifecycleManager.transition(CONFIRMED) [@Transactional]
|
||||
* - 更新工单状态
|
||||
* - 发布 OrderStateChangedEvent
|
||||
* ↓
|
||||
* 事务提交
|
||||
* ↓
|
||||
* CleanOrderEventListener.onOrderStateChanged() [@TransactionalEventListener(AFTER_COMMIT)]
|
||||
* - 记录业务日志
|
||||
* - 发送 TTS "工单已确认,请前往作业区域开始作业"
|
||||
* </pre>
|
||||
* <p>
|
||||
* 设计说明:
|
||||
* - Handler 只负责消息接收和状态转换
|
||||
* - 日志记录和通知发送由 CleanOrderEventListener 在事务提交后处理
|
||||
* - 设备状态由 BadgeDeviceStatusServiceImpl 在 BEFORE_COMMIT 阶段同步
|
||||
*
|
||||
* @author AI
|
||||
*/
|
||||
@@ -40,10 +61,6 @@ public class CleanOrderConfirmEventHandler implements RocketMQListener<String> {
|
||||
private static final String DEDUP_KEY_PATTERN = "ops:clean:dedup:confirm:%s";
|
||||
private static final int DEDUP_TTL_SECONDS = 300;
|
||||
|
||||
private static final String TTS_ORDER_IN_PROGRESS = "工单已在进行中";
|
||||
private static final String TTS_CANNOT_CONFIRM = "当前状态无法确认工单";
|
||||
private static final String TTS_CONFIRM_SUCCESS = "工单已确认,请前往作业区域开始作业";
|
||||
|
||||
@Resource
|
||||
private ObjectMapper objectMapper;
|
||||
|
||||
@@ -56,12 +73,6 @@ public class CleanOrderConfirmEventHandler implements RocketMQListener<String> {
|
||||
@Resource
|
||||
private OrderLifecycleManager orderLifecycleManager;
|
||||
|
||||
@Resource
|
||||
private EventLogRecorder eventLogRecorder;
|
||||
|
||||
@Resource
|
||||
private VoiceBroadcastService voiceBroadcastService;
|
||||
|
||||
@Override
|
||||
public void onMessage(String message) {
|
||||
try {
|
||||
@@ -88,60 +99,43 @@ public class CleanOrderConfirmEventHandler implements RocketMQListener<String> {
|
||||
}
|
||||
|
||||
WorkOrderStatusEnum currentStatus = WorkOrderStatusEnum.fromStatus(order.getStatus());
|
||||
log.info("[CleanOrderConfirmEventHandler] 收到确认事件: eventId={}, orderId={}, currentStatus={}",
|
||||
eventId, orderId, currentStatus);
|
||||
log.info("[CleanOrderConfirmEventHandler] 收到确认事件: eventId={}, orderId={}, currentStatus={}, deviceId={}",
|
||||
eventId, orderId, currentStatus, event.getDeviceId());
|
||||
|
||||
// 4. 状态检查
|
||||
// 如果已在进行中 (CONFIRMED or ARRIVED),提示"工单已在进行中"
|
||||
// 如果已在进行中 (CONFIRMED or ARRIVED),直接返回(TTS 由 Listener 处理)
|
||||
if (currentStatus == WorkOrderStatusEnum.CONFIRMED || currentStatus == WorkOrderStatusEnum.ARRIVED) {
|
||||
sendTts(event.getDeviceId(), TTS_ORDER_IN_PROGRESS);
|
||||
log.debug("[CleanOrderConfirmEventHandler] 工单已在进行中: orderId={}, status={}", orderId, currentStatus);
|
||||
return;
|
||||
}
|
||||
|
||||
// 检查是否可以确认
|
||||
if (!currentStatus.canConfirm()) {
|
||||
log.warn("[CleanOrderConfirmEventHandler] 当前状态无法确认工单: orderId={}, status={}", orderId, currentStatus);
|
||||
sendTts(event.getDeviceId(), TTS_CANNOT_CONFIRM);
|
||||
return;
|
||||
}
|
||||
|
||||
// 5. 状态流转 -> CONFIRMED
|
||||
// 5. 构建状态转换请求(包含 deviceId,供 Listener 使用)
|
||||
OrderTransitionRequest request = OrderTransitionRequest.builder()
|
||||
.orderId(orderId)
|
||||
.targetStatus(WorkOrderStatusEnum.CONFIRMED)
|
||||
.reason("工牌按键确认")
|
||||
.operatorType(OperatorTypeEnum.CLEANER)
|
||||
.operatorId(order.getAssigneeId() != null ? order.getAssigneeId() : 0L)
|
||||
.operatorId(event.getDeviceId() != null ? event.getDeviceId() : order.getAssigneeId())
|
||||
.build();
|
||||
// 将 deviceId 放入 payload,供 Listener 使用
|
||||
request.putPayload("deviceId", event.getDeviceId());
|
||||
request.putPayload("triggerSource", "BADGE_BUTTON");
|
||||
|
||||
// 6. 执行状态转换
|
||||
// 注意:日志记录和 TTS 由 CleanOrderEventListener 在 AFTER_COMMIT 阶段处理
|
||||
orderLifecycleManager.transition(request);
|
||||
|
||||
// 6. 记录业务日志
|
||||
eventLogRecorder.info("clean", EventDomain.AUDIT, "ORDER_CONFIRM",
|
||||
"工单已确认 (工牌按键)", orderId, event.getDeviceId(), order.getAssigneeId());
|
||||
|
||||
// 7. 发送 TTS 通知
|
||||
// "工单已确认,请前往{AreaName}开始作业"
|
||||
sendTts(event.getDeviceId(), TTS_CONFIRM_SUCCESS);
|
||||
log.info("[CleanOrderConfirmEventHandler] 工单确认成功: orderId={}, deviceId={}", orderId, event.getDeviceId());
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("[CleanOrderConfirmEventHandler] 消息处理失败: message={}", message, e);
|
||||
throw new RuntimeException("保洁工单确认事件处理失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送 TTS 语音播报
|
||||
*/
|
||||
private void sendTts(Long deviceId, String text) {
|
||||
if (deviceId == null) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
voiceBroadcastService.broadcast(deviceId, text);
|
||||
log.info("[CleanOrderConfirmEventHandler] TTS 下发成功: deviceId={}, text={}", deviceId, text);
|
||||
} catch (Exception e) {
|
||||
log.error("[CleanOrderConfirmEventHandler] TTS 发送失败: deviceId={}", deviceId, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
package com.viewsh.module.ops.environment.integration.consumer;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.viewsh.module.iot.api.device.IotDeviceControlApi;
|
||||
import com.viewsh.module.iot.api.device.dto.ResetTrafficCounterReqDTO;
|
||||
import com.viewsh.module.ops.enums.PriorityEnum;
|
||||
import com.viewsh.module.ops.environment.dal.dataobject.CleanOrderAutoCreateReqDTO;
|
||||
import com.viewsh.module.ops.environment.integration.dto.CleanOrderCreateEventDTO;
|
||||
@@ -63,9 +61,6 @@ public class CleanOrderCreateEventHandler implements RocketMQListener<String> {
|
||||
@Resource
|
||||
private CleanOrderService cleanOrderService;
|
||||
|
||||
@Resource
|
||||
private IotDeviceControlApi iotDeviceControlApi;
|
||||
|
||||
@Resource
|
||||
private EventLogRecorder eventLogRecorder;
|
||||
|
||||
@@ -110,11 +105,10 @@ public class CleanOrderCreateEventHandler implements RocketMQListener<String> {
|
||||
createReq.setPriority(PriorityEnum.fromPriority(event.getPriority() != null ?
|
||||
Integer.parseInt(event.getPriority()) : 2).getPriority());
|
||||
createReq.setAreaId(event.getAreaId());
|
||||
// location 字段由 areaId 自动关联,不需要在事件中传递
|
||||
|
||||
// 扩展字段
|
||||
createReq.setExpectedDuration(calculateExpectedDuration(event));
|
||||
createReq.setCleaningType("ROUTINE"); // 可根据triggerSource动态设置
|
||||
createReq.setCleaningType("ROUTINE");
|
||||
createReq.setDifficultyLevel(3);
|
||||
|
||||
// IoT集成字段
|
||||
@@ -122,6 +116,7 @@ public class CleanOrderCreateEventHandler implements RocketMQListener<String> {
|
||||
createReq.setTriggerRuleId(extractRuleId(event));
|
||||
createReq.setTriggerDeviceId(event.getTriggerDeviceId());
|
||||
createReq.setTriggerDeviceKey(event.getTriggerDeviceKey());
|
||||
createReq.setTriggerData(event.getTriggerData());
|
||||
|
||||
// 2. 创建工单(同时创建主表+扩展表)
|
||||
Long orderId = cleanOrderService.createAutoCleanOrder(createReq);
|
||||
@@ -129,11 +124,7 @@ public class CleanOrderCreateEventHandler implements RocketMQListener<String> {
|
||||
// 3. 记录业务日志
|
||||
recordOrderCreatedLog(event, orderId, createReq);
|
||||
|
||||
// 4. 如果是客流触发的工单,重置客流计数器基准值
|
||||
// TODO: 需要优化这个工单是否创建成功,才重置
|
||||
if ("IOT_TRAFFIC".equals(event.getTriggerSource()) && event.getTriggerData() != null) {
|
||||
resetTrafficCounter(event, orderId);
|
||||
}
|
||||
// 注意:客流计数器重置已移至 CleanOrderEventListener,在事务提交后执行
|
||||
|
||||
log.info("[CleanOrderCreateEventHandler] 工单创建成功: eventId={}, orderId={}, areaId={}",
|
||||
event.getEventId(), orderId, event.getAreaId());
|
||||
@@ -144,9 +135,8 @@ public class CleanOrderCreateEventHandler implements RocketMQListener<String> {
|
||||
*/
|
||||
private void recordOrderCreatedLog(CleanOrderCreateEventDTO event, Long orderId, CleanOrderAutoCreateReqDTO createReq) {
|
||||
try {
|
||||
// 确定事件域和类型
|
||||
// 确定事件域
|
||||
EventDomain domain = determineDomain(event.getTriggerSource());
|
||||
String eventType = "ORDER_CREATED";
|
||||
|
||||
// 构建扩展信息
|
||||
Map<String, Object> extra = new HashMap<>();
|
||||
@@ -159,19 +149,12 @@ public class CleanOrderCreateEventHandler implements RocketMQListener<String> {
|
||||
extra.putAll(event.getTriggerData());
|
||||
}
|
||||
|
||||
// 记录日志
|
||||
eventLogRecorder.info("clean", domain, eventType,
|
||||
buildLogMessage(event, createReq),
|
||||
orderId,
|
||||
event.getTriggerDeviceId(),
|
||||
null);
|
||||
|
||||
// 添加扩展信息
|
||||
// 记录日志(合并为一次调用)
|
||||
eventLogRecorder.record(EventLogRecord.builder()
|
||||
.module("clean")
|
||||
.domain(domain)
|
||||
.eventType(eventType + "_DETAIL")
|
||||
.message("工单创建详细数据")
|
||||
.eventType("ORDER_CREATED")
|
||||
.message(buildLogMessage(event, createReq))
|
||||
.targetId(orderId)
|
||||
.targetType("order")
|
||||
.deviceId(event.getTriggerDeviceId())
|
||||
@@ -213,56 +196,6 @@ public class CleanOrderCreateEventHandler implements RocketMQListener<String> {
|
||||
event.getTriggerDeviceKey(), event.getTriggerSource());
|
||||
}
|
||||
|
||||
/**
|
||||
* 重置客流计数器基准值
|
||||
* <p>
|
||||
* 工单创建成功后,通知 IoT 模块重置客流计数器,以便统计下一波客流
|
||||
*
|
||||
* @param event 工单创建事件
|
||||
* @param orderId 工单ID
|
||||
*/
|
||||
private void resetTrafficCounter(CleanOrderCreateEventDTO event, Long orderId) {
|
||||
try {
|
||||
// 获取当前客流值作为新的基准值
|
||||
Object currentCountObj = event.getTriggerData().get("actualCount");
|
||||
Object baseValueObj = event.getTriggerData().get("baseValue");
|
||||
|
||||
if (currentCountObj == null || baseValueObj == null) {
|
||||
log.warn("[CleanOrderCreateEventHandler] 缺少客流数据,跳过重置: eventId={}, actualCount={}, baseValue={}",
|
||||
event.getEventId(), currentCountObj, baseValueObj);
|
||||
return;
|
||||
}
|
||||
|
||||
// 计算新的基准值 = 当前值
|
||||
Long currentCount = ((Number) currentCountObj).longValue();
|
||||
Long newBaseValue = currentCount; // 将当前客流设为新的基准值
|
||||
|
||||
// 构建重置请求
|
||||
ResetTrafficCounterReqDTO reqDTO = ResetTrafficCounterReqDTO.builder()
|
||||
.deviceId(event.getTriggerDeviceId())
|
||||
.newBaseValue(newBaseValue)
|
||||
.orderId(orderId)
|
||||
.remark("工单创建后重置计数器")
|
||||
.build();
|
||||
|
||||
// 调用 IoT 模块 RPC 接口
|
||||
var result = iotDeviceControlApi.resetTrafficCounter(reqDTO);
|
||||
|
||||
if (result.getData() != null && result.getData()) {
|
||||
log.info("[CleanOrderCreateEventHandler] 客流计数器重置成功: eventId={}, deviceId={}, newBaseValue={}",
|
||||
event.getEventId(), event.getTriggerDeviceId(), newBaseValue);
|
||||
} else {
|
||||
log.warn("[CleanOrderCreateEventHandler] 客流计数器重置失败: eventId={}, deviceId={}",
|
||||
event.getEventId(), event.getTriggerDeviceId());
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
// 重置失败不应影响主流程
|
||||
log.error("[CleanOrderCreateEventHandler] 客流计数器重置异常: eventId={}, deviceId={}",
|
||||
event.getEventId(), event.getTriggerDeviceId(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成工单标题
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user