fix: 微信小程序接口对接修改。
This commit is contained in:
@@ -71,7 +71,7 @@ public class DeviceController extends BaseController {
|
||||
/**
|
||||
* 新增设备管理
|
||||
*/
|
||||
@SaCheckPermission("fishery:device:add")
|
||||
// @SaCheckPermission("fishery:device:add")
|
||||
@Log(title = "设备管理", businessType = BusinessType.INSERT)
|
||||
@RepeatSubmit()
|
||||
@PostMapping()
|
||||
|
||||
@@ -38,7 +38,7 @@ public class MessageOpRecordController extends BaseController {
|
||||
/**
|
||||
* 查询用户操作记录列表
|
||||
*/
|
||||
@SaCheckPermission("fishery:messageOpRecord:list")
|
||||
// @SaCheckPermission("fishery:messageOpRecord:list")
|
||||
@GetMapping("/list")
|
||||
public TableDataInfo<MessageOpRecordVo> list(MessageOpRecordBo bo, PageQuery pageQuery) {
|
||||
return messageOpRecordService.queryPageList(bo, pageQuery);
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
package com.intc.fishery.controller;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import com.intc.common.excel.utils.ExcelUtil;
|
||||
import com.intc.common.satoken.utils.LoginHelper;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import jakarta.validation.constraints.*;
|
||||
@@ -38,7 +40,7 @@ public class MessageWarnController extends BaseController {
|
||||
/**
|
||||
* 查询设备告警记录列表
|
||||
*/
|
||||
@SaCheckPermission("fishery:messageWarn:list")
|
||||
// @SaCheckPermission("fishery:messageWarn:list")
|
||||
@GetMapping("/list")
|
||||
public TableDataInfo<MessageWarnVo> list(MessageWarnBo bo, PageQuery pageQuery) {
|
||||
return messageWarnService.queryPageList(bo, pageQuery);
|
||||
@@ -101,4 +103,21 @@ public class MessageWarnController extends BaseController {
|
||||
@PathVariable Long[] ids) {
|
||||
return toAjax(messageWarnService.deleteWithValidByIds(List.of(ids), true));
|
||||
}
|
||||
|
||||
/**
|
||||
* 已读一条消息
|
||||
*/
|
||||
@PutMapping("/read")
|
||||
public R<Void> readMessage(@RequestParam("id") Long id) {
|
||||
return toAjax(messageWarnService.readMessage(id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 已读全部消息
|
||||
*/
|
||||
@PutMapping("/read/all")
|
||||
public R<Void> readAllMessages() {
|
||||
Long userId = LoginHelper.getUserId();
|
||||
return toAjax(messageWarnService.readAllMessages(userId));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ public class PayOrderController extends BaseController {
|
||||
/**
|
||||
* 查询充值订单列表
|
||||
*/
|
||||
@SaCheckPermission("fishery:payOrder:list")
|
||||
// @SaCheckPermission("fishery:payOrder:list")
|
||||
@GetMapping("/list")
|
||||
public TableDataInfo<PayOrderVo> list(PayOrderBo bo, PageQuery pageQuery) {
|
||||
return payOrderService.queryPageList(bo, pageQuery);
|
||||
|
||||
@@ -69,7 +69,7 @@ public class PondController extends BaseController {
|
||||
*
|
||||
* @param id 主键
|
||||
*/
|
||||
@SaCheckPermission("fishery:pond:query")
|
||||
// @SaCheckPermission("fishery:pond:query")
|
||||
@GetMapping("/{id}")
|
||||
public R<PondVo> getInfo(@NotNull(message = "主键不能为空")
|
||||
@PathVariable Long id) {
|
||||
@@ -120,7 +120,7 @@ public class PondController extends BaseController {
|
||||
/**
|
||||
* 修改塘口管理
|
||||
*/
|
||||
@SaCheckPermission("fishery:pond:edit")
|
||||
// @SaCheckPermission("fishery:pond:edit")
|
||||
@Log(title = "塘口管理", businessType = BusinessType.UPDATE)
|
||||
@RepeatSubmit()
|
||||
@PutMapping()
|
||||
@@ -133,7 +133,7 @@ public class PondController extends BaseController {
|
||||
*
|
||||
* @param ids 主键串
|
||||
*/
|
||||
@SaCheckPermission("fishery:pond:remove")
|
||||
// @SaCheckPermission("fishery:pond:remove")
|
||||
@Log(title = "塘口管理", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/{ids}")
|
||||
public R<Void> remove(@NotEmpty(message = "主键不能为空")
|
||||
|
||||
@@ -65,4 +65,20 @@ public interface IMessageWarnService {
|
||||
* @return 是否删除成功
|
||||
*/
|
||||
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
|
||||
|
||||
/**
|
||||
* 已读一条消息
|
||||
*
|
||||
* @param id 消息ID
|
||||
* @return 是否成功
|
||||
*/
|
||||
Boolean readMessage(Long id);
|
||||
|
||||
/**
|
||||
* 已读全部消息
|
||||
*
|
||||
* @param userId 用户ID
|
||||
* @return 是否成功
|
||||
*/
|
||||
Boolean readAllMessages(Long userId);
|
||||
}
|
||||
|
||||
@@ -197,4 +197,38 @@ public class MessageWarnServiceImpl implements IMessageWarnService {
|
||||
}
|
||||
return baseMapper.deleteByIds(ids) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 已读一条消息
|
||||
*
|
||||
* @param id 消息ID
|
||||
* @return 是否成功
|
||||
*/
|
||||
@Override
|
||||
public Boolean readMessage(Long id) {
|
||||
MessageWarn messageWarn = baseMapper.selectById(id);
|
||||
if (messageWarn == null) {
|
||||
return false;
|
||||
}
|
||||
messageWarn.setIsRead(1);
|
||||
return baseMapper.updateById(messageWarn) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 已读全部消息
|
||||
*
|
||||
* @param userId 用户ID
|
||||
* @return 是否成功
|
||||
*/
|
||||
@Override
|
||||
public Boolean readAllMessages(Long userId) {
|
||||
MessageWarn update = new MessageWarn();
|
||||
update.setIsRead(1);
|
||||
|
||||
LambdaQueryWrapper<MessageWarn> wrapper = Wrappers.lambdaQuery(MessageWarn.class)
|
||||
.eq(MessageWarn::getUserId, userId)
|
||||
.eq(MessageWarn::getIsRead, 0);
|
||||
|
||||
return baseMapper.update(update, wrapper) > 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,6 +47,13 @@ public class AliyunIotProperties {
|
||||
*/
|
||||
private String categoryKey;
|
||||
|
||||
/**
|
||||
* 设备类型到产品Key的映射
|
||||
* 1: 水质检测仪
|
||||
* 2: 控制一体机
|
||||
*/
|
||||
private DeviceTypeMapping deviceType = new DeviceTypeMapping();
|
||||
|
||||
/**
|
||||
* MQTT 配置(可选,用于设备直连)
|
||||
*/
|
||||
@@ -158,4 +165,39 @@ public class AliyunIotProperties {
|
||||
private Integer reconnectDelay = 30000;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设备类型映射配置
|
||||
*/
|
||||
@Data
|
||||
public static class DeviceTypeMapping {
|
||||
/**
|
||||
* 水质检测仪 ProductKey
|
||||
*/
|
||||
private String waterQualityMonitor;
|
||||
|
||||
/**
|
||||
* 控制一体机 ProductKey
|
||||
*/
|
||||
private String controlIntegrated;
|
||||
|
||||
/**
|
||||
* 根据设备类型获取 ProductKey
|
||||
* @param deviceType 1-水质检测仪, 2-控制一体机
|
||||
* @return ProductKey
|
||||
*/
|
||||
public String getProductKeyByType(Integer deviceType) {
|
||||
if (deviceType == null) {
|
||||
return null;
|
||||
}
|
||||
switch (deviceType) {
|
||||
case 1:
|
||||
return waterQualityMonitor;
|
||||
case 2:
|
||||
return controlIntegrated;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -3,7 +3,13 @@ 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.satoken.utils.LoginHelper;
|
||||
import com.intc.common.web.core.BaseController;
|
||||
import com.intc.fishery.domain.Device;
|
||||
import com.intc.fishery.mapper.DeviceMapper;
|
||||
import com.intc.fishery.mapper.PondMapper;
|
||||
import com.intc.iot.config.AliyunIotProperties;
|
||||
import com.intc.iot.domain.bo.AddDeviceDetectorBo;
|
||||
import com.intc.iot.domain.bo.DeviceRealtimeDataBo;
|
||||
import com.intc.iot.domain.vo.DeviceRealtimeDataVo;
|
||||
import com.intc.iot.service.DeviceDataService;
|
||||
@@ -23,6 +29,7 @@ import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
@@ -37,6 +44,8 @@ import java.util.Map;
|
||||
@Tag(name = "生活物联网平台管理", description = "阿里云飞燕平台对接接口")
|
||||
public class IotController extends BaseController {
|
||||
|
||||
private final AliyunIotProperties aliyunIotProperties;
|
||||
|
||||
@Autowired(required = false)
|
||||
private IotDeviceService iotDeviceService;
|
||||
|
||||
@@ -64,6 +73,12 @@ public class IotController extends BaseController {
|
||||
@Autowired(required = false)
|
||||
private javax.jms.Connection amqpConnection;
|
||||
|
||||
@Autowired(required = false)
|
||||
private DeviceMapper deviceMapper;
|
||||
|
||||
@Autowired(required = false)
|
||||
private PondMapper pondMapper;
|
||||
|
||||
@Operation(summary = "测试接口")
|
||||
@GetMapping("/test")
|
||||
public R<String> test() {
|
||||
@@ -74,7 +89,7 @@ public class IotController extends BaseController {
|
||||
@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);
|
||||
@@ -94,7 +109,7 @@ public class IotController extends BaseController {
|
||||
status.put("message", "AMQP 连接已关闭或异常: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return R.ok(status);
|
||||
}
|
||||
|
||||
@@ -111,7 +126,7 @@ public class IotController extends BaseController {
|
||||
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);
|
||||
@@ -119,14 +134,14 @@ public class IotController extends BaseController {
|
||||
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(
|
||||
@@ -143,7 +158,7 @@ public class IotController extends BaseController {
|
||||
return R.fail("查询设备信息失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Operation(summary = "查询设备列表")
|
||||
@GetMapping("/device/list")
|
||||
public R<Map<String, Object>> queryDeviceList(
|
||||
@@ -261,19 +276,93 @@ public class IotController extends BaseController {
|
||||
}
|
||||
}
|
||||
|
||||
@Operation(summary = "查询设备当前状态")
|
||||
@Operation(summary = "查询设备当前状态(从物联网平台)")
|
||||
@GetMapping("/device/status")
|
||||
public R<com.intc.iot.domain.IotDeviceStatus> queryDeviceStatus(
|
||||
@Parameter(description = "产品Key") @RequestParam String productKey,
|
||||
@Parameter(description = "设备名称") @RequestParam String deviceName) {
|
||||
public R<Integer> queryDeviceStatus(
|
||||
@Parameter(description = "设备类型(1-水质检测仪, 2-控制一体机)") @RequestParam Integer devicetype,
|
||||
@Parameter(description = "设备编号/设备名称") @RequestParam String serialnum) {
|
||||
try {
|
||||
if (deviceStatusService == null) {
|
||||
return R.fail("设备状态服务未启用");
|
||||
if (iotDeviceService == null) {
|
||||
return R.fail("飞燕平台配置未启用");
|
||||
}
|
||||
com.intc.iot.domain.IotDeviceStatus status = deviceStatusService.queryDeviceStatus(productKey, deviceName);
|
||||
return R.ok(status);
|
||||
|
||||
// 根据设备类型获取 ProductKey
|
||||
String productKey = aliyunIotProperties.getDeviceType().getProductKeyByType(devicetype);
|
||||
if (productKey == null || productKey.isEmpty()) {
|
||||
return R.fail("未配置该设备类型的 ProductKey,请检查配置文件(deviceType: " + devicetype + ")");
|
||||
}
|
||||
|
||||
// 先查询设备信息获取 iotId
|
||||
Map<String, Object> deviceInfo = iotDeviceService.findDeviceByProductKeyAndName(productKey, serialnum);
|
||||
|
||||
// 检查返回结果
|
||||
if (deviceInfo == null || !Boolean.TRUE.equals(deviceInfo.get("success"))) {
|
||||
String errorMsg = deviceInfo != null ? (String) deviceInfo.get("errorMessage") : "查询失败";
|
||||
return R.fail("未找到该设备,ProductKey: " + productKey + ", DeviceName: " + serialnum + ", 原因: " + errorMsg);
|
||||
}
|
||||
|
||||
// 从返回结构中提取设备信息
|
||||
Map<String, Object> data = (Map<String, Object>) deviceInfo.get("data");
|
||||
if (data == null || !data.containsKey("deviceList")) {
|
||||
return R.fail("设备信息格式异常");
|
||||
}
|
||||
|
||||
java.util.List<?> deviceList = (java.util.List<?>) data.get("deviceList");
|
||||
if (deviceList == null || deviceList.isEmpty()) {
|
||||
return R.fail("未找到该设备,ProductKey: " + productKey + ", DeviceName: " + serialnum);
|
||||
}
|
||||
|
||||
// 获取第一个设备对象
|
||||
Object deviceObj = deviceList.get(0);
|
||||
String iotId = null;
|
||||
|
||||
// 尝试从设备对象中提取 iotId
|
||||
if (deviceObj instanceof Map) {
|
||||
iotId = (String) ((Map<?, ?>) deviceObj).get("iotId");
|
||||
} else {
|
||||
// 如果是 SDK 对象,尝试通过反射获取
|
||||
try {
|
||||
java.lang.reflect.Method method = deviceObj.getClass().getMethod("getIotId");
|
||||
iotId = (String) method.invoke(deviceObj);
|
||||
} catch (Exception ex) {
|
||||
log.error("无法从设备对象中获取 iotId: {}", ex.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
if (iotId == null || iotId.isEmpty()) {
|
||||
return R.fail("设备 iotId 为空");
|
||||
}
|
||||
// 查询设备详情(包含在线状态)
|
||||
Map<String, Object> deviceDetail = iotDeviceService.queryDeviceInfo(iotId);
|
||||
|
||||
// 从设备详情中提取状态并转换为前端需要的状态码
|
||||
Object detailData = deviceDetail.get("data");
|
||||
Integer statusCode = 0; // 默认为设备未激活
|
||||
|
||||
if (detailData instanceof Map) {
|
||||
Map<?, ?> detailMap = (Map<?, ?>) detailData;
|
||||
Object statusObj = detailMap.get("status");
|
||||
|
||||
if (statusObj != null) {
|
||||
String statusStr = statusObj.toString();
|
||||
// 根据物联网平台返回的状态转换为前端状态码
|
||||
// 0-未激活, 1-在线, 3-离线, 8-禁用
|
||||
if ("ONLINE".equalsIgnoreCase(statusStr) || "online".equals(statusStr)) {
|
||||
statusCode = 1;
|
||||
} else if ("OFFLINE".equalsIgnoreCase(statusStr) || "offline".equals(statusStr)) {
|
||||
statusCode = 3;
|
||||
} else if ("UNACTIVE".equalsIgnoreCase(statusStr) || "unactive".equals(statusStr)) {
|
||||
statusCode = 0;
|
||||
} else if ("DISABLE".equalsIgnoreCase(statusStr) || "disable".equals(statusStr)) {
|
||||
statusCode = 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 直接返回状态码给前端
|
||||
return R.ok(statusCode);
|
||||
} catch (Exception e) {
|
||||
log.error("查询设备状态失败: {}", e.getMessage());
|
||||
log.error("查询设备状态失败: {}", e.getMessage(), e);
|
||||
return R.fail("查询设备状态失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
@@ -465,13 +554,13 @@ public class IotController extends BaseController {
|
||||
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());
|
||||
@@ -582,4 +671,248 @@ public class IotController extends BaseController {
|
||||
return R.fail("清理失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
// ======================== 设备管理相关接口 ========================
|
||||
|
||||
@Operation(summary = "添加设备探测器(水质检测仪)")
|
||||
@PostMapping("/device/add_device_detector")
|
||||
public R<Void> addDeviceDetector(@RequestBody AddDeviceDetectorBo bo) {
|
||||
try {
|
||||
if (iotDeviceService == null) {
|
||||
return R.fail("飞燕平台配置未启用");
|
||||
}
|
||||
if (deviceMapper == null) {
|
||||
return R.fail("设备数据库服务未启用");
|
||||
}
|
||||
|
||||
// 获取当前登录用户ID
|
||||
Long userId = LoginHelper.getUserId();
|
||||
if (userId == null) {
|
||||
return R.fail("未登录或登录已过期");
|
||||
}
|
||||
|
||||
// 验证塘口是否存在且属于当前用户
|
||||
if (bo.getPondId() != null && bo.getPondId() > 0 && pondMapper != null) {
|
||||
long count = pondMapper.selectCount(
|
||||
new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<com.intc.fishery.domain.Pond>()
|
||||
.eq(com.intc.fishery.domain.Pond::getUserId, userId)
|
||||
.eq(com.intc.fishery.domain.Pond::getId, bo.getPondId())
|
||||
);
|
||||
if (count == 0) {
|
||||
return R.fail("塘口不存在或无权限访问");
|
||||
}
|
||||
}
|
||||
|
||||
// 检查设备是否已被绑定
|
||||
Device existDevice = deviceMapper.selectOne(
|
||||
new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<Device>()
|
||||
.eq(Device::getDeviceType, 1) // 1-水质检测仪
|
||||
.eq(Device::getSerialNum, bo.getSerialNum())
|
||||
);
|
||||
if (existDevice != null && existDevice.getUserId() != null) {
|
||||
return R.fail("该设备号已被绑定");
|
||||
}
|
||||
|
||||
// 获取水质检测仪的 ProductKey
|
||||
String productKey = aliyunIotProperties.getDeviceType().getWaterQualityMonitor();
|
||||
if (productKey == null || productKey.isEmpty()) {
|
||||
return R.fail("未配置水质检测仪的 ProductKey");
|
||||
}
|
||||
|
||||
// 查询设备基础信息
|
||||
Map<String, Object> deviceInfo = iotDeviceService.findDeviceByProductKeyAndName(productKey, bo.getSerialNum());
|
||||
if (deviceInfo == null || !Boolean.TRUE.equals(deviceInfo.get("success"))) {
|
||||
return R.fail("设备不存在");
|
||||
}
|
||||
|
||||
// 提取设备数据
|
||||
Map<String, Object> data = (Map<String, Object>) deviceInfo.get("data");
|
||||
if (data == null || !data.containsKey("deviceList")) {
|
||||
return R.fail("设备信息格式异常");
|
||||
}
|
||||
|
||||
java.util.List<?> deviceList = (java.util.List<?>) data.get("deviceList");
|
||||
if (deviceList == null || deviceList.isEmpty()) {
|
||||
return R.fail("设备不存在");
|
||||
}
|
||||
|
||||
Object deviceObj = deviceList.get(0);
|
||||
String iotId = null;
|
||||
String status = null;
|
||||
|
||||
// 提取 iotId 和 status
|
||||
if (deviceObj instanceof Map) {
|
||||
Map<?, ?> deviceMap = (Map<?, ?>) deviceObj;
|
||||
iotId = (String) deviceMap.get("iotId");
|
||||
Object statusObj = deviceMap.get("status");
|
||||
status = statusObj != null ? statusObj.toString() : null;
|
||||
} else {
|
||||
try {
|
||||
iotId = (String) deviceObj.getClass().getMethod("getIotId").invoke(deviceObj);
|
||||
Object statusObj = deviceObj.getClass().getMethod("getStatus").invoke(deviceObj);
|
||||
status = statusObj != null ? statusObj.toString() : null;
|
||||
} catch (Exception ex) {
|
||||
log.error("无法从设备对象中获取信息: {}", ex.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
if (iotId == null || iotId.isEmpty()) {
|
||||
return R.fail("设备 iotId 为空");
|
||||
}
|
||||
|
||||
// 检查设备状态
|
||||
if (status != null) {
|
||||
if ("UNACTIVE".equalsIgnoreCase(status)) {
|
||||
return R.fail("设备未激活");
|
||||
}
|
||||
if ("DISABLE".equalsIgnoreCase(status)) {
|
||||
return R.fail("设备禁用");
|
||||
}
|
||||
}
|
||||
|
||||
// 设置盐度补偿
|
||||
Map<String, Object> properties = new java.util.HashMap<>();
|
||||
properties.put("salinitySet", bo.getSalinityCompensation());
|
||||
String propertiesJson = cn.hutool.json.JSONUtil.toJsonStr(properties);
|
||||
Map<String, Object> setResult = iotDeviceService.setDeviceProperty(iotId, propertiesJson);
|
||||
if (setResult == null || !Boolean.TRUE.equals(setResult.get("success"))) {
|
||||
return R.fail("设置盐度补偿失败");
|
||||
}
|
||||
|
||||
// 获取设备属性
|
||||
Map<String, Object> deviceProperties = iotDeviceService.queryDeviceProperties(iotId);
|
||||
|
||||
// 初始化警告码:默认探头未校准 (0x0001)
|
||||
int warnCode = 0x0001;
|
||||
|
||||
// 计算设备数量,用于生成设备名称
|
||||
long deviceCount = deviceMapper.selectCount(
|
||||
new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<Device>()
|
||||
.eq(Device::getUserId, userId)
|
||||
.eq(Device::getDeviceType, 1)
|
||||
);
|
||||
|
||||
// 创建或更新设备信息
|
||||
Date now = new Date();
|
||||
boolean isNew = (existDevice == null);
|
||||
Device device = isNew ? new Device() : existDevice;
|
||||
|
||||
if (isNew) {
|
||||
device.setIotId(iotId);
|
||||
device.setSerialNum(bo.getSerialNum());
|
||||
device.setDeviceType(1); // 1-水质检测仪
|
||||
device.setDeadTime(new Date(now.getTime() + 365L * 24 * 60 * 60 * 1000)); // 一年后到期
|
||||
device.setIsOxygenUsed(1);
|
||||
} else {
|
||||
// 检查是否已过期
|
||||
if (device.getDeadTime() != null && now.after(device.getDeadTime())) {
|
||||
warnCode |= 0x0040; // 设备时间到期 (0x0040)
|
||||
}
|
||||
}
|
||||
|
||||
// 设置基本信息
|
||||
device.setUserId(userId);
|
||||
device.setDeviceName("溶解氧" + (deviceCount + 1));
|
||||
device.setBindTime(now);
|
||||
device.setPondId(bo.getPondId() != null && bo.getPondId() > 0 ? bo.getPondId() : null);
|
||||
device.setSalinityCompensation(bo.getSalinityCompensation());
|
||||
device.setOxyWarnLower(bo.getOxyWarnLower());
|
||||
device.setOxyWarnCallOpen(1);
|
||||
device.setOxyWarnCallNoDis(1);
|
||||
device.setTempWarnCallOpen(0);
|
||||
device.setTempWarnCallNoDis(0);
|
||||
|
||||
// 解析并设置设备属性
|
||||
if (deviceProperties != null && Boolean.TRUE.equals(deviceProperties.get("success"))) {
|
||||
Object propData = deviceProperties.get("data");
|
||||
if (propData instanceof Map) {
|
||||
Map<?, ?> propMap = (Map<?, ?>) propData;
|
||||
Object listObj = propMap.get("list");
|
||||
if (listObj instanceof java.util.List) {
|
||||
java.util.List<?> propList = (java.util.List<?>) listObj;
|
||||
for (Object item : propList) {
|
||||
if (item instanceof Map) {
|
||||
Map<?, ?> prop = (Map<?, ?>) item;
|
||||
String attribute = (String) prop.get("identifier");
|
||||
Object value = prop.get("value");
|
||||
|
||||
if (attribute != null && value != null) {
|
||||
switch (attribute) {
|
||||
case "dissolvedOxygen": // 溶解氧
|
||||
device.setValueDissolvedOxygen(Double.parseDouble(value.toString()));
|
||||
break;
|
||||
case "currentTemperature": // 温度
|
||||
device.setValueTemperature(Double.parseDouble(value.toString()));
|
||||
break;
|
||||
case "dosat": // 饱和度
|
||||
device.setValueSaturability(Double.parseDouble(value.toString()));
|
||||
break;
|
||||
case "PH":
|
||||
device.setValuePh(Double.parseDouble(value.toString()));
|
||||
break;
|
||||
case "salinity": // 盐度
|
||||
device.setValueSalinity(Double.parseDouble(value.toString()));
|
||||
break;
|
||||
case "sensorErrorCode": // 警告码
|
||||
try {
|
||||
int errorCode = Integer.parseInt(value.toString());
|
||||
warnCode |= errorCode;
|
||||
} catch (NumberFormatException e) {
|
||||
log.warn("无法解析警告码: {}", value);
|
||||
}
|
||||
break;
|
||||
case "Tcorrect": // 设备校准状态
|
||||
try {
|
||||
int tcorrect = Integer.parseInt(value.toString());
|
||||
if (tcorrect == 1) {
|
||||
warnCode &= ~0x0001; // 清除未校准标记
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
log.warn("无法解析校准状态: {}", value);
|
||||
}
|
||||
break;
|
||||
case "ICCID": // 物联网卡号
|
||||
device.setIccId(value.toString());
|
||||
break;
|
||||
case "Treference": // 参比值
|
||||
device.setTreference(Double.parseDouble(value.toString()));
|
||||
break;
|
||||
case "Tfluorescence": // 荧光值
|
||||
device.setTfluorescence(Double.parseDouble(value.toString()));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 如果设备离线,添加离线警告
|
||||
if (status != null && "OFFLINE".equalsIgnoreCase(status)) {
|
||||
warnCode |= 0x0080; // 设备离线 (0x0080)
|
||||
}
|
||||
|
||||
device.setWarnCode(warnCode);
|
||||
|
||||
// 验证 ICCID 是否存在
|
||||
if (device.getIccId() == null || device.getIccId().isEmpty()) {
|
||||
return R.fail("设备缺少物联网卡号(ICCID)");
|
||||
}
|
||||
|
||||
// 保存到数据库
|
||||
if (isNew) {
|
||||
deviceMapper.insert(device);
|
||||
log.info("新设备添加成功: userId={}, iotId={}, serialNum={}", userId, iotId, bo.getSerialNum());
|
||||
} else {
|
||||
deviceMapper.updateById(device);
|
||||
log.info("设备更新成功: userId={}, iotId={}, serialNum={}", userId, iotId, bo.getSerialNum());
|
||||
}
|
||||
|
||||
return R.ok();
|
||||
} catch (Exception e) {
|
||||
log.error("添加设备失败: {}", e.getMessage(), e);
|
||||
return R.fail("添加设备失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
package com.intc.iot.domain.bo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 添加设备探测器业务对象
|
||||
*
|
||||
* @author intc
|
||||
*/
|
||||
@Data
|
||||
@Schema(description = "添加设备探测器请求对象")
|
||||
public class AddDeviceDetectorBo implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 设备编号/序列号
|
||||
*/
|
||||
@Schema(description = "设备编号/序列号")
|
||||
@NotBlank(message = "设备编号不能为空")
|
||||
private String serialNum;
|
||||
|
||||
/**
|
||||
* 塘口ID
|
||||
*/
|
||||
@Schema(description = "塘口ID")
|
||||
private Long pondId;
|
||||
|
||||
/**
|
||||
* 盐度补偿值
|
||||
*/
|
||||
@Schema(description = "盐度补偿值")
|
||||
@NotNull(message = "盐度补偿值不能为空")
|
||||
private Double salinityCompensation;
|
||||
|
||||
/**
|
||||
* 溶解氧报警下限
|
||||
*/
|
||||
@Schema(description = "溶解氧报警下限")
|
||||
@NotNull(message = "溶解氧报警下限不能为空")
|
||||
private Double oxyWarnLower;
|
||||
}
|
||||
Reference in New Issue
Block a user