fix: 物联网平台,amqp数据接入并插入TD数据库相关逻辑编码。

This commit is contained in:
tianyongbao
2026-01-10 01:20:51 +08:00
parent d1c829d410
commit 5bd63f83df
56 changed files with 4842 additions and 158 deletions

View File

@@ -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 = "地域 IDcn-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());
}
}
}