fix(ops): 保洁工单日志去重,修复到岗/完成日志设备字段为 null

- AuditEventHandler 跳过 BEACON_ARRIVE_CONFIRMED 和
  BEACON_COMPLETE_REQUESTED 审计事件,避免与状态变更日志重复
- recordOrderArrivedLog 当 payload 无 deviceKey 时从工单主表兜底,
  null 字段不再输出
- recordOrderCompletedLog 同样增加 deviceKey 兜底逻辑

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
lzh
2026-03-11 17:34:42 +08:00
parent 5f804605c7
commit 6c8c57b932
2 changed files with 68 additions and 19 deletions

View File

@@ -11,6 +11,8 @@ import com.viewsh.module.ops.environment.service.voice.TtsQueueMessage;
import com.viewsh.module.ops.environment.service.voice.VoiceBroadcastService;
import com.viewsh.module.ops.infrastructure.log.enumeration.EventDomain;
import com.viewsh.module.ops.infrastructure.log.enumeration.EventLevel;
import com.viewsh.module.ops.infrastructure.log.enumeration.LogModule;
import com.viewsh.module.ops.infrastructure.log.enumeration.LogType;
import com.viewsh.module.ops.infrastructure.log.recorder.EventLogRecord;
import com.viewsh.module.ops.infrastructure.log.recorder.EventLogRecorder;
import jakarta.annotation.Resource;
@@ -112,15 +114,25 @@ public class CleanOrderAuditEventHandler implements RocketMQListener<String> {
return;
}
// 1. 确定日志级别和域
EventDomain domain = determineDomain(event.getAuditType());
EventLevel level = determineLevel(event.getAuditType());
String eventType = event.getAuditType() != null ? event.getAuditType() : "AUDIT";
// 1. 跳过与状态变更日志重复的审计事件(到岗确认/自动完成请求已由 CleanOrderEventListener 记录)
String auditType = event.getAuditType();
if (LogType.BEACON_ARRIVE_CONFIRMED.getCode().equals(auditType)
|| LogType.BEACON_COMPLETE_REQUESTED.getCode().equals(auditType)) {
log.debug("[CleanOrderAuditEventHandler] 跳过重复审计事件: eventId={}, auditType={}",
event.getEventId(), auditType);
return;
}
// 2. 记录审计日志
// 2. 确定日志级别和域
EventDomain domain = determineDomain(auditType);
EventLevel level = determineLevel(auditType);
LogType logType = auditType != null ? LogType.getByCode(auditType) : null;
String eventType = logType != null ? logType.getCode() : (auditType != null ? auditType : "AUDIT");
// 3. 记录审计日志
eventLogRecorder.record(
EventLogRecord.builder()
.module("clean")
.module(LogModule.CLEAN)
.domain(domain)
.eventType(eventType)
.message(event.getMessage())
@@ -132,10 +144,10 @@ public class CleanOrderAuditEventHandler implements RocketMQListener<String> {
);
log.debug("[CleanOrderAuditEventHandler] 审计日志已记录: eventId={}, auditType={}",
event.getEventId(), event.getAuditType());
event.getEventId(), auditType);
// 3. 如果是 TTS 请求,调用 IoT 模块下发语音
if ("TTS_REQUEST".equals(event.getAuditType()) && event.getDeviceId() != null) {
// 2. 如果是 TTS 请求,调用 IoT 模块下发语音
if (LogType.TTS_REQUEST.getCode().equals(auditType) && event.getDeviceId() != null) {
handleTtsRequest(event);
}
}
@@ -227,7 +239,7 @@ public class CleanOrderAuditEventHandler implements RocketMQListener<String> {
}
if (auditType.startsWith("BEACON_") || auditType.contains("BEACON")) {
return EventDomain.BEACON;
} else if (auditType.equals("TTS_REQUEST")) {
} else if (LogType.TTS_REQUEST.getCode().equals(auditType)) {
return EventDomain.DEVICE;
} else {
return EventDomain.AUDIT;

View File

@@ -20,6 +20,8 @@ import com.viewsh.module.ops.environment.service.cleanorder.CleanOrderService;
import com.viewsh.module.ops.environment.service.voice.TtsQueueMessage;
import com.viewsh.module.ops.environment.service.voice.VoiceBroadcastService;
import com.viewsh.module.ops.infrastructure.log.enumeration.EventDomain;
import com.viewsh.module.ops.infrastructure.log.enumeration.LogModule;
import com.viewsh.module.ops.infrastructure.log.enumeration.LogType;
import com.viewsh.module.ops.infrastructure.log.recorder.EventLogRecord;
import com.viewsh.module.ops.infrastructure.log.recorder.EventLogRecorder;
import com.viewsh.module.system.api.notify.NotifyMessageSendApi;
@@ -930,9 +932,9 @@ public class CleanOrderEventListener {
private void recordOrderConfirmedLog(Long orderId, Long deviceId, OrderStateChangedEvent event) {
try {
eventLogRecorder.record(EventLogRecord.builder()
.module("clean")
.module(LogModule.CLEAN)
.domain(EventDomain.DEVICE)
.eventType("ORDER_CONFIRM")
.eventType(LogType.ORDER_CONFIRM.getCode())
.message("工单已确认 (工牌按键)")
.targetId(orderId)
.targetType("order")
@@ -954,12 +956,37 @@ public class CleanOrderEventListener {
String deviceKey = (String) event.getPayload().get("deviceKey");
String beaconMac = (String) event.getPayload().get("beaconMac");
// 兜底payload 中没有 deviceKey 时从工单主表取
if (deviceKey == null && orderId != null) {
OpsOrderDO order = opsOrderMapper.selectById(orderId);
if (order != null) {
deviceKey = order.getAssigneeDeviceKey();
}
}
// 构建可读消息,跳过值为 null 的字段
StringBuilder msgBuilder = new StringBuilder("蓝牙信标自动到岗确认");
StringBuilder detail = new StringBuilder();
if (deviceKey != null) {
detail.append("设备:").append(deviceKey);
}
if (areaId != null) {
if (detail.length() > 0) detail.append(", ");
detail.append("区域:").append(areaId);
}
if (beaconMac != null) {
if (detail.length() > 0) detail.append(", ");
detail.append("信标:").append(beaconMac);
}
if (detail.length() > 0) {
msgBuilder.append(" [").append(detail).append("]");
}
eventLogRecorder.record(EventLogRecord.builder()
.module("clean")
.module(LogModule.CLEAN)
.domain(EventDomain.BEACON)
.eventType("ORDER_ARRIVED")
.message(String.format("蓝牙信标自动到岗确认 [设备:%s, 区域:%d, 信标:%s]",
deviceKey, areaId, beaconMac))
.eventType(LogType.ORDER_ARRIVED.getCode())
.message(msgBuilder.toString())
.targetId(orderId)
.targetType("order")
.deviceId(deviceId)
@@ -980,6 +1007,14 @@ public class CleanOrderEventListener {
String triggerSource = (String) event.getPayload().get("triggerSource");
String deviceKey = (String) event.getPayload().get("deviceKey");
// 兜底payload 中没有 deviceKey 时从工单主表取
if (deviceKey == null && orderId != null) {
OpsOrderDO order = opsOrderMapper.selectById(orderId);
if (order != null) {
deviceKey = order.getAssigneeDeviceKey();
}
}
// 构建日志消息
String message = "工单已完成";
if ("SIGNAL_LOSS_TIMEOUT".equals(triggerSource)) {
@@ -989,13 +1024,15 @@ public class CleanOrderEventListener {
long durationMinutes = ((Number) durationMs).longValue() / 60000;
durationInfo = String.format(",作业时长: %d分钟", durationMinutes);
}
message = "信号丢失超时自动完成 [设备:" + deviceKey + durationInfo + "]";
message = "信号丢失超时自动完成"
+ (deviceKey != null ? " [设备:" + deviceKey + durationInfo + "]"
: (durationInfo.isEmpty() ? "" : " [" + durationInfo.substring(1) + "]"));
}
EventLogRecord.EventLogRecordBuilder builder = EventLogRecord.builder()
.module("clean")
.module(LogModule.CLEAN)
.domain(EventDomain.BEACON)
.eventType("ORDER_COMPLETED")
.eventType(LogType.ORDER_COMPLETED.getCode())
.message(message)
.targetId(orderId)
.targetType("order");