diff --git a/pom.xml b/pom.xml
index ea47435..f22b25b 100644
--- a/pom.xml
+++ b/pom.xml
@@ -105,6 +105,19 @@
provided
+
+
+ org.springframework.integration
+ spring-integration-mqtt
+
+
+
+
+ org.eclipse.paho
+ org.eclipse.paho.mqttv5.client
+ 1.2.5
+
+
diff --git a/src/main/java/com/ruoyi/device/domain/impl/djimqtt/README.md b/src/main/java/com/ruoyi/device/domain/impl/djimqtt/README.md
new file mode 100644
index 0000000..1798220
--- /dev/null
+++ b/src/main/java/com/ruoyi/device/domain/impl/djimqtt/README.md
@@ -0,0 +1,202 @@
+# DJI MQTT 模块使用说明(支持多客户端)
+
+## 概述
+
+本模块实现了大疆MQTT消息的接收和处理功能,支持动态创建多个MQTT客户端,每个客户端可以连接到不同的服务器。
+
+## 核心特性
+
+✅ **多客户端支持** - 可以同时创建多个MQTT客户端
+✅ **动态配置** - 每个客户端可以独立配置IP、端口、用户名等
+✅ **独立消息处理** - 每个客户端有独立的消息处理器
+✅ **共享订阅可选** - 支持开启/关闭共享订阅
+✅ **完整数据模型** - 包含所有无人机和机场字段
+✅ **自动区分设备** - 自动识别无人机和机场数据
+
+## 架构设计
+
+```
+DjiMqttClientManager (管理器)
+ ↓
+DjiMqttClientService (客户端实例)
+ ↓
+DjiMqttMessageHandler (消息处理器)
+ ↓
+IDroneDataCallback / IDockDataCallback (回调接口)
+```
+
+## 快速开始
+
+### 1. 注入管理器
+
+```java
+@Autowired
+private DjiMqttClientManager clientManager;
+```
+
+### 2. 创建客户端
+
+```java
+// 构建配置
+DjiMqttClientConfig config = DjiMqttClientConfig.builder()
+ .host("mqtt.t-aaron.com") // MQTT服务器地址
+ .port(10883) // 端口
+ .clientId("my_client_1") // 客户端ID(必须唯一)
+ .username("admin") // 用户名
+ .password("admin") // 密码
+ .useSharedSubscription(true) // 是否使用共享订阅
+ .sharedGroupName("dji-group") // 共享订阅组名
+ .build();
+
+// 创建并连接客户端
+String clientId = clientManager.createClient(config);
+```
+
+### 3. 注册回调
+
+```java
+// 获取消息处理器
+DjiMqttMessageHandler handler = clientManager.getHandler(clientId);
+
+// 注册无人机数据回调
+handler.registerDroneDataCallback(droneData -> {
+ System.out.println("无人机SN: " + droneData.getDeviceSn());
+ System.out.println("位置: " + droneData.getLatitude() + ", " + droneData.getLongitude());
+});
+
+// 注册机场数据回调
+handler.registerDockDataCallback(dockData -> {
+ System.out.println("机场SN: " + dockData.getDeviceSn());
+ System.out.println("温度: " + dockData.getTemperature());
+});
+```
+
+## 多客户端示例
+
+### 场景:同时连接多个MQTT服务器
+
+```java
+@Component
+public class MyMqttService {
+
+ @Autowired
+ private DjiMqttClientManager clientManager;
+
+ public void init() {
+ // 客户端1:连接到服务器A
+ DjiMqttClientConfig config1 = DjiMqttClientConfig.builder()
+ .host("mqtt.server-a.com")
+ .port(10883)
+ .clientId("client_a")
+ .username("admin")
+ .password("admin")
+ .useSharedSubscription(true)
+ .build();
+
+ String clientId1 = clientManager.createClient(config1);
+ DjiMqttMessageHandler handler1 = clientManager.getHandler(clientId1);
+ handler1.registerDroneDataCallback(data -> processServerA(data));
+
+ // 客户端2:连接到服务器B
+ DjiMqttClientConfig config2 = DjiMqttClientConfig.builder()
+ .host("mqtt.server-b.com")
+ .port(1883)
+ .clientId("client_b")
+ .username("user2")
+ .password("pass2")
+ .useSharedSubscription(false)
+ .build();
+
+ String clientId2 = clientManager.createClient(config2);
+ DjiMqttMessageHandler handler2 = clientManager.getHandler(clientId2);
+ handler2.registerDroneDataCallback(data -> processServerB(data));
+ }
+}
+```
+
+## 管理器API
+
+### 创建客户端
+```java
+String clientId = clientManager.createClient(config);
+```
+
+### 获取消息处理器
+```java
+DjiMqttMessageHandler handler = clientManager.getHandler(clientId);
+```
+
+### 获取客户端
+```java
+DjiMqttClientService client = clientManager.getClient(clientId);
+boolean isConnected = client.isConnected();
+```
+
+### 移除客户端
+```java
+clientManager.removeClient(clientId);
+```
+
+### 断开所有客户端
+```java
+clientManager.disconnectAll();
+```
+
+### 获取所有客户端ID
+```java
+Set clientIds = clientManager.getAllClientIds();
+```
+
+## 配置参数说明
+
+| 参数 | 类型 | 必填 | 默认值 | 说明 |
+|------|------|------|--------|------|
+| host | String | 是 | - | MQTT服务器地址 |
+| port | Integer | 是 | - | MQTT服务器端口 |
+| clientId | String | 是 | - | 客户端ID(必须唯一) |
+| username | String | 是 | - | 用户名 |
+| password | String | 是 | - | 密码 |
+| connectionTimeout | Integer | 否 | 30 | 连接超时时间(秒) |
+| keepAliveInterval | Integer | 否 | 60 | 保持连接时间(秒) |
+| autoReconnect | Boolean | 否 | true | 自动重连 |
+| cleanSession | Boolean | 否 | false | 清除会话 |
+| useSharedSubscription | Boolean | 否 | true | 是否使用共享订阅 |
+| sharedGroupName | String | 否 | dji-group | 共享订阅组名 |
+
+## 数据模型
+
+### DroneData(无人机数据)
+
+包含100+字段,主要分类:
+- **基础信息**:固件版本、飞行器状态、档位等
+- **位置信息**:经纬度、高度、Home点等
+- **姿态信息**:偏航角、横滚角、俯仰角
+- **速度信息**:水平速度、垂直速度、风速
+- **电池信息**:电量、剩余飞行时间、电池详情
+- **相机信息**:拍照录像状态、变焦、红外测温等
+- **避障信息**:水平/上视/下视避障状态
+- **保养信息**:保养状态、累计飞行时间/架次
+
+### DockData(机场数据)
+
+包含60+字段,主要分类:
+- **基础信息**:固件版本、机场状态、任务状态
+- **位置信息**:经纬度、高度、朝向角
+- **环境信息**:温度、湿度、风速、降雨量
+- **设备状态**:舱盖状态、飞行器在舱状态、补光灯等
+- **电池信息**:充电状态、备用电池、电池保养
+- **网络信息**:网络类型、质量、速率
+- **图传信息**:4G/SDR链路状态、信号质量
+
+## 注意事项
+
+1. **clientId必须唯一**:每个MQTT客户端的clientId必须全局唯一
+2. **部分字段推送**:每次MQTT消息可能只包含部分字段,使用时需要判空
+3. **原始数据访问**:所有字段都保存在`rawData`中,可以通过Map访问
+4. **共享订阅**:多实例部署时建议开启共享订阅,避免重复消费
+5. **独立处理器**:每个客户端有独立的消息处理器,互不影响
+6. **自动重连**:连接断开后会自动重连(可配置)
+
+## 完整示例
+
+参考 `DjiMqttUsageExample.java` 获取完整示例代码。
diff --git a/src/main/java/com/ruoyi/device/domain/impl/djimqtt/callback/IDockDataCallback.java b/src/main/java/com/ruoyi/device/domain/impl/djimqtt/callback/IDockDataCallback.java
new file mode 100644
index 0000000..9fb14d6
--- /dev/null
+++ b/src/main/java/com/ruoyi/device/domain/impl/djimqtt/callback/IDockDataCallback.java
@@ -0,0 +1,18 @@
+package com.ruoyi.device.domain.impl.djimqtt.callback;
+
+import com.ruoyi.device.domain.impl.djimqtt.model.DockData;
+
+/**
+ * 机场数据回调接口
+ *
+ * @author ruoyi
+ */
+public interface IDockDataCallback {
+
+ /**
+ * 处理机场数据
+ *
+ * @param dockData 机场数据
+ */
+ void onDockData(DockData dockData);
+}
diff --git a/src/main/java/com/ruoyi/device/domain/impl/djimqtt/callback/IDroneDataCallback.java b/src/main/java/com/ruoyi/device/domain/impl/djimqtt/callback/IDroneDataCallback.java
new file mode 100644
index 0000000..4bb7f74
--- /dev/null
+++ b/src/main/java/com/ruoyi/device/domain/impl/djimqtt/callback/IDroneDataCallback.java
@@ -0,0 +1,18 @@
+package com.ruoyi.device.domain.impl.djimqtt.callback;
+
+import com.ruoyi.device.domain.impl.djimqtt.model.DroneData;
+
+/**
+ * 无人机数据回调接口
+ *
+ * @author ruoyi
+ */
+public interface IDroneDataCallback {
+
+ /**
+ * 处理无人机数据
+ *
+ * @param droneData 无人机数据
+ */
+ void onDroneData(DroneData droneData);
+}
diff --git a/src/main/java/com/ruoyi/device/domain/impl/djimqtt/config/DjiMqttClientConfig.java b/src/main/java/com/ruoyi/device/domain/impl/djimqtt/config/DjiMqttClientConfig.java
new file mode 100644
index 0000000..94b395f
--- /dev/null
+++ b/src/main/java/com/ruoyi/device/domain/impl/djimqtt/config/DjiMqttClientConfig.java
@@ -0,0 +1,76 @@
+package com.ruoyi.device.domain.impl.djimqtt.config;
+
+import lombok.Builder;
+import lombok.Data;
+
+/**
+ * DJI MQTT客户端配置
+ * 用于动态创建MQTT客户端
+ *
+ * @author ruoyi
+ */
+@Data
+@Builder
+public class DjiMqttClientConfig {
+
+ /**
+ * MQTT服务器地址
+ */
+ private String host;
+
+ /**
+ * MQTT服务器端口
+ */
+ private Integer port;
+
+ /**
+ * 客户端ID(必须唯一)
+ */
+ private String clientId;
+
+ /**
+ * 用户名
+ */
+ private String username;
+
+ /**
+ * 密码
+ */
+ private String password;
+
+ /**
+ * 连接超时时间(秒)
+ */
+ @Builder.Default
+ private Integer connectionTimeout = 30;
+
+ /**
+ * 保持连接时间(秒)
+ */
+ @Builder.Default
+ private Integer keepAliveInterval = 60;
+
+ /**
+ * 自动重连
+ */
+ @Builder.Default
+ private Boolean autoReconnect = true;
+
+ /**
+ * 清除会话
+ */
+ @Builder.Default
+ private Boolean cleanSession = false;
+
+ /**
+ * 是否使用共享订阅
+ */
+ @Builder.Default
+ private Boolean useSharedSubscription = true;
+
+ /**
+ * 共享订阅组名
+ */
+ @Builder.Default
+ private String sharedGroupName = "dji-group";
+}
diff --git a/src/main/java/com/ruoyi/device/domain/impl/djimqtt/example/DjiMqttUsageExample.java b/src/main/java/com/ruoyi/device/domain/impl/djimqtt/example/DjiMqttUsageExample.java
new file mode 100644
index 0000000..9b34bde
--- /dev/null
+++ b/src/main/java/com/ruoyi/device/domain/impl/djimqtt/example/DjiMqttUsageExample.java
@@ -0,0 +1,153 @@
+package com.ruoyi.device.domain.impl.djimqtt.example;
+
+import com.ruoyi.device.domain.impl.djimqtt.callback.IDockDataCallback;
+import com.ruoyi.device.domain.impl.djimqtt.callback.IDroneDataCallback;
+import com.ruoyi.device.domain.impl.djimqtt.config.DjiMqttClientConfig;
+import com.ruoyi.device.domain.impl.djimqtt.handler.DjiMqttMessageHandler;
+import com.ruoyi.device.domain.impl.djimqtt.manager.DjiMqttClientManager;
+import com.ruoyi.device.domain.impl.djimqtt.model.DockData;
+import com.ruoyi.device.domain.impl.djimqtt.model.DroneData;
+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;
+
+/**
+ * DJI MQTT使用示例(支持多客户端)
+ *
+ * 使用说明:
+ * 1. 注入 DjiMqttClientManager
+ * 2. 使用 DjiMqttClientConfig.builder() 创建配置
+ * 3. 调用 manager.createClient(config) 创建客户端
+ * 4. 通过 manager.getHandler(clientId) 获取消息处理器
+ * 5. 注册回调处理数据
+ *
+ * @author ruoyi
+ */
+@Slf4j
+@Component
+public class DjiMqttUsageExample {
+
+// @Autowired
+// private DjiMqttClientManager clientManager;
+//
+// /**
+// * 应用启动后创建MQTT客户端
+// */
+// @EventListener(ApplicationReadyEvent.class)
+// public void onApplicationReady() {
+// // 示例1:创建第一个MQTT客户端
+// createClient1();
+//
+// // 示例2:创建第二个MQTT客户端(不同的服务器)
+// createClient2();
+// }
+//
+// /**
+// * 创建第一个MQTT客户端
+// */
+// private void createClient1() {
+// // 构建配置
+// DjiMqttClientConfig config = DjiMqttClientConfig.builder()
+// .host("mqtt.t-aaron.com")
+// .port(10883)
+// .clientId("client_1")
+// .username("admin")
+// .password("admin")
+// .useSharedSubscription(true)
+// .sharedGroupName("dji-group-1")
+// .build();
+//
+// // 创建客户端
+// String clientId = clientManager.createClient(config);
+//
+// // 获取消息处理器
+// DjiMqttMessageHandler handler = clientManager.getHandler(clientId);
+//
+// // 注册无人机数据回调
+// handler.registerDroneDataCallback(new IDroneDataCallback() {
+// @Override
+// public void onDroneData(DroneData droneData) {
+// handleDroneDataForClient1(droneData);
+// }
+// });
+//
+// // 注册机场数据回调
+// handler.registerDockDataCallback(new IDockDataCallback() {
+// @Override
+// public void onDockData(DockData dockData) {
+// handleDockDataForClient1(dockData);
+// }
+// });
+//
+// log.info("客户端1已创建并注册回调");
+// }
+//
+// /**
+// * 创建第二个MQTT客户端(连接到不同的服务器)
+// */
+// private void createClient2() {
+// // 构建配置
+// DjiMqttClientConfig config = DjiMqttClientConfig.builder()
+// .host("mqtt.another-server.com")
+// .port(1883)
+// .clientId("client_2")
+// .username("user2")
+// .password("pass2")
+// .useSharedSubscription(false) // 不使用共享订阅
+// .build();
+//
+// // 创建客户端
+// String clientId = clientManager.createClient(config);
+//
+// // 获取消息处理器
+// DjiMqttMessageHandler handler = clientManager.getHandler(clientId);
+//
+// // 注册回调
+// handler.registerDroneDataCallback(droneData -> handleDroneDataForClient2(droneData));
+// handler.registerDockDataCallback(dockData -> handleDockDataForClient2(dockData));
+//
+// log.info("客户端2已创建并注册回调");
+// }
+//
+// /**
+// * 处理客户端1的无人机数据
+// */
+// private void handleDroneDataForClient1(DroneData droneData) {
+// log.info("[客户端1] 收到无人机数据 - SN: {}, Type: {}",
+// droneData.getDeviceSn(),
+// droneData.getMessageType());
+//
+// // 处理位置信息
+// if (droneData.getLatitude() != null && droneData.getLongitude() != null) {
+// log.info("[客户端1] 无人机位置 - 纬度: {}, 经度: {}, 高度: {}",
+// droneData.getLatitude(),
+// droneData.getLongitude(),
+// droneData.getElevation());
+// }
+// }
+//
+// /**
+// * 处理客户端1的机场数据
+// */
+// private void handleDockDataForClient1(DockData dockData) {
+// log.info("[客户端1] 收到机场数据 - SN: {}, Type: {}",
+// dockData.getDeviceSn(),
+// dockData.getMessageType());
+// }
+//
+// /**
+// * 处理客户端2的无人机数据
+// */
+// private void handleDroneDataForClient2(DroneData droneData) {
+// log.info("[客户端2] 收到无人机数据 - SN: {}", droneData.getDeviceSn());
+// }
+//
+// /**
+// * 处理客户端2的机场数据
+// */
+// private void handleDockDataForClient2(DockData dockData) {
+// log.info("[客户端2] 收到机场数据 - SN: {}", dockData.getDeviceSn());
+// }
+}
diff --git a/src/main/java/com/ruoyi/device/domain/impl/djimqtt/handler/DjiMqttMessageHandler.java b/src/main/java/com/ruoyi/device/domain/impl/djimqtt/handler/DjiMqttMessageHandler.java
new file mode 100644
index 0000000..e6489c6
--- /dev/null
+++ b/src/main/java/com/ruoyi/device/domain/impl/djimqtt/handler/DjiMqttMessageHandler.java
@@ -0,0 +1,216 @@
+package com.ruoyi.device.domain.impl.djimqtt.handler;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.ruoyi.device.domain.impl.djimqtt.callback.IDockDataCallback;
+import com.ruoyi.device.domain.impl.djimqtt.callback.IDroneDataCallback;
+import com.ruoyi.device.domain.impl.djimqtt.model.DjiMqttMessage;
+import com.ruoyi.device.domain.impl.djimqtt.model.DockData;
+import com.ruoyi.device.domain.impl.djimqtt.model.DroneData;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Component;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * DJI MQTT消息处理器
+ *
+ * @author ruoyi
+ */
+@Slf4j
+@Component
+public class DjiMqttMessageHandler {
+
+ private final ObjectMapper objectMapper = new ObjectMapper();
+
+ /**
+ * 无人机数据回调列表
+ */
+ private final List droneDataCallbacks = new ArrayList<>();
+
+ /**
+ * 机场数据回调列表
+ */
+ private final List dockDataCallbacks = new ArrayList<>();
+
+ /**
+ * 无人机SN正则表达式(根据文档示例:1581F6Q8X251C00G04H8)
+ */
+ private static final Pattern DRONE_SN_PATTERN = Pattern.compile("^[0-9A-Z]{20}$");
+
+ /**
+ * 机场SN正则表达式(根据文档示例:7CTXN5K00B0AXM)
+ */
+ private static final Pattern DOCK_SN_PATTERN = Pattern.compile("^[0-9A-Z]{14}$");
+
+ /**
+ * 注册无人机数据回调
+ *
+ * @param callback 回调接口
+ */
+ public void registerDroneDataCallback(IDroneDataCallback callback) {
+ if (callback != null && !droneDataCallbacks.contains(callback)) {
+ droneDataCallbacks.add(callback);
+ log.info("注册无人机数据回调: {}", callback.getClass().getSimpleName());
+ }
+ }
+
+ /**
+ * 注册机场数据回调
+ *
+ * @param callback 回调接口
+ */
+ public void registerDockDataCallback(IDockDataCallback callback) {
+ if (callback != null && !dockDataCallbacks.contains(callback)) {
+ dockDataCallbacks.add(callback);
+ log.info("注册机场数据回调: {}", callback.getClass().getSimpleName());
+ }
+ }
+
+ /**
+ * 处理MQTT消息
+ *
+ * @param topic 主题
+ * @param payload 消息内容
+ */
+ public void handleMessage(String topic, String payload) {
+ try {
+ log.debug("收到MQTT消息 - Topic: {}, Payload: {}", topic, payload);
+
+ // 解析设备SN和消息类型
+ String deviceSn = extractDeviceSnFromTopic(topic);
+ String messageType = extractMessageTypeFromTopic(topic);
+
+ if (deviceSn == null || messageType == null) {
+ log.warn("无法从Topic解析设备SN或消息类型: {}", topic);
+ return;
+ }
+
+ // 解析JSON消息
+ @SuppressWarnings("unchecked")
+ DjiMqttMessage