From 5cd7f39d6ebce2cd35656ec43e25d65948c960e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AD=99=E5=B0=8F=E4=BA=91?= Date: Wed, 25 Feb 2026 13:06:56 +0800 Subject: [PATCH] =?UTF-8?q?websocket=E6=97=A5=E5=BF=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../IAirportFlyControlDataCallback.java | 5 + .../handler/TuohengMqttMessageHandler.java | 28 ++++ .../tuohengmqtt/model/DroneRealTimeData.java | 6 + .../ruoyi/device/mapper/FlightLogMapper.java | 40 +++++ .../com/ruoyi/device/mapper/FlightMapper.java | 73 ++++++++ .../device/mapper/PreCheckLogMapper.java | 49 ++++++ .../device/mapper/entity/FlightEntity.java | 92 ++++++++++ .../device/mapper/entity/FlightLogEntity.java | 64 +++++++ .../mapper/entity/PreCheckLogEntity.java | 78 +++++++++ .../ruoyi/device/service/FlightService.java | 96 +++++++++++ .../service/impl/FlightEventCallback.java | 109 ++++++++++++ .../service/impl/FlightLogCallback.java | 85 ++++++++++ .../service/impl/FlightServiceImpl.java | 158 ++++++++++++++++++ .../impl/FlightStateChangeListener.java | 78 +++++++++ .../device/service/impl/TuohengService.java | 5 + .../device/websocket/FlightLogWebSocket.java | 100 +++++++++++ .../websocket/PreCheckLogWebSocket.java | 101 +++++++++++ .../V6__Create_flight_log_tables.sql | 48 ++++++ ...V7__Add_success_field_to_pre_check_log.sql | 11 ++ .../mapper/device/FlightLogMapper.xml | 53 ++++++ .../resources/mapper/device/FlightMapper.xml | 95 +++++++++++ .../mapper/device/PreCheckLogMapper.xml | 64 +++++++ 22 files changed, 1438 insertions(+) create mode 100644 src/main/java/com/ruoyi/device/domain/impl/tuohengmqtt/callback/IAirportFlyControlDataCallback.java create mode 100644 src/main/java/com/ruoyi/device/mapper/FlightLogMapper.java create mode 100644 src/main/java/com/ruoyi/device/mapper/FlightMapper.java create mode 100644 src/main/java/com/ruoyi/device/mapper/PreCheckLogMapper.java create mode 100644 src/main/java/com/ruoyi/device/mapper/entity/FlightEntity.java create mode 100644 src/main/java/com/ruoyi/device/mapper/entity/FlightLogEntity.java create mode 100644 src/main/java/com/ruoyi/device/mapper/entity/PreCheckLogEntity.java create mode 100644 src/main/java/com/ruoyi/device/service/FlightService.java create mode 100644 src/main/java/com/ruoyi/device/service/impl/FlightEventCallback.java create mode 100644 src/main/java/com/ruoyi/device/service/impl/FlightLogCallback.java create mode 100644 src/main/java/com/ruoyi/device/service/impl/FlightServiceImpl.java create mode 100644 src/main/java/com/ruoyi/device/service/impl/FlightStateChangeListener.java create mode 100644 src/main/java/com/ruoyi/device/websocket/FlightLogWebSocket.java create mode 100644 src/main/java/com/ruoyi/device/websocket/PreCheckLogWebSocket.java create mode 100644 src/main/resources/db/migration/V6__Create_flight_log_tables.sql create mode 100644 src/main/resources/db/migration/V7__Add_success_field_to_pre_check_log.sql create mode 100644 src/main/resources/mapper/device/FlightLogMapper.xml create mode 100644 src/main/resources/mapper/device/FlightMapper.xml create mode 100644 src/main/resources/mapper/device/PreCheckLogMapper.xml diff --git a/src/main/java/com/ruoyi/device/domain/impl/tuohengmqtt/callback/IAirportFlyControlDataCallback.java b/src/main/java/com/ruoyi/device/domain/impl/tuohengmqtt/callback/IAirportFlyControlDataCallback.java new file mode 100644 index 0000000..e100c91 --- /dev/null +++ b/src/main/java/com/ruoyi/device/domain/impl/tuohengmqtt/callback/IAirportFlyControlDataCallback.java @@ -0,0 +1,5 @@ +package com.ruoyi.device.domain.impl.tuohengmqtt.callback; + +public interface IAirportFlyControlDataCallback { + void onAirportFlyControlData(String deviceSn, String payload, String topic); +} diff --git a/src/main/java/com/ruoyi/device/domain/impl/tuohengmqtt/handler/TuohengMqttMessageHandler.java b/src/main/java/com/ruoyi/device/domain/impl/tuohengmqtt/handler/TuohengMqttMessageHandler.java index a43c12d..1849ece 100644 --- a/src/main/java/com/ruoyi/device/domain/impl/tuohengmqtt/handler/TuohengMqttMessageHandler.java +++ b/src/main/java/com/ruoyi/device/domain/impl/tuohengmqtt/handler/TuohengMqttMessageHandler.java @@ -5,6 +5,7 @@ import com.ruoyi.device.domain.impl.machine.mqtt.MqttCallbackRegistry; import com.ruoyi.device.domain.impl.tuohengmqtt.callback.IDroneRealTimeCallback; import com.ruoyi.device.domain.impl.tuohengmqtt.callback.IHeartbeatMessageCallback; import com.ruoyi.device.domain.impl.tuohengmqtt.callback.IRealTimeBasicCallback; +import com.ruoyi.device.domain.impl.tuohengmqtt.callback.IAirportFlyControlDataCallback; import com.ruoyi.device.domain.impl.tuohengmqtt.callback.ITuohengEventsCallback; import com.ruoyi.device.domain.impl.tuohengmqtt.callback.ITuohengOsdCallback; import com.ruoyi.device.domain.impl.tuohengmqtt.callback.ITuohengRealTimeDataCallback; @@ -34,6 +35,7 @@ public class TuohengMqttMessageHandler { private final List realTimeBasicCallbacks = new ArrayList<>(); private final List droneRealTimeCallbacks = new ArrayList<>(); private final List heartbeatMessageCallbacks = new ArrayList<>(); + private final List airportFlyControlDataCallbacks = new ArrayList<>(); private static final Pattern TUOHENG_SN_PATTERN = Pattern.compile("^TH[0-9A-Z]+"); @@ -87,6 +89,13 @@ public class TuohengMqttMessageHandler { } } + public void registerAirportFlyControlDataCallback(IAirportFlyControlDataCallback callback) { + if (callback != null && !airportFlyControlDataCallbacks.contains(callback)) { + airportFlyControlDataCallbacks.add(callback); + log.info("注册机场飞行控制数据回调: {}", callback.getClass().getSimpleName()); + } + } + public void handleMessage(String topic, String payload) { try { log.debug("收到MQTT消息 - Topic: {}", topic); @@ -149,6 +158,9 @@ public class TuohengMqttMessageHandler { case "events": handleEventsData(deviceSn, payload); break; + case "control/data": + handleAirportFlyControlData(deviceSn, payload, topic); + break; default: log.debug("未知消息类型: {}", messageType); } @@ -254,6 +266,22 @@ public class TuohengMqttMessageHandler { } } + private void handleAirportFlyControlData(String deviceSn, String payload, String topic) { + try { + log.debug("处理机场飞行控制数据 - 设备SN: {}, Topic: {}", deviceSn, topic); + + for (com.ruoyi.device.domain.impl.tuohengmqtt.callback.IAirportFlyControlDataCallback callback : airportFlyControlDataCallbacks) { + try { + callback.onAirportFlyControlData(deviceSn, payload, topic); + } catch (Exception e) { + log.error("机场飞行控制数据回调执行失败: {}", e.getMessage(), e); + } + } + } catch (Exception e) { + log.error("处理机场飞行控制数据失败 - SN: {}, Error: {}", deviceSn, e.getMessage(), e); + } + } + private String extractDeviceSnFromTopic(String topic) { if (topic == null) { return null; diff --git a/src/main/java/com/ruoyi/device/domain/impl/tuohengmqtt/model/DroneRealTimeData.java b/src/main/java/com/ruoyi/device/domain/impl/tuohengmqtt/model/DroneRealTimeData.java index 8c4859a..d05e965 100644 --- a/src/main/java/com/ruoyi/device/domain/impl/tuohengmqtt/model/DroneRealTimeData.java +++ b/src/main/java/com/ruoyi/device/domain/impl/tuohengmqtt/model/DroneRealTimeData.java @@ -14,6 +14,9 @@ public class DroneRealTimeData { @JsonProperty("code") private Integer code; + @JsonProperty("messageID") + private String messageID; + @JsonProperty("data") private DroneInfo data; @@ -142,5 +145,8 @@ public class DroneRealTimeData { @JsonProperty("flowRate") private String flowRate; + + @JsonProperty("jiancha") + private String jiancha; } } diff --git a/src/main/java/com/ruoyi/device/mapper/FlightLogMapper.java b/src/main/java/com/ruoyi/device/mapper/FlightLogMapper.java new file mode 100644 index 0000000..f5c7819 --- /dev/null +++ b/src/main/java/com/ruoyi/device/mapper/FlightLogMapper.java @@ -0,0 +1,40 @@ +package com.ruoyi.device.mapper; + +import com.ruoyi.device.mapper.entity.FlightLogEntity; +import org.apache.ibatis.annotations.Mapper; + +import java.util.List; + +/** + * 飞行日志表Mapper接口 + * + * @author ruoyi + * @date 2026-02-25 + */ +@Mapper +public interface FlightLogMapper +{ + /** + * 根据日志主键查询飞行日志 + * + * @param logId 日志主键 + * @return 飞行日志信息 + */ + FlightLogEntity selectFlightLogByLogId(Long logId); + + /** + * 根据飞行ID查询飞行日志列表 + * + * @param flightId 飞行ID + * @return 飞行日志集合 + */ + List selectFlightLogListByFlightId(Long flightId); + + /** + * 新增飞行日志 + * + * @param flightLog 飞行日志信息 + * @return 影响行数 + */ + int insertFlightLog(FlightLogEntity flightLog); +} diff --git a/src/main/java/com/ruoyi/device/mapper/FlightMapper.java b/src/main/java/com/ruoyi/device/mapper/FlightMapper.java new file mode 100644 index 0000000..31d6e42 --- /dev/null +++ b/src/main/java/com/ruoyi/device/mapper/FlightMapper.java @@ -0,0 +1,73 @@ +package com.ruoyi.device.mapper; + +import com.ruoyi.device.mapper.entity.FlightEntity; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +/** + * 飞行表Mapper接口 + * + * @author ruoyi + * @date 2026-02-25 + */ +@Mapper +public interface FlightMapper +{ + /** + * 根据飞行主键查询飞行记录 + * + * @param flightId 飞行主键 + * @return 飞行信息 + */ + FlightEntity selectFlightByFlightId(Long flightId); + + /** + * 根据设备SN查询最新的飞行记录 + * + * @param deviceSn 设备SN号 + * @return 飞行信息 + */ + FlightEntity selectLatestFlightByDeviceSn(String deviceSn); + + /** + * 根据设备SN和状态查询飞行记录 + * + * @param deviceSn 设备SN号 + * @param status 状态 + * @return 飞行信息 + */ + FlightEntity selectFlightByDeviceSnAndStatus(@Param("deviceSn") String deviceSn, @Param("status") String status); + + /** + * 新增飞行记录 + * + * @param flight 飞行信息 + * @return 影响行数 + */ + int insertFlight(FlightEntity flight); + + /** + * 修改飞行记录 + * + * @param flight 飞行信息 + * @return 影响行数 + */ + int updateFlight(FlightEntity flight); + + /** + * 更新飞行状态 + * + * @param flightId 飞行主键 + * @param status 状态 + * @return 影响行数 + */ + int updateFlightStatus(@Param("flightId") Long flightId, @Param("status") String status); + + /** + * 更新返航时间 + * + * @param flightId 飞行主键 + * @return 影响行数 + */ + int updateReturnTime(Long flightId); +} diff --git a/src/main/java/com/ruoyi/device/mapper/PreCheckLogMapper.java b/src/main/java/com/ruoyi/device/mapper/PreCheckLogMapper.java new file mode 100644 index 0000000..3957b97 --- /dev/null +++ b/src/main/java/com/ruoyi/device/mapper/PreCheckLogMapper.java @@ -0,0 +1,49 @@ +package com.ruoyi.device.mapper; + +import com.ruoyi.device.mapper.entity.PreCheckLogEntity; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + * 自检日志表Mapper接口 + * + * @author ruoyi + * @date 2026-02-25 + */ +@Mapper +public interface PreCheckLogMapper +{ + /** + * 根据日志主键查询自检日志 + * + * @param logId 日志主键 + * @return 自检日志信息 + */ + PreCheckLogEntity selectPreCheckLogByLogId(Long logId); + + /** + * 根据飞行ID查询自检日志列表 + * + * @param flightId 飞行ID + * @return 自检日志集合 + */ + List selectPreCheckLogListByFlightId(Long flightId); + + /** + * 新增自检日志 + * + * @param preCheckLog 自检日志信息 + * @return 影响行数 + */ + int insertPreCheckLog(PreCheckLogEntity preCheckLog); + + /** + * 批量新增自检日志 + * + * @param preCheckLogList 自检日志集合 + * @return 影响行数 + */ + int insertPreCheckLogBatch(List preCheckLogList); +} diff --git a/src/main/java/com/ruoyi/device/mapper/entity/FlightEntity.java b/src/main/java/com/ruoyi/device/mapper/entity/FlightEntity.java new file mode 100644 index 0000000..249245c --- /dev/null +++ b/src/main/java/com/ruoyi/device/mapper/entity/FlightEntity.java @@ -0,0 +1,92 @@ +package com.ruoyi.device.mapper.entity; + +import com.ruoyi.common.core.web.domain.BaseEntity; + +/** + * 飞行表实体对象 device_flight + * Mapper 层实体,对应数据库表 + * + * @author ruoyi + * @date 2026-02-25 + */ +public class FlightEntity extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 飞行主键 */ + private Long flightId; + + /** 无人机SN */ + private String deviceSn; + + /** 外部飞行ID (来自MQTT的taskId) */ + private String flightIdExternal; + + /** 状态:自检中、飞行中、已返航 */ + private String status; + + /** 返航时间 */ + private java.util.Date returnTime; + + public Long getFlightId() + { + return flightId; + } + + public void setFlightId(Long flightId) + { + this.flightId = flightId; + } + + public String getDeviceSn() + { + return deviceSn; + } + + public void setDeviceSn(String deviceSn) + { + this.deviceSn = deviceSn; + } + + public String getFlightIdExternal() + { + return flightIdExternal; + } + + public void setFlightIdExternal(String flightIdExternal) + { + this.flightIdExternal = flightIdExternal; + } + + public String getStatus() + { + return status; + } + + public void setStatus(String status) + { + this.status = status; + } + + public java.util.Date getReturnTime() + { + return returnTime; + } + + public void setReturnTime(java.util.Date returnTime) + { + this.returnTime = returnTime; + } + + @Override + public String toString() + { + return "FlightEntity{" + + "flightId=" + flightId + + ", deviceSn='" + deviceSn + '\'' + + ", flightIdExternal='" + flightIdExternal + '\'' + + ", status='" + status + '\'' + + ", returnTime=" + returnTime + + '}'; + } +} diff --git a/src/main/java/com/ruoyi/device/mapper/entity/FlightLogEntity.java b/src/main/java/com/ruoyi/device/mapper/entity/FlightLogEntity.java new file mode 100644 index 0000000..891094b --- /dev/null +++ b/src/main/java/com/ruoyi/device/mapper/entity/FlightLogEntity.java @@ -0,0 +1,64 @@ +package com.ruoyi.device.mapper.entity; + +import com.ruoyi.common.core.web.domain.BaseEntity; + +/** + * 飞行日志表实体对象 device_flight_log + * Mapper 层实体,对应数据库表 + * + * @author ruoyi + * @date 2026-02-25 + */ +public class FlightLogEntity extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 飞行日志主键 */ + private Long logId; + + /** 关联飞行表ID */ + private Long flightId; + + /** 日志内容 */ + private String logContent; + + public Long getLogId() + { + return logId; + } + + public void setLogId(Long logId) + { + this.logId = logId; + } + + public Long getFlightId() + { + return flightId; + } + + public void setFlightId(Long flightId) + { + this.flightId = flightId; + } + + public String getLogContent() + { + return logContent; + } + + public void setLogContent(String logContent) + { + this.logContent = logContent; + } + + @Override + public String toString() + { + return "FlightLogEntity{" + + "logId=" + logId + + ", flightId=" + flightId + + ", logContent='" + logContent + '\'' + + '}'; + } +} diff --git a/src/main/java/com/ruoyi/device/mapper/entity/PreCheckLogEntity.java b/src/main/java/com/ruoyi/device/mapper/entity/PreCheckLogEntity.java new file mode 100644 index 0000000..d0c4620 --- /dev/null +++ b/src/main/java/com/ruoyi/device/mapper/entity/PreCheckLogEntity.java @@ -0,0 +1,78 @@ +package com.ruoyi.device.mapper.entity; + +import com.ruoyi.common.core.web.domain.BaseEntity; + +/** + * 自检日志表实体对象 device_pre_check_log + * Mapper 层实体,对应数据库表 + * + * @author ruoyi + * @date 2026-02-25 + */ +public class PreCheckLogEntity extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 自检日志主键 */ + private Long logId; + + /** 关联飞行表ID */ + private Long flightId; + + /** 日志内容 (JSON字符串) */ + private String logContent; + + /** 是否成功 (true=成功, false=失败) */ + private Boolean success; + + public Long getLogId() + { + return logId; + } + + public void setLogId(Long logId) + { + this.logId = logId; + } + + public Long getFlightId() + { + return flightId; + } + + public void setFlightId(Long flightId) + { + this.flightId = flightId; + } + + public String getLogContent() + { + return logContent; + } + + public void setLogContent(String logContent) + { + this.logContent = logContent; + } + + public Boolean getSuccess() + { + return success; + } + + public void setSuccess(Boolean success) + { + this.success = success; + } + + @Override + public String toString() + { + return "PreCheckLogEntity{" + + "logId=" + logId + + ", flightId=" + flightId + + ", logContent='" + logContent + '\'' + + ", success=" + success + + '}'; + } +} diff --git a/src/main/java/com/ruoyi/device/service/FlightService.java b/src/main/java/com/ruoyi/device/service/FlightService.java new file mode 100644 index 0000000..ea93bf0 --- /dev/null +++ b/src/main/java/com/ruoyi/device/service/FlightService.java @@ -0,0 +1,96 @@ +package com.ruoyi.device.service; + +import com.ruoyi.device.mapper.entity.FlightEntity; + +import java.util.Map; + +/** + * 飞行服务接口 + * + * @author ruoyi + * @date 2026-02-25 + */ +public interface FlightService +{ + /** + * 获取或创建当前正在进行的飞行记录 + * 用于MQTT回调,如果最新记录已返航则创建新记录 + * + * @param deviceSn 设备SN号 + * @return 飞行记录 + */ + FlightEntity getOrCreateCurrentFlight(String deviceSn); + + /** + * 获取或创建飞行记录(通过messageID匹配) + * 如果存在相同messageID的飞行记录,返回该记录 + * 如果不存在或messageID不同,创建新记录 + * + * @param deviceSn 设备SN号 + * @param messageId 消息ID(对应flightIdExternal) + * @return 飞行记录 + */ + FlightEntity getOrCreateFlightByMessageId(String deviceSn, String messageId); + + /** + * 获取最新的飞行记录(包括已返航的) + * 用于WebSocket推送 + * + * @param deviceSn 设备SN号 + * @return 飞行记录 + */ + FlightEntity getLatestFlight(String deviceSn); + + /** + * 创建新的飞行记录 + * + * @param deviceSn 设备SN号 + * @return 飞行记录 + */ + FlightEntity createFlight(String deviceSn); + + /** + * 更新飞行ID(外部ID) + * + * @param flightId 飞行ID + * @param flightIdExternal 外部飞行ID + */ + void updateFlightIdExternal(Long flightId, String flightIdExternal); + + /** + * 更新飞行状态 + * + * @param flightId 飞行ID + * @param status 状态:自检中、飞行中、已返航 + */ + void updateFlightStatus(Long flightId, String status); + + /** + * 更新返航时间 + * + * @param flightId 飞行ID + */ + void updateReturnTime(Long flightId); + + /** + * 获取飞行记录和日志(用于WebSocket推送) + * + * @param deviceSn 设备SN号 + * @return 飞行记录和日志 + */ + Map getLatestFlightWithLogs(String deviceSn); + + /** + * 保存自检日志 + * + * @param logEntity 自检日志实体 + */ + void insertPreCheckLog(com.ruoyi.device.mapper.entity.PreCheckLogEntity logEntity); + + /** + * 保存飞行日志 + * + * @param logEntity 飞行日志实体 + */ + void insertFlightLog(com.ruoyi.device.mapper.entity.FlightLogEntity logEntity); +} diff --git a/src/main/java/com/ruoyi/device/service/impl/FlightEventCallback.java b/src/main/java/com/ruoyi/device/service/impl/FlightEventCallback.java new file mode 100644 index 0000000..9de4d70 --- /dev/null +++ b/src/main/java/com/ruoyi/device/service/impl/FlightEventCallback.java @@ -0,0 +1,109 @@ +package com.ruoyi.device.service.impl; + +import com.alibaba.fastjson2.JSONObject; +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.service.FlightService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +/** + * 飞行事件回调处理器 + * 处理飞行事件日志(如起飞、返航等) + * + * @author ruoyi + * @date 2026-02-25 + */ +@Slf4j +@Component +public class FlightEventCallback implements IAirportFlyControlDataCallback { + + @Autowired + private FlightService flightService; + + @Override + public void onAirportFlyControlData(String deviceSn, String payload, String topic) { + try { + JSONObject data = JSONObject.parseObject(payload); + if (data == null) { + return; + } + + String msg = data.getString("msg"); + String messageID = data.getString("messageID"); + + String action = data.getString("action"); + if (action == null || action.isEmpty()) { + JSONObject dataObj = data.getJSONObject("data"); + if (dataObj != null) { + action = dataObj.getString("action"); + } + } + + FlightEntity flight; + if (messageID != null && !messageID.isEmpty()) { + flight = handleFlightIdExternal(deviceSn, messageID); + } else { + flight = flightService.getOrCreateCurrentFlight(deviceSn); + } + + if (msg != null && !msg.isEmpty()) { + handleFlightLog(deviceSn, msg, flight); + handleFlightStatus(deviceSn, action, data, flight); + } + } catch (Exception e) { + log.error("处理飞行事件失败: deviceSn={}, topic={}, error={}", deviceSn, topic, e.getMessage(), e); + } + } + + private FlightEntity handleFlightIdExternal(String deviceSn, String messageId) { + if (messageId != null && !messageId.isEmpty()) { + return flightService.getOrCreateFlightByMessageId(deviceSn, messageId); + } else { + return flightService.getOrCreateCurrentFlight(deviceSn); + } + } + + private void handleFlightLog(String deviceSn, String message, FlightEntity flight) { + if (flight == null) { + log.warn("飞行记录为空,无法保存飞行日志: deviceSn={}, message={}", deviceSn, message); + return; + } + try { + FlightLogEntity logEntity = new FlightLogEntity(); + logEntity.setFlightId(flight.getFlightId()); + logEntity.setLogContent(message); + flightService.insertFlightLog(logEntity); + log.info("保存飞行日志: deviceSn={}, flightId={}, message={}", + deviceSn, flight.getFlightId(), message); + } catch (Exception e) { + log.error("保存飞行日志失败: deviceSn={}, message={}, error={}", + deviceSn, message, e.getMessage(), e); + } + } + + private void handleFlightStatus(String deviceSn, String action, JSONObject data, FlightEntity flight) { + if (flight == null) { + log.warn("飞行记录为空,无法更新状态: deviceSn={}, action={}", deviceSn, action); + return; + } + try { + String msg = data.getString("msg"); + String dataContent = data.getString("data"); + + if ((msg != null && msg.contains("起飞成功")) || (dataContent != null && dataContent.contains("起飞成功"))) { + flightService.updateFlightStatus(flight.getFlightId(), "飞行中"); + log.info("飞行状态更新: deviceSn={}, status=飞行中", deviceSn); + } else if ((msg != null && msg.contains("返航成功")) || (dataContent != null && dataContent.contains("返航成功")) || + (dataContent != null && dataContent.contains("任务飞行完成"))) { + flightService.updateFlightStatus(flight.getFlightId(), "已返航"); + log.info("飞行状态更新: deviceSn={}, status=已返航", deviceSn); + } + } catch (Exception e) { + log.error("更新飞行状态失败: deviceSn={}, action={}, error={}", + deviceSn, action, e.getMessage(), e); + } + } +} diff --git a/src/main/java/com/ruoyi/device/service/impl/FlightLogCallback.java b/src/main/java/com/ruoyi/device/service/impl/FlightLogCallback.java new file mode 100644 index 0000000..f054da3 --- /dev/null +++ b/src/main/java/com/ruoyi/device/service/impl/FlightLogCallback.java @@ -0,0 +1,85 @@ +package com.ruoyi.device.service.impl; + +import com.alibaba.fastjson2.JSON; +import com.alibaba.fastjson2.JSONArray; +import com.alibaba.fastjson2.JSONObject; +import com.ruoyi.device.domain.impl.tuohengmqtt.callback.IDroneRealTimeCallback; +import com.ruoyi.device.domain.impl.tuohengmqtt.model.DroneRealTimeData; +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.List; + +/** + * 飞行日志回调处理器 + * 处理自检日志和飞行事件日志 + * + * @author ruoyi + * @date 2026-02-25 + */ +@Slf4j +@Component +public class FlightLogCallback implements IDroneRealTimeCallback { + + @Autowired + private FlightService flightService; + + @Override + public void onDroneRealTimeData(String deviceSn, DroneRealTimeData data) { + if (data == null || data.getData() == null) { + return; + } + + DroneRealTimeData.DroneInfo droneInfo = data.getData(); + + try { + if (droneInfo.getJiancha() != null && !droneInfo.getJiancha().isEmpty()) { + handlePreCheckLog(deviceSn, data.getMessageID(), droneInfo.getJiancha()); + } + } catch (Exception e) { + log.error("处理自检日志失败: deviceSn={}, error={}", deviceSn, e.getMessage(), e); + } + } + + private void handlePreCheckLog(String deviceSn, String messageID, String jianchaJson) { + try { + FlightEntity flight; + + if (messageID != null && !messageID.isEmpty()) { + flight = flightService.getOrCreateFlightByMessageId(deviceSn, messageID); + } else { + flight = flightService.getOrCreateCurrentFlight(deviceSn); + } + + JSONArray checkItems = JSON.parseArray(jianchaJson); + if (checkItems != null && !checkItems.isEmpty()) { + for (int i = 0; i < checkItems.size(); i++) { + JSONObject item = checkItems.getJSONObject(i); + PreCheckLogEntity logEntity = new PreCheckLogEntity(); + logEntity.setFlightId(flight.getFlightId()); + + String check = item.getString("check"); + String value = item.getString("value"); + Boolean result = item.getBoolean("result"); + + String statusText = result != null && result ? "自检成功" : "自检失败"; + String logContent = check + " " + value + " " + statusText; + + logEntity.setLogContent(logContent); + logEntity.setSuccess(result != null ? result : false); + flightService.insertPreCheckLog(logEntity); + } + log.info("保存自检日志: deviceSn={}, flightId={}, 检查项数量={}", + deviceSn, flight.getFlightId(), checkItems.size()); + } + } catch (Exception e) { + log.error("保存自检日志失败: deviceSn={}, jiancha={}, error={}", + deviceSn, jianchaJson, e.getMessage(), e); + } + } +} diff --git a/src/main/java/com/ruoyi/device/service/impl/FlightServiceImpl.java b/src/main/java/com/ruoyi/device/service/impl/FlightServiceImpl.java new file mode 100644 index 0000000..00cfe4c --- /dev/null +++ b/src/main/java/com/ruoyi/device/service/impl/FlightServiceImpl.java @@ -0,0 +1,158 @@ +package com.ruoyi.device.service.impl; + +import com.ruoyi.device.mapper.FlightLogMapper; +import com.ruoyi.device.mapper.FlightMapper; +import com.ruoyi.device.mapper.PreCheckLogMapper; +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.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * 飞行服务实现类 + * + * @author ruoyi + * @date 2026-02-25 + */ +@Slf4j +@Service +public class FlightServiceImpl implements FlightService +{ + @Autowired + private FlightMapper flightMapper; + + @Autowired + private PreCheckLogMapper preCheckLogMapper; + + @Autowired + private FlightLogMapper flightLogMapper; + + @Override + public FlightEntity getOrCreateCurrentFlight(String deviceSn) { + FlightEntity flight = flightMapper.selectLatestFlightByDeviceSn(deviceSn); + + if (flight == null || "已返航".equals(flight.getStatus())) { + flight = createFlight(deviceSn); + } + + return flight; + } + + @Override + @Transactional(rollbackFor = Exception.class) + public FlightEntity getOrCreateFlightByMessageId(String deviceSn, String messageId) { + FlightEntity flight = flightMapper.selectLatestFlightByDeviceSn(deviceSn); + + if (flight == null) { + flight = createFlight(deviceSn); + if (messageId != null && !messageId.isEmpty()) { + updateFlightIdExternal(flight.getFlightId(), messageId); + } + return flight; + } + + String existingFlightIdExternal = flight.getFlightIdExternal(); + if (existingFlightIdExternal == null || existingFlightIdExternal.isEmpty()) { + if (messageId != null && !messageId.isEmpty()) { + updateFlightIdExternal(flight.getFlightId(), messageId); + } + return flight; + } + + if (existingFlightIdExternal.equals(messageId)) { + return flight; + } + + flight = createFlight(deviceSn); + if (messageId != null && !messageId.isEmpty()) { + updateFlightIdExternal(flight.getFlightId(), messageId); + } + log.info("messageId不同,创建新飞行 - deviceSn={}, flightId={}, oldMessageId={}, newMessageId={}", + deviceSn, flight.getFlightId(), existingFlightIdExternal, messageId); + return flight; + } + + @Override + public FlightEntity getLatestFlight(String deviceSn) { + return flightMapper.selectLatestFlightByDeviceSn(deviceSn); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public FlightEntity createFlight(String deviceSn) { + FlightEntity flight = new FlightEntity(); + flight.setDeviceSn(deviceSn); + flight.setStatus("自检中"); + flightMapper.insertFlight(flight); + log.info("创建新的飞行记录: deviceSn={}, flightId={}", deviceSn, flight.getFlightId()); + return flight; + } + + @Override + public void updateFlightIdExternal(Long flightId, String flightIdExternal) { + FlightEntity flight = new FlightEntity(); + flight.setFlightId(flightId); + flight.setFlightIdExternal(flightIdExternal); + flightMapper.updateFlight(flight); + log.info("更新飞行ID: flightId={}, flightIdExternal={}", flightId, flightIdExternal); + } + + @Override + public void updateFlightStatus(Long flightId, String status) { + flightMapper.updateFlightStatus(flightId, status); + log.info("更新飞行状态: flightId={}, status={}", flightId, status); + + if ("已返航".equals(status)) { + flightMapper.updateReturnTime(flightId); + log.info("更新返航时间: flightId={}", flightId); + } + } + + @Override + public void updateReturnTime(Long flightId) { + flightMapper.updateReturnTime(flightId); + } + + @Override + public Map getLatestFlightWithLogs(String deviceSn) { + FlightEntity flight = flightMapper.selectLatestFlightByDeviceSn(deviceSn); + if (flight == null) { + return null; + } + + Map result = new HashMap<>(); + result.put("flightId", flight.getFlightId()); + result.put("deviceSn", flight.getDeviceSn()); + result.put("flightIdExternal", flight.getFlightIdExternal()); + result.put("status", flight.getStatus()); + result.put("returnTime", flight.getReturnTime()); + result.put("createTime", flight.getCreateTime()); + + List preCheckLogs = preCheckLogMapper.selectPreCheckLogListByFlightId(flight.getFlightId()); + result.put("preCheckLogs", preCheckLogs); + + List flightLogs = flightLogMapper.selectFlightLogListByFlightId(flight.getFlightId()); + result.put("flightLogs", flightLogs); + + return result; + } + + @Override + public void insertPreCheckLog(PreCheckLogEntity logEntity) { + preCheckLogMapper.insertPreCheckLog(logEntity); + } + + @Override + public void insertFlightLog(FlightLogEntity logEntity) { + flightLogMapper.insertFlightLog(logEntity); + } +} diff --git a/src/main/java/com/ruoyi/device/service/impl/FlightStateChangeListener.java b/src/main/java/com/ruoyi/device/service/impl/FlightStateChangeListener.java new file mode 100644 index 0000000..8ac1f0c --- /dev/null +++ b/src/main/java/com/ruoyi/device/service/impl/FlightStateChangeListener.java @@ -0,0 +1,78 @@ +package com.ruoyi.device.service.impl; + +import com.ruoyi.device.domain.impl.machine.state.DroneState; +import com.ruoyi.device.domain.impl.machine.state.MachineStates; +import com.ruoyi.device.domain.impl.machine.statemachine.StateChangeListener; +import com.ruoyi.device.mapper.entity.FlightEntity; +import com.ruoyi.device.service.FlightService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.context.event.ApplicationReadyEvent; +import org.springframework.context.event.EventListener; +import org.springframework.stereotype.Component; + +/** + * 飞行状态变化监听器 + * 监听状态机的状态变化,更新飞行表中的状态 + * + * @author ruoyi + * @date 2026-02-25 + */ +@Slf4j +@Component +public class FlightStateChangeListener implements StateChangeListener { + + @Autowired + private FlightService flightService; + + @Autowired + private com.ruoyi.device.domain.impl.machine.statemachine.MachineStateManager stateManager; + + @EventListener(ApplicationReadyEvent.class) + public void onApplicationReady() { + stateManager.registerStateChangeListener("flight-state-changer", this); + log.info("飞行状态变化监听器已注册"); + } + + @Override + public void onStateChange(String sn, MachineStates newStates) { + try { + DroneState droneState = newStates.getDroneState(); + if (droneState == DroneState.UNKNOWN) { + return; + } + + FlightEntity flight = flightService.getOrCreateCurrentFlight(sn); + if (flight == null) { + return; + } + + String currentStatus = flight.getStatus(); + String newStatus = mapDroneStateToFlightStatus(droneState); + + if (!currentStatus.equals(newStatus)) { + flightService.updateFlightStatus(flight.getFlightId(), newStatus); + log.info("状态变化更新飞行状态: sn={}, droneState={}, flightStatus={}", + sn, droneState, newStatus); + } + } catch (Exception e) { + log.error("状态变化监听器处理失败: sn={}, error={}", sn, e.getMessage(), e); + } + } + + private String mapDroneStateToFlightStatus(DroneState droneState) { + switch (droneState) { + case ONLINE: + return "自检中"; + case FLYING: + return "飞行中"; + case ARRIVED: + return "已返航"; + case RETURNING: + return "已返航"; + case UNKNOWN: + default: + return "自检中"; + } + } +} diff --git a/src/main/java/com/ruoyi/device/service/impl/TuohengService.java b/src/main/java/com/ruoyi/device/service/impl/TuohengService.java index 811da82..802c9c5 100644 --- a/src/main/java/com/ruoyi/device/service/impl/TuohengService.java +++ b/src/main/java/com/ruoyi/device/service/impl/TuohengService.java @@ -12,6 +12,7 @@ import com.ruoyi.device.domain.impl.machine.state.AirportState; import com.ruoyi.device.domain.impl.machine.state.MachineStates; import com.ruoyi.device.domain.impl.machine.statemachine.MachineStateManager; import com.ruoyi.device.domain.impl.tuohengmqtt.callback.IRealTimeBasicCallback; +import com.ruoyi.device.domain.impl.tuohengmqtt.callback.IAirportFlyControlDataCallback; import com.ruoyi.device.domain.impl.tuohengmqtt.callback.ITuohengEventsCallback; import com.ruoyi.device.domain.impl.tuohengmqtt.callback.ITuohengOsdCallback; import com.ruoyi.device.domain.impl.tuohengmqtt.callback.ITuohengRealTimeDataCallback; @@ -183,6 +184,10 @@ public class TuohengService { } }); + handler.registerDroneRealTimeCallback(new FlightLogCallback()); + + handler.registerAirportFlyControlDataCallback(new FlightEventCallback()); + log.info("TuohengService 初始化完成,已注册所有回调"); } diff --git a/src/main/java/com/ruoyi/device/websocket/FlightLogWebSocket.java b/src/main/java/com/ruoyi/device/websocket/FlightLogWebSocket.java new file mode 100644 index 0000000..2b2652c --- /dev/null +++ b/src/main/java/com/ruoyi/device/websocket/FlightLogWebSocket.java @@ -0,0 +1,100 @@ +package com.ruoyi.device.websocket; + +import com.alibaba.fastjson2.JSON; +import com.ruoyi.device.mapper.entity.FlightLogEntity; +import com.ruoyi.device.service.FlightService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; + +import jakarta.websocket.*; +import jakarta.websocket.server.PathParam; +import jakarta.websocket.server.ServerEndpoint; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CopyOnWriteArraySet; + +/** + * 飞行日志WebSocket + * + * @author ruoyi + * @date 2026-02-25 + */ +@Slf4j +@Component +@ServerEndpoint("/websocket/flightLog/{deviceSn}") +public class FlightLogWebSocket { + + private Session session; + + private String deviceSn; + + private static final CopyOnWriteArraySet sessions = new CopyOnWriteArraySet<>(); + + private static final Map sessionMap = new ConcurrentHashMap<>(); + + @Autowired + private FlightService flightService; + + @OnOpen + public void onOpen(Session session, @PathParam("deviceSn") String deviceSn) { + this.session = session; + this.deviceSn = deviceSn; + sessions.add(this); + sessionMap.put(session.getId(), this); + log.info("飞行日志WebSocket连接建立: sessionId={}, deviceSn={}", session.getId(), deviceSn); + } + + @OnClose + public void onClose() { + sessions.remove(this); + if (session != null) { + sessionMap.remove(session.getId()); + log.info("飞行日志WebSocket连接关闭: sessionId={}, deviceSn={}", session.getId(), deviceSn); + } else { + log.info("飞行日志WebSocket连接关闭: session为null"); + } + } + + @OnMessage + public void onMessage(String message) { + log.info("收到飞行日志WebSocket消息: sessionId={}, message={}", session.getId(), message); + } + + @OnError + public void onError(Session session, Throwable error) { + log.error("飞行日志WebSocket错误: sessionId={}, deviceSn={}, error={}", + session.getId(), deviceSn, error.getMessage(), error); + } + + private void sendMessage(String message) { + try { + if (session != null && session.isOpen()) { + session.getBasicRemote().sendText(message); + } + } catch (Exception e) { + log.error("发送飞行日志WebSocket消息失败: deviceSn={}, error={}", deviceSn, e.getMessage(), e); + } + } + + @Scheduled(fixedRate = 3000) + public void broadcast() { + for (FlightLogWebSocket ws : sessions) { + Map flightData = flightService.getLatestFlightWithLogs(ws.deviceSn); + if (flightData == null) { + continue; + } + + String status = (String) flightData.get("status"); + List logs = (List) flightData.get("flightLogs"); + + Map response = new ConcurrentHashMap<>(); + response.put("status", status); + response.put("logs", logs); + + ws.sendMessage(JSON.toJSONString(response)); + } + } +} diff --git a/src/main/java/com/ruoyi/device/websocket/PreCheckLogWebSocket.java b/src/main/java/com/ruoyi/device/websocket/PreCheckLogWebSocket.java new file mode 100644 index 0000000..2c4ed25 --- /dev/null +++ b/src/main/java/com/ruoyi/device/websocket/PreCheckLogWebSocket.java @@ -0,0 +1,101 @@ +package com.ruoyi.device.websocket; + +import com.alibaba.fastjson2.JSON; +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.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; + +import jakarta.websocket.*; +import jakarta.websocket.server.PathParam; +import jakarta.websocket.server.ServerEndpoint; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CopyOnWriteArraySet; + +/** + * 自检日志WebSocket + * + * @author ruoyi + * @date 2026-02-25 + */ +@Slf4j +@Component +@ServerEndpoint("/websocket/preCheckLog/{deviceSn}") +public class PreCheckLogWebSocket { + + private Session session; + + private String deviceSn; + + private static final CopyOnWriteArraySet sessions = new CopyOnWriteArraySet<>(); + + private static final Map sessionMap = new ConcurrentHashMap<>(); + + @Autowired + private FlightService flightService; + + @OnOpen + public void onOpen(Session session, @PathParam("deviceSn") String deviceSn) { + this.session = session; + this.deviceSn = deviceSn; + sessions.add(this); + sessionMap.put(session.getId(), this); + log.info("自检日志WebSocket连接建立: sessionId={}, deviceSn={}", session.getId(), deviceSn); + } + + @OnClose + public void onClose() { + sessions.remove(this); + if (session != null) { + sessionMap.remove(session.getId()); + log.info("自检日志WebSocket连接关闭: sessionId={}, deviceSn={}", session.getId(), deviceSn); + } else { + log.info("自检日志WebSocket连接关闭: session为null"); + } + } + + @OnMessage + public void onMessage(String message) { + log.info("收到自检日志WebSocket消息: sessionId={}, message={}", session.getId(), message); + } + + @OnError + public void onError(Session session, Throwable error) { + log.error("自检日志WebSocket错误: sessionId={}, deviceSn={}, error={}", + session.getId(), deviceSn, error.getMessage(), error); + } + + private void sendMessage(String message) { + try { + if (session != null && session.isOpen()) { + session.getBasicRemote().sendText(message); + } + } catch (Exception e) { + log.error("发送自检日志WebSocket消息失败: deviceSn={}, error={}", deviceSn, e.getMessage(), e); + } + } + + @Scheduled(fixedRate = 3000) + public void broadcast() { + for (PreCheckLogWebSocket ws : sessions) { + Map flightData = flightService.getLatestFlightWithLogs(ws.deviceSn); + if (flightData == null) { + continue; + } + + String status = (String) flightData.get("status"); + List logs = (List) flightData.get("preCheckLogs"); + + Map response = new ConcurrentHashMap<>(); + response.put("status", status); + response.put("logs", logs); + + ws.sendMessage(JSON.toJSONString(response)); + } + } +} diff --git a/src/main/resources/db/migration/V6__Create_flight_log_tables.sql b/src/main/resources/db/migration/V6__Create_flight_log_tables.sql new file mode 100644 index 0000000..1afe1b0 --- /dev/null +++ b/src/main/resources/db/migration/V6__Create_flight_log_tables.sql @@ -0,0 +1,48 @@ +-- ============================================================ +-- Flyway Migration Script +-- Version: V3 +-- Description: Create flight log tables (flight, pre_check_log, flight_log) +-- Author: ruoyi +-- Date: 2026-02-25 +-- ============================================================ + +-- 创建飞行表 +CREATE TABLE IF NOT EXISTS device_flight ( + flight_id BIGINT NOT NULL AUTO_INCREMENT COMMENT '飞行主键', + device_sn VARCHAR(100) NOT NULL COMMENT '无人机SN', + flight_id_external VARCHAR(100) COMMENT '外部飞行ID (来自MQTT的taskId)', + status VARCHAR(20) COMMENT '状态:自检中、飞行中、已返航', + create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + return_time DATETIME COMMENT '返航时间', + create_by VARCHAR(64) COMMENT '创建者', + update_by VARCHAR(64) COMMENT '更新者', + update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + remark VARCHAR(500) COMMENT '备注', + PRIMARY KEY (flight_id), + KEY idx_flight_device_sn (device_sn), + KEY idx_flight_id_external (flight_id_external), + KEY idx_flight_status (status), + KEY idx_flight_create_time (create_time) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='飞行表'; + +-- 创建自检日志表 +CREATE TABLE IF NOT EXISTS device_pre_check_log ( + log_id BIGINT NOT NULL AUTO_INCREMENT COMMENT '自检日志主键', + flight_id BIGINT NOT NULL COMMENT '关联飞行表ID', + log_content TEXT COMMENT '日志内容 (JSON字符串)', + create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + PRIMARY KEY (log_id), + KEY idx_pre_check_flight_id (flight_id), + KEY idx_pre_check_create_time (create_time) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='自检日志表'; + +-- 创建飞行日志表 +CREATE TABLE IF NOT EXISTS device_flight_log ( + log_id BIGINT NOT NULL AUTO_INCREMENT COMMENT '飞行日志主键', + flight_id BIGINT NOT NULL COMMENT '关联飞行表ID', + log_content TEXT COMMENT '日志内容', + create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + PRIMARY KEY (log_id), + KEY idx_flight_log_flight_id (flight_id), + KEY idx_flight_log_create_time (create_time) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='飞行日志表'; diff --git a/src/main/resources/db/migration/V7__Add_success_field_to_pre_check_log.sql b/src/main/resources/db/migration/V7__Add_success_field_to_pre_check_log.sql new file mode 100644 index 0000000..3e8469e --- /dev/null +++ b/src/main/resources/db/migration/V7__Add_success_field_to_pre_check_log.sql @@ -0,0 +1,11 @@ +-- ============================================================ +-- Flyway Migration Script +-- Version: V6 +-- Description: Add success field to device_pre_check_log table +-- Author: ruoyi +-- Date: 2026-02-25 +-- ============================================================ + +ALTER TABLE device_pre_check_log +ADD COLUMN success TINYINT(1) DEFAULT 0 COMMENT '是否成功 (1=成功, 0=失败)' +AFTER log_content; diff --git a/src/main/resources/mapper/device/FlightLogMapper.xml b/src/main/resources/mapper/device/FlightLogMapper.xml new file mode 100644 index 0000000..efa3801 --- /dev/null +++ b/src/main/resources/mapper/device/FlightLogMapper.xml @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + + select log_id, flight_id, log_content, + create_by, create_time, update_by, update_time, remark + from device_flight_log + + + + + + + + insert into device_flight_log + + flight_id, + log_content, + create_by, + remark, + create_time + + + #{flightId}, + #{logContent}, + #{createBy}, + #{remark}, + now() + + + + diff --git a/src/main/resources/mapper/device/FlightMapper.xml b/src/main/resources/mapper/device/FlightMapper.xml new file mode 100644 index 0000000..8e551b3 --- /dev/null +++ b/src/main/resources/mapper/device/FlightMapper.xml @@ -0,0 +1,95 @@ + + + + + + + + + + + + + + + + + + + select flight_id, device_sn, flight_id_external, status, return_time, + create_by, create_time, update_by, update_time, remark + from device_flight + + + + + + + + + + insert into device_flight + + device_sn, + flight_id_external, + status, + return_time, + create_by, + remark, + create_time + + + #{deviceSn}, + #{flightIdExternal}, + #{status}, + #{returnTime}, + #{createBy}, + #{remark}, + now() + + + + + update device_flight + + flight_id_external = #{flightIdExternal}, + status = #{status}, + return_time = #{returnTime}, + update_by = #{updateBy}, + remark = #{remark}, + update_time = now() + + where flight_id = #{flightId} + + + + update device_flight + set status = #{status}, + update_time = now() + where flight_id = #{flightId} + + + + update device_flight + set return_time = now(), + update_time = now() + where flight_id = #{flightId} + + + diff --git a/src/main/resources/mapper/device/PreCheckLogMapper.xml b/src/main/resources/mapper/device/PreCheckLogMapper.xml new file mode 100644 index 0000000..3b5af82 --- /dev/null +++ b/src/main/resources/mapper/device/PreCheckLogMapper.xml @@ -0,0 +1,64 @@ + + + + + + + + + + + + + + + + + + select log_id, flight_id, log_content, success, + create_by, create_time, update_by, update_time, remark + from device_pre_check_log + + + + + + + + insert into device_pre_check_log + + flight_id, + log_content, + success, + create_by, + remark, + create_time + + + #{flightId}, + #{logContent}, + #{success}, + #{createBy}, + #{remark}, + now() + + + + + insert into device_pre_check_log (flight_id, log_content, success, create_time) + values + + (#{item.flightId}, #{item.logContent}, #{item.success}, now()) + + + +