diff --git a/viewsh-module-ops/viewsh-module-environment-biz/src/main/java/com/viewsh/module/ops/environment/integration/consumer/CleanOrderArriveEventHandler.java b/viewsh-module-ops/viewsh-module-environment-biz/src/main/java/com/viewsh/module/ops/environment/integration/consumer/CleanOrderArriveEventHandler.java index dbdc49c..068da7b 100644 --- a/viewsh-module-ops/viewsh-module-environment-biz/src/main/java/com/viewsh/module/ops/environment/integration/consumer/CleanOrderArriveEventHandler.java +++ b/viewsh-module-ops/viewsh-module-environment-biz/src/main/java/com/viewsh/module/ops/environment/integration/consumer/CleanOrderArriveEventHandler.java @@ -8,6 +8,9 @@ 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; @@ -73,6 +76,9 @@ public class CleanOrderArriveEventHandler implements RocketMQListener { @Resource private OrderLifecycleManager orderLifecycleManager; + @Resource + private EventLogRecorder eventLogRecorder; + @Override public void onMessage(String message) { try { @@ -146,7 +152,10 @@ public class CleanOrderArriveEventHandler implements RocketMQListener { // 5. 通过生命周期管理器执行状态转换(DISPATCHED/CONFIRMED -> ARRIVED) orderLifecycleManager.transition(request); - // 6. 更新 Redis 缓存(设备当前工单) + // 6. 记录业务日志 + recordOrderArrivedLog(event, request); + + // 7. 更新 Redis 缓存(设备当前工单) cacheDeviceCurrentOrder(event); log.info("[CleanOrderArriveEventHandler] 工单到岗成功: eventId={}, orderId={}, deviceId={}", @@ -190,4 +199,36 @@ public class CleanOrderArriveEventHandler implements RocketMQListener { log.error("[CleanOrderArriveEventHandler] 设备工单缓存更新失败: deviceId={}", event.getDeviceId(), e); } } + + /** + * 记录工单到岗业务日志 + */ + private void recordOrderArrivedLog(CleanOrderArriveEventDTO event, OrderTransitionRequest request) { + try { + // 构建扩展信息 + Map 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); + } + } } diff --git a/viewsh-module-ops/viewsh-module-environment-biz/src/main/java/com/viewsh/module/ops/environment/integration/consumer/CleanOrderCompleteEventHandler.java b/viewsh-module-ops/viewsh-module-environment-biz/src/main/java/com/viewsh/module/ops/environment/integration/consumer/CleanOrderCompleteEventHandler.java index 16fc7ca..904a0c3 100644 --- a/viewsh-module-ops/viewsh-module-environment-biz/src/main/java/com/viewsh/module/ops/environment/integration/consumer/CleanOrderCompleteEventHandler.java +++ b/viewsh-module-ops/viewsh-module-environment-biz/src/main/java/com/viewsh/module/ops/environment/integration/consumer/CleanOrderCompleteEventHandler.java @@ -9,6 +9,9 @@ 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; @@ -72,6 +75,9 @@ public class CleanOrderCompleteEventHandler implements RocketMQListener @Resource private CleanOrderService cleanOrderService; + @Resource + private EventLogRecorder eventLogRecorder; + @Override public void onMessage(String message) { try { @@ -143,10 +149,13 @@ public class CleanOrderCompleteEventHandler implements RocketMQListener // 5. 通过生命周期管理器执行状态转换(ARRIVED -> COMPLETED) orderLifecycleManager.completeOrder(event.getOrderId(), null, remark); - // 6. 清除 Redis 缓存(设备当前工单) + // 6. 记录业务日志 + recordOrderCompletedLog(event, order, remark); + + // 7. 清除 Redis 缓存(设备当前工单) clearDeviceCurrentOrder(event.getDeviceId()); - // 7. 自动调度下一个任务(优先恢复被中断的任务) + // 8. 自动调度下一个任务(优先恢复被中断的任务) if (order.getAssigneeId() != null) { cleanOrderService.autoDispatchNextOrder(event.getOrderId(), order.getAssigneeId()); } @@ -187,4 +196,49 @@ public class CleanOrderCompleteEventHandler implements RocketMQListener log.error("[CleanOrderCompleteEventHandler] 设备工单缓存清除失败: deviceId={}", deviceId, e); } } + + /** + * 记录工单完成业务日志 + */ + private void recordOrderCompletedLog(CleanOrderCompleteEventDTO event, OpsOrderDO order, String remark) { + try { + // 构建扩展信息 + Map 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); + } + } } diff --git a/viewsh-module-ops/viewsh-module-environment-biz/src/main/java/com/viewsh/module/ops/environment/integration/consumer/CleanOrderCreateEventHandler.java b/viewsh-module-ops/viewsh-module-environment-biz/src/main/java/com/viewsh/module/ops/environment/integration/consumer/CleanOrderCreateEventHandler.java index 5ffcdf6..98e3c09 100644 --- a/viewsh-module-ops/viewsh-module-environment-biz/src/main/java/com/viewsh/module/ops/environment/integration/consumer/CleanOrderCreateEventHandler.java +++ b/viewsh-module-ops/viewsh-module-environment-biz/src/main/java/com/viewsh/module/ops/environment/integration/consumer/CleanOrderCreateEventHandler.java @@ -7,6 +7,10 @@ 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; 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.enumeration.EventLevel; +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; @@ -15,6 +19,8 @@ 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,6 +66,9 @@ public class CleanOrderCreateEventHandler implements RocketMQListener { @Resource private IotDeviceControlApi iotDeviceControlApi; + @Resource + private EventLogRecorder eventLogRecorder; + @Override public void onMessage(String message) { try { @@ -117,7 +126,10 @@ public class CleanOrderCreateEventHandler implements RocketMQListener { // 2. 创建工单(同时创建主表+扩展表) Long orderId = cleanOrderService.createAutoCleanOrder(createReq); - // 3. 如果是客流触发的工单,重置客流计数器基准值 + // 3. 记录业务日志 + recordOrderCreatedLog(event, orderId, createReq); + + // 4. 如果是客流触发的工单,重置客流计数器基准值 // TODO: 需要优化这个工单是否创建成功,才重置 if ("IOT_TRAFFIC".equals(event.getTriggerSource()) && event.getTriggerData() != null) { resetTrafficCounter(event, orderId); @@ -127,6 +139,81 @@ public class CleanOrderCreateEventHandler implements RocketMQListener { event.getEventId(), orderId, event.getAreaId()); } + /** + * 记录工单创建业务日志 + */ + private void recordOrderCreatedLog(CleanOrderCreateEventDTO event, Long orderId, CleanOrderAutoCreateReqDTO createReq) { + try { + // 确定事件域和类型 + EventDomain domain = determineDomain(event.getTriggerSource()); + String eventType = "ORDER_CREATED"; + + // 构建扩展信息 + Map extra = new HashMap<>(); + extra.put("eventId", event.getEventId()); + extra.put("triggerSource", event.getTriggerSource()); + extra.put("areaId", event.getAreaId()); + extra.put("priority", createReq.getPriority()); + extra.put("expectedDuration", createReq.getExpectedDuration()); + if (event.getTriggerData() != null) { + 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("工单创建详细数据") + .targetId(orderId) + .targetType("order") + .deviceId(event.getTriggerDeviceId()) + .level(EventLevel.INFO) + .payload(extra) + .build()); + + } catch (Exception e) { + log.warn("[CleanOrderCreateEventHandler] 记录业务日志失败: orderId={}", orderId, e); + } + } + + /** + * 确定事件域 + */ + private EventDomain determineDomain(String triggerSource) { + if ("IOT_TRAFFIC".equals(triggerSource)) { + return EventDomain.TRAFFIC; + } else if ("IOT_BEACON".equals(triggerSource)) { + return EventDomain.BEACON; + } else if ("IOT_SIGNAL_LOSS".equals(triggerSource)) { + return EventDomain.BEACON; + } + return EventDomain.SYSTEM; + } + + /** + * 构建日志消息 + */ + private String buildLogMessage(CleanOrderCreateEventDTO event, CleanOrderAutoCreateReqDTO createReq) { + if ("IOT_TRAFFIC".equals(event.getTriggerSource())) { + return String.format("客流阈值触发工单创建 [设备:%s, 区域:%d]", + event.getTriggerDeviceKey(), event.getAreaId()); + } else if ("IOT_BEACON".equals(event.getTriggerSource())) { + return String.format("信标检测触发工单创建 [设备:%s, 区域:%d]", + event.getTriggerDeviceKey(), event.getAreaId()); + } + return String.format("IoT设备触发工单创建 [设备:%s, 来源:%s]", + event.getTriggerDeviceKey(), event.getTriggerSource()); + } + } + /** * 重置客流计数器基准值 *