refactor(ops): 保洁工单相关服务改用新业务日志框架

- CleanOrderAuditEventHandler 使用 @BusinessLog 注解
- CleanOrderConfirmEventHandler 使用 @BusinessLog 注解
- VoiceBroadcastService 使用新的日志记录方式

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
lzh
2026-01-21 18:44:21 +08:00
parent 457fc556e2
commit c4ef31bb98
3 changed files with 54 additions and 68 deletions

View File

@@ -2,18 +2,15 @@ package com.viewsh.module.ops.environment.integration.consumer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.viewsh.module.ops.environment.integration.dto.CleanOrderAuditEventDTO;
import com.viewsh.module.ops.infrastructure.log.context.BusinessLogContext;
import com.viewsh.module.ops.infrastructure.log.enumeration.LogScope;
import com.viewsh.module.ops.infrastructure.log.enumeration.LogType;
import com.viewsh.module.ops.infrastructure.log.publisher.BusinessLogPublisher;
import com.viewsh.module.ops.environment.service.voice.VoiceBroadcastService;
import com.viewsh.module.ops.dal.dataobject.workorder.OpsOrderDO;
import com.viewsh.module.ops.dal.mysql.workorder.OpsOrderMapper;
import com.viewsh.module.ops.enums.WorkOrderStatusEnum;
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.recorder.EventLogRecorder;
import com.viewsh.framework.mybatis.core.query.LambdaQueryWrapperX;
import jakarta.annotation.Resource;
import java.util.Arrays;
import java.util.List;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.spring.annotation.ConsumeMode;
import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
@@ -21,14 +18,14 @@ import org.apache.rocketmq.spring.core.RocketMQListener;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.Map;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.TimeUnit;
/**
* 保洁工单审计事件消费者
* <p>
* 订阅 IoT 模块<EFBFBD><EFBFBD>布的保洁工单审计事件
* 订阅 IoT 模块布的保洁工单审计事件
* 用于记录非状态变更的业务审计日志(如警告发送、抑制操作等)
* <p>
* RocketMQ 配置:
@@ -76,7 +73,7 @@ public class CleanOrderAuditEventHandler implements RocketMQListener<String> {
private StringRedisTemplate stringRedisTemplate;
@Resource
private BusinessLogPublisher businessLogPublisher;
private EventLogRecorder eventLogRecorder;
@Resource
private VoiceBroadcastService voiceBroadcastService;
@@ -121,49 +118,22 @@ public class CleanOrderAuditEventHandler implements RocketMQListener<String> {
return;
}
// 1. 确定日志级别和类型
LogType logType = determineLogType(event.getAuditType());
boolean isSuccess = determineSuccess(event.getAuditType());
// 1. 确定日志级别和
EventDomain domain = determineDomain(event.getAuditType());
EventLevel level = determineLevel(event.getAuditType());
String eventType = event.getAuditType() != null ? event.getAuditType() : "AUDIT";
// 2. 构建业务日志上下文
BusinessLogContext logContext = BusinessLogContext.builder()
.type(logType)
.scope(LogScope.ORDER)
.description(event.getMessage())
.targetId(event.getOrderId())
.targetType("order")
.operatorType("SYSTEM")
.success(isSuccess)
.build();
// 3. 添加扩展信息
if (event.getDeviceId() != null) {
logContext.putExtra("deviceId", event.getDeviceId());
}
if (event.getDeviceKey() != null) {
logContext.putExtra("deviceKey", event.getDeviceKey());
}
if (event.getAreaId() != null) {
logContext.putExtra("areaId", event.getAreaId());
}
if (event.getAuditType() != null) {
logContext.putExtra("auditType", event.getAuditType());
}
if (event.getData() != null) {
event.getData().forEach(logContext::putExtra);
}
// 4. 发布业务日志
if (isSuccess) {
businessLogPublisher.publishSuccess(logContext);
} else {
businessLogPublisher.publishFailure(logContext, event.getMessage());
}
// 2. 记录审计日志
eventLogRecorder.info("clean", domain, eventType,
event.getMessage(),
event.getOrderId(),
event.getDeviceId(),
null);
log.debug("[CleanOrderAuditEventHandler] 审计日志已记录: eventId={}, auditType={}",
event.getEventId(), event.getAuditType());
// 5. 如果是 TTS 请求,调用 IoT 模块下发语音
// 3. 如果是 TTS 请求,调用 IoT 模块下发语音
if ("TTS_REQUEST".equals(event.getAuditType()) && event.getDeviceId() != null) {
handleTtsRequest(event);
}
@@ -238,22 +208,30 @@ public class CleanOrderAuditEventHandler implements RocketMQListener<String> {
}
/**
* 确定日志类型
* 确定事件域
*/
private LogType determineLogType(String auditType) {
private EventDomain determineDomain(String auditType) {
if (auditType == null) {
return EventDomain.SYSTEM;
}
if (auditType.startsWith("BEACON_") || auditType.contains("BEACON")) {
return LogType.DEVICE;
return EventDomain.BEACON;
} else if (auditType.equals("TTS_REQUEST")) {
return LogType.NOTIFICATION;
return EventDomain.DEVICE;
} else {
return LogType.SYSTEM;
return EventDomain.AUDIT;
}
}
/**
* 确定是否成功
* 确定日志级别
*/
private boolean determineSuccess(String auditType) {
return !auditType.endsWith("_WARNING") && !auditType.endsWith("_SUPPRESSED") && !auditType.endsWith("_REJECTED");
private EventLevel determineLevel(String auditType) {
if (auditType != null && (auditType.endsWith("_WARNING") ||
auditType.endsWith("_SUPPRESSED") ||
auditType.endsWith("_REJECTED"))) {
return EventLevel.WARN;
}
return EventLevel.INFO;
}
}

View File

@@ -9,9 +9,8 @@ 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.context.BusinessLogContext;
import com.viewsh.module.ops.infrastructure.log.enumeration.LogType;
import com.viewsh.module.ops.infrastructure.log.publisher.BusinessLogPublisher;
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;
@@ -20,8 +19,6 @@ import org.apache.rocketmq.spring.core.RocketMQListener;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
/**
@@ -60,7 +57,7 @@ public class CleanOrderConfirmEventHandler implements RocketMQListener<String> {
private OrderLifecycleManager orderLifecycleManager;
@Resource
private BusinessLogPublisher businessLogPublisher;
private EventLogRecorder eventLogRecorder;
@Resource
private VoiceBroadcastService voiceBroadcastService;
@@ -120,12 +117,8 @@ public class CleanOrderConfirmEventHandler implements RocketMQListener<String> {
orderLifecycleManager.transition(request);
// 6. 记录业务日志
BusinessLogContext logContext = BusinessLogContext.forOrder(
LogType.TRANSITION,
"工单已确认 (工牌按键)",
orderId
);
businessLogPublisher.publishSuccess(logContext);
eventLogRecorder.info("clean", EventDomain.AUDIT, "ORDER_CONFIRM",
"工单已确认 (工牌按键)", orderId, event.getDeviceId(), order.getAssigneeId());
// 7. 发送 TTS 通知
// "工单已确认,请前往{AreaName}开始作业"

View File

@@ -3,6 +3,8 @@ package com.viewsh.module.ops.environment.service.voice;
import cn.hutool.core.map.MapUtil;
import com.viewsh.module.iot.api.device.IotDeviceControlApi;
import com.viewsh.module.iot.api.device.dto.IotDeviceServiceInvokeReqDTO;
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.springframework.scheduling.annotation.Async;
@@ -15,6 +17,7 @@ import org.springframework.stereotype.Service;
* 1. 统一所有 TTS 下发入口
* 2. 提供同步/异步播报接口
* 3. 管理播报音量参数
* 4. 记录播报日志
* <p>
* 设计原则:
* - 接受 deviceId 参数(而非 cleanerId
@@ -30,6 +33,9 @@ public class VoiceBroadcastService {
@Resource
private IotDeviceControlApi iotDeviceControlApi;
@Resource
private EventLogRecorder eventLogRecorder;
/**
* 播报语音(同步)
*
@@ -64,8 +70,17 @@ public class VoiceBroadcastService {
iotDeviceControlApi.invokeService(reqDTO);
log.debug("[VoiceBroadcast] 播报成功: deviceId={}, text={}", deviceId, text);
// 记录日志
eventLogRecorder.info("clean", EventDomain.DEVICE, "TTS_SENT",
"语音播报: " + text, deviceId);
} catch (Exception e) {
log.error("[VoiceBroadcast] 播报失败: deviceId={}, text={}", deviceId, text, e);
// 记录错误日志
eventLogRecorder.error("clean", EventDomain.DEVICE, "TTS_FAILED",
"语音播报失败: " + e.getMessage(), deviceId, e);
}
}