Forráskód Böngészése

fix: TypeReference

jackzhou 6 hónapja
szülő
commit
34a29f3008
22 módosított fájl, 361 hozzáadás és 128 törlés
  1. 13 1
      snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/core/alarm/bean/SensorAlarm.java
  2. 2 0
      snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/core/alarm/bean/SensorThreshold.java
  3. 31 19
      snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/core/alarm/service/check/DefaultSensorAlarmChecker.java
  4. 10 8
      snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/core/alarm/service/messagepush/SensorAlarmMessagePushService.java
  5. 6 11
      snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/core/cache/monitordevice/MonitorDeviceCacheInitializer.java
  6. 80 0
      snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/core/handler/IntegerListTypeHandler.java
  7. 22 0
      snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/core/handler/ParamItemTypeHandler.java
  8. 1 0
      snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/core/handler/SensorAlarmUserTypeHandler.java
  9. 48 33
      snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/core/handler/abs/ListTypeHandler.java
  10. 3 0
      snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/core/renke/listener/JfcloudColdChainRenKeDefaultDataListener.java
  11. 84 19
      snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/core/service/dataprocess/dataclean/impl/AbsRenkeMonitorDataProcessor.java
  12. 0 6
      snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/core/service/dataprocess/handler/AbstractColdChainDataHandler.java
  13. 8 0
      snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/core/service/dataprocess/handler/ColdChainDataHandler.java
  14. 6 0
      snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/core/service/dataprocess/handler/impl/HaierColdChainDataHandler.java
  15. 25 4
      snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/core/service/dataprocess/handler/impl/RenKeColdChainDataHandler.java
  16. 3 0
      snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/core/service/dataprocess/model/RenKeColdChainMessageData.java
  17. 1 1
      snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/modular/app/service/AppDeviceService.java
  18. 11 7
      snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/modular/monitordevice/entity/MonitorDevice.java
  19. 0 8
      snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/modular/monitordevice/mapper/mapping/MonitorDeviceMapper.xml
  20. 2 3
      snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/modular/monitordevice/service/impl/MonitorDeviceServiceImpl.java
  21. 1 1
      snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/modular/monitortarget/entity/MonitorTarget.java
  22. 4 7
      snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/modular/monitortargetregion/entity/MonitorTargetRegion.java

+ 13 - 1
snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/core/alarm/bean/SensorAlarm.java

@@ -21,7 +21,7 @@ import java.util.List;
  * @date 2024/11/26
  */
 @Data
