package com.hfln.device.application.event; import com.hfln.device.domain.service.DeviceService; import com.hfln.device.domain.entity.Device; import com.hfln.device.domain.event.*; import com.hfln.device.domain.constant.EventConstants; import com.hfln.device.domain.gateway.DeviceGateway; import com.hfln.device.domain.gateway.MqttGateway; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; /** * 事件处理器实现类 * 处理各种设备事件 */ @Service @Slf4j public class EventHandlerImpl implements EventHandler { @Autowired private DeviceService deviceService; @Autowired private MqttGateway mqttGateway; @Autowired private DeviceGateway deviceGateway; @Override public void handleFallEvent(FallEvent event) { log.debug("处理跌倒事件: {}", event); String deviceId = event.getDeviceId(); try { Device device = deviceService.getDeviceById(deviceId); if (device == null) { log.debug("设备不存在: {}", deviceId); return; } device.setLastReportFallTime(event.getTimestamp()); String fallStatus = event.getFallStatus(); if (EventConstants.FallStatus.FALL_SUSPECTED.equals(fallStatus)) { mqttGateway.sendFallAlarmMessage(deviceId, event.getPose(), event.getTargetPoint()); deviceGateway.recordFallEvent(deviceId, event.getPose(), event.getTargetPoint()); log.info("疑似跌倒事件: {}", deviceId); } else if (EventConstants.FallStatus.FALL_CONFIRMED.equals(fallStatus)) { mqttGateway.sendFallAlarmMessage(deviceId, event.getPose(), event.getTargetPoint()); deviceGateway.recordFallEvent(deviceId, event.getPose(), event.getTargetPoint()); log.info("确认跌倒事件: {}", deviceId); device.setAlarmAck(false); device.setLastAlarmAckTime(event.getTimestamp()); saveAlarmRecord(device, event); } else if (EventConstants.FallStatus.FALL_CANCELED.equals(fallStatus)) { List> targets = Collections.singletonList(event.getTargetPoint()); mqttGateway.sendEventMessage(deviceId, Collections.emptyList(), event.getPose(), targets, fallStatus); log.info("取消跌倒事件: {}", deviceId); } deviceService.updateDevice(device); } catch (Exception e) { log.error("处理跌倒事件异常: {}", deviceId, e); } } @Override public void handlePresenceEvent(PresenceEvent event) { log.debug("处理存在事件: {}", event); String deviceId = event.getDeviceId(); try { Device device = deviceService.getDeviceById(deviceId); if (device == null) { log.warn("设备不存在: {}", deviceId); return; } String presenceStatus = event.getPresenceStatus(); if (EventConstants.PresenceStatus.PRESENCE_DETECTED.equals(presenceStatus)) { device.setEnterTs(event.getTimestamp()); device.resetLeaveTs(); mqttGateway.sendExistenceMessage(deviceId, presenceStatus); deviceGateway.recordExistEvent(deviceId, presenceStatus); log.info("检测到存在事件: {}", deviceId); } else if (EventConstants.PresenceStatus.PRESENCE_LOST.equals(presenceStatus)) { device.setLeaveTs(event.getTimestamp()); device.updateStayTime(); mqttGateway.sendExistenceMessage(deviceId, presenceStatus); deviceGateway.recordExistEvent(deviceId, presenceStatus); log.info("存在消失事件: {}, 停留时间: {}秒", deviceId, device.getStayTime() / 1000); saveStayTimeRecord(device); } deviceService.updateDevice(device); } catch (Exception e) { log.error("处理存在事件异常: {}", deviceId, e); } } @Override public void handleRetentionEvent(RetentionEvent event) { log.debug("处理滞留事件: {}", event); String deviceId = event.getDeviceId(); try { Device device = deviceService.getDeviceById(deviceId); if (device == null) { log.warn("设备不存在: {}", deviceId); return; } String retentionStatus = event.getRetentionStatus(); if (EventConstants.RetentionStatus.RETENTION_STARTED.equals(retentionStatus)) { device.setRetentionTime(event.getStartTimestamp()); mqttGateway.sendAlarmMessage(deviceId, EventConstants.EventType.RETENTION_EVENT, buildRetentionMessage(event)); deviceGateway.recordDeviceRetentionAlarm(deviceId, event.getStartTimestamp(), EventConstants.EventType.RETENTION_EVENT, retentionStatus); log.info("开始滞留事件: {}", deviceId); } else if (EventConstants.RetentionStatus.RETENTION_ONGOING.equals(retentionStatus)) { device.setRetentionKeepTime(event.getDuration()); log.debug("滞留持续事件: {}, 持续时间: {}秒", deviceId, event.getDuration()); } else if (EventConstants.RetentionStatus.RETENTION_ENDED.equals(retentionStatus)) { device.setRetentionTime(null); device.setRetentionKeepTime(null); mqttGateway.sendAlarmMessage(deviceId, EventConstants.EventType.RETENTION_EVENT, buildRetentionMessage(event)); deviceGateway.recordDeviceStayTime(deviceId, event.getStartTimestamp(), event.getDuration(), retentionStatus); log.info("滞留结束事件: {}", deviceId); } else if (EventConstants.RetentionStatus.RETENTION_ALARM.equals(retentionStatus)) { String description = "滞留告警: 设备" + deviceId + "滞留时间超过阈值"; mqttGateway.sendAlarmEventMessage(deviceId, description, "retention_alarm", 0); log.info("滞留告警事件: {}, 滞留时间: {}秒", deviceId, event.getDuration()); device.setAlarmAck(false); device.setLastAlarmAckTime(event.getTimestamp()); saveRetentionAlarmRecord(device, event); } deviceService.updateDevice(device); } catch (Exception e) { log.error("处理滞留事件异常: {}", deviceId, e); } } private Map buildRetentionMessage(RetentionEvent event) { Map message = new HashMap<>(); message.put("status", event.getRetentionStatus()); message.put("startTime", event.getStartTimestamp()); message.put("duration", event.getDuration()); return message; } @Override public void handleAlarmAcknowledgement(String deviceId, Long eventId, String eventType) { log.debug("处理告警确认: 设备={}, 事件ID={}, 事件类型={}", deviceId, eventId, eventType); Device device = deviceService.getDeviceById(deviceId); if (device == null) { log.warn("设备不存在: {}", deviceId); return; } // 设置告警已确认 device.setAlarmAck(true); device.setLastAlarmAckTime(System.currentTimeMillis()); // 发送告警确认消息 mqttGateway.sendAlarmAckMessage(deviceId, eventId); log.info("告警已确认: 设备={}, 事件ID={}", deviceId, eventId); // 更新数据库中的告警记录 updateAlarmAckStatus(eventId, eventType); // 更新设备信息 deviceService.updateDevice(device); } /** * 保存告警记录到数据库 * @param device 设备信息 * @param event 跌倒事件 */ private void saveAlarmRecord(Device device, FallEvent event) { // 持久化告警事件到数据库 deviceGateway.recordAlarmEvent(device.getDevId(), "跌倒告警", "fall_event", 1, event.getTimestamp()); log.debug("保存跌倒告警记录: {}", event); } /** * 保存停留记录到数据库 * @param device 设备信息 */ private void saveStayTimeRecord(Device device) { // 持久化停留事件到数据库 deviceGateway.recordDeviceStayTime(device.getDevId(), device.getEnterTs(), device.getLeaveTs(), "未知区域"); log.debug("保存停留记录: 设备={}, 进入时间={}, 离开时间={}, 停留时间={}秒", device.getDevId(), device.getEnterTs(), device.getLeaveTs(), device.getStayTime() / 1000); } /** * 保存滞留告警记录到数据库 * @param device 设备信息 * @param event 滞留事件 */ private void saveRetentionAlarmRecord(Device device, RetentionEvent event) { // 持久化滞留告警到数据库 deviceGateway.recordDeviceRetentionAlarm(device.getDevId(), event.getTimestamp(), "retention_alarm", "滞留超时"); log.debug("保存滞留告警记录: {}", event); } /** * 更新告警确认状态 * @param eventId 事件ID * @param eventType 事件类型 */ private void updateAlarmAckStatus(Long eventId, String eventType) { // 更新告警确认状态到数据库 deviceGateway.updateAlarmAckStatus(eventId, null); // userId可从上下文获取 log.debug("更新告警确认状态: 事件ID={}, 事件类型={}", eventId, eventType); } }