fix: 物联网平台,amqp数据接入并插入TD数据库相关逻辑编码。
This commit is contained in:
@@ -1,10 +1,20 @@
|
||||
package com.intc.iot.controller;
|
||||
|
||||
import com.intc.common.core.domain.R;
|
||||
import com.intc.common.mybatis.core.page.PageQuery;
|
||||
import com.intc.common.mybatis.core.page.TableDataInfo;
|
||||
import com.intc.common.web.core.BaseController;
|
||||
import com.intc.iot.domain.bo.DeviceRealtimeDataBo;
|
||||
import com.intc.iot.domain.vo.DeviceRealtimeDataVo;
|
||||
import com.intc.iot.service.DeviceDataService;
|
||||
import com.intc.iot.service.DeviceRealtimeDataService;
|
||||
import com.intc.iot.service.DeviceStatusService;
|
||||
import com.intc.iot.service.IotDeviceService;
|
||||
import com.intc.iot.service.MqttService;
|
||||
import com.intc.iot.service.VmsMnsConsumerService;
|
||||
import com.intc.iot.service.VmsNoticeService;
|
||||
import com.intc.iot.service.WarnCallNoticeService;
|
||||
import com.intc.iot.utils.AliyunAmqpSignUtil;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
@@ -36,22 +46,115 @@ public class IotController extends BaseController {
|
||||
@Autowired(required = false)
|
||||
private DeviceDataService deviceDataService;
|
||||
|
||||
@Autowired(required = false)
|
||||
private DeviceRealtimeDataService deviceRealtimeDataService;
|
||||
|
||||
@Autowired(required = false)
|
||||
private DeviceStatusService deviceStatusService;
|
||||
|
||||
@Autowired(required = false)
|
||||
private VmsNoticeService vmsNoticeService;
|
||||
|
||||
@Autowired(required = false)
|
||||
private VmsMnsConsumerService vmsMnsConsumerService;
|
||||
|
||||
@Autowired(required = false)
|
||||
private WarnCallNoticeService warnCallNoticeService;
|
||||
|
||||
@Autowired(required = false)
|
||||
private javax.jms.Connection amqpConnection;
|
||||
|
||||
@Operation(summary = "测试接口")
|
||||
@GetMapping("/test")
|
||||
public R<String> test() {
|
||||
return R.ok("飞燕平台模块测试成功!");
|
||||
}
|
||||
|
||||
@Operation(summary = "查询 AMQP 连接状态")
|
||||
@GetMapping("/amqp/status")
|
||||
public R<Map<String, Object>> getAmqpStatus() {
|
||||
Map<String, Object> status = new java.util.HashMap<>();
|
||||
|
||||
if (amqpConnection == null) {
|
||||
status.put("configured", false);
|
||||
status.put("connected", false);
|
||||
status.put("message", "AMQP 未启用或未配置");
|
||||
} else {
|
||||
try {
|
||||
status.put("configured", true);
|
||||
// JMS Connection 没有直接的 isOpen 方法,通过尝试获取元数据来检查连接
|
||||
javax.jms.ConnectionMetaData metaData = amqpConnection.getMetaData();
|
||||
status.put("connected", true);
|
||||
status.put("provider", metaData.getJMSProviderName());
|
||||
status.put("version", metaData.getProviderVersion());
|
||||
status.put("message", "AMQP 连接正常");
|
||||
} catch (Exception e) {
|
||||
status.put("configured", true);
|
||||
status.put("connected", false);
|
||||
status.put("message", "AMQP 连接已关闭或异常: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
return R.ok(status);
|
||||
}
|
||||
|
||||
@Operation(summary = "生成 AMQP 配置信息")
|
||||
@GetMapping("/amqp/generate-config")
|
||||
public R<Map<String, Object>> generateAmqpConfig(
|
||||
@Parameter(description = "AccessKey ID") @RequestParam String accessKeyId,
|
||||
@Parameter(description = "AccessKey Secret") @RequestParam String accessKeySecret,
|
||||
@Parameter(description = "消费组 ID") @RequestParam String consumerGroupId,
|
||||
@Parameter(description = "阿里云账号 UID") @RequestParam String uid,
|
||||
@Parameter(description = "地域 ID(如:cn-shanghai)") @RequestParam String regionId) {
|
||||
try {
|
||||
String host = AliyunAmqpSignUtil.generateHost(uid, regionId);
|
||||
String virtualHost = AliyunAmqpSignUtil.generateVirtualHost(accessKeyId);
|
||||
String username = AliyunAmqpSignUtil.generateUsername(accessKeyId);
|
||||
String password = AliyunAmqpSignUtil.generatePassword(accessKeySecret, consumerGroupId);
|
||||
|
||||
Map<String, Object> config = new java.util.HashMap<>();
|
||||
config.put("host", host);
|
||||
config.put("port", 5672);
|
||||
config.put("virtualHost", virtualHost);
|
||||
config.put("username", username);
|
||||
config.put("password", password);
|
||||
config.put("consumerGroupId", consumerGroupId);
|
||||
|
||||
return R.ok(config);
|
||||
} catch (Exception e) {
|
||||
log.error("生成 AMQP 配置失败", e);
|
||||
return R.fail("生成配置失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Operation(summary = "根据 ProductKey 和 DeviceName 查询设备信息")
|
||||
@GetMapping("/device/find")
|
||||
public R<Map<String, Object>> findDeviceByProductKeyAndName(
|
||||
@Parameter(description = "产品Key") @RequestParam String productKey,
|
||||
@Parameter(description = "设备名称") @RequestParam String deviceName) {
|
||||
try {
|
||||
if (iotDeviceService == null) {
|
||||
return R.fail("飞燕平台配置未启用");
|
||||
}
|
||||
Map<String, Object> response = iotDeviceService.findDeviceByProductKeyAndName(productKey, deviceName);
|
||||
return R.ok(response);
|
||||
} catch (Exception e) {
|
||||
log.error("根据 ProductKey 和 DeviceName 查询设备信息失败", e);
|
||||
return R.fail("查询设备信息失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Operation(summary = "查询设备列表")
|
||||
@GetMapping("/device/list")
|
||||
public R<Map<String, Object>> queryDeviceList(
|
||||
@Parameter(description = "产品Key(必填)") @RequestParam(value = "productKey", required = true) String productKey,
|
||||
@Parameter(description = "页码") @RequestParam(defaultValue = "1") Integer pageNo,
|
||||
@Parameter(description = "每页大小") @RequestParam(defaultValue = "20") Integer pageSize) {
|
||||
try {
|
||||
if (iotDeviceService == null) {
|
||||
return R.fail("飞燕平台配置未启用");
|
||||
}
|
||||
Map<String, Object> response = iotDeviceService.queryDeviceList(pageNo, pageSize);
|
||||
Map<String, Object> response = iotDeviceService.queryDeviceList(productKey, pageNo, pageSize);
|
||||
return R.ok(response);
|
||||
} catch (Exception e) {
|
||||
log.error("查询设备列表失败", e);
|
||||
@@ -103,7 +206,7 @@ public class IotController extends BaseController {
|
||||
Map<String, Object> response = iotDeviceService.setDeviceProperty(iotId, properties);
|
||||
return R.ok(response);
|
||||
} catch (Exception e) {
|
||||
log.error("设置设备属性失败", e);
|
||||
log.error("设置设备属性失败: {}", e.getMessage());
|
||||
return R.fail("设置设备属性失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
@@ -121,7 +224,7 @@ public class IotController extends BaseController {
|
||||
Map<String, Object> response = iotDeviceService.invokeService(iotId, identifier, args);
|
||||
return R.ok(response);
|
||||
} catch (Exception e) {
|
||||
log.error("调用设备服务失败", e);
|
||||
log.error("调用设备服务失败: {}", e.getMessage());
|
||||
return R.fail("调用设备服务失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
@@ -137,11 +240,65 @@ public class IotController extends BaseController {
|
||||
Map<String, Object> response = iotDeviceService.unbindDevice(iotId);
|
||||
return R.ok(response);
|
||||
} catch (Exception e) {
|
||||
log.error("解绑设备失败", e);
|
||||
log.error("解绑设备失败: {}", e.getMessage());
|
||||
return R.fail("解绑设备失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Operation(summary = "查询设备物模型(模板)")
|
||||
@GetMapping("/device/thing-model")
|
||||
public R<Map<String, Object>> queryThingModel(
|
||||
@Parameter(description = "产品Key") @RequestParam String productKey) {
|
||||
try {
|
||||
if (iotDeviceService == null) {
|
||||
return R.fail("飞燕平台配置未启用");
|
||||
}
|
||||
Map<String, Object> response = iotDeviceService.queryThingModel(productKey);
|
||||
return R.ok(response);
|
||||
} catch (Exception e) {
|
||||
log.error("查询设备物模型失败: {}", e.getMessage());
|
||||
return R.fail("查询设备物模型失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Operation(summary = "查询设备当前状态")
|
||||
@GetMapping("/device/status")
|
||||
public R<com.intc.iot.domain.IotDeviceStatus> queryDeviceStatus(
|
||||
@Parameter(description = "产品Key") @RequestParam String productKey,
|
||||
@Parameter(description = "设备名称") @RequestParam String deviceName) {
|
||||
try {
|
||||
if (deviceStatusService == null) {
|
||||
return R.fail("设备状态服务未启用");
|
||||
}
|
||||
com.intc.iot.domain.IotDeviceStatus status = deviceStatusService.queryDeviceStatus(productKey, deviceName);
|
||||
return R.ok(status);
|
||||
} catch (Exception e) {
|
||||
log.error("查询设备状态失败: {}", e.getMessage());
|
||||
return R.fail("查询设备状态失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Operation(summary = "判断设备是否在线")
|
||||
@GetMapping("/device/online")
|
||||
public R<Map<String, Object>> isDeviceOnline(
|
||||
@Parameter(description = "产品Key") @RequestParam String productKey,
|
||||
@Parameter(description = "设备名称") @RequestParam String deviceName) {
|
||||
try {
|
||||
if (deviceStatusService == null) {
|
||||
return R.fail("设备状态服务未启用");
|
||||
}
|
||||
boolean online = deviceStatusService.isDeviceOnline(productKey, deviceName);
|
||||
Map<String, Object> result = new java.util.HashMap<>();
|
||||
result.put("online", online);
|
||||
result.put("productKey", productKey);
|
||||
result.put("deviceName", deviceName);
|
||||
return R.ok(result);
|
||||
} catch (Exception e) {
|
||||
log.error("查询设备在线状态失败: {}", e.getMessage());
|
||||
return R.fail("查询设备在线状态失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Operation(summary = "发布MQTT消息")
|
||||
@PostMapping("/mqtt/publish")
|
||||
public R<String> publishMqtt(
|
||||
@@ -155,7 +312,7 @@ public class IotController extends BaseController {
|
||||
mqttService.publish(topic, payload, qos);
|
||||
return R.ok("消息发布成功");
|
||||
} catch (Exception e) {
|
||||
log.error("发布MQTT消息失败", e);
|
||||
log.error("发布MQTT消息失败: {}", e.getMessage());
|
||||
return R.fail("发布MQTT消息失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
@@ -172,7 +329,7 @@ public class IotController extends BaseController {
|
||||
mqttService.subscribe(topic, qos);
|
||||
return R.ok("订阅成功");
|
||||
} catch (Exception e) {
|
||||
log.error("订阅MQTT主题失败", e);
|
||||
log.error("订阅MQTT主题失败: {}", e.getMessage());
|
||||
return R.fail("订阅MQTT主题失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
@@ -188,11 +345,28 @@ public class IotController extends BaseController {
|
||||
mqttService.unsubscribe(topic);
|
||||
return R.ok("取消订阅成功");
|
||||
} catch (Exception e) {
|
||||
log.error("取消订阅MQTT主题失败", e);
|
||||
log.error("取消订阅失败: {}", e.getMessage());
|
||||
return R.fail("取消订阅MQTT主题失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Operation(summary = "订阅设备状态 Topic")
|
||||
@PostMapping("/mqtt/subscribe/status")
|
||||
public R<String> subscribeDeviceStatus(
|
||||
@Parameter(description = "产品Key") @RequestParam String productKey,
|
||||
@Parameter(description = "设备名称") @RequestParam String deviceName) {
|
||||
try {
|
||||
if (mqttService == null) {
|
||||
return R.fail("MQTT配置未启用");
|
||||
}
|
||||
mqttService.subscribeDeviceStatus(productKey, deviceName);
|
||||
return R.ok("订阅设备状态成功");
|
||||
} catch (Exception e) {
|
||||
log.error("订阅设备状态失败: {}", e.getMessage());
|
||||
return R.fail("订阅设备状态失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Operation(summary = "订阅设备实时数据(按产品)")
|
||||
@PostMapping("/device/data/subscribe")
|
||||
public R<String> subscribeDeviceData(
|
||||
@@ -204,9 +378,208 @@ public class IotController extends BaseController {
|
||||
deviceDataService.subscribeAllDevices(productKey);
|
||||
return R.ok("订阅成功,设备数据将实时推送");
|
||||
} catch (Exception e) {
|
||||
log.error("订阅设备数据失败", e);
|
||||
log.error("订阅设备数据失败: {}", e.getMessage());
|
||||
return R.fail("订阅设备数据失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Operation(summary = "查询设备实时数据列表(分页)")
|
||||
@GetMapping("/device/realtime/list")
|
||||
public R<TableDataInfo<DeviceRealtimeDataVo>> queryRealtimeDataList(
|
||||
DeviceRealtimeDataBo bo, PageQuery pageQuery) {
|
||||
try {
|
||||
if (deviceRealtimeDataService == null) {
|
||||
return R.fail("设备数据服务未启用");
|
||||
}
|
||||
TableDataInfo<DeviceRealtimeDataVo> dataInfo = deviceRealtimeDataService.queryPageList(bo, pageQuery);
|
||||
return R.ok(dataInfo);
|
||||
} catch (Exception e) {
|
||||
log.error("查询实时数据失败: {}", e.getMessage());
|
||||
return R.fail("查询设备实时数据列表失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Operation(summary = "查询设备最新数据")
|
||||
@GetMapping("/device/realtime/latest")
|
||||
public R<DeviceRealtimeDataVo> queryLatestData(
|
||||
@Parameter(description = "产品Key") @RequestParam String productKey,
|
||||
@Parameter(description = "设备名称") @RequestParam String deviceName) {
|
||||
try {
|
||||
if (deviceRealtimeDataService == null) {
|
||||
return R.fail("设备数据服务未启用");
|
||||
}
|
||||
DeviceRealtimeDataVo data = deviceRealtimeDataService.queryLatestData(productKey, deviceName);
|
||||
return R.ok(data);
|
||||
} catch (Exception e) {
|
||||
log.error("查询最新数据失败: {}", e.getMessage());
|
||||
return R.fail("查询设备最新数据失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Operation(summary = "查询设备最新属性数据")
|
||||
@GetMapping("/device/realtime/latest-property")
|
||||
public R<DeviceRealtimeDataVo> queryLatestPropertyData(
|
||||
@Parameter(description = "产品Key") @RequestParam String productKey,
|
||||
@Parameter(description = "设备名称") @RequestParam String deviceName) {
|
||||
try {
|
||||
if (deviceRealtimeDataService == null) {
|
||||
return R.fail("设备数据服务未启用");
|
||||
}
|
||||
DeviceRealtimeDataVo data = deviceRealtimeDataService.queryLatestPropertyData(productKey, deviceName);
|
||||
return R.ok(data);
|
||||
} catch (Exception e) {
|
||||
log.error("查询最新属性失败: {}", e.getMessage());
|
||||
return R.fail("查询设备最新属性数据失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Operation(summary = "删除设备实时数据")
|
||||
@DeleteMapping("/device/realtime/{ids}")
|
||||
public R<Void> deleteRealtimeData(
|
||||
@Parameter(description = "主键ID数组") @PathVariable Long[] ids) {
|
||||
try {
|
||||
if (deviceRealtimeDataService == null) {
|
||||
return R.fail("设备数据服务未启用");
|
||||
}
|
||||
boolean success = deviceRealtimeDataService.deleteByIds(ids);
|
||||
return success ? R.ok() : R.fail("删除失败");
|
||||
} catch (Exception e) {
|
||||
log.error("删除实时数据失败: {}", e.getMessage());
|
||||
return R.fail("删除设备实时数据失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
// ======================== VMS 语音通知相关接口 ========================
|
||||
|
||||
@Operation(summary = "发送语音通知(测试接口)")
|
||||
@PostMapping("/vms/call")
|
||||
public R<Map<String, Object>> sendVoiceCall(
|
||||
@Parameter(description = "手机号") @RequestParam String phoneNumber,
|
||||
@Parameter(description = "模板参数JSON") @RequestParam String params,
|
||||
@Parameter(description = "业务ID") @RequestParam(required = false) String outId) {
|
||||
try {
|
||||
if (vmsNoticeService == null) {
|
||||
return R.fail("VMS语音服务未启用");
|
||||
}
|
||||
Map<String, String> paramsMap = cn.hutool.json.JSONUtil.toBean(params, Map.class);
|
||||
com.intc.iot.domain.VmsNoticeResponse response = vmsNoticeService.sendTtsCall(
|
||||
phoneNumber, paramsMap, outId != null ? outId : "TEST"
|
||||
);
|
||||
|
||||
Map<String, Object> result = new java.util.HashMap<>();
|
||||
result.put("success", response.isSuccess());
|
||||
result.put("code", response.getCode());
|
||||
result.put("message", response.getMessage());
|
||||
result.put("callId", response.getCallId());
|
||||
|
||||
return R.ok(result);
|
||||
} catch (Exception e) {
|
||||
log.error("发送语音通知失败: {}", e.getMessage());
|
||||
return R.fail("发送语音通知失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Operation(summary = "启动 VMS MNS 回执消费服务")
|
||||
@PostMapping("/vms/mns/start")
|
||||
public R<String> startVmsMnsConsumer() {
|
||||
try {
|
||||
if (vmsMnsConsumerService == null) {
|
||||
return R.fail("VMS MNS消费服务未配置");
|
||||
}
|
||||
if (vmsMnsConsumerService.isRunning()) {
|
||||
return R.fail("VMS MNS消费服务已在运行中");
|
||||
}
|
||||
vmsMnsConsumerService.start();
|
||||
return R.ok("VMS MNS消费服务启动成功");
|
||||
} catch (Exception e) {
|
||||
log.error("启动VMS失败: {}", e.getMessage());
|
||||
return R.fail("启动失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Operation(summary = "停止 VMS MNS 回执消费服务")
|
||||
@PostMapping("/vms/mns/stop")
|
||||
public R<String> stopVmsMnsConsumer() {
|
||||
try {
|
||||
if (vmsMnsConsumerService == null) {
|
||||
return R.fail("VMS MNS消费服务未配置");
|
||||
}
|
||||
if (!vmsMnsConsumerService.isRunning()) {
|
||||
return R.fail("VMS MNS消费服务未在运行");
|
||||
}
|
||||
vmsMnsConsumerService.stop();
|
||||
return R.ok("VMS MNS消费服务已停止");
|
||||
} catch (Exception e) {
|
||||
log.error("停止VMS失败: {}", e.getMessage());
|
||||
return R.fail("停止失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Operation(summary = "查询 VMS MNS 消费服务运行状态")
|
||||
@GetMapping("/vms/mns/status")
|
||||
public R<Map<String, Object>> getVmsMnsStatus() {
|
||||
try {
|
||||
if (vmsMnsConsumerService == null) {
|
||||
return R.fail("VMS MNS消费服务未配置");
|
||||
}
|
||||
Map<String, Object> status = new java.util.HashMap<>();
|
||||
status.put("running", vmsMnsConsumerService.isRunning());
|
||||
return R.ok(status);
|
||||
} catch (Exception e) {
|
||||
log.error("查询VMS状态失败: {}", e.getMessage());
|
||||
return R.fail("查询失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Operation(summary = "手动触发 VMS 回执处理")
|
||||
@PostMapping("/vms/callback/process")
|
||||
public R<Map<String, Object>> processVmsCallbacks() {
|
||||
try {
|
||||
if (warnCallNoticeService == null) {
|
||||
return R.fail("告警通知服务未启用");
|
||||
}
|
||||
int count = warnCallNoticeService.processUnhandledCallbacks();
|
||||
Map<String, Object> result = new java.util.HashMap<>();
|
||||
result.put("processedCount", count);
|
||||
return R.ok(result);
|
||||
} catch (Exception e) {
|
||||
log.error("处理回执失败: {}", e.getMessage());
|
||||
return R.fail("处理失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Operation(summary = "移除指定设备的待通知记录")
|
||||
@DeleteMapping("/vms/pending/{deviceId}")
|
||||
public R<Map<String, Object>> removePendingNotifications(
|
||||
@Parameter(description = "设备ID") @PathVariable Long deviceId) {
|
||||
try {
|
||||
if (warnCallNoticeService == null) {
|
||||
return R.fail("告警通知服务未启用");
|
||||
}
|
||||
int count = warnCallNoticeService.removePendingNotificationsByDevice(deviceId);
|
||||
Map<String, Object> result = new java.util.HashMap<>();
|
||||
result.put("removedCount", count);
|
||||
return R.ok(result);
|
||||
} catch (Exception e) {
|
||||
log.error("移除待通知失败: {}", e.getMessage());
|
||||
return R.fail("移除失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Operation(summary = "手动清理超时的通知记录")
|
||||
@PostMapping("/vms/cleanup/expired")
|
||||
public R<Map<String, Object>> cleanupExpiredNotifications() {
|
||||
try {
|
||||
if (warnCallNoticeService == null) {
|
||||
return R.fail("告警通知服务未启用");
|
||||
}
|
||||
int count = warnCallNoticeService.cleanupExpiredNotifications();
|
||||
Map<String, Object> result = new java.util.HashMap<>();
|
||||
result.put("cleanedCount", count);
|
||||
return R.ok(result);
|
||||
} catch (Exception e) {
|
||||
log.error("清理超时失败: {}", e.getMessage());
|
||||
return R.fail("清理失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user