-@TableName("sensor_alarm")
+@TableName(value = "sensor_alarm", autoResultMap = true)
 public class SensorAlarm extends CommonEntity {
     @TableId(type = IdType.ASSIGN_UUID)
     private String id;
@@ -127,6 +127,18 @@ public class SensorAlarm extends CommonEntity {
     @Schema(description = "微信请求状态码")
     private String weixinRequestCode;
 
+    /**
+     * 传感器路数
+     */
+    @Schema(description = "传感器路数")
+    private Integer sensorRoute;
+
+    /**
+     * 监控监控对象
+     */
+    @Schema(description = "监控监控对象")
+    private String monitorTargetId;
+
 
     public SensorAlarm() {
     }

+ 2 - 0
snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/core/alarm/bean/SensorThreshold.java

@@ -1,6 +1,7 @@
 package vip.xiaonuo.coldchain.core.alarm.bean;
 
 import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fasterxml.jackson.annotation.JsonIgnore;
 import com.fasterxml.jackson.databind.annotation.JsonSerialize;
 import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Data;
@@ -64,6 +65,7 @@ public class SensorThreshold {
     private Float co2Down;
 
     @Schema(description = "设备探头信息")
+    @JsonIgnore
     private MonitorTargetRegion monitorTargetRegion;
 
     public SensorThreshold() {

+ 31 - 19
snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/core/alarm/service/check/DefaultSensorAlarmChecker.java

@@ -1,5 +1,6 @@
 package vip.xiaonuo.coldchain.core.alarm.service.check;
 
+import cn.hutool.json.JSONUtil;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.context.ApplicationEventPublisher;
@@ -12,9 +13,11 @@ import vip.xiaonuo.coldchain.core.alarm.service.threshold.SensorThresholdService
 import vip.xiaonuo.coldchain.core.bean.influxdb.SensorData;
 import vip.xiaonuo.coldchain.core.event.SensorAlarmEvent;
 import vip.xiaonuo.coldchain.core.util.DateFormatter;
+import vip.xiaonuo.coldchain.modular.monitortargetregion.entity.MonitorTargetRegion;
 
 import java.text.SimpleDateFormat;
 import java.util.Date;
+import java.util.List;
 
 @Component
 @RequiredArgsConstructor
@@ -37,18 +40,17 @@ public class DefaultSensorAlarmChecker implements SensorAlarmChecker {
             log.warn("没有找到设备 {} 的阈值配置", sensorData.getDeviceId());
             return false;
         }
-        final String deviceName = threshold.getMonitorTargetRegion().getName();
-        final String deviceId = threshold.getMonitorTargetRegion().getMonitorTargetId();
+        MonitorTargetRegion monitorTargetRegion = threshold.getMonitorTargetRegion();
         // 检查传感器数据并触发报警
         boolean alarmTriggered = false;
         if (isNull(sensorData.getTemperature())) {
-            alarmTriggered = checkThreshold(sensorData.getTemperature(), threshold.getTemperatureUp(), threshold.getTemperatureDown(), "温度", deviceName, deviceId);
+            alarmTriggered = checkThreshold(sensorData.getTemperature(), threshold.getTemperatureUp(), threshold.getTemperatureDown(), "温度", monitorTargetRegion);
         }
         if (isNull(sensorData.getHumidity())) {
-            alarmTriggered |= checkThreshold(sensorData.getHumidity(), threshold.getHumidityUp(), threshold.getHumidityDown(), "湿度", deviceName, deviceId);
+            alarmTriggered |= checkThreshold(sensorData.getHumidity(), threshold.getHumidityUp(), threshold.getHumidityDown(), "湿度", monitorTargetRegion);
         }
         if (isNull(sensorData.getCo2())) {
-            alarmTriggered |= checkThreshold(sensorData.getCo2(), threshold.getCo2Up(), threshold.getCo2Down(), "二氧化碳", deviceName, deviceId);
+            alarmTriggered |= checkThreshold(sensorData.getCo2(), threshold.getCo2Up(), threshold.getCo2Down(), "二氧化碳", monitorTargetRegion);
         }
         return alarmTriggered;
     }
@@ -60,20 +62,19 @@ public class DefaultSensorAlarmChecker implements SensorAlarmChecker {
      * @param upperThreshold 阈值上限
      * @param lowerThreshold 阈值下限
      * @param type           数据类型(温度、湿度、二氧化碳)
-     * @param deviceName     设备名称
      * @return 是否触发报警
      */
-    private boolean checkThreshold(Float value, Float upperThreshold, Float lowerThreshold, String type, String deviceName, String deviceId) {
+    private boolean checkThreshold(Float value, Float upperThreshold, Float lowerThreshold, String type, MonitorTargetRegion monitorTargetRegion) {
         boolean alarmTriggered = false;
         String time = DATE_FORMAT.format(new Date()); // 获取当前时间
         String unit = getUnit(type);
         if (value > upperThreshold) {
             // 超过上限,触发超标报警
-            publishAlarm(type + "超标", value, unit, deviceName, time, upperThreshold, deviceId);
+            publishAlarm(type + "超标", value, unit, time, upperThreshold, monitorTargetRegion);
             alarmTriggered = true;
         } else if (value < lowerThreshold) {
             // 低于下限,触发低于阈值报警
-            publishAlarm(type + "过低", value, unit, deviceName, time, lowerThreshold, deviceId);
+            publishAlarm(type + "过低", value, unit, time, lowerThreshold, monitorTargetRegion);
             alarmTriggered = true;
         }
         return alarmTriggered;
@@ -83,16 +84,17 @@ public class DefaultSensorAlarmChecker implements SensorAlarmChecker {
     /**
      * 发布报警事件
      *
-     * @param alarmType  报警类型(例如 温度超标、湿度过低等)
-     * @param value      传感器数据值
-     * @param unit       传感器数据单位
-     * @param deviceName 设备名称
-     * @param time       时间戳
+     * @param alarmType 报警类型(例如 温度超标、湿度过低等)
+     * @param value     传感器数据值
+     * @param unit      传感器数据单位
+     * @param time      时间戳
      */
-    private void publishAlarm(String alarmType, Float value, String unit, String deviceName, String time, float threshold, String deviceId) {
-        // 获取对应的报警消息模板
+    private void publishAlarm(String alarmType, Float value, String unit, String time, float threshold, MonitorTargetRegion monitorTargetRegion) {
+        String monitorTargetId = monitorTargetRegion.getMonitorTargetId();
+        Integer sensorRoute = monitorTargetRegion.getSensorRoute();
+        String deviceName = monitorTargetRegion.getName();
+        String deviceId = monitorTargetRegion.getId();
         String alarmMessage = getAlarmMessage(alarmType, value, unit, deviceName, time, threshold);
-        // 构建 SensorAlarm 对象
         SensorAlarm sensorAlarm = new SensorAlarm();
         sensorAlarm.setAlarmType(alarmType);  // 设置报警类型(例如 温度超标、湿度过低等)
         sensorAlarm.setValue(value);  // 设置传感器值
@@ -105,14 +107,24 @@ public class DefaultSensorAlarmChecker implements SensorAlarmChecker {
         sensorAlarm.setAlarmTime(time);  // 设置报警时间
         sensorAlarm.setMessage(alarmMessage);  // 设置报警消息
         sensorAlarm.setThreshold(threshold);  // 设置预警值
-        sensorAlarm.getAlarmUsers().add(new SensorAlarmUser(null, "oltp26cDdkiAAsualbzKMyiZbJrU"));
-        sensorAlarm.getAlarmUsers().add(new SensorAlarmUser(null, "oltp26fXeljOKUxYGhAx_dRqVAak"));
+        sensorAlarm.setMonitorTargetId(monitorTargetId);
+        sensorAlarm.setSensorRoute(sensorRoute);
+        List<SensorAlarmUser> alarmUsers = monitorTargetRegion.getAlarmUsers();
+        sensorAlarm.setAlarmUsers(alarmUsers);
+        sensorAlarm.setThreshold(threshold);
         log.warn("触发报警: 类型: {},详细报警内容 : {}", alarmType, alarmMessage);
         // 发布报警事件
         applicationEventPublisher.publishEvent(new SensorAlarmEvent(this, sensorAlarm));
     }
 
 
+    public static void main(String[] args) {
+        SensorAlarm sensorAlarm = new SensorAlarm();
+        sensorAlarm.getAlarmUsers().add(new SensorAlarmUser(null, "oltp26cDdkiAAsualbzKMyiZbJrU"));
+        sensorAlarm.getAlarmUsers().add(new SensorAlarmUser(null, "oltp26fXeljOKUxYGhAx_dRqVAak"));
+        System.out.println(JSONUtil.toJsonStr(sensorAlarm.getAlarmUsers()));
+    }
+
     /**
      * 获取报警消息模板并替换占位符
      *

+ 10 - 8
snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/core/alarm/service/messagepush/SensorAlarmMessagePushService.java

@@ -10,9 +10,7 @@ import vip.xiaonuo.coldchain.core.alarm.bean.SensorAlarmUser;
 import vip.xiaonuo.coldchain.core.alarm.mapper.SensorAlarmMapper;
 import vip.xiaonuo.coldchain.core.config.JfcloudColdChainConstants;
 
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
 import java.util.concurrent.ConcurrentHashMap;
 
 @Service
@@ -34,22 +32,26 @@ public class SensorAlarmMessagePushService {
     public void pushAlarmMessage(SensorAlarm alarm) {
         String deviceID = alarm.getDeviceId(); // 获取设备ID
         String alarmType = alarm.getAlarmType(); // 获取告警类型
-        List<String> openids = alarm.getAlarmUsers().stream().map(SensorAlarmUser::getOpenId).toList();
-        // 遍历每个 openid,针对每个用户进行推送次数限制和推送
+        List<String> openids = Optional.ofNullable(alarm.getAlarmUsers())
+                .orElse(Collections.emptyList())
+                .stream()
+                .filter(Objects::nonNull)
+                .map(SensorAlarmUser::getOpenId)
+                .filter(Objects::nonNull)
+                .toList();
+
         for (String openid : openids) {
             // 判断该用户对该设备和告警类型的推送是否超过限制
             if (hasExceededPushLimit(openid, deviceID, alarmType)) {
-                log.info("用户 {} 对设备 {} 的告警类型 {} 在过去一个小时内推送次数超过限制,跳过推送", openid, deviceID, alarmType);
+                log.info("用户 {} 对设备 {} 的告警类型 {} 在过去{}小时内推送次数超过限制,跳过推送", openid, deviceID, alarmType, JfcloudColdChainConstants.MESS_PUSH_TIME_WINDOW / 60 / 60 / 1000);
                 continue; // 跳过该用户
             }
             // 遍历每个接收人和通知渠道,发送告警信息
             for (NotificationChannel channel : alarm.getNotificationChannel()) {
                 MessagePushService pushService = pushServices.get(channel.name());
                 log.info("推送消息渠道: {}", channel.getChannelName());
-
                 if (pushService != null) {
                     try {
-                        // 调用推送服务
                         pushService.sendAlarmMessage(alarm);
                         log.info("告警信息成功推送至渠道: {}", channel.getChannelName());
                     } catch (Exception e) {

+ 6 - 11
snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/core/cache/monitordevice/MonitorDeviceCacheInitializer.java

@@ -1,13 +1,11 @@
 package vip.xiaonuo.coldchain.core.cache.monitordevice;
 
-import cn.hutool.core.lang.TypeReference;
-import cn.hutool.core.util.StrUtil;
-import cn.hutool.json.JSONUtil;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.boot.CommandLineRunner;
 import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.stereotype.Component;
+import rk.netDevice.sdk.p2.ParamItem;
 import vip.xiaonuo.coldchain.core.renke.RenKeService;
 import vip.xiaonuo.coldchain.modular.monitordevice.entity.MonitorDevice;
 import vip.xiaonuo.coldchain.modular.monitordevice.service.MonitorDeviceService;
@@ -49,19 +47,16 @@ public class MonitorDeviceCacheInitializer implements CommandLineRunner {
                 }
                 Integer parsedDeviceCode = Integer.parseInt(deviceCode);
                 // 调用设备编号配置上报参数接口
-                String paramIds = monitorDevice.getParamIds();
-                if (paramIds == null || StrUtil.isBlank(paramIds)) {  // Explicitly check for null and empty list
+                List<Integer> paramIds = monitorDevice.getParamIds();
+                if (paramIds == null || paramIds.isEmpty()) {  // Explicitly check for null and empty list
                     log.info("触发设备【编号】配置上报参数接口:采集设备编号 = {}, 采集设备型号 = {}", deviceCode, deviceModel);
                     renKeService.callParamIds(parsedDeviceCode);
                 }
                 // 调用设备参数配置上报参数接口
-                String parameters = monitorDevice.getParameters();
-                if (StrUtil.isNotBlank(paramIds) && StrUtil.isBlank(parameters)) {  // Check for null and empty list
+                List<ParamItem> parameters = monitorDevice.getParameters();
+                if (paramIds!=null && (parameters==null || parameters.isEmpty())) {  // Check for null and empty list
                     log.info("触发设备【完整参数】配置上报参数接口:采集设备编号 = {}, 采集设备型号 = {}", deviceCode, deviceModel);
-                    TypeReference<List<Integer>> typeReference = new TypeReference<>() {
-                    };
-                    List<Integer> paramId2s = JSONUtil.toBean(paramIds, typeReference, true);
-                    renKeService.callParameters(parsedDeviceCode, paramId2s);
+                    renKeService.callParameters(parsedDeviceCode, paramIds);
                 }
 
                 // 判断设备是否已经缓存

+ 80 - 0
snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/core/handler/IntegerListTypeHandler.java

@@ -0,0 +1,80 @@
+package vip.xiaonuo.coldchain.core.handler;
+
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.json.JSONUtil;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.ibatis.type.BaseTypeHandler;
+import org.apache.ibatis.type.JdbcType;
+import org.apache.ibatis.type.MappedJdbcTypes;
+import org.apache.ibatis.type.MappedTypes;
+
+import java.sql.CallableStatement;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.List;
+
+@Slf4j
+@MappedJdbcTypes(JdbcType.VARCHAR)
+@MappedTypes({List.class})
+public class IntegerListTypeHandler extends BaseTypeHandler<List<Integer>> {
+
+    @Override
+    public void setNonNullParameter(PreparedStatement preparedStatement, int i, List<Integer> ts, JdbcType jdbcType) throws SQLException {
+        String content = (ts == null || ts.isEmpty()) ? null : toJSONString(ts);  // 将 List 转换为 JSON 字符串
+        preparedStatement.setString(i, content);  // 存储为 VARCHAR 类型
+    }
+
+    @Override
+    public List<Integer> getNullableResult(ResultSet resultSet, String s) throws SQLException {
+        try {
+            String content = resultSet.getString(s);
+            return this.getListByJsonArrayString(content);
+        } catch (JsonProcessingException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    @Override
+    public List<Integer> getNullableResult(ResultSet resultSet, int i) throws SQLException {
+        try {
+            String content = resultSet.getString(i);
+            return this.getListByJsonArrayString(content);
+        } catch (JsonProcessingException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    @Override
+    public List<Integer> getNullableResult(CallableStatement callableStatement, int i) throws SQLException {
+        try {
+            String content = callableStatement.getString(i);
+            return this.getListByJsonArrayString(content);
+        } catch (JsonProcessingException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    public List<Integer> getListByJsonArrayString(String content) throws JsonProcessingException {
+        if (StrUtil.isEmpty(content)) {
+            return new ArrayList<>();
+        } else {
+            return new ObjectMapper().readValue(content, new TypeReference<List<Integer>>() {});  // 反序列化为 List<Integer>
+        }
+    }
+
+    /**
+     * 将对象转换为 JSON 字符串
+     */
+    public String toJSONString(Object obj) {
+        try {
+            return (obj == null) ? null : JSONUtil.toJsonStr(obj);
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+}

+ 22 - 0
snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/core/handler/ParamItemTypeHandler.java

@@ -0,0 +1,22 @@
+package vip.xiaonuo.coldchain.core.handler;
+
+import com.fasterxml.jackson.core.type.TypeReference;
+import rk.netDevice.sdk.p2.ParamItem;
+import vip.xiaonuo.coldchain.core.handler.abs.ListTypeHandler;
+
+import java.util.List;
+
+/**
+ * @author jackzhou
+ * @version 1.0
+ * @project jfcloud-coldchain
+ * @description
+ * @date 2024/11/27 13:34:43
+ */
+public class ParamItemTypeHandler extends ListTypeHandler<ParamItem> {
+    @Override
+    public TypeReference<List<ParamItem>> specificType() {
+        return new TypeReference<List<ParamItem>>() {
+        };
+    }
+}

+ 1 - 0
snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/core/handler/SensorAlarmUserTypeHandler.java

@@ -18,4 +18,5 @@ public class SensorAlarmUserTypeHandler extends ListTypeHandler<SensorAlarmUser>
     public TypeReference<List<SensorAlarmUser>> specificType() {
         return new TypeReference<List<SensorAlarmUser>>() {};
     }
+
 }

+ 48 - 33
snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/core/handler/abs/ListTypeHandler.java

@@ -1,13 +1,5 @@
 package vip.xiaonuo.coldchain.core.handler.abs;
 
-/**
- * @author jackzhou
- * @version 1.0
- * @project jfcloud-coldchain
- * @description
- * @date 2024/11/20 16:45:56
- */
-
 import cn.hutool.core.collection.CollectionUtil;
 import cn.hutool.json.JSONUtil;
 import com.fasterxml.jackson.core.JsonProcessingException;
@@ -27,71 +19,94 @@ import java.sql.SQLException;
 import java.util.ArrayList;
 import java.util.List;
 
+/**
+ * 自定义 MyBatis 类型处理器,用于处理 List<T> 类型的字段,存储为字符串(JSON 格式)。
+ * @param <T> 泛型类型
+ */
 @Slf4j
-@MappedJdbcTypes(JdbcType.VARCHAR)
+@MappedJdbcTypes({JdbcType.VARCHAR})
 @MappedTypes({List.class})
-public class ListTypeHandler<T> extends BaseTypeHandler<List<T>> {
+public abstract class ListTypeHandler<T> extends BaseTypeHandler<List<T>> {
+    // 静态实例化 ObjectMapper,避免每次调用都创建新的实例
+    private static final ObjectMapper objectMapper = new ObjectMapper();
 
     public ListTypeHandler() {
     }
 
     @Override
     public void setNonNullParameter(PreparedStatement preparedStatement, int i, List<T> ts, JdbcType jdbcType) throws SQLException {
+        // 将 List<T> 转换为 JSON 字符串存储
         String content = CollectionUtil.isEmpty(ts) ? null : this.toJSONString(ts);
         preparedStatement.setString(i, content);
     }
 
     @Override
-    public List<T> getNullableResult(ResultSet resultSet, String s) throws SQLException {
+    public List<T> getNullableResult(ResultSet resultSet, String columnName) throws SQLException {
         try {
-            return this.getListByJsonArrayString(resultSet.getString(s));
+            return this.getListByJsonArrayString(resultSet.getString(columnName));
         } catch (JsonProcessingException e) {
-            throw new RuntimeException(e);
+            log.error("从 ResultSet 获取数据并转换为 List<T> 时出错,column: {}", columnName, e);
+            throw new SQLException("JSON 解析错误", e);
         }
     }
 
     @Override
-    public List<T> getNullableResult(ResultSet resultSet, int i) throws SQLException {
+    public List<T> getNullableResult(ResultSet resultSet, int columnIndex) throws SQLException {
         try {
-            return this.getListByJsonArrayString(resultSet.getString(i));
+            return this.getListByJsonArrayString(resultSet.getString(columnIndex));
         } catch (JsonProcessingException e) {
-            throw new RuntimeException(e);
+            log.error("从 ResultSet 获取数据并转换为 List<T> 时出错,columnIndex: {}", columnIndex, e);
+            throw new SQLException("JSON 解析错误", e);
         }
     }
 
     @Override
-    public List<T> getNullableResult(CallableStatement callableStatement, int i) throws SQLException {
+    public List<T> getNullableResult(CallableStatement callableStatement, int parameterIndex) throws SQLException {
         try {
-            return this.getListByJsonArrayString(callableStatement.getString(i));
+            return this.getListByJsonArrayString(callableStatement.getString(parameterIndex));
         } catch (JsonProcessingException e) {
-            throw new RuntimeException(e);
+            log.error("从 CallableStatement 获取数据并转换为 List<T> 时出错,parameterIndex: {}", parameterIndex, e);
+            throw new SQLException("JSON 解析错误", e);
         }
     }
 
-    private List<T> getListByJsonArrayString(String content) throws JsonProcessingException {
-        return StringUtils.isEmpty(content) ? new ArrayList<>() : new ObjectMapper().readValue(content, this.specificType());
+    /**
+     * 将 JSON 字符串转换为 List<T>。
+     * @param content JSON 字符串
+     * @return List<T> 对象
+     * @throws JsonProcessingException 如果 JSON 解析失败
+     */
+    public List<T> getListByJsonArrayString(String content) throws JsonProcessingException {
+        if (StringUtils.isEmpty(content)) {
+            return new ArrayList<>();
+        } else {
+            try {
+                return objectMapper.readValue(content, this.specificType());
+            } catch (JsonProcessingException e) {
+                log.error("JSON 解析失败,无法将字符串转换为 List<T>,content: {}", content, e);
+                throw e;
+            }
+        }
     }
 
     /**
      * 默认的 TypeReference 提供了 List<T> 的类型信息。
      * 子类可以覆盖此方法以提供更具体的类型信息。
+     * @return List<T> 的 TypeReference 类型信息
      */
+    public abstract TypeReference<List<T>> specificType();
+
     /**
-     * 返回 List<T> 的 TypeReference 类型信息。
-     * 可以直接用于 JSON 反序列化。
+     * 将对象转换为 JSON 字符串。
+     * @param obj 对象
+     * @return JSON 字符串
      */
-    public TypeReference<List<T>> specificType() {
-        return new TypeReference<List<T>>() {}; // 默认返回 List<T> 类型
-    }
-
-
     public String toJSONString(Object obj) {
         try {
-            return null == obj ? null : JSONUtil.toJsonStr(obj);
-        } catch (Exception var2) {
-            throw new RuntimeException(var2);
+            return obj == null ? null : JSONUtil.toJsonStr(obj);
+        } catch (Exception e) {
+            log.error("对象转换为 JSON 字符串时失败,obj: {}", obj, e);
+            throw new RuntimeException("对象转换为 JSON 失败", e);
         }
     }
 }
-
-

+ 3 - 0
snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/core/renke/listener/JfcloudColdChainRenKeDefaultDataListener.java

@@ -49,6 +49,9 @@ public class JfcloudColdChainRenKeDefaultDataListener implements IDataListener {
 
         data.getNodeList().forEach(nodeData -> log.info("记录ID: {}, 记录时间: {}, 温度: {}, 湿度: {}", nodeData.getNodeId(), nodeData.getRecordTime(), nodeData.getTem(), nodeData.getHum()));
         log.info("*************************************************************************");
+        RenKeColdChainMessageData renKeColdChainMessageData = new RenKeColdChainMessageData();
+        renKeColdChainMessageData.setStoreData(data);
+        renKeColdChainDataHandler.handleStoreData(renKeColdChainMessageData);
     }
 
     @Override

+ 84 - 19
snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/core/service/dataprocess/dataclean/impl/AbsRenkeMonitorDataProcessor.java

@@ -1,19 +1,24 @@
 package vip.xiaonuo.coldchain.core.service.dataprocess.dataclean.impl;
 
 import com.github.jfcloud.influxdb.util.InfluxdbTypeConverter;
+import com.google.common.collect.Lists;
 import lombok.SneakyThrows;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.context.ApplicationEventPublisher;
+import rk.netDevice.sdk.p2.NodeData;
 import rk.netDevice.sdk.p2.RealTimeData;
+import rk.netDevice.sdk.p2.StoreData;
 import vip.xiaonuo.coldchain.core.bean.influxdb.SensorData;
 import vip.xiaonuo.coldchain.core.event.MonitorDeviceHeartBeatEvent;
 import vip.xiaonuo.coldchain.core.event.MonitorDeviceLoginEvent;
 import vip.xiaonuo.coldchain.core.event.SensorDataEvent;
 import vip.xiaonuo.coldchain.core.service.dataprocess.dataclean.MonitorDataProcessor;
 import vip.xiaonuo.coldchain.core.service.dataprocess.model.RenKeColdChainMessageData;
+import vip.xiaonuo.coldchain.core.util.DateFormatter;
 import vip.xiaonuo.coldchain.modular.monitordevice.enums.DeviceModelEnum;
 
 import java.time.Instant;
+import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
 import java.util.Objects;
@@ -51,37 +56,99 @@ public abstract class AbsRenkeMonitorDataProcessor implements MonitorDataProcess
      */
     @Override
     public Boolean processData(RenKeColdChainMessageData renKeColdChainMessageData) {
-        RealTimeData data = renKeColdChainMessageData.getRealTimeData();
-        // 1. 确保实时数据不为空
-        if (Objects.isNull(data) || Objects.isNull(data.getNodeList()) || data.getNodeList().isEmpty()) {
+        // Step 1: 检查输入数据是否为 null
+        if (Objects.isNull(renKeColdChainMessageData)) {
+            log.error("接收到的处理数据为空.");
             return false;
         }
-        // 2. 数据前处理(如果有需要)
-        preProcess(data);
-        // 3. 获取设备ID,并从设备缓存中获取设备型号
-        final String deviceId = String.valueOf(data.getDeviceId());
-        // 4. 日志记录:输出当前设备的型号信息
-//        log.info("开始处理设备数据,设备ID: {}, 设备型号: {}", deviceId, getModelName());
-        // 5. 将实时数据转换为传感器数据列表
-        List<SensorData> sensorDataList = transRealTimeData2SensorDatas(data);
-        // 6. 发布传感器数据事件
+        // Step 2: 初始化数据和设备型号
+        RealTimeData realTimeData = renKeColdChainMessageData.getRealTimeData();
+        StoreData storeData = renKeColdChainMessageData.getStoreData();
+        // 保存数据集合
+        List<SensorData> sensorDataList = Lists.newArrayList();
+        this.modelName = renKeColdChainMessageData.getModelName();
+        // Step 3: 进行数据前处理
+        preProcess(renKeColdChainMessageData);
+        final String deviceId = String.valueOf(realTimeData.getDeviceId());
+        // Step 4: 处理实时数据
+        if (isValidRealTimeData(realTimeData)) {
+            List<SensorData> realTimeSensorData = transRealTimeData2SensorDatas(realTimeData);
+            if (realTimeSensorData != null && !realTimeSensorData.isEmpty()) {
+                sensorDataList.addAll(realTimeSensorData);
+            } else {
+                log.warn("设备ID: {} 的实时数据中没有有效的传感器数据", deviceId);
+            }
+        }
+        // Step 5: 处理缓存数据(存储数据)
+        if (isValidStoreData(storeData)) {
+            List<SensorData> storeSensorData = transStoreData2SensorDatas(storeData);
+            if (storeSensorData != null && !storeSensorData.isEmpty()) {
+                sensorDataList.addAll(storeSensorData);
+            } else {
+                log.warn("设备ID: {} 的缓存数据中没有有效的传感器数据", deviceId);
+            }
+        }
+        // Step 6: 保存传感器数据(实时数据 + 缓存数据)
         boolean result = writeSensorDatas(sensorDataList);
-        // 7. 日志记录:输出处理结果
+        // Step 7: 输出处理结果日志,并在保存成功后进行后置处理
         if (result) {
             postProcess(sensorDataList);
+            log.info("设备ID: {}, 型号: {} 的数据处理成功", deviceId, modelName);
         } else {
-            log.error("处理设备数据结束,但保存失败,设备ID: {}, 设备型号: {}", deviceId, getModelName());
+            log.error("设备ID: {}, 型号: {} 的数据处理失败", deviceId, modelName);
         }
         return result;
     }
 
+    // 校验实时数据是否有效
+    private boolean isValidRealTimeData(RealTimeData data) {
+        return Objects.nonNull(data) && Objects.nonNull(data.getNodeList()) && !data.getNodeList().isEmpty();
+    }
+
+    // 校验缓存数据是否有效
+    private boolean isValidStoreData(StoreData data) {
+        return Objects.nonNull(data) && Objects.nonNull(data.getNodeList()) && !data.getNodeList().isEmpty();
+    }
+
+
+    /**
+     * 处理缓存数据
+     *
+     * @param storeData
+     * @return
+     */
+
+    protected List<SensorData> transStoreData2SensorDatas(StoreData storeData) {
+        List<SensorData> rlts = new ArrayList<>();
+        int deviceId = storeData.getDeviceId();
+        if (deviceId == 0 || Objects.isNull(storeData) || storeData.getNodeList() == null || storeData.getNodeList().size() == 0) {
+            return null;
+        }
+        List<NodeData> nodeList = storeData.getNodeList();
+        for (NodeData nodeData : nodeList) {
+            Date recordTime = nodeData.getRecordTime();
+            int nodeId = nodeData.getNodeId();
+            if (recordTime != null && nodeData.getCoordinateType() == 2) {
+                SensorData sensorData = new SensorData();
+                sensorData.setDeviceId(String.valueOf(deviceId));
+                sensorData.setRoads(nodeId);
+                sensorData.setModelName(modelName);
+                sensorData.setCreateTime(DateFormatter.now(recordTime));
+                sensorData.setTemperature(floatValue(nodeData.getTem()));
+                sensorData.setHumidity(floatValue(nodeData.getHum()));
+                rlts.add(sensorData);
+            }
+        }
+        return rlts;
+    }
+
     /**
      * 数据前处理
      * 子类可以重写此方法执行特定的预处理操作,如数据校验、转换等。
      *
      * @param data 实时数据
      */
-    protected void preProcess(RealTimeData data) {
+    protected void preProcess(RenKeColdChainMessageData data) {
         // 默认不做处理,子类可根据需求重写
     }
 
@@ -122,13 +189,13 @@ public abstract class AbsRenkeMonitorDataProcessor implements MonitorDataProcess
 
     /**
      * 发布传感器数据事件列表
+     * 待优化的功能  jackzhou-2024-1127
      *
      * @param sensorDataList 传感器数据列表
      * @return 是否成功发布所有事件
      */
     protected boolean writeSensorDatas(List<SensorData> sensorDataList) {
         if (sensorDataList.isEmpty()) {
-//            log.warn("传感器数据列表为空,无法发布事件");
             return false;
         }
         // 遍历传感器数据列表并发布每个数据的事件
@@ -143,7 +210,6 @@ public abstract class AbsRenkeMonitorDataProcessor implements MonitorDataProcess
                 return false;
             }
         }
-
         return true;
     }
 
@@ -191,8 +257,7 @@ public abstract class AbsRenkeMonitorDataProcessor implements MonitorDataProcess
             // 默认使用当前时间
             timestamp = new Date();
         }
-        applicationEventPublisher.publishEvent(eventType.getConstructor(Object.class, Integer.class, String.class, Date.class)
-                .newInstance(this, deviceId, null, timestamp));
+        applicationEventPublisher.publishEvent(eventType.getConstructor(Object.class, Integer.class, String.class, Date.class).newInstance(this, deviceId, null, timestamp));
     }
 
     @Override

+ 0 - 6
snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/core/service/dataprocess/handler/AbstractColdChainDataHandler.java

@@ -13,12 +13,6 @@ import java.lang.reflect.Type;
  * @date 2024/11/12 13:40:41
  */
 public abstract class AbstractColdChainDataHandler<T extends ColdChainMessageData> implements ColdChainDataHandler<T> {
-
-    /**
-     * 处理实时数据
-     */
-    public abstract boolean handleRealTimeData(T data);
-
     /**
      * 注册处理器到 HandlerRegistry
      */

+ 8 - 0
snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/core/service/dataprocess/handler/ColdChainDataHandler.java

@@ -1,6 +1,7 @@
 package vip.xiaonuo.coldchain.core.service.dataprocess.handler;
 
 import vip.xiaonuo.coldchain.core.service.dataprocess.model.ColdChainMessageData;
+import vip.xiaonuo.coldchain.core.service.dataprocess.model.RenKeColdChainMessageData;
 
 /**
  * @author jackzhou
@@ -16,6 +17,11 @@ public interface ColdChainDataHandler<T extends ColdChainMessageData> {
      */
     boolean handleRealTimeData(T data);
 
+    /**
+     * 处理缓存数据
+     */
+    boolean handleStoreData(RenKeColdChainMessageData renKeColdChainMessageData);
+
     /**
      * 注册处理器到 HandlerRegistry
      */
@@ -38,4 +44,6 @@ public interface ColdChainDataHandler<T extends ColdChainMessageData> {
      * 处理心跳
      */
     void heartbeat(T data);
+
+
 }

+ 6 - 0
snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/core/service/dataprocess/handler/impl/HaierColdChainDataHandler.java

@@ -4,6 +4,7 @@ import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Component;
 import vip.xiaonuo.coldchain.core.service.dataprocess.handler.AbstractColdChainDataHandler;
 import vip.xiaonuo.coldchain.core.service.dataprocess.model.HaierColdChainMessageData;
+import vip.xiaonuo.coldchain.core.service.dataprocess.model.RenKeColdChainMessageData;
 
 /**
  * @author jackzhou
@@ -21,4 +22,9 @@ public class HaierColdChainDataHandler extends AbstractColdChainDataHandler<Haie
         log.info("海尔数据处理器正在实时处理时间,{}");
         return false;
     }
+
+    @Override
+    public boolean handleStoreData(RenKeColdChainMessageData renKeColdChainMessageData) {
+        return false;
+    }
 }

+ 25 - 4
snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/core/service/dataprocess/handler/impl/RenKeColdChainDataHandler.java

@@ -5,6 +5,7 @@ import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Component;
 import rk.netDevice.sdk.p2.RealTimeData;
+import rk.netDevice.sdk.p2.StoreData;
 import vip.xiaonuo.coldchain.core.cache.monitordevice.MonitorDeviceCache;
 import vip.xiaonuo.coldchain.core.service.dataprocess.dataclean.MonitorDataProcessor;
 import vip.xiaonuo.coldchain.core.service.dataprocess.dataclean.impl.AbsRenkeMonitorDataProcessor;
@@ -30,15 +31,35 @@ public class RenKeColdChainDataHandler extends AbstractColdChainDataHandler<RenK
     @Override
     public boolean handleRealTimeData(RenKeColdChainMessageData renKeColdChainMessageData) {
         RealTimeData data = renKeColdChainMessageData.getRealTimeData();
-        final String deviceId = String.valueOf(data.getDeviceId());
-        final String modelName = monitorDeviceCache.getDeviceModel(deviceId);
+        return handleData(data.getDeviceId(), renKeColdChainMessageData);
+    }
+
+    @Override
+    public boolean handleStoreData(RenKeColdChainMessageData renKeColdChainMessageData) {
+        StoreData data = renKeColdChainMessageData.getStoreData();
+        return handleData(data.getDeviceId(), renKeColdChainMessageData);
+    }
+
+    private boolean handleData(Integer deviceId, RenKeColdChainMessageData renKeColdChainMessageData) {
+        final String deviceIdStr = String.valueOf(deviceId);
+        final String modelName = monitorDeviceCache.getDeviceModel(deviceIdStr);
         if (StrUtil.isNotBlank(modelName)) {
-            AbsRenkeMonitorDataProcessor monitorDataProcessor = (AbsRenkeMonitorDataProcessor) monitorDataProcessorMap.get(modelName);
-            monitorDataProcessor.processData(renKeColdChainMessageData);
+            renKeColdChainMessageData.setModelName(modelName);
+            AbsRenkeMonitorDataProcessor monitorDataProcessor =
+                    (AbsRenkeMonitorDataProcessor) monitorDataProcessorMap.get(modelName);
+
+            if (monitorDataProcessor != null) {
+                monitorDataProcessor.processData(renKeColdChainMessageData);
+            } else {
+                log.warn("No processor found for model: " + modelName);
+            }
+        } else {
+            log.warn("Model name not found for deviceId: " + deviceIdStr);
         }
         return Boolean.TRUE;
     }
 
+
     @Override
     public void login(RenKeColdChainMessageData data) {
         processMonitorData(data, "login");

+ 3 - 0
snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/core/service/dataprocess/model/RenKeColdChainMessageData.java

@@ -2,6 +2,7 @@ package vip.xiaonuo.coldchain.core.service.dataprocess.model;
 
 import lombok.Data;
 import rk.netDevice.sdk.p2.RealTimeData;
+import rk.netDevice.sdk.p2.StoreData;
 
 /**
  * @author jackzhou
@@ -13,5 +14,7 @@ import rk.netDevice.sdk.p2.RealTimeData;
 @Data
 public class RenKeColdChainMessageData implements ColdChainMessageData {
     private Integer deviceId;
+    private String modelName;
     private RealTimeData realTimeData;
+    private StoreData storeData;
 }

+ 1 - 1
snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/modular/app/service/AppDeviceService.java

@@ -151,7 +151,7 @@ public class AppDeviceService {
      * @return
      */
     public DeviceStatus getDeviceStatus(String keyword) {
-        TargetStatus targetCount = monitorTargetService.getTargetCount();
+        TargetStatus targetCount = monitorTargetService.getTargetCount(keyword);
         DeviceStatus deviceStatus = new DeviceStatus();
         BeanUtil.copyProperties(targetCount, deviceStatus);
         return deviceStatus;

+ 11 - 7
snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/modular/monitordevice/entity/MonitorDevice.java

@@ -18,12 +18,16 @@ import com.baomidou.mybatisplus.annotation.TableName;
 import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Getter;
 import lombok.Setter;
+import rk.netDevice.sdk.p2.ParamItem;
+import vip.xiaonuo.coldchain.core.handler.IntegerListTypeHandler;
+import vip.xiaonuo.coldchain.core.handler.ParamItemTypeHandler;
 import vip.xiaonuo.coldchain.modular.monitordevice.enums.MonitorDeviceStatusEnum;
 import vip.xiaonuo.common.pojo.CommonEntity;
 
 import javax.validation.constraints.NotNull;
 import javax.validation.constraints.Size;
 import java.util.Date;
+import java.util.List;
 
 /**
  * 采集器管理实体
@@ -33,7 +37,7 @@ import java.util.Date;
  **/
 @Getter
 @Setter
-@TableName("monitor_device")
+@TableName(value ="monitor_device", autoResultMap = true)
 public class MonitorDevice  extends CommonEntity {
 
     /**
@@ -97,17 +101,17 @@ public class MonitorDevice  extends CommonEntity {
      * 设备参数编号信息
      */
     @Schema(description = "设备参数编号信息")
-    @TableField(value = "param_ids")//, typeHandler = JacksonTypeHandler.class)
-//    private List<Integer> paramIds;
-    private String paramIds;
+    @TableField(value = "param_ids", typeHandler = IntegerListTypeHandler.class)
+    private List<Integer> paramIds;
+//    private String paramIds;
 
     /**
      * 设备参数信息
      */
     @Schema(description = "设备参数信息")
-    @TableField(value = "parameters")//, typeHandler = JacksonTypeHandler.class)
-//    private List<ParamItem> parameters;
-    private String parameters;
+    @TableField(value = "parameters",typeHandler = ParamItemTypeHandler.class)
+    private List<ParamItem> parameters;
+//    private String parameters;
 
     /**
      * 设备类型名称

+ 0 - 8
snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/modular/monitordevice/mapper/mapping/MonitorDeviceMapper.xml

@@ -1,12 +1,4 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 <mapper namespace="vip.xiaonuo.coldchain.modular.monitordevice.mapper.MonitorDeviceMapper">
-    <resultMap id="MonitorDevice" type="vip.xiaonuo.coldchain.modular.monitordevice.entity.MonitorDevice">
-        <result column="parameters" property="parameters"
-                jdbcType="VARCHAR"
-                typeHandler="com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler"/>
-        <result column="param_ids" property="paramIds"
-                jdbcType="VARCHAR"
-                typeHandler="com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler"/>
-    </resultMap>
 </mapper>

+ 2 - 3
snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/modular/monitordevice/service/impl/MonitorDeviceServiceImpl.java

@@ -16,7 +16,6 @@ import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.collection.CollStreamUtil;
 import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.core.util.StrUtil;
-import cn.hutool.json.JSONUtil;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
@@ -219,7 +218,7 @@ public class MonitorDeviceServiceImpl extends ServiceImpl<MonitorDeviceMapper, M
         if (device != null) {
             List<Integer> pararmIdList = data.getPararmIdList();
             if (!pararmIdList.isEmpty()) {
-                device.setParamIds(JSONUtil.toJsonStr(pararmIdList));
+                device.setParamIds(pararmIdList);
             }
         }
         return this.updateById(device);
@@ -231,7 +230,7 @@ public class MonitorDeviceServiceImpl extends ServiceImpl<MonitorDeviceMapper, M
         MonitorDevice device = this.getOne(new QueryWrapper<MonitorDevice>().like("device_code", deviceId));
         if (device != null && !data.getParameterList().isEmpty()) {
             if (!data.getParameterList().isEmpty()) {
-                device.setParameters(JSONUtil.toJsonStr(data.getParameterList()));
+                device.setParameters(data.getParameterList());
             }
         }
         return this.updateById(device);

+ 1 - 1
snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/modular/monitortarget/entity/MonitorTarget.java

@@ -37,7 +37,7 @@ import java.util.List;
  **/
 @Getter
 @Setter
-@TableName("monitor_target")
+@TableName(value = "monitor_target", autoResultMap = true)
 public class MonitorTarget extends CommonEntity {
 
     /**

+ 4 - 7
snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/modular/monitortargetregion/entity/MonitorTargetRegion.java

@@ -16,9 +16,7 @@ import com.baomidou.mybatisplus.annotation.TableField;
 import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableName;
 import com.fasterxml.jackson.annotation.JsonFormat;
-import com.fasterxml.jackson.annotation.JsonIgnore;
 import com.fasterxml.jackson.databind.annotation.JsonSerialize;
-
 import com.google.common.collect.Lists;
 import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Getter;
@@ -30,7 +28,6 @@ import vip.xiaonuo.coldchain.core.handler.SensorAlarmUserTypeHandler;
 import vip.xiaonuo.coldchain.modular.app.param.FloatNullToDashSerializer;
 import vip.xiaonuo.common.pojo.CommonEntity;
 
-import java.util.Date;
 import java.util.List;
 
 /**
@@ -41,7 +38,7 @@ import java.util.List;
  **/
 @Getter
 @Setter
-@TableName("monitor_target_region")
+@TableName(value = "monitor_target_region", autoResultMap = true)
 public class MonitorTargetRegion extends CommonEntity {
     /**
      * 区域唯一标识符,UUID
@@ -168,9 +165,8 @@ public class MonitorTargetRegion extends CommonEntity {
     /**
      * 告警接收人,存储告警通知的接收用户信息
      */
-    @TableField(value = "alarm_users", typeHandler = SensorAlarmUserTypeHandler.class)
     @Schema(description = "告警接收人,存储告警通知的接收用户信息")
-    @JsonIgnore
+    @TableField(value = "alarm_users", typeHandler = SensorAlarmUserTypeHandler.class)
     private List<SensorAlarmUser> alarmUsers = Lists.newArrayList();
 
     /**
@@ -178,7 +174,8 @@ public class MonitorTargetRegion extends CommonEntity {
      */
     @Schema(description = "用户的通知渠道设置,支持选择接收告警的多个渠道,如短信、邮件、APP通知等")
     @TableField(value = "notification_channel", typeHandler = NotificationChannelListTypeHandler.class)
-    @JsonIgnore
     private List<NotificationChannel> notificationChannel = List.of(NotificationChannel.WECHAT);
 
+
+
 }