package com.ruoyi.device.service.impl; import com.alibaba.fastjson2.JSONObject; import com.ruoyi.device.domain.impl.tuohengmqtt.callback.IAirportFlyControlCallback; import com.ruoyi.device.domain.impl.tuohengmqtt.callback.IAirportFlyControlDataCallback; import com.ruoyi.device.mapper.entity.FlightEntity; import com.ruoyi.device.mapper.entity.FlightLogEntity; import com.ruoyi.device.mapper.entity.PreCheckLogEntity; import com.ruoyi.device.service.FlightService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import java.util.Arrays; import java.util.List; @Slf4j @Component public class FlightEventCallback implements IAirportFlyControlCallback, IAirportFlyControlDataCallback { @Autowired private FlightService flightService; @Override public void onAirportFlyControl(String deviceSn, String payload, String topic) { log.info("【FlightEventCallback】收到飞行控制消息: deviceSn={}, topic={}, payload={}", deviceSn, topic, payload); try { JSONObject data = JSONObject.parseObject(payload); if (data == null) { log.warn("【FlightEventCallback】解析payload失败: deviceSn={}, topic={}, payload={}", deviceSn, topic, payload); return; } handleControlMessage(deviceSn, data); } catch (Exception e) { log.error("【FlightEventCallback】处理飞行控制消息失败: deviceSn={}, topic={}, error={}", deviceSn, topic, e.getMessage(), e); } } @Override public void onAirportFlyControlData(String deviceSn, String payload, String topic) { log.info("【FlightEventCallback】收到飞行控制数据消息: deviceSn={}, topic={}, payload={}", deviceSn, topic, payload); try { JSONObject data = JSONObject.parseObject(payload); if (data == null) { log.warn("【FlightEventCallback】解析payload失败: deviceSn={}, topic={}, payload={}", deviceSn, topic, payload); return; } handleControlDataMessage(deviceSn, data); } catch (Exception e) { log.error("【FlightEventCallback】处理飞行控制数据消息失败: deviceSn={}, topic={}, error={}", deviceSn, topic, e.getMessage(), e); } } /** * 处理 /control 主题消息 * 收到 airlineFlight 动作时创建飞行记录 */ private void handleControlMessage(String deviceSn, JSONObject data) { String action = data.getString("action"); String messageID = data.getString("messageID"); log.info("【FlightEventCallback】处理control消息: deviceSn={}, action={}, messageID={}", deviceSn, action, messageID); if ("airlineFlight".equals(action) && messageID != null && !messageID.isEmpty()) { // 创建飞行记录(如果不存在) flightService.getOrCreateFlightByMessageId(deviceSn, messageID); log.info("【FlightEventCallback】创建/获取飞行记录: deviceSn={}, messageID={}", deviceSn, messageID); } else if ("immediateReturn".equals(action) && messageID != null && !messageID.isEmpty()) { FlightEntity flight = flightService.getOrCreateFlightByMessageId(deviceSn, messageID); flightService.updateFlightStatus(flight.getFlightId(), "RETURNING"); log.info("【FlightEventCallback】更新飞行状态为RETURNING: deviceSn={}, flightId={}", deviceSn, flight.getFlightId()); } } /** * 处理 /control/data 主题消息 * 根据消息内容写入自检日志或飞行日志,并更新飞行状态 */ private void handleControlDataMessage(String deviceSn, JSONObject data) { String msg = data.getString("msg"); String messageID = data.getString("messageID"); Integer code = data.getInteger("code"); if (messageID == null || messageID.isEmpty()) { log.warn("【FlightEventCallback】消息缺少messageID: deviceSn={}, msg={}", deviceSn, msg); return; } // 通过 messageID 获取飞行记录 FlightEntity flight = flightService.getOrCreateFlightByMessageId(deviceSn, messageID); if (flight == null) { log.error("【FlightEventCallback】获取飞行记录失败: deviceSn={}, messageID={}", deviceSn, messageID); return; } log.info("【FlightEventCallback】处理control/data消息: deviceSn={}, flightId={}, messageID={}, msg={}, code={}", deviceSn, flight.getFlightId(), messageID, msg, code); // 判断是否为 [地面站]无人机起飞成功 if (msg != null && msg.contains("[地面站]无人机起飞成功")) { // 起飞成功,存到 device_flight_log handleFlightLog(deviceSn, msg, flight); // 更新状态为 FLYING log.info("【FlightEventCallback】检测到起飞成功,更新状态为FLYING: deviceSn={}, flightId={}", deviceSn, flight.getFlightId()); flightService.updateFlightStatus(flight.getFlightId(), "FLYING"); return; } // 检查 device_flight_log 是否有数据,判断是否已起飞 boolean hasTakenOff = flightService.hasFlightLog(flight.getFlightId()); if (hasTakenOff) { // 已起飞,所有消息存到 device_flight_log log.info("【FlightEventCallback】已起飞,存入飞行日志: deviceSn={}, flightId={}, msg={}", deviceSn, flight.getFlightId(), msg); handleFlightLog(deviceSn, msg, flight); // 检查是否任务完成 String dataContent = data.getString("data"); if ("操作成功".equals(msg) && "[地面站]任务飞行完成".equals(dataContent)) { log.info("【FlightEventCallback】检测到任务完成,更新状态为HOME: deviceSn={}, flightId={}", deviceSn, flight.getFlightId()); flightService.updateFlightStatus(flight.getFlightId(), "HOME"); } } else { // 未起飞,所有消息存到 device_pre_check_log log.info("【FlightEventCallback】未起飞,存入自检日志: deviceSn={}, flightId={}, msg={}, code={}", deviceSn, flight.getFlightId(), msg, code); handlePreCheckLog(deviceSn, msg, code, flight); // 检查是否自检失败(code=1 表示失败) if (code != null && (code == 1 || code == -1)) { log.info("【FlightEventCallback】检测到自检失败(code=1),更新状态为ERROR: deviceSn={}, flightId={}", deviceSn, flight.getFlightId()); flightService.updateFlightStatus(flight.getFlightId(), "ERROR"); } } } /** * 保存自检日志 * @param code 0=成功,1=失败 */ private void handlePreCheckLog(String deviceSn, String msg, Integer code, FlightEntity flight) { if (flight == null) { log.error("【FlightEventCallback】飞行记录为空,无法保存自检日志: deviceSn={}, msg={}", deviceSn, msg); return; } log.info("【FlightEventCallback】准备保存自检日志: deviceSn={}, flightId={}, msg={}, code={}", deviceSn, flight.getFlightId(), msg, code); try { // code=0 表示成功,code=1 表示失败 Boolean success = (code != null && code == 0); PreCheckLogEntity logEntity = new PreCheckLogEntity(); logEntity.setFlightId(flight.getFlightId()); logEntity.setLogContent(msg); logEntity.setSuccess(success); flightService.insertPreCheckLog(logEntity); log.info("【FlightEventCallback】成功保存自检日志: deviceSn={}, flightId={}, logId={}, msg={}, code={}, success={}", deviceSn, flight.getFlightId(), logEntity.getLogId(), msg, code, success); } catch (Exception e) { log.error("【FlightEventCallback】保存自检日志失败: deviceSn={}, flightId={}, msg={}, error={}", deviceSn, flight.getFlightId(), msg, e.getMessage(), e); } } /** * 保存飞行日志 */ private void handleFlightLog(String deviceSn, String message, FlightEntity flight) { if (flight == null) { log.error("【FlightEventCallback】飞行记录为空,无法保存飞行日志: deviceSn={}, message={}", deviceSn, message); return; } log.info("【FlightEventCallback】准备保存飞行日志: deviceSn={}, flightId={}, message={}", deviceSn, flight.getFlightId(), message); try { FlightLogEntity logEntity = new FlightLogEntity(); logEntity.setFlightId(flight.getFlightId()); logEntity.setLogContent(message); flightService.insertFlightLog(logEntity); log.info("【FlightEventCallback】成功保存飞行日志: deviceSn={}, flightId={}, logId={}, message={}", deviceSn, flight.getFlightId(), logEntity.getLogId(), message); } catch (Exception e) { log.error("【FlightEventCallback】保存飞行日志失败: deviceSn={}, flightId={}, message={}, error={}", deviceSn, flight.getFlightId(), message, e.getMessage(), e); } } }