Przeglądaj źródła

refactor(alarm): 重构报警数据模型和阈值判断逻辑

- 移除设备名称和设备类型字段,精简AlarmData实体类结构
- 将单一预警阈值字段拆分为最小值和最大值两个字段,支持范围报警判断
- 更新控制器接口参数,移除设备名称相关参数
- 修改服务层方法签名,调整参数列表结构
- 重构报警判断逻辑,从单一阈值比较改为范围区间判断
- 集成预警阈值配置功能,支持动态获取报警阈值
- 更新测试控制器中的模拟报警逻辑,适配新的数据结构
- 统一各设备服务中的报警工具类实现,标准化报警处理流程
- 添加详细的报警数据创建时间和备注信息存储
林仔 5 dni temu
rodzic
commit
7c1cb6180f
23 zmienionych plików z 853 dodań i 368 usunięć
  1. 128 12
      environment-service/src/main/java/com/zksy/environment/config/RSServerService.java
  2. 20 11
      environment-service/src/main/java/com/zksy/environment/utils/AlarmUtil.java
  3. 59 16
      firefighting-pressure-service/src/main/java/com/zksy/pressure/utils/MessageHandler.java
  4. 20 11
      flammable-gas-service/src/main/java/com/zksy/gas/utils/AlarmUtil.java
  5. 116 86
      flammable-gas-service/src/main/java/com/zksy/gas/utils/MessageHandler.java
  6. 63 22
      manhole-service/src/main/java/com/zksy/manhole/service/impl/ManholeDataServiceImpl.java
  7. 20 11
      manhole-service/src/main/java/com/zksy/manhole/utils/AlarmUtil.java
  8. 3 5
      pipe-network-service/zksy-admin/src/main/java/com/zksy/web/controller/base/alarm/AlarmDataController.java
  9. 15 35
      pipe-network-service/zksy-admin/src/main/java/com/zksy/web/controller/base/alarm/AlarmTestController.java
  10. 4 5
      pipe-network-service/zksy-admin/src/main/java/com/zksy/web/controller/base/alarm/WarningThresholdController.java
  11. 7 11
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/alarm/domain/AlarmData.java
  12. 11 53
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/alarm/domain/WarningThreshold.java
  13. 2 2
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/alarm/service/AlarmDataService.java
  14. 2 2
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/alarm/service/WarningThresholdService.java
  15. 5 7
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/alarm/service/impl/AlarmDataServiceImpl.java
  16. 4 6
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/alarm/service/impl/WarningThresholdServiceImpl.java
  17. 5 2
      pipe-network-service/zksy-system/src/main/java/com/zksy/manhole/dto/out/WarningThresholdOutDTO.java
  18. 124 1
      radar-service/src/main/java/com/zksy/radar/utils/MessageHandler.java
  19. 118 1
      water-level-service/src/main/java/com/zksy/water/utils/MessageHandler.java
  20. 7 11
      zk-api-service/src/main/java/com/zksy/api/domain/AlarmData.java
  21. 11 18
      zk-api-service/src/main/java/com/zksy/api/domain/WarningThreshold.java
  22. 14 2
      zk-api-service/src/main/java/com/zksy/api/service/impl/WarningThresholdServiceImpl.java
  23. 95 38
      zk-api-service/src/main/java/com/zksy/api/utils/SmsUtil.java

+ 128 - 12
environment-service/src/main/java/com/zksy/environment/config/RSServerService.java

@@ -1,5 +1,7 @@
 package com.zksy.environment.config;
 
+import com.zksy.api.domain.WarningThreshold;
+import com.zksy.api.service.WarningThresholdService;
 import com.zksy.api.utils.SmsUtil;
 import com.zksy.environment.domain.ERealTimeData;
 import com.zksy.environment.mapper.ERealTimeDataMapper;
@@ -37,6 +39,8 @@ public class RSServerService {
     @Autowired
     private ERealTimeDataMapper realTimeDataMapper;
 
+    @Autowired
+    private WarningThresholdService warningThresholdService;
     @Autowired
     private SmsUtil smsUtil;
     @Autowired
@@ -176,21 +180,124 @@ public class RSServerService {
 
                             // ====================== 报警处理 ======================
                             String deviceId = String.valueOf(data.getDeviceId());
-                            String deviceName = "环境设备";
-                            String deviceType = "environment";
-
-                            // 温度判断(
-                            if (!Float.isNaN(nd.getTem())) {
-                                alarmUtil.checkAndSaveAlarm(deviceName, deviceId, deviceType,
-                                        "温度预警", "WARN-TEMPERATURE", 40.0,
-                                        BigDecimal.valueOf(nd.getTem()), "环境温度报警");
+
+                            // 悬浮物判断
+                            if (!"".equals(realTimeData.getFloatValue()) && nd.getNodeId() == 1) {
+                                String temWarningCode = "WARN-SUSPENDED-SOLIDS";
+                                WarningThreshold temThreshold = checkThreshold(deviceId, temWarningCode);
+                                Double temMinValue = temThreshold != null ? temThreshold.getMinValue() : null;
+                                Double temMaxValue = temThreshold != null ? temThreshold.getMaxValue() : null;
+                                String temWarningType = temThreshold != null ? temThreshold.getWarningType() : "悬浮物预警";
+                                String temRemark = temThreshold != null ? temThreshold.getRemark() : "环境悬浮物报警";
+
+                                boolean temShouldAlarm = false;
+                                BigDecimal temValue = BigDecimal.valueOf(nd.getTem());
+                                if (temMinValue != null && nd.getTem() <= temMinValue) {
+                                    temShouldAlarm = true;
+                                }
+                                if (temMaxValue != null && nd.getTem() >= temMaxValue) {
+                                    temShouldAlarm = true;
+                                }
+                                if (temShouldAlarm) {
+                                    alarmUtil.saveAlarm(deviceId, temWarningType, temWarningCode,
+                                            temMinValue != null ? BigDecimal.valueOf(temMinValue) : null,
+                                            temMaxValue != null ? BigDecimal.valueOf(temMaxValue) : null,
+                                            temValue, temRemark);
+                                }
                             }
 
                             // 只有非节点1才判断湿度报警(节点1无湿度数据)
-                            if (nodeId != 1 && !Float.isNaN(nd.getHum())) {
-                                alarmUtil.checkAndSaveAlarm(deviceName, deviceId, deviceType,
-                                        "湿度预警", "WARN-HUMIDITY", 90.0,
-                                        BigDecimal.valueOf(finalValue), "环境湿度报警");
+                            if (nodeId == 2 && !Float.isNaN(nd.getHum())) {
+                                String humWarningCode = "WARN-HUMIDITY";
+                                WarningThreshold humThreshold = checkThreshold(deviceId, humWarningCode);
+                                Double humMinValue = humThreshold != null ? humThreshold.getMinValue() : null;
+                                Double humMaxValue = humThreshold != null ? humThreshold.getMaxValue() : 90.0;
+                                String humWarningType = humThreshold != null ? humThreshold.getWarningType() : "湿度预警";
+                                String humRemark = humThreshold != null ? humThreshold.getRemark() : "环境湿度报警";
+
+                                boolean humShouldAlarm = false;
+                                BigDecimal humValue = BigDecimal.valueOf(finalValue);
+                                if (humMinValue != null && finalValue <= humMinValue) {
+                                    humShouldAlarm = true;
+                                }
+                                if (humMaxValue != null && finalValue >= humMaxValue) {
+                                    humShouldAlarm = true;
+                                }
+                                if (humShouldAlarm) {
+                                    alarmUtil.saveAlarm(deviceId, humWarningType, humWarningCode,
+                                            humMinValue != null ? BigDecimal.valueOf(humMinValue) : null,
+                                            humMaxValue != null ? BigDecimal.valueOf(humMaxValue) : null,
+                                            humValue, humRemark);
+                                }
+                            }
+                            if (nodeId == 3 && !Float.isNaN(nd.getHum())) {
+                                String humWarningCode = "WARN-AMMONIA-NITROGEN";
+                                WarningThreshold humThreshold = checkThreshold(deviceId, humWarningCode);
+                                Double humMinValue = humThreshold != null ? humThreshold.getMinValue() : null;
+                                Double humMaxValue = humThreshold != null ? humThreshold.getMaxValue() : null;
+                                String humWarningType = humThreshold != null ? humThreshold.getWarningType() : "氨氮预警";
+                                String humRemark = humThreshold != null ? humThreshold.getRemark() : "环境氨氮报警";
+
+                                boolean humShouldAlarm = false;
+                                BigDecimal humValue = BigDecimal.valueOf(finalValue);
+                                if (humMinValue != null && finalValue <= humMinValue) {
+                                    humShouldAlarm = true;
+                                }
+                                if (humMaxValue != null && finalValue >= humMaxValue) {
+                                    humShouldAlarm = true;
+                                }
+                                if (humShouldAlarm) {
+                                    alarmUtil.saveAlarm(deviceId, humWarningType, humWarningCode,
+                                            humMinValue != null ? BigDecimal.valueOf(humMinValue) : null,
+                                            humMaxValue != null ? BigDecimal.valueOf(humMaxValue) : null,
+                                            humValue, humRemark);
+                                }
+                            }
+                            if (nodeId == 4 && !Float.isNaN(nd.getHum())) {
+                                String humWarningCode = "WARN-CONDUCTIVITY";
+                                WarningThreshold humThreshold = checkThreshold(deviceId, humWarningCode);
+                                Double humMinValue = humThreshold != null ? humThreshold.getMinValue() : null;
+                                Double humMaxValue = humThreshold != null ? humThreshold.getMaxValue() : null;
+                                String humWarningType = humThreshold != null ? humThreshold.getWarningType() : "电导率预警";
+                                String humRemark = humThreshold != null ? humThreshold.getRemark() : "环境电导率报警";
+
+                                boolean humShouldAlarm = false;
+                                BigDecimal humValue = BigDecimal.valueOf(finalValue);
+                                if (humMinValue != null && finalValue <= humMinValue) {
+                                    humShouldAlarm = true;
+                                }
+                                if (humMaxValue != null && finalValue >= humMaxValue) {
+                                    humShouldAlarm = true;
+                                }
+                                if (humShouldAlarm) {
+                                    alarmUtil.saveAlarm(deviceId, humWarningType, humWarningCode,
+                                            humMinValue != null ? BigDecimal.valueOf(humMinValue) : null,
+                                            humMaxValue != null ? BigDecimal.valueOf(humMaxValue) : null,
+                                            humValue, humRemark);
+                                }
+                            }
+                            if (nodeId == 5 && !Float.isNaN(nd.getHum())) {
+                                String humWarningCode = "WARN-PH";
+                                WarningThreshold humThreshold = checkThreshold(deviceId, humWarningCode);
+                                Double humMinValue = humThreshold != null ? humThreshold.getMinValue() : null;
+                                Double humMaxValue = humThreshold != null ? humThreshold.getMaxValue() : null;
+                                String humWarningType = humThreshold != null ? humThreshold.getWarningType() : "PH预警";
+                                String humRemark = humThreshold != null ? humThreshold.getRemark() : "环境PH报警";
+
+                                boolean humShouldAlarm = false;
+                                BigDecimal humValue = BigDecimal.valueOf(finalValue);
+                                if (humMinValue != null && finalValue <= humMinValue) {
+                                    humShouldAlarm = true;
+                                }
+                                if (humMaxValue != null && finalValue >= humMaxValue) {
+                                    humShouldAlarm = true;
+                                }
+                                if (humShouldAlarm) {
+                                    alarmUtil.saveAlarm(deviceId, humWarningType, humWarningCode,
+                                            humMinValue != null ? BigDecimal.valueOf(humMinValue) : null,
+                                            humMaxValue != null ? BigDecimal.valueOf(humMaxValue) : null,
+                                            humValue, humRemark);
+                                }
                             }
 
                             // 获取手机号并发送短信
@@ -307,4 +414,13 @@ public class RSServerService {
         }
         log.info("RSServer资源关闭完成");
     }
+
+    private WarningThreshold checkThreshold(String deviceCode, String warningCode) {
+        try {
+            return warningThresholdService.getWarningThresholdByDeviceAndCode(deviceCode, warningCode);
+        } catch (Exception e) {
+            log.error("查询预警阈值失败:deviceCode={}, warningCode={}", deviceCode, warningCode, e);
+            return null;
+        }
+    }
 }

+ 20 - 11
environment-service/src/main/java/com/zksy/environment/utils/AlarmUtil.java

@@ -14,30 +14,39 @@ public class AlarmUtil {
     @Autowired
     private AlarmDataService alarmDataService;
 
-    public void checkAndSaveAlarm(String deviceName, String deviceCode, String deviceType,
-                                    String warningType, String warningCode, Double warningValue,
+    public void checkAndSaveAlarm(String deviceCode,
+                                    String warningType, String warningCode, Double minValue, Double maxValue,
                                     BigDecimal actualValue, String remark) {
-        if (warningValue == null || actualValue == null) {
+        if (actualValue == null) {
             return;
         }
 
-        if (actualValue.doubleValue() > warningValue) {
-            saveAlarm(deviceName, deviceCode, deviceType, warningType, warningCode,
-                    BigDecimal.valueOf(warningValue), actualValue, remark);
+        boolean shouldAlarm = false;
+        if (minValue != null && actualValue.doubleValue() <= minValue) {
+            shouldAlarm = true;
+        }
+        if (maxValue != null && actualValue.doubleValue() >= maxValue) {
+            shouldAlarm = true;
+        }
+
+        if (shouldAlarm) {
+            saveAlarm(deviceCode, warningType, warningCode,
+                    minValue != null ? BigDecimal.valueOf(minValue) : null,
+                    maxValue != null ? BigDecimal.valueOf(maxValue) : null,
+                    actualValue, remark);
         }
     }
 
-    public void saveAlarm(String deviceName, String deviceCode, String deviceType,
-                           String warningType, String warningCode, BigDecimal warningValue,
+    public void saveAlarm(String deviceCode,
+                           String warningType, String warningCode, BigDecimal minValue, BigDecimal maxValue,
                            BigDecimal actualValue, String remark) {
         try {
             AlarmData alarmData = new AlarmData();
-            alarmData.setDeviceName(deviceName);
             alarmData.setDeviceCode(deviceCode);
-            alarmData.setDeviceType(deviceType);
             alarmData.setWarningType(warningType);
             alarmData.setWarningCode(warningCode);
-            alarmData.setWarningValue(warningValue);
+            alarmData.setMinValue(minValue);
+            alarmData.setMaxValue(maxValue);
             alarmData.setActualValue(actualValue);
             alarmData.setAlarmStatus(0);
             alarmData.setAlarmTime(LocalDateTime.now());

+ 59 - 16
firefighting-pressure-service/src/main/java/com/zksy/pressure/utils/MessageHandler.java

@@ -5,10 +5,10 @@ import com.alibaba.fastjson.JSONObject;
 import com.aliyun.apache.hc.client5.http.utils.Hex;
 import com.zksy.api.domain.WarningThreshold;
 import com.zksy.api.service.WarningThresholdService;
+import com.zksy.api.domain.AlarmData;
+import com.zksy.api.service.AlarmDataService;
 import com.zksy.api.utils.SmsUtil;
 import com.zksy.common.exception.InvalidMessageException;
-import com.zksy.pressure.domain.Enum.FirefightingDeviceCodeEnum;
-import com.zksy.pressure.domain.Enum.FirefightingWarningCodeEnum;
 import com.zksy.pressure.domain.FirefightingPressure;
 import com.zksy.pressure.service.FirefightingPressureService;
 import com.zksy.utils.DevicePhoneFetchUtil;
@@ -26,6 +26,7 @@ import org.springframework.stereotype.Component;
 
 import java.math.BigDecimal;
 import java.nio.charset.StandardCharsets;
+import java.time.LocalDateTime;
 import java.util.List;
 import java.util.Map;
 
@@ -36,7 +37,9 @@ public class MessageHandler extends ChannelInboundHandlerAdapter {
 	private static Logger logger = LoggerFactory.getLogger(MessageHandler.class);
 	private final FirefightingPressureService firefightingPressureService;
 	@Autowired
-	private WarningThresholdService service;
+	private WarningThresholdService warningThresholdService;
+	@Autowired
+	private AlarmDataService alarmDataService;
 	@Autowired
 	private SmsUtil smsUtil;
 	@Autowired
@@ -221,54 +224,94 @@ public class MessageHandler extends ChannelInboundHandlerAdapter {
 		try {
 			//用遥测站地址作为设备的设备编号
 			String deviceId = resultData.getTelemeteringStation();
-			//1、获取到压力阈值
-			Double warningValue = null;
-			//1.1获取到设备编码
-			String deviceWarningCode = FirefightingDeviceCodeEnum.FIREFIGHTING_DEVICE.getCode();
-			FirefightingWarningCodeEnum targetWarningType=FirefightingWarningCodeEnum.PRESSURE;
 
-			String warningCode = targetWarningType.getCode();
-			String warningMsg = targetWarningType.getName();
+			//1、获取到压力阈值
+			String warningCode = "WARN-PRESSURE";
+			WarningThreshold threshold = null;
 			try {
 				//1.2根据设备编码获取压力阈值
-				WarningThreshold threshold = service.getWarningThresholdByDeviceAndCode(deviceWarningCode, warningCode);
-				warningValue = threshold.getWarningValue();
+				threshold = warningThresholdService.getWarningThresholdByDeviceAndCode(deviceId, warningCode);
 			} catch (Exception e) {
 				log.error("查询预警阈值失败");
 			}
+
+			String warningType = threshold != null ? threshold.getWarningType() : "压力预警";
+			String remark = threshold != null ? threshold.getRemark() : null;
+			Double minValue = threshold != null ? threshold.getMinValue() : null;
+			Double maxValue = threshold != null ? threshold.getMaxValue() : null;
+
 			//1.2获取到实际压力值
 			Double pressureValue = resultData.getPressureValue();
-			boolean isOverThreshold = pressureValue > warningValue;
-			//1.3超出了阈值则发送短信,设备编号这里不是很清楚
+			boolean isOverThreshold = false;
+			if (minValue != null && pressureValue != null && pressureValue <= minValue) {
+				isOverThreshold = true;
+			}
+			if (maxValue != null && pressureValue != null && pressureValue >= maxValue) {
+				isOverThreshold = true;
+			}
+			//1.3超出了阈值则发送短信,先保存告警数据再发送短信
 			if(isOverThreshold){
-				sendMessage(deviceId,warningMsg,resultData.getLongitude(),resultData.getLatitude());
+				saveAlarmData(deviceId, warningType, warningCode,
+						minValue != null ? BigDecimal.valueOf(minValue) : null,
+						maxValue != null ? BigDecimal.valueOf(maxValue) : null,
+						pressureValue != null ? BigDecimal.valueOf(pressureValue) : null,
+						remark != null ? remark : "压力报警");
+				sendMessage(deviceId,warningType,resultData.getLongitude(),resultData.getLatitude());
 			}
 			if(resultData.getD14()==1){
+				saveAlarmData(deviceId, "压力变幅报警", "WARN-PRESSURE-VARY", null, null, null, "压力变幅报警");
 				sendMessage(deviceId,"压力变幅报警",resultData.getLongitude(),resultData.getLatitude());
 			}
 			if(resultData.getD13()==1){
+				saveAlarmData(deviceId, "压力下下限报警", "WARN-PRESSURE-LOW-LOW", null, null, null, "压力下下限报警");
 				sendMessage(deviceId,"压力下下限报警",resultData.getLongitude(),resultData.getLatitude());
 			}
 			if(resultData.getD12()==1){
+				saveAlarmData(deviceId, "压力上上限报警", "WARN-PRESSURE-HIGH-HIGH", null, null, null, "压力上上限报警");
 				sendMessage(deviceId,"压力上上限报警",resultData.getLongitude(),resultData.getLatitude());
 			}
 			if(resultData.getD11()==1){
+				saveAlarmData(deviceId, "压力下线报警", "WARN-PRESSURE-LOW", null, null, null, "压力下线报警");
 				sendMessage(deviceId,"压力下线报警",resultData.getLongitude(),resultData.getLatitude());
 			}
 			if(resultData.getD10()==1){
+				saveAlarmData(deviceId, "压力上限报警", "WARN-PRESSURE-HIGH", null, null, null, "压力上限报警");
 				sendMessage(deviceId,"压力上限报警",resultData.getLongitude(),resultData.getLatitude());
 			}
 			if(resultData.getD9()==1){
+				saveAlarmData(deviceId, "传感器状态", "WARN-SENSOR-STATUS", null, null, null, "传感器状态");
 				sendMessage(deviceId,"传感器状态",resultData.getLongitude(),resultData.getLatitude());
 			}
 			if(resultData.getD1()==1){
+				saveAlarmData(deviceId, "倾斜报警1", "WARN-TILT-1", null, null, null, "倾斜报警1");
 				sendMessage(deviceId,"倾斜报警1",resultData.getLongitude(),resultData.getLatitude());
 			}
 		} catch (Exception e) {
-			log.error("设备报警处理失败");
+			log.error("设备报警处理失败", e);
 		}
 
 	}
+
+	private void saveAlarmData(String deviceCode, String warningType, String warningCode,
+							  BigDecimal minValue, BigDecimal maxValue,
+							  BigDecimal actualValue, String remark) {
+		try {
+			AlarmData alarmData = new AlarmData();
+			alarmData.setDeviceCode(deviceCode);
+			alarmData.setWarningType(warningType);
+			alarmData.setWarningCode(warningCode);
+			alarmData.setMinValue(minValue);
+			alarmData.setMaxValue(maxValue);
+			alarmData.setActualValue(actualValue);
+			alarmData.setAlarmStatus(0);
+			alarmData.setAlarmTime(LocalDateTime.now());
+			alarmData.setRemark(remark);
+			alarmData.setCreateTime(LocalDateTime.now());
+			alarmDataService.saveAlarmData(alarmData);
+		} catch (Exception e) {
+			log.error("保存告警数据失败", e);
+		}
+	}
 	//构造发送短信参数&&发送短信
 	public void sendMessage(String deviceNo,String alarmType,BigDecimal lng,BigDecimal lat){
 		// 构造短信参数

+ 20 - 11
flammable-gas-service/src/main/java/com/zksy/gas/utils/AlarmUtil.java

@@ -14,30 +14,39 @@ public class AlarmUtil {
     @Autowired
     private AlarmDataService alarmDataService;
 
-    public void checkAndSaveAlarm(String deviceName, String deviceCode, String deviceType,
-                                    String warningType, String warningCode, Double warningValue,
+    public void checkAndSaveAlarm(String deviceCode,
+                                    String warningType, String warningCode, Double minValue, Double maxValue,
                                     BigDecimal actualValue, String remark) {
-        if (warningValue == null || actualValue == null) {
+        if (actualValue == null) {
             return;
         }
 
-        if (actualValue.doubleValue() > warningValue) {
-            saveAlarm(deviceName, deviceCode, deviceType, warningType, warningCode,
-                    BigDecimal.valueOf(warningValue), actualValue, remark);
+        boolean shouldAlarm = false;
+        if (minValue != null && actualValue.doubleValue() <= minValue) {
+            shouldAlarm = true;
+        }
+        if (maxValue != null && actualValue.doubleValue() >= maxValue) {
+            shouldAlarm = true;
+        }
+
+        if (shouldAlarm) {
+            saveAlarm(deviceCode, warningType, warningCode,
+                    minValue != null ? BigDecimal.valueOf(minValue) : null,
+                    maxValue != null ? BigDecimal.valueOf(maxValue) : null,
+                    actualValue, remark);
         }
     }
 
-    public void saveAlarm(String deviceName, String deviceCode, String deviceType,
-                           String warningType, String warningCode, BigDecimal warningValue,
+    public void saveAlarm(String deviceCode,
+                           String warningType, String warningCode, BigDecimal minValue, BigDecimal maxValue,
                            BigDecimal actualValue, String remark) {
         try {
             AlarmData alarmData = new AlarmData();
-            alarmData.setDeviceName(deviceName);
             alarmData.setDeviceCode(deviceCode);
-            alarmData.setDeviceType(deviceType);
             alarmData.setWarningType(warningType);
             alarmData.setWarningCode(warningCode);
-            alarmData.setWarningValue(warningValue);
+            alarmData.setMinValue(minValue);
+            alarmData.setMaxValue(maxValue);
             alarmData.setActualValue(actualValue);
             alarmData.setAlarmStatus(0);
             alarmData.setAlarmTime(LocalDateTime.now());

+ 116 - 86
flammable-gas-service/src/main/java/com/zksy/gas/utils/MessageHandler.java

@@ -4,10 +4,10 @@ import cn.hutool.core.lang.UUID;
 import com.alibaba.fastjson.JSONObject;
 import com.zksy.api.domain.WarningThreshold;
 import com.zksy.api.service.WarningThresholdService;
+import com.zksy.api.domain.AlarmData;
+import com.zksy.api.service.AlarmDataService;
 import com.zksy.api.utils.SmsUtil;
 import com.zksy.common.exception.InvalidMessageException;
-import com.zksy.gas.domain.Enum.GasDeviceCodeEnum;
-import com.zksy.gas.domain.Enum.GasWarningCodeEnum;
 import com.zksy.gas.domain.GasMonitorData;
 import com.zksy.gas.service.GasMonitorDataService;
 import com.zksy.utils.DevicePhoneFetchUtil;
@@ -26,6 +26,7 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
 import java.math.BigDecimal;
+import java.time.LocalDateTime;
 import java.util.Arrays;
 import java.util.List;
 import java.util.Map;
@@ -39,6 +40,8 @@ public class MessageHandler extends ChannelInboundHandlerAdapter {
 	@Autowired
 	private WarningThresholdService warningThresholdService;
 	@Autowired
+	private AlarmDataService alarmDataService;
+	@Autowired
 	private SmsUtil smsUtil;
 	@Autowired
 	private DevicePhoneFetchUtil devicePhoneFetchUtil;
@@ -176,160 +179,187 @@ public class MessageHandler extends ChannelInboundHandlerAdapter {
 		}
 	}
 	public void checkIfSmsAlertNeeded(GasMonitorData resultData){
-
 		//用MAC地址作为设备的设备编号
 		String deviceId = resultData.getMacAddress();
-		String deviceName = "可燃气体设备";
-		String deviceType = "flammable-gas";
 
 		//获取温度阈值
-		String deviceWarningCode = GasDeviceCodeEnum.FIREFIGHTING_DEVICE.getCode();
-		GasWarningCodeEnum temTargetWarningType=GasWarningCodeEnum.TEMPERATRUE;
-		String temWarningCode = temTargetWarningType.getCode();
-		String temWarningMsg = temTargetWarningType.getName();
-		Double temWarningValue = checkTemAndHum(deviceWarningCode, temWarningCode);
+		String temWarningCode = "WARN-GAS-TEMPERATURE";
+		WarningThreshold temThreshold = checkThreshold(deviceId, temWarningCode);
+		Double temMinValue = temThreshold != null ? temThreshold.getMinValue() : null;
+		Double temMaxValue = temThreshold != null ? temThreshold.getMaxValue() : null;
+		String temWarningType = temThreshold != null ? temThreshold.getWarningType() : "可燃气体温度预警";
+		String temRemark = temThreshold != null ? temThreshold.getRemark() : null;
+
 		//获取湿度阈值
-		GasWarningCodeEnum humTargetWarningType=GasWarningCodeEnum.HUMIDITY;
-		String humWarningCode = humTargetWarningType.getCode();
-		String humWarningMsg = humTargetWarningType.getName();
-		Double humWarningValue = checkTemAndHum(deviceWarningCode, humWarningCode);
+		String humWarningCode = "WARN-GAS-HUMIDITY";
+		WarningThreshold humThreshold = checkThreshold(deviceId, humWarningCode);
+		Double humMinValue = humThreshold != null ? humThreshold.getMinValue() : null;
+		Double humMaxValue = humThreshold != null ? humThreshold.getMaxValue() : null;
+		String humWarningType = humThreshold != null ? humThreshold.getWarningType() : "湿度预警";
+		String humRemark = humThreshold != null ? humThreshold.getRemark() : null;
+
 		//获取气体浓度阈值
-		GasWarningCodeEnum gasTargetWarningType=GasWarningCodeEnum.GASCONCENTRATION;
-		String gasWarningCode = gasTargetWarningType.getCode();
-		String gasWarningMsg = gasTargetWarningType.getName();
-		Double gasWarningValue = checkTemAndHum(deviceWarningCode, gasWarningCode);
+		String gasWarningCode = "WARN-GAS-CONCENTRATION";
+		WarningThreshold gasThreshold = checkThreshold(deviceId, gasWarningCode);
+		Double gasMinValue = gasThreshold != null ? gasThreshold.getMinValue() : null;
+		Double gasMaxValue = gasThreshold != null ? gasThreshold.getMaxValue() : null;
+		String gasWarningType = gasThreshold != null ? gasThreshold.getWarningType() : "气体浓度预警";
+		String gasRemark = gasThreshold != null ? gasThreshold.getRemark() : null;
 
 		//判断温度
 		float temperature = resultData.getTemperature();
-		boolean temperatureIsOverThreshold = temperature > temWarningValue;
+		boolean temperatureIsOverThreshold = false;
+		if (temMinValue != null && temperature <= temMinValue) {
+			temperatureIsOverThreshold = true;
+		}
+		if (temMaxValue != null && temperature >= temMaxValue) {
+			temperatureIsOverThreshold = true;
+		}
 		if(temperatureIsOverThreshold){
-			sendMessage(deviceId,temWarningMsg,resultData.getLongitude(),resultData.getLatitude());
-			alarmUtil.saveAlarm(deviceName, deviceId, deviceType,
-					temWarningMsg, temWarningCode, BigDecimal.valueOf(temWarningValue),
-					BigDecimal.valueOf(temperature), "可燃气体温度报警");
+			//先保存告警数据
+			saveAlarmData(deviceId, temWarningType, temWarningCode,
+					temMinValue != null ? BigDecimal.valueOf(temMinValue) : null,
+					temMaxValue != null ? BigDecimal.valueOf(temMaxValue) : null,
+					BigDecimal.valueOf(temperature), temRemark != null ? temRemark : "可燃气体温度报警");
+			//再发送短信
+			sendMessage(deviceId, temWarningType, resultData.getLongitude(), resultData.getLatitude());
 		}
+
 		//判断湿度
 		float humidity = resultData.getHumidity();
-		boolean humidityIsOverThreshold=humidity>humWarningValue;
+		boolean humidityIsOverThreshold = false;
+		if (humMinValue != null && humidity <= humMinValue) {
+			humidityIsOverThreshold = true;
+		}
+		if (humMaxValue != null && humidity >= humMaxValue) {
+			humidityIsOverThreshold = true;
+		}
 		if(humidityIsOverThreshold){
-			sendMessage(deviceId,humWarningMsg,resultData.getLongitude(),resultData.getLatitude());
-			alarmUtil.saveAlarm(deviceName, deviceId, deviceType,
-					humWarningMsg, humWarningCode, BigDecimal.valueOf(humWarningValue),
-					BigDecimal.valueOf(humidity), "可燃气体湿度报警");
+			//先保存告警数据
+			saveAlarmData(deviceId, humWarningType, humWarningCode,
+					humMinValue != null ? BigDecimal.valueOf(humMinValue) : null,
+					humMaxValue != null ? BigDecimal.valueOf(humMaxValue) : null,
+					BigDecimal.valueOf(humidity), humRemark != null ? humRemark : "可燃气体湿度报警");
+			//再发送短信
+			sendMessage(deviceId, humWarningType, resultData.getLongitude(), resultData.getLatitude());
 		}
+
 		//判断气体浓度
 		BigDecimal gasConcentration = resultData.getGasConcentration();
-		float actualGasConcentration=gasConcentration.floatValue();
-		boolean concentrationIsOverThreshold=actualGasConcentration>gasWarningValue;
+		float actualGasConcentration = gasConcentration != null ? gasConcentration.floatValue() : 0f;
+		boolean concentrationIsOverThreshold = false;
+		if (gasMinValue != null && actualGasConcentration <= gasMinValue) {
+			concentrationIsOverThreshold = true;
+		}
+		if (gasMaxValue != null && actualGasConcentration >= gasMaxValue) {
+			concentrationIsOverThreshold = true;
+		}
 		if(concentrationIsOverThreshold){
-			sendMessage(deviceId,gasWarningMsg,resultData.getLongitude(),resultData.getLatitude());
-			alarmUtil.saveAlarm(deviceName, deviceId, deviceType,
-					gasWarningMsg, gasWarningCode, BigDecimal.valueOf(gasWarningValue),
-					gasConcentration, "可燃气体浓度报警");
+			//先保存告警数据
+			saveAlarmData(deviceId, gasWarningType, gasWarningCode,
+					gasMinValue != null ? BigDecimal.valueOf(gasMinValue) : null,
+					gasMaxValue != null ? BigDecimal.valueOf(gasMaxValue) : null,
+					gasConcentration, gasRemark != null ? gasRemark : "可燃气体浓度报警");
+			//再发送短信
+			sendMessage(deviceId, gasWarningType, resultData.getLongitude(), resultData.getLatitude());
 		}
+
 		//获取到的数据逐一进行判断
 		Map<String, Boolean> alarmBits = resultData.parseAlarmBits();
 		if(alarmBits.get("unknownAlarm")){
+			saveAlarmData(deviceId, "未知报警", "WARN-UNKNOWN", null, null, null, "可燃气体未知报警");
 			sendMessage(deviceId,"未知报警",resultData.getLongitude(),resultData.getLatitude());
-			alarmUtil.saveAlarm(deviceName, deviceId, deviceType,
-					"未知报警", "WARN-UNKNOWN", null,
-					null, "可燃气体未知报警");
 		}
 		if(alarmBits.get("highAlarm")){
+			saveAlarmData(deviceId, "高报警", "WARN-HIGH", null, null, null, "可燃气体高报警");
 			sendMessage(deviceId,"高报警",resultData.getLongitude(),resultData.getLatitude());
-			alarmUtil.saveAlarm(deviceName, deviceId, deviceType,
-					"高报警", "WARN-HIGH", null,
-					null, "可燃气体高报警");
 		}
 		if(alarmBits.get("overRange")){
+			saveAlarmData(deviceId, "超量程", "WARN-OVER-RANGE", null, null, null, "可燃气体超量程报警");
 			sendMessage(deviceId,"超量程",resultData.getLongitude(),resultData.getLatitude());
-			alarmUtil.saveAlarm(deviceName, deviceId, deviceType,
-					"超量程", "WARN-OVER-RANGE", null,
-					null, "可燃气体超量程报警");
 		}
 		if(alarmBits.get("calibrationCycle")){
+			saveAlarmData(deviceId, "标定周期", "WARN-CALIBRATION-CYCLE", null, null, null, "可燃气体标定周期报警");
 			sendMessage(deviceId,"标定周期",resultData.getLongitude(),resultData.getLatitude());
-			alarmUtil.saveAlarm(deviceName, deviceId, deviceType,
-					"标定周期", "WARN-CALIBRATION-CYCLE", null,
-					null, "可燃气体标定周期报警");
 		}
 		if(alarmBits.get("overLife")){
+			saveAlarmData(deviceId, "超寿命", "WARN-OVER-LIFE", null, null, null, "可燃气体超寿命报警");
 			sendMessage(deviceId,"超寿命",resultData.getLongitude(),resultData.getLatitude());
-			alarmUtil.saveAlarm(deviceName, deviceId, deviceType,
-					"超寿命", "WARN-OVER-LIFE", null,
-					null, "可燃气体超寿命报警");
 		}
 		if(alarmBits.get("fallAlarm")){
+			saveAlarmData(deviceId, "跌倒报警", "WARN-FALL", null, null, null, "可燃气体跌倒报警");
 			sendMessage(deviceId,"跌倒报警",resultData.getLongitude(),resultData.getLatitude());
-			alarmUtil.saveAlarm(deviceName, deviceId, deviceType,
-					"跌倒报警", "WARN-FALL", null,
-					null, "可燃气体跌倒报警");
 		}
 		if(alarmBits.get("undervoltage")){
+			saveAlarmData(deviceId, "欠压报警", "WARN-UNDERVOLTAGE", null, null, null, "可燃气体欠压报警");
 			sendMessage(deviceId,"欠压报警",resultData.getLongitude(),resultData.getLatitude());
-			alarmUtil.saveAlarm(deviceName, deviceId, deviceType,
-					"欠压报警", "WARN-UNDERVOLTAGE", null,
-					null, "可燃气体欠压报警");
 		}
 		if(alarmBits.get("rangeAlarm")){
+			saveAlarmData(deviceId, "区间报警", "WARN-RANGE", null, null, null, "可燃气体区间报警");
 			sendMessage(deviceId,"区间报警",resultData.getLongitude(),resultData.getLatitude());
-			alarmUtil.saveAlarm(deviceName, deviceId, deviceType,
-					"区间报警", "WARN-RANGE", null,
-					null, "可燃气体区间报警");
 		}
 		if(alarmBits.get("keyAlarm")){
+			saveAlarmData(deviceId, "按键报警", "WARN-KEY", null, null, null, "可燃气体按键报警");
 			sendMessage(deviceId,"按键报警",resultData.getLongitude(),resultData.getLatitude());
-			alarmUtil.saveAlarm(deviceName, deviceId, deviceType,
-					"按键报警", "WARN-KEY", null,
-					null, "可燃气体按键报警");
 		}
 		if(alarmBits.get("vibrationAlarm")){
+			saveAlarmData(deviceId, "震动报警", "WARN-VIBRATION", null, null, null, "可燃气体震动报警");
 			sendMessage(deviceId,"震动报警",resultData.getLongitude(),resultData.getLatitude());
-			alarmUtil.saveAlarm(deviceName, deviceId, deviceType,
-					"震动报警", "WARN-VIBRATION", null,
-					null, "可燃气体震动报警");
 		}
 		if(alarmBits.get("waterLevelAlarm")){
+			saveAlarmData(deviceId, "水位报警", "WARN-WATER-LEVEL", null, null, null, "可燃气体水位报警");
 			sendMessage(deviceId,"水位报警",resultData.getLongitude(),resultData.getLatitude());
-			alarmUtil.saveAlarm(deviceName, deviceId, deviceType,
-					"水位报警", "WARN-WATER-LEVEL", null,
-					null, "可燃气体水位报警");
 		}
 		if(alarmBits.get("powerOffAlarm")){
+			saveAlarmData(deviceId, "断电报警", "WARN-POWER-OFF", null, null, null, "可燃气体断电报警");
 			sendMessage(deviceId,"断电报警",resultData.getLongitude(),resultData.getLatitude());
-			alarmUtil.saveAlarm(deviceName, deviceId, deviceType,
-					"断电报警", "WARN-POWER-OFF", null,
-					null, "可燃气体断电报警");
 		}
 		if(alarmBits.get("sensorFault")){
+			saveAlarmData(deviceId, "传感器故障", "WARN-SENSOR-FAULT", null, null, null, "可燃气体传感器故障");
 			sendMessage(deviceId,"传感器故障",resultData.getLongitude(),resultData.getLatitude());
-			alarmUtil.saveAlarm(deviceName, deviceId, deviceType,
-					"传感器故障", "WARN-SENSOR-FAULT", null,
-					null, "可燃气体传感器故障");
 		}
 		if(alarmBits.get("overHumidity")){
+			saveAlarmData(deviceId, "超湿报警", "WARN-OVER-HUMIDITY", null, null, null, "可燃气体超湿报警");
 			sendMessage(deviceId,"超湿报警",resultData.getLongitude(),resultData.getLatitude());
-			alarmUtil.saveAlarm(deviceName, deviceId, deviceType,
-					"超湿报警", "WARN-OVER-HUMIDITY", null,
-					null, "可燃气体超湿报警");
 		}
 		if(alarmBits.get("overTemperature")){
+			saveAlarmData(deviceId, "超温报警", "WARN-OVER-TEMPERATURE", null, null, null, "可燃气体超温报警");
 			sendMessage(deviceId,"超温报警",resultData.getLongitude(),resultData.getLatitude());
-			alarmUtil.saveAlarm(deviceName, deviceId, deviceType,
-					"超温报警", "WARN-OVER-TEMPERATURE", null,
-					null, "可燃气体超温报警");
 		}
 		if(alarmBits.get("systemFault")){
+			saveAlarmData(deviceId, "系统故障", "WARN-SYSTEM-FAULT", null, null, null, "可燃气体系统故障");
 			sendMessage(deviceId,"系统故障",resultData.getLongitude(),resultData.getLatitude());
-			alarmUtil.saveAlarm(deviceName, deviceId, deviceType,
-					"系统故障", "WARN-SYSTEM-FAULT", null,
-					null, "可燃气体系统故障");
 		}
 	}
-	public Double checkTemAndHum(String deviceWarningCode,String warningCode){
-		//获取数据库中的阈值
-		WarningThreshold threshold = warningThresholdService.getWarningThresholdByDeviceAndCode(deviceWarningCode, warningCode);
-		return threshold.getWarningValue();
+
+	private WarningThreshold checkThreshold(String deviceCode, String warningCode) {
+		try {
+			return warningThresholdService.getWarningThresholdByDeviceAndCode(deviceCode, warningCode);
+		} catch (Exception e) {
+			log.error("查询预警阈值失败:deviceCode={}, warningCode={}", deviceCode, warningCode, e);
+			return null;
+		}
+	}
+
+	private void saveAlarmData(String deviceCode, String warningType, String warningCode,
+							  BigDecimal minValue, BigDecimal maxValue,
+							  BigDecimal actualValue, String remark) {
+		try {
+			AlarmData alarmData = new AlarmData();
+			alarmData.setDeviceCode(deviceCode);
+			alarmData.setWarningType(warningType);
+			alarmData.setWarningCode(warningCode);
+			alarmData.setMinValue(minValue);
+			alarmData.setMaxValue(maxValue);
+			alarmData.setActualValue(actualValue);
+			alarmData.setAlarmStatus(0);
+			alarmData.setAlarmTime(LocalDateTime.now());
+			alarmData.setRemark(remark);
+			alarmData.setCreateTime(LocalDateTime.now());
+			alarmDataService.saveAlarmData(alarmData);
+		} catch (Exception e) {
+			log.error("保存告警数据失败", e);
+		}
 	}
 	//构造发送短信参数&&发送短信
 	public void sendMessage(String deviceNo, String alarmType, BigDecimal lng, BigDecimal lat){

+ 63 - 22
manhole-service/src/main/java/com/zksy/manhole/service/impl/ManholeDataServiceImpl.java

@@ -3,10 +3,13 @@ package com.zksy.manhole.service.impl;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.zksy.api.domain.WarningThreshold;
+import com.zksy.api.service.WarningThresholdService;
 import com.zksy.manhole.domain.ManholeData;
 import com.zksy.manhole.mapper.ManholeDataMapper;
 import com.zksy.manhole.service.ManholeDataService;
 import com.zksy.manhole.utils.AlarmUtil;
+import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.http.ResponseEntity;
@@ -24,12 +27,15 @@ import java.util.stream.Collectors;
  * @description
  * @date 2025/2/20 10:55:03
  */
+@Slf4j
 @Service
 public class ManholeDataServiceImpl extends ServiceImpl<ManholeDataMapper, ManholeData> implements ManholeDataService {
     @Autowired
     private ManholeDataMapper manholeDataMapper;
     @Autowired
     private AlarmUtil alarmUtil;
+    @Autowired
+    private WarningThresholdService warningThresholdService;
     //@Autowired
     //private BaseDevicesService baseDevicesService;
     @Autowired
@@ -63,50 +69,85 @@ public class ManholeDataServiceImpl extends ServiceImpl<ManholeDataMapper, Manho
 
     private void checkAndSaveAlarm(ManholeData result) {
         String deviceCode = result.getImeiCardNumber();
-        String deviceName = "井盖设备";
-        String deviceType = "manhole";
 
+        // 温度判断
         if (result.getTemperatureValue() != null && !result.getTemperatureValue().isEmpty()) {
             try {
-                alarmUtil.checkAndSaveAlarm(deviceName, deviceCode, deviceType,
-                        "温度预警", "WARN-TEMPERATURE", 50.0,
-                        new BigDecimal(result.getTemperatureValue()),
-                        "井盖温度报警");
+                String temWarningCode = "WARN-TEMPERATURE";
+                WarningThreshold temThreshold = checkThreshold(deviceCode, temWarningCode);
+                Double temMinValue = temThreshold != null ? temThreshold.getMinValue() : null;
+                Double temMaxValue = temThreshold != null ? temThreshold.getMaxValue() : 50.0;
+                String temWarningType = temThreshold != null ? temThreshold.getWarningType() : "温度预警";
+                String temRemark = temThreshold != null ? temThreshold.getRemark() : "井盖温度报警";
+
+                BigDecimal temValue = new BigDecimal(result.getTemperatureValue());
+                boolean temShouldAlarm = false;
+                if (temMinValue != null && temValue.doubleValue() <= temMinValue) {
+                    temShouldAlarm = true;
+                }
+                if (temMaxValue != null && temValue.doubleValue() >= temMaxValue) {
+                    temShouldAlarm = true;
+                }
+                if (temShouldAlarm) {
+                    alarmUtil.saveAlarm(deviceCode, temWarningType, temWarningCode,
+                            temMinValue != null ? BigDecimal.valueOf(temMinValue) : null,
+                            temMaxValue != null ? BigDecimal.valueOf(temMaxValue) : null,
+                            temValue, temRemark);
+                }
             } catch (Exception e) {
-                e.printStackTrace();
+                log.error("处理温度报警失败", e);
             }
         }
 
+        // 倾斜判断
         if (result.getTiltAngle() != null && !result.getTiltAngle().isEmpty() 
                 && result.getAngleAlarmThreshold() != null && !result.getAngleAlarmThreshold().isEmpty()) {
             try {
+                String tiltWarningCode = "WARN-TILT";
+                WarningThreshold tiltThreshold = checkThreshold(deviceCode, tiltWarningCode);
+                Double tiltMinValue = tiltThreshold != null ? tiltThreshold.getMinValue() : null;
+                Double tiltMaxValue = tiltThreshold != null ? tiltThreshold.getMaxValue() : Double.parseDouble(result.getAngleAlarmThreshold());
+                String tiltWarningType = tiltThreshold != null ? tiltThreshold.getWarningType() : "倾斜预警";
+                String tiltRemark = tiltThreshold != null ? tiltThreshold.getRemark() : "井盖倾斜报警";
+
                 double tiltAngle = Double.parseDouble(result.getTiltAngle());
-                double threshold = Double.parseDouble(result.getAngleAlarmThreshold());
-                alarmUtil.checkAndSaveAlarm(deviceName, deviceCode, deviceType,
-                        "倾斜预警", "WARN-TILT", threshold,
-                        BigDecimal.valueOf(tiltAngle),
-                        "井盖倾斜报警");
+                boolean tiltShouldAlarm = false;
+                if (tiltMinValue != null && tiltAngle <= tiltMinValue) {
+                    tiltShouldAlarm = true;
+                }
+                if (tiltMaxValue != null && tiltAngle >= tiltMaxValue) {
+                    tiltShouldAlarm = true;
+                }
+                if (tiltShouldAlarm) {
+                    alarmUtil.saveAlarm(deviceCode, tiltWarningType, tiltWarningCode,
+                            tiltMinValue != null ? BigDecimal.valueOf(tiltMinValue) : null,
+                            tiltMaxValue != null ? BigDecimal.valueOf(tiltMaxValue) : null,
+                            BigDecimal.valueOf(tiltAngle), tiltRemark);
+                }
             } catch (Exception e) {
-                e.printStackTrace();
+                log.error("处理倾斜报警失败", e);
             }
         }
 
         if ("1".equals(result.getAlarmStatus())) {
-            alarmUtil.saveAlarm(deviceName, deviceCode, deviceType,
-                    "设备报警", "WARN-DEVICE-ALARM", null,
-                    null, "井盖设备状态报警");
+            alarmUtil.saveAlarm(deviceCode, "设备报警", "WARN-DEVICE-ALARM", null, null, null, "井盖设备状态报警");
         }
 
         if ("1".equals(result.getWaterInfiltrationAlarmStatus())) {
-            alarmUtil.saveAlarm(deviceName, deviceCode, deviceType,
-                    "水浸预警", "WARN-WATER-INFILTRATION", null,
-                    null, "井盖水浸报警");
+            alarmUtil.saveAlarm(deviceCode, "水浸预警", "WARN-WATER-INFILTRATION", null, null, null, "井盖水浸报警");
         }
 
         if ("1".equals(result.getWaterLevelAlarmStatus())) {
-            alarmUtil.saveAlarm(deviceName, deviceCode, deviceType,
-                    "水位预警", "WARN-WATER-LEVEL", null,
-                    null, "井盖水位报警");
+            alarmUtil.saveAlarm(deviceCode, "水位预警", "WARN-WATER-LEVEL", null, null, null, "井盖水位报警");
+        }
+    }
+
+    private WarningThreshold checkThreshold(String deviceCode, String warningCode) {
+        try {
+            return warningThresholdService.getWarningThresholdByDeviceAndCode(deviceCode, warningCode);
+        } catch (Exception e) {
+            log.error("查询预警阈值失败:deviceCode={}, warningCode={}", deviceCode, warningCode, e);
+            return null;
         }
     }
 }

+ 20 - 11
manhole-service/src/main/java/com/zksy/manhole/utils/AlarmUtil.java

@@ -24,30 +24,39 @@ public class AlarmUtil {
     @Value("${alarm.api.url:http://zk-api-service/alarmData/save}")
     private String alarmApiUrl;
 
-    public void checkAndSaveAlarm(String deviceName, String deviceCode, String deviceType,
-                                    String warningType, String warningCode, Double warningValue,
+    public void checkAndSaveAlarm(String deviceCode,
+                                    String warningType, String warningCode, Double minValue, Double maxValue,
                                     BigDecimal actualValue, String remark) {
-        if (warningValue == null || actualValue == null) {
+        if (actualValue == null) {
             return;
         }
 
-        if (actualValue.doubleValue() > warningValue) {
-            saveAlarm(deviceName, deviceCode, deviceType, warningType, warningCode,
-                    BigDecimal.valueOf(warningValue), actualValue, remark);
+        boolean shouldAlarm = false;
+        if (minValue != null && actualValue.doubleValue() <= minValue) {
+            shouldAlarm = true;
+        }
+        if (maxValue != null && actualValue.doubleValue() >= maxValue) {
+            shouldAlarm = true;
+        }
+
+        if (shouldAlarm) {
+            saveAlarm(deviceCode, warningType, warningCode,
+                    minValue != null ? BigDecimal.valueOf(minValue) : null,
+                    maxValue != null ? BigDecimal.valueOf(maxValue) : null,
+                    actualValue, remark);
         }
     }
 
-    public void saveAlarm(String deviceName, String deviceCode, String deviceType,
-                           String warningType, String warningCode, BigDecimal warningValue,
+    public void saveAlarm(String deviceCode,
+                           String warningType, String warningCode, BigDecimal minValue, BigDecimal maxValue,
                            BigDecimal actualValue, String remark) {
         try {
             Map<String, Object> alarmData = new HashMap<>();
-            alarmData.put("deviceName", deviceName);
             alarmData.put("deviceCode", deviceCode);
-            alarmData.put("deviceType", deviceType);
             alarmData.put("warningType", warningType);
             alarmData.put("warningCode", warningCode);
-            alarmData.put("warningValue", warningValue);
+            alarmData.put("minValue", minValue);
+            alarmData.put("maxValue", maxValue);
             alarmData.put("actualValue", actualValue);
             alarmData.put("alarmStatus", 0);
             alarmData.put("alarmTime", LocalDateTime.now().toString());

+ 3 - 5
pipe-network-service/zksy-admin/src/main/java/com/zksy/web/controller/base/alarm/AlarmDataController.java

@@ -25,23 +25,21 @@ public class AlarmDataController {
     @Anonymous
     public AjaxResult findByPage(@ApiParam(value = "页码", required = true) long pageNum,
                                  @ApiParam(value = "页数", required = true) long pageSize,
-                                 @ApiParam(value = "设备名称", required = false) String deviceName,
                                  @ApiParam(value = "设备编码", required = false) String deviceCode,
                                  @ApiParam(value = "预警类型", required = false) String warningType,
                                  @ApiParam(value = "预警编码", required = false) String warningCode,
                                  @ApiParam(value = "报警状态 0-未处理 1-已处理", required = false) Integer alarmStatus) {
-        return AjaxResult.success(service.findByPage(pageNum, pageSize, deviceName, deviceCode, warningType, warningCode, alarmStatus));
+        return AjaxResult.success(service.findByPage(pageNum, pageSize, deviceCode, warningType, warningCode, alarmStatus));
     }
 
     @GetMapping("/getAlarmDataList")
     @ApiOperation(value = "报警数据信息查询")
     @Anonymous
-    public AjaxResult getAlarmDataList(@ApiParam(value = "设备名称", required = false) String deviceName,
-                                         @ApiParam(value = "设备编码", required = false) String deviceCode,
+    public AjaxResult getAlarmDataList(@ApiParam(value = "设备编码", required = false) String deviceCode,
                                          @ApiParam(value = "预警类型", required = false) String warningType,
                                          @ApiParam(value = "预警编码", required = false) String warningCode,
                                          @ApiParam(value = "报警状态 0-未处理 1-已处理", required = false) Integer alarmStatus) {
-        return AjaxResult.success(service.getAlarmDataList(deviceName, deviceCode, warningType, warningCode, alarmStatus));
+        return AjaxResult.success(service.getAlarmDataList(deviceCode, warningType, warningCode, alarmStatus));
     }
 
     @GetMapping("/getById/{id}")

+ 15 - 35
pipe-network-service/zksy-admin/src/main/java/com/zksy/web/controller/base/alarm/AlarmTestController.java

@@ -28,8 +28,6 @@ public class AlarmTestController {
     @ApiOperation(value = "模拟井盖设备采集数据并报警")
     public AjaxResult simulateManhole() {
         String deviceCode = "TEST-MANHOLE-001";
-        String deviceName = "测试井盖设备";
-        String deviceType = "manhole";
 
         double temperature = 30 + random.nextDouble() * 40;
         double tiltAngle = 0 + random.nextDouble() * 90;
@@ -37,19 +35,16 @@ public class AlarmTestController {
 
         Map<String, Object> result = new HashMap<>();
         result.put("deviceCode", deviceCode);
-        result.put("deviceName", deviceName);
         result.put("temperature", temperature);
         result.put("tiltAngle", tiltAngle);
         result.put("threshold", threshold);
 
         if (temperature > 50) {
             AlarmData alarmData = new AlarmData();
-            alarmData.setDeviceName(deviceName);
             alarmData.setDeviceCode(deviceCode);
-            alarmData.setDeviceType(deviceType);
             alarmData.setWarningType("温度预警");
             alarmData.setWarningCode("WARN-TEMPERATURE");
-            alarmData.setWarningValue(BigDecimal.valueOf(50.0));
+            alarmData.setMaxValue(BigDecimal.valueOf(50.0));
             alarmData.setActualValue(BigDecimal.valueOf(temperature));
             alarmData.setAlarmStatus(0);
             alarmData.setAlarmTime(LocalDateTime.now());
@@ -63,12 +58,10 @@ public class AlarmTestController {
 
         if (tiltAngle > threshold) {
             AlarmData alarmData = new AlarmData();
-            alarmData.setDeviceName(deviceName);
             alarmData.setDeviceCode(deviceCode);
-            alarmData.setDeviceType(deviceType);
             alarmData.setWarningType("倾斜预警");
             alarmData.setWarningCode("WARN-TILT");
-            alarmData.setWarningValue(BigDecimal.valueOf(threshold));
+            alarmData.setMaxValue(BigDecimal.valueOf(threshold));
             alarmData.setActualValue(BigDecimal.valueOf(tiltAngle));
             alarmData.setAlarmStatus(0);
             alarmData.setAlarmTime(LocalDateTime.now());
@@ -87,8 +80,6 @@ public class AlarmTestController {
     @ApiOperation(value = "模拟可燃气体设备采集数据并报警")
     public AjaxResult simulateGas() {
         String deviceCode = "TEST-GAS-001";
-        String deviceName = "测试可燃气体设备";
-        String deviceType = "flammable-gas";
 
         float temperature = 20 + random.nextFloat() * 40;
         float humidity = 40 + random.nextFloat() * 40;
@@ -96,19 +87,16 @@ public class AlarmTestController {
 
         Map<String, Object> result = new HashMap<>();
         result.put("deviceCode", deviceCode);
-        result.put("deviceName", deviceName);
         result.put("temperature", temperature);
         result.put("humidity", humidity);
         result.put("gasConcentration", gasConcentration);
 
         if (temperature > 50) {
             AlarmData alarmData = new AlarmData();
-            alarmData.setDeviceName(deviceName);
             alarmData.setDeviceCode(deviceCode);
-            alarmData.setDeviceType(deviceType);
             alarmData.setWarningType("温度预警");
             alarmData.setWarningCode("WARN-TEMPERATURE");
-            alarmData.setWarningValue(BigDecimal.valueOf(50.0));
+            alarmData.setMaxValue(BigDecimal.valueOf(50.0));
             alarmData.setActualValue(BigDecimal.valueOf(temperature));
             alarmData.setAlarmStatus(0);
             alarmData.setAlarmTime(LocalDateTime.now());
@@ -122,12 +110,10 @@ public class AlarmTestController {
 
         if (humidity > 80) {
             AlarmData alarmData = new AlarmData();
-            alarmData.setDeviceName(deviceName);
             alarmData.setDeviceCode(deviceCode);
-            alarmData.setDeviceType(deviceType);
             alarmData.setWarningType("湿度预警");
             alarmData.setWarningCode("WARN-HUMIDITY");
-            alarmData.setWarningValue(BigDecimal.valueOf(80.0));
+            alarmData.setMaxValue(BigDecimal.valueOf(80.0));
             alarmData.setActualValue(BigDecimal.valueOf(humidity));
             alarmData.setAlarmStatus(0);
             alarmData.setAlarmTime(LocalDateTime.now());
@@ -141,12 +127,10 @@ public class AlarmTestController {
 
         if (gasConcentration.doubleValue() > 50) {
             AlarmData alarmData = new AlarmData();
-            alarmData.setDeviceName(deviceName);
             alarmData.setDeviceCode(deviceCode);
-            alarmData.setDeviceType(deviceType);
             alarmData.setWarningType("气体浓度预警");
             alarmData.setWarningCode("WARN-GAS-CONCENTRATION");
-            alarmData.setWarningValue(BigDecimal.valueOf(50.0));
+            alarmData.setMaxValue(BigDecimal.valueOf(50.0));
             alarmData.setActualValue(gasConcentration);
             alarmData.setAlarmStatus(0);
             alarmData.setAlarmTime(LocalDateTime.now());
@@ -165,26 +149,21 @@ public class AlarmTestController {
     @ApiOperation(value = "模拟环境设备采集数据并报警")
     public AjaxResult simulateEnvironment() {
         String deviceCode = "TEST-ENV-001";
-        String deviceName = "测试环境设备";
-        String deviceType = "environment";
 
         double temperature = 15 + random.nextDouble() * 50;
         double humidity = 30 + random.nextDouble() * 60;
 
         Map<String, Object> result = new HashMap<>();
         result.put("deviceCode", deviceCode);
-        result.put("deviceName", deviceName);
         result.put("temperature", temperature);
         result.put("humidity", humidity);
 
         if (temperature > 50) {
             AlarmData alarmData = new AlarmData();
-            alarmData.setDeviceName(deviceName);
             alarmData.setDeviceCode(deviceCode);
-            alarmData.setDeviceType(deviceType);
             alarmData.setWarningType("温度预警");
             alarmData.setWarningCode("WARN-TEMPERATURE");
-            alarmData.setWarningValue(BigDecimal.valueOf(50.0));
+            alarmData.setMaxValue(BigDecimal.valueOf(50.0));
             alarmData.setActualValue(BigDecimal.valueOf(temperature));
             alarmData.setAlarmStatus(0);
             alarmData.setAlarmTime(LocalDateTime.now());
@@ -198,12 +177,10 @@ public class AlarmTestController {
 
         if (humidity > 90) {
             AlarmData alarmData = new AlarmData();
-            alarmData.setDeviceName(deviceName);
             alarmData.setDeviceCode(deviceCode);
-            alarmData.setDeviceType(deviceType);
             alarmData.setWarningType("湿度预警");
             alarmData.setWarningCode("WARN-HUMIDITY");
-            alarmData.setWarningValue(BigDecimal.valueOf(90.0));
+            alarmData.setMaxValue(BigDecimal.valueOf(90.0));
             alarmData.setActualValue(BigDecimal.valueOf(humidity));
             alarmData.setAlarmStatus(0);
             alarmData.setAlarmTime(LocalDateTime.now());
@@ -222,15 +199,18 @@ public class AlarmTestController {
     @ApiOperation(value = "自定义报警测试")
     public AjaxResult customAlarm(@RequestBody Map<String, Object> params) {
         AlarmData alarmData = new AlarmData();
-        alarmData.setDeviceName((String) params.get("deviceName"));
         alarmData.setDeviceCode((String) params.get("deviceCode"));
-        alarmData.setDeviceType((String) params.get("deviceType"));
         alarmData.setWarningType((String) params.get("warningType"));
         alarmData.setWarningCode((String) params.get("warningCode"));
         
-        Object warningValueObj = params.get("warningValue");
-        if (warningValueObj != null) {
-            alarmData.setWarningValue(new BigDecimal(warningValueObj.toString()));
+        Object minValueObj = params.get("minValue");
+        if (minValueObj != null) {
+            alarmData.setMinValue(new BigDecimal(minValueObj.toString()));
+        }
+        
+        Object maxValueObj = params.get("maxValue");
+        if (maxValueObj != null) {
+            alarmData.setMaxValue(new BigDecimal(maxValueObj.toString()));
         }
         
         Object actualValueObj = params.get("actualValue");

+ 4 - 5
pipe-network-service/zksy-admin/src/main/java/com/zksy/web/controller/base/alarm/WarningThresholdController.java

@@ -30,21 +30,20 @@ public class WarningThresholdController {
     @ApiOperation(value = "预警阈值信息查询分页")
     @Anonymous
     public AjaxResult findByPage(@ApiParam(value = "页码", required = true)long pageNum,
-                                 @ApiParam(value = "页数", required = true)long pageSize, @ApiParam(value = "设备名称", example = "反应釜A", required = false)String deviceName,
+                                 @ApiParam(value = "页数", required = true)long pageSize,
                                  @ApiParam(value = "设备编码", required = false)String deviceCode,
                                  @ApiParam(value = "预警类型", allowableValues = "温度预警,压力预警,湿度预警", required = false) String warningType,
                                  @ApiParam(value = "预警编码", required = false) String warningCode){
-        return AjaxResult.success(service.findByPage(pageNum, pageSize, deviceName,deviceCode,warningType,warningCode));
+        return AjaxResult.success(service.findByPage(pageNum, pageSize, deviceCode,warningType,warningCode));
     }
     @GetMapping("/getWarningThresholdList")
     @ApiOperation(value = "预警阈值信息查询")
     @Anonymous
-    public AjaxResult getWarningThresholdList(@ApiParam(value = "设备名称", required = false)String deviceName,
-                                              @ApiParam(value = "设备编码",  required = false)String deviceCode,
+    public AjaxResult getWarningThresholdList(@ApiParam(value = "设备编码",  required = false)String deviceCode,
                                               @ApiParam(value = "预警类型",  allowableValues = "温度预警,压力预警,湿度预警", required = false) String warningType,
                                               @ApiParam(value = "预警编码",  required = false) String warningCode
     ){
-        return AjaxResult.success(service.getWarningThresholdList(deviceName,deviceCode,warningType,warningCode));
+        return AjaxResult.success(service.getWarningThresholdList(deviceCode,warningType,warningCode));
     }
     @GetMapping("/getById/{id}")
     @ApiOperation(value = "根据Id查询预警阈值信息")

+ 7 - 11
pipe-network-service/zksy-system/src/main/java/com/zksy/base/alarm/domain/AlarmData.java

@@ -19,18 +19,10 @@ public class AlarmData implements Serializable {
     @ApiModelProperty(value = "主键")
     private String id;
 
-    @TableField(value = "device_name")
-    @ApiModelProperty(value = "设备名称")
-    private String deviceName;
-
     @TableField(value = "device_code")
     @ApiModelProperty(value = "设备编码")
     private String deviceCode;
 
-    @TableField(value = "device_type")
-    @ApiModelProperty(value = "设备类型")
-    private String deviceType;
-
     @TableField(value = "warning_type")
     @ApiModelProperty(value = "预警类型")
     private String warningType;
@@ -39,9 +31,13 @@ public class AlarmData implements Serializable {
     @ApiModelProperty(value = "预警编码")
     private String warningCode;
 
-    @TableField(value = "warning_value")
-    @ApiModelProperty(value = "预警阈值")
-    private BigDecimal warningValue;
+    @TableField(value = "min_value")
+    @ApiModelProperty(value = "预警最小值,小于等于该值视为报警")
+    private BigDecimal minValue;
+
+    @TableField(value = "max_value")
+    @ApiModelProperty(value = "预警最大值,大于等于该值视为报警")
+    private BigDecimal maxValue;
 
     @TableField(value = "actual_value")
     @ApiModelProperty(value = "实际值")

+ 11 - 53
pipe-network-service/zksy-system/src/main/java/com/zksy/base/alarm/domain/WarningThreshold.java

@@ -24,13 +24,6 @@ public class WarningThreshold implements Serializable {
     @ApiModelProperty(value = "主键")
     private String id;
 
-    /**
-     * 设备名称
-     */
-    @TableField(value = "device_name")
-    @ApiModelProperty(value = "设备名称")
-    private String deviceName;
-
     /**
      * 设备编码
      */
@@ -38,13 +31,6 @@ public class WarningThreshold implements Serializable {
     @ApiModelProperty(value = "设备编码")
     private String deviceCode;
 
-    /**
-     * 设备类型
-     */
-    @TableField(value = "device_type")
-    @ApiModelProperty(value = "设备类型")
-    private String deviceType;
-
     /**
      * 预警类型
      */
@@ -60,11 +46,18 @@ public class WarningThreshold implements Serializable {
     private String warningCode;
 
     /**
-     * 预警值
+     * 预警最小
      */
-    @TableField(value = "warning_value")
-    @ApiModelProperty(value = "预警值")
-    private Double warningValue;
+    @TableField(value = "min_value")
+    @ApiModelProperty(value = "预警最小值,小于等于该值视为报警")
+    private Double minValue;
+
+    /**
+     * 预警最大值
+     */
+    @TableField(value = "max_value")
+    @ApiModelProperty(value = "预警最大值,大于等于该值视为报警")
+    private Double maxValue;
 
     /**
      * 备注
@@ -73,41 +66,6 @@ public class WarningThreshold implements Serializable {
     @ApiModelProperty(value = "备注")
     private String remark;
 
-    /**
-     * 关联设备ID
-     */
-    @TableField(value = "equipment_id")
-    @ApiModelProperty(value = "关联设备ID")
-    private String equipmentId;
-
-    /**
-     * 关联监测点ID
-     */
-    @TableField(value = "point_id")
-    @ApiModelProperty(value = "关联监测点ID")
-    private String pointId;
-
-    /**
-     * 监测类型
-     */
-    @TableField(value = "monitor_type")
-    @ApiModelProperty(value = "监测类型(水位、流量、压力、温度等)")
-    private String monitorType;
-
-    /**
-     * 预警级别
-     */
-    @TableField(value = "warning_level")
-    @ApiModelProperty(value = "预警级别(1-蓝色 2-黄色 3-橙色 4-红色)")
-    private String warningLevel;
-
-    /**
-     * 比较运算符
-     */
-    @TableField(value = "operator")
-    @ApiModelProperty(value = "比较运算符(>、<、>=、<=、=、!=)")
-    private String operator;
-
     /**
      * 创建时间
      */

+ 2 - 2
pipe-network-service/zksy-system/src/main/java/com/zksy/base/alarm/service/AlarmDataService.java

@@ -7,10 +7,10 @@ import com.zksy.base.alarm.domain.AlarmData;
 import java.util.List;
 
 public interface AlarmDataService extends IService<AlarmData> {
-    Page<AlarmData> findByPage(long pageNum, long pageSize, String deviceName, String deviceCode, 
+    Page<AlarmData> findByPage(long pageNum, long pageSize, String deviceCode, 
                                  String warningType, String warningCode, Integer alarmStatus);
     
-    List<AlarmData> getAlarmDataList(String deviceName, String deviceCode, 
+    List<AlarmData> getAlarmDataList(String deviceCode, 
                                        String warningType, String warningCode, Integer alarmStatus);
     
     boolean saveAlarmData(AlarmData alarmData);

+ 2 - 2
pipe-network-service/zksy-system/src/main/java/com/zksy/base/alarm/service/WarningThresholdService.java

@@ -12,8 +12,8 @@ import java.util.List;
 * @createDate 2025-09-01 09:59:43
 */
 public interface WarningThresholdService extends IService<WarningThreshold> {
-    Page<WarningThreshold> findByPage(long pageNum, long pageSize, String deviceName,String deviceCode,String warningType,String warningCode);
-    List<WarningThreshold> getWarningThresholdList(String deviceName,String deviceCode,String warningType,String warningCode);
+    Page<WarningThreshold> findByPage(long pageNum, long pageSize, String deviceCode,String warningType,String warningCode);
+    List<WarningThreshold> getWarningThresholdList(String deviceCode,String warningType,String warningCode);
 
     /**
      * 根据设备编号查询该设备所有预警值

+ 5 - 7
pipe-network-service/zksy-system/src/main/java/com/zksy/base/alarm/service/impl/AlarmDataServiceImpl.java

@@ -16,13 +16,12 @@ public class AlarmDataServiceImpl extends ServiceImpl<AlarmDataMapper, AlarmData
     implements AlarmDataService {
 
     @Override
-    public Page<AlarmData> findByPage(long pageNum, long pageSize, String deviceName, 
-                                        String deviceCode, String warningType, String warningCode, 
+    public Page<AlarmData> findByPage(long pageNum, long pageSize, String deviceCode, 
+                                        String warningType, String warningCode, 
                                         Integer alarmStatus) {
         Page<AlarmData> page = new Page<>(pageNum, pageSize);
         LambdaQueryWrapper<AlarmData> queryWrapper = new LambdaQueryWrapper<>();
-        queryWrapper.like(deviceName != null, AlarmData::getDeviceName, deviceName)
-                .like(deviceCode != null, AlarmData::getDeviceCode, deviceCode)
+        queryWrapper.like(deviceCode != null, AlarmData::getDeviceCode, deviceCode)
                 .like(warningType != null, AlarmData::getWarningType, warningType)
                 .like(warningCode != null, AlarmData::getWarningCode, warningCode)
                 .eq(alarmStatus != null, AlarmData::getAlarmStatus, alarmStatus);
@@ -31,12 +30,11 @@ public class AlarmDataServiceImpl extends ServiceImpl<AlarmDataMapper, AlarmData
     }
 
     @Override
-    public List<AlarmData> getAlarmDataList(String deviceName, String deviceCode, 
+    public List<AlarmData> getAlarmDataList(String deviceCode, 
                                               String warningType, String warningCode, 
                                               Integer alarmStatus) {
         LambdaQueryWrapper<AlarmData> queryWrapper = new LambdaQueryWrapper<>();
-        queryWrapper.like(deviceName != null, AlarmData::getDeviceName, deviceName)
-                .like(deviceCode != null, AlarmData::getDeviceCode, deviceCode)
+        queryWrapper.like(deviceCode != null, AlarmData::getDeviceCode, deviceCode)
                 .like(warningType != null, AlarmData::getWarningType, warningType)
                 .like(warningCode != null, AlarmData::getWarningCode, warningCode)
                 .eq(alarmStatus != null, AlarmData::getAlarmStatus, alarmStatus);

+ 4 - 6
pipe-network-service/zksy-system/src/main/java/com/zksy/base/alarm/service/impl/WarningThresholdServiceImpl.java

@@ -21,11 +21,10 @@ public class WarningThresholdServiceImpl extends ServiceImpl<WarningThresholdMap
     implements WarningThresholdService {
 
     @Override
-    public Page<WarningThreshold> findByPage(long pageNum, long pageSize, String deviceName, String deviceCode, String warningType, String warningCode) {
+    public Page<WarningThreshold> findByPage(long pageNum, long pageSize, String deviceCode, String warningType, String warningCode) {
         Page<WarningThreshold> page = new Page<>(pageNum, pageSize);
         LambdaQueryWrapper<WarningThreshold> queryWrapper = new LambdaQueryWrapper<>();
-        queryWrapper.like(WarningThreshold::getDeviceName,deviceName)
-                .like(WarningThreshold::getDeviceCode,deviceCode)
+        queryWrapper.like(WarningThreshold::getDeviceCode,deviceCode)
                 .like(WarningThreshold::getWarningType,warningType)
                 .like(WarningThreshold::getWarningCode,warningCode);
         queryWrapper.orderByDesc(WarningThreshold::getUpdateTime);
@@ -33,10 +32,9 @@ public class WarningThresholdServiceImpl extends ServiceImpl<WarningThresholdMap
     }
 
     @Override
-    public List<WarningThreshold> getWarningThresholdList(String deviceName, String deviceCode, String warningType, String warningCode) {
+    public List<WarningThreshold> getWarningThresholdList(String deviceCode, String warningType, String warningCode) {
         LambdaQueryWrapper<WarningThreshold> queryWrapper = new LambdaQueryWrapper<>();
-        queryWrapper.like(WarningThreshold::getDeviceName,deviceName)
-                .like(WarningThreshold::getDeviceCode,deviceCode)
+        queryWrapper.like(WarningThreshold::getDeviceCode,deviceCode)
                 .like(WarningThreshold::getWarningType,warningType)
                 .like(WarningThreshold::getWarningCode,warningCode);
         queryWrapper.orderByDesc(WarningThreshold::getUpdateTime);

+ 5 - 2
pipe-network-service/zksy-system/src/main/java/com/zksy/manhole/dto/out/WarningThresholdOutDTO.java

@@ -22,8 +22,11 @@ public class WarningThresholdOutDTO implements Serializable {
     @ApiModelProperty(value = "预警编码")
     private String warningCode;
 
-    @ApiModelProperty(value = "预警值")
-    private Double warningValue;
+    @ApiModelProperty(value = "预警最小值,小于等于该值视为报警")
+    private Double minValue;
+
+    @ApiModelProperty(value = "预警最大值,大于等于该值视为报警")
+    private Double maxValue;
 
     @ApiModelProperty(value = "备注")
     private String remark;

+ 124 - 1
radar-service/src/main/java/com/zksy/radar/utils/MessageHandler.java

@@ -1,5 +1,9 @@
 package com.zksy.radar.utils;
 
+import com.zksy.api.domain.AlarmData;
+import com.zksy.api.domain.WarningThreshold;
+import com.zksy.api.service.AlarmDataService;
+import com.zksy.api.service.WarningThresholdService;
 import com.zksy.common.exception.InvalidMessageException;
 import com.zksy.radar.domain.RadarData;
 import com.zksy.radar.service.RadarDataService;
@@ -16,15 +20,22 @@ import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+
 @ChannelHandler.Sharable
 @Slf4j
 @Component
 public class MessageHandler extends ChannelInboundHandlerAdapter {
 	private static Logger logger = LoggerFactory.getLogger(MessageHandler.class);
 	private final RadarDataService service;
+	private final WarningThresholdService warningThresholdService;
+	private final AlarmDataService alarmDataService;
 	@Autowired
-	public MessageHandler(RadarDataService RadarDataService) {
+	public MessageHandler(RadarDataService RadarDataService, WarningThresholdService warningThresholdService, AlarmDataService alarmDataService) {
 		this.service = RadarDataService;
+		this.warningThresholdService = warningThresholdService;
+		this.alarmDataService = alarmDataService;
 	}
 
 	@Override
@@ -72,6 +83,9 @@ public class MessageHandler extends ChannelInboundHandlerAdapter {
 				// 入库
 				service.save(resultData);
 				logger.info("上报历史记录数据入库成功: {}", resultData);
+				
+				// 瞬时流量和流速告警入库
+				handleRadarAlarm(resultData);
 
 				// 如果结束位=1,可以根据需要在此处理关闭逻辑
 				if (Boolean.TRUE.equals(resultData.getIsLastPacket())) {
@@ -164,4 +178,113 @@ public class MessageHandler extends ChannelInboundHandlerAdapter {
 			logger.error("发送数据失败: {}", e.getMessage());
 		}
 	}
+
+	/**
+	 * 处理雷达设备告警
+	 */
+	private void handleRadarAlarm(RadarData resultData) {
+		try {
+			// 设备编码从设备数据获取
+			String deviceCode = resultData.getDeviceCode();
+			if (deviceCode == null) {
+				deviceCode = resultData.getSystemIdentifier();
+			}
+
+			// 1. 处理瞬时流量告警
+			if (resultData.getMeter1InstantFlow() != null) {
+				handleAlarm(deviceCode, "WARN_INSTANT_FLOW", "瞬时流量", 
+					resultData.getMeter1InstantFlow());
+			}
+
+			// 2. 处理流速告警
+			if (resultData.getFlowSpeed() != null) {
+				handleAlarm(deviceCode, "WARN_FLOW_SPEED", "流速", 
+					resultData.getFlowSpeed());
+			}
+
+		} catch (Exception e) {
+			logger.error("雷达告警处理异常", e);
+		}
+	}
+
+	/**
+	 * 处理单个告警
+	 */
+	private void handleAlarm(String deviceCode, String warningCode, String warningType, String valueStr) {
+		try {
+			// 解析实际值
+			Double actualValue = null;
+			try {
+				actualValue = Double.parseDouble(valueStr);
+			} catch (NumberFormatException e) {
+				logger.warn("无法解析告警值: {}", valueStr);
+				return;
+			}
+
+			// 查询预警阈值表
+			WarningThreshold threshold = null;
+			try {
+				threshold = warningThresholdService.getWarningThresholdByDeviceAndCode(deviceCode, warningCode);
+			} catch (Exception e) {
+				logger.error("查询预警阈值失败: deviceCode={}, warningCode={}", deviceCode, warningCode, e);
+			}
+
+			// 使用阈值表中的预警类型(如果有的话)
+			if (threshold != null && threshold.getWarningType() != null) {
+				warningType = threshold.getWarningType();
+			}
+
+			// 获取最小值和最大值
+			Double minValue = threshold != null ? threshold.getMinValue() : null;
+			Double maxValue = threshold != null ? threshold.getMaxValue() : null;
+			String remark = threshold != null ? threshold.getRemark() : null;
+
+			// 判断是否触发报警
+			boolean isOverThreshold = false;
+			if (minValue != null && actualValue <= minValue) {
+				isOverThreshold = true;
+			}
+			if (maxValue != null && actualValue >= maxValue) {
+				isOverThreshold = true;
+			}
+
+			if (isOverThreshold) {
+				logger.warn("设备{}触发{}告警(当前值:{},最小值:{},最大值:{})",
+					deviceCode, warningType, actualValue, minValue, maxValue);
+
+				// 保存到 alarm_data 表
+				saveAlarmData(deviceCode, warningType, warningCode,
+					minValue != null ? BigDecimal.valueOf(minValue) : null,
+					maxValue != null ? BigDecimal.valueOf(maxValue) : null,
+					BigDecimal.valueOf(actualValue), remark);
+			}
+
+		} catch (Exception e) {
+			logger.error("处理告警异常", e);
+		}
+	}
+
+	/**
+	 * 保存告警数据到 alarm_data 表
+	 */
+	private void saveAlarmData(String deviceCode, String warningType, String warningCode,
+	                           BigDecimal minValue, BigDecimal maxValue, BigDecimal actualValue, String remark) {
+		try {
+			AlarmData alarmData = new AlarmData();
+			alarmData.setDeviceCode(deviceCode);
+			alarmData.setWarningType(warningType);
+			alarmData.setWarningCode(warningCode);
+			alarmData.setMinValue(minValue);
+			alarmData.setMaxValue(maxValue);
+			alarmData.setActualValue(actualValue);
+			alarmData.setAlarmStatus(0);
+			alarmData.setAlarmTime(LocalDateTime.now());
+			alarmData.setRemark(remark);
+			alarmData.setCreateTime(LocalDateTime.now());
+			alarmDataService.saveAlarmData(alarmData);
+			logger.info("告警数据入库成功: deviceCode={}, warningCode={}", deviceCode, warningCode);
+		} catch (Exception e) {
+			logger.error("保存告警数据失败", e);
+		}
+	}
 }

+ 118 - 1
water-level-service/src/main/java/com/zksy/water/utils/MessageHandler.java

@@ -1,5 +1,9 @@
 package com.zksy.water.utils;
 
+import com.zksy.api.domain.AlarmData;
+import com.zksy.api.domain.WarningThreshold;
+import com.zksy.api.service.AlarmDataService;
+import com.zksy.api.service.WarningThresholdService;
 import com.zksy.common.exception.InvalidMessageException;
 import com.zksy.water.domain.WaterMonitorData;
 import com.zksy.water.service.WaterMonitorDataService;
@@ -16,15 +20,22 @@ import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+
 @ChannelHandler.Sharable
 @Slf4j
 @Component
 public class MessageHandler extends ChannelInboundHandlerAdapter {
 	private static Logger logger = LoggerFactory.getLogger(MessageHandler.class);
 	private final WaterMonitorDataService service;
+	private final WarningThresholdService warningThresholdService;
+	private final AlarmDataService alarmDataService;
 	@Autowired
-	public MessageHandler(WaterMonitorDataService waterMonitorDataService) {
+	public MessageHandler(WaterMonitorDataService waterMonitorDataService, WarningThresholdService warningThresholdService, AlarmDataService alarmDataService) {
 		this.service = waterMonitorDataService;
+		this.warningThresholdService = warningThresholdService;
+		this.alarmDataService = alarmDataService;
 	}
 
 	@Override
@@ -72,6 +83,9 @@ public class MessageHandler extends ChannelInboundHandlerAdapter {
 				// 入库
 				service.save(resultData);
 				logger.info("上报历史记录数据入库成功: {}", resultData);
+				
+				// 水位告警入库
+				handleWaterLevelAlarm(resultData);
 
 				// 如果结束位=1,可以根据需要在此处理关闭逻辑
 				if (Boolean.TRUE.equals(resultData.getIsLastPacket())) {
@@ -164,4 +178,107 @@ public class MessageHandler extends ChannelInboundHandlerAdapter {
 			logger.error("发送数据失败: {}", e.getMessage());
 		}
 	}
+
+	/**
+	 * 处理水位告警
+	 */
+	private void handleWaterLevelAlarm(WaterMonitorData resultData) {
+		try {
+			// 设备编码从设备数据获取
+			String deviceCode = resultData.getDeviceCode();
+			if (deviceCode == null) {
+				deviceCode = resultData.getSystemIdentifier();
+			}
+
+			// 处理水位告警
+			if (resultData.getWaterLevel() != null) {
+				handleAlarm(deviceCode, "WARN_WATER_LEVEL", "水位", 
+					resultData.getWaterLevel());
+			}
+
+		} catch (Exception e) {
+			logger.error("水位告警处理异常", e);
+		}
+	}
+
+	/**
+	 * 处理单个告警
+	 */
+	private void handleAlarm(String deviceCode, String warningCode, String warningType, String valueStr) {
+		try {
+			// 解析实际值
+			Double actualValue = null;
+			try {
+				actualValue = Double.parseDouble(valueStr);
+			} catch (NumberFormatException e) {
+				logger.warn("无法解析告警值: {}", valueStr);
+				return;
+			}
+
+			// 查询预警阈值表
+			WarningThreshold threshold = null;
+			try {
+				threshold = warningThresholdService.getWarningThresholdByDeviceAndCode(deviceCode, warningCode);
+			} catch (Exception e) {
+				logger.error("查询预警阈值失败: deviceCode={}, warningCode={}", deviceCode, warningCode, e);
+			}
+
+			// 使用阈值表中的预警类型(如果有的话)
+			if (threshold != null && threshold.getWarningType() != null) {
+				warningType = threshold.getWarningType();
+			}
+
+			// 获取最小值和最大值
+			Double minValue = threshold != null ? threshold.getMinValue() : null;
+			Double maxValue = threshold != null ? threshold.getMaxValue() : null;
+			String remark = threshold != null ? threshold.getRemark() : null;
+
+			// 判断是否触发报警
+			boolean isOverThreshold = false;
+			if (minValue != null && actualValue <= minValue) {
+				isOverThreshold = true;
+			}
+			if (maxValue != null && actualValue >= maxValue) {
+				isOverThreshold = true;
+			}
+
+			if (isOverThreshold) {
+				logger.warn("设备{}触发{}告警(当前值:{},最小值:{},最大值:{})",
+					deviceCode, warningType, actualValue, minValue, maxValue);
+
+				// 保存到 alarm_data 表
+				saveAlarmData(deviceCode, warningType, warningCode,
+					minValue != null ? BigDecimal.valueOf(minValue) : null,
+					maxValue != null ? BigDecimal.valueOf(maxValue) : null,
+					BigDecimal.valueOf(actualValue), remark);
+			}
+
+		} catch (Exception e) {
+			logger.error("处理告警异常", e);
+		}
+	}
+
+	/**
+	 * 保存告警数据到 alarm_data 表
+	 */
+	private void saveAlarmData(String deviceCode, String warningType, String warningCode,
+	                           BigDecimal minValue, BigDecimal maxValue, BigDecimal actualValue, String remark) {
+		try {
+			AlarmData alarmData = new AlarmData();
+			alarmData.setDeviceCode(deviceCode);
+			alarmData.setWarningType(warningType);
+			alarmData.setWarningCode(warningCode);
+			alarmData.setMinValue(minValue);
+			alarmData.setMaxValue(maxValue);
+			alarmData.setActualValue(actualValue);
+			alarmData.setAlarmStatus(0);
+			alarmData.setAlarmTime(LocalDateTime.now());
+			alarmData.setRemark(remark);
+			alarmData.setCreateTime(LocalDateTime.now());
+			alarmDataService.saveAlarmData(alarmData);
+			logger.info("告警数据入库成功: deviceCode={}, warningCode={}", deviceCode, warningCode);
+		} catch (Exception e) {
+			logger.error("保存告警数据失败", e);
+		}
+	}
 }

+ 7 - 11
zk-api-service/src/main/java/com/zksy/api/domain/AlarmData.java

@@ -19,18 +19,10 @@ public class AlarmData implements Serializable {
     @ApiModelProperty(value = "主键")
     private String id;
 
-    @TableField(value = "device_name")
-    @ApiModelProperty(value = "设备名称")
-    private String deviceName;
-
     @TableField(value = "device_code")
     @ApiModelProperty(value = "设备编码")
     private String deviceCode;
 
-    @TableField(value = "device_type")
-    @ApiModelProperty(value = "设备类型")
-    private String deviceType;
-
     @TableField(value = "warning_type")
     @ApiModelProperty(value = "预警类型")
     private String warningType;
@@ -39,9 +31,13 @@ public class AlarmData implements Serializable {
     @ApiModelProperty(value = "预警编码")
     private String warningCode;
 
-    @TableField(value = "warning_value")
-    @ApiModelProperty(value = "预警阈值")
-    private BigDecimal warningValue;
+    @TableField(value = "min_value")
+    @ApiModelProperty(value = "预警最小值,小于等于该值视为报警")
+    private BigDecimal minValue;
+
+    @TableField(value = "max_value")
+    @ApiModelProperty(value = "预警最大值,大于等于该值视为报警")
+    private BigDecimal maxValue;
 
     @TableField(value = "actual_value")
     @ApiModelProperty(value = "实际值")

+ 11 - 18
zk-api-service/src/main/java/com/zksy/api/domain/WarningThreshold.java

@@ -24,13 +24,6 @@ public class WarningThreshold implements Serializable {
     @ApiModelProperty(value = "主键")
     private String id;
 
-    /**
-     * 设备名称
-     */
-    @TableField(value = "device_name")
-    @ApiModelProperty(value = "设备名称")
-    private String deviceName;
-
     /**
      * 设备编码
      */
@@ -38,13 +31,6 @@ public class WarningThreshold implements Serializable {
     @ApiModelProperty(value = "设备编码")
     private String deviceCode;
 
-    /**
-     * 设备类型
-     */
-    @TableField(value = "device_type")
-    @ApiModelProperty(value = "设备类型")
-    private String deviceType;
-
     /**
      * 预警类型
      */
@@ -60,11 +46,18 @@ public class WarningThreshold implements Serializable {
     private String warningCode;
 
     /**
-     * 预警值
+     * 预警最小值
+     */
+    @TableField(value = "min_value")
+    @ApiModelProperty(value = "预警最小值,小于等于该值视为报警")
+    private Double minValue;
+
+    /**
+     * 预警最大值
      */
-    @TableField(value = "warning_value")
-    @ApiModelProperty(value = "预警值")
-    private Double warningValue;
+    @TableField(value = "max_value")
+    @ApiModelProperty(value = "预警最大,大于等于该值视为报警")
+    private Double maxValue;
 
     /**
      * 备注

+ 14 - 2
zk-api-service/src/main/java/com/zksy/api/service/impl/WarningThresholdServiceImpl.java

@@ -21,14 +21,26 @@ public class WarningThresholdServiceImpl extends ServiceImpl<WarningThresholdMap
     implements WarningThresholdService{
     /**
      * 根据设备编号查询该设备所有预警值
+     * 先尝试精确匹配设备编码,没找到再查询通用阈值(deviceCode = "*")
      */
     @Override
     public WarningThreshold getWarningThresholdByDeviceAndCode(String deviceCode, String warningCodes) {
+        // 1. 先尝试精确匹配设备编码
         LambdaQueryWrapper<WarningThreshold> lambdaQueryWrapper = Wrappers.lambdaQuery(WarningThreshold.class)
                 .eq(WarningThreshold::getDeviceCode, deviceCode)
-                .eq(WarningThreshold::getWarningCode,warningCodes);
+                .eq(WarningThreshold::getWarningCode, warningCodes);
 
-        return baseMapper.selectOne(lambdaQueryWrapper);
+        WarningThreshold result = baseMapper.selectOne(lambdaQueryWrapper);
+
+        // 2. 如果没找到,查询通用阈值(deviceCode = "*")
+        if (result == null) {
+            LambdaQueryWrapper<WarningThreshold> defaultQueryWrapper = Wrappers.lambdaQuery(WarningThreshold.class)
+                    .eq(WarningThreshold::getDeviceCode, "*")
+                    .eq(WarningThreshold::getWarningCode, warningCodes);
+            result = baseMapper.selectOne(defaultQueryWrapper);
+        }
+
+        return result;
     }
 }
 

+ 95 - 38
zk-api-service/src/main/java/com/zksy/api/utils/SmsUtil.java

@@ -8,9 +8,9 @@ import com.aliyun.sdk.service.dysmsapi20170525.models.SendBatchSmsRequest;
 import com.aliyun.sdk.service.dysmsapi20170525.models.SendBatchSmsResponse;
 import com.google.gson.Gson;
 import com.zksy.api.config.AliyunSmsConfig;
-import com.zksy.api.domain.Enum.DeviceCodeEnum;
-import com.zksy.api.domain.Enum.WarningCodeEnum;
+import com.zksy.api.domain.AlarmData;
 import com.zksy.api.domain.WarningThreshold;
+import com.zksy.api.service.AlarmDataService;
 import com.zksy.api.service.WarningThresholdService;
 import darabonba.core.client.ClientOverrideConfiguration;
 import lombok.extern.slf4j.Slf4j;
@@ -19,7 +19,9 @@ import org.springframework.stereotype.Component;
 import rk.netDevice.sdk.p2.NodeData;
 import rk.netDevice.sdk.p2.RealTimeData;
 
+import java.math.BigDecimal;
 import java.time.Duration;
+import java.time.LocalDateTime;
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
@@ -34,15 +36,17 @@ public class SmsUtil {
     private final AsyncClient client;
 
     private final WarningThresholdService service;
+    private final AlarmDataService alarmDataService;
 
     // 报警缓存和冷却时间
 //    private static final Map<String, Long> ALARM_CACHE = new ConcurrentHashMap<>();
 //    private static final long ALARM_COOLDOWN_MS = 5 * 60 * 1000;
 
     @Autowired
-    public SmsUtil(AliyunSmsConfig aliyunSmsConfig, WarningThresholdService service) {
+    public SmsUtil(AliyunSmsConfig aliyunSmsConfig, WarningThresholdService service, AlarmDataService alarmDataService) {
         this.aliyunSmsConfig = aliyunSmsConfig;
-        this.service=service;
+        this.service = service;
+        this.alarmDataService = alarmDataService;
 
         try {
             StaticCredentialProvider provider = StaticCredentialProvider.create(Credential.builder()
@@ -134,7 +138,6 @@ public class SmsUtil {
         }
 
         try {
-
             //TODO 冷处理待定
 //            String cacheKey = realTimeData.getDeviceId() + "_" + nodeId;
 //            Long lastAlarmTime = ALARM_CACHE.get(cacheKey);
@@ -143,48 +146,65 @@ public class SmsUtil {
 //                return false;
 //            }
 
-            // 根据node_id匹配唯一预警类型
-            WarningCodeEnum targetWarningType = getWarningTypeByNodeId(nodeId);
-            if (targetWarningType == null) {
-                log.warn("设备{}节点{}无对应预警类型,跳过检查", realTimeData.getDeviceId(), nodeId);
+            // 根据node_id获取预警编码(自定义写死,不从枚举获取)
+            String warningCode = getWarningCodeByNodeId(nodeId);
+            if (warningCode == null) {
+                log.warn("设备{}节点{}无对应预警编码,跳过检查", realTimeData.getDeviceId(), nodeId);
                 return false;
             }
-            String warningCode = targetWarningType.getCode();
-            String warningMsg = targetWarningType.getName();
 
-            // 直接查询该预警类型的阈值
-            double actualThreshold;
-            try {
-                String deviceCode = DeviceCodeEnum.ENVIRONMENT_DEVICE.getCode();
-                WarningThreshold threshold = service.getWarningThresholdByDeviceAndCode(deviceCode, warningCode);
+            // 设备编号从设备数据获取
+            String deviceCode = String.valueOf(realTimeData.getDeviceId());
 
-                // 优先使用数据库配置,无配置则用枚举默认值
-                actualThreshold = (threshold != null && threshold.getWarningValue() != null)
-                        ? threshold.getWarningValue()
-                        : targetWarningType.getDefaultVal();
+            // 查询预警阈值表
+            WarningThreshold threshold = null;
+            try {
+                threshold = service.getWarningThresholdByDeviceAndCode(deviceCode, warningCode);
             } catch (Exception e) {
-                log.error("查询预警阈值失败,使用默认值", e);
-                actualThreshold = targetWarningType.getDefaultVal();
+                log.error("查询预警阈值失败", e);
             }
 
+            // 获取预警类型,默认使用节点对应的名称
+            String warningType = getWarningTypeNameByNodeId(nodeId);
+            if (threshold != null && threshold.getWarningType() != null) {
+                warningType = threshold.getWarningType();
+            }
+
+            // 获取最小值和最大值
+            Double minValue = threshold != null ? threshold.getMinValue() : null;
+            Double maxValue = threshold != null ? threshold.getMaxValue() : null;
+            String remark = threshold != null ? threshold.getRemark() : null;
+
             // 获取当前节点的指标数值
             double currentValue = getCurrentValueByNodeId(nodeData, nodeId);
 
-            boolean isOverThreshold = currentValue > actualThreshold;
+            // 判断是否触发报警
+            boolean isOverThreshold = false;
+            if (minValue != null && currentValue <= minValue) {
+                isOverThreshold = true;
+            }
+            if (maxValue != null && currentValue >= maxValue) {
+                isOverThreshold = true;
+            }
 
-            log.debug("设备{}节点{} - 预警类型:{},当前值:{},阈值:{},是否超限:{}",
-                    realTimeData.getDeviceId(), nodeId, warningMsg, currentValue, actualThreshold, isOverThreshold);
+            log.debug("设备{}节点{} - 预警类型:{},当前值:{},最小值:{},最大值:{},是否超限:{}",
+                    realTimeData.getDeviceId(), nodeId, warningType, currentValue, minValue, maxValue, isOverThreshold);
 
-            // 超过期限,触发报警
+            // 触发报警
             if (isOverThreshold) {
-                log.warn("设备{}节点{}触发预警:{}(当前值:{} > 阈值:{})",
-                        realTimeData.getDeviceId(), nodeId, warningMsg, currentValue, actualThreshold);
+                log.warn("设备{}节点{}触发预警:{}(当前值:{},最小值:{},最大值:{})",
+                        realTimeData.getDeviceId(), nodeId, warningType, currentValue, minValue, maxValue);
+
+                // 1. 先保存 alarm_data
+                saveAlarmData(deviceCode, warningType, warningCode,
+                        minValue != null ? BigDecimal.valueOf(minValue) : null,
+                        maxValue != null ? BigDecimal.valueOf(maxValue) : null,
+                        BigDecimal.valueOf(currentValue), remark);
 
-                // 构造短信参数
+                // 2. 再构造并发送短信
                 JSONObject params = new JSONObject();
                 params.put("deviceNo", realTimeData.getDeviceId());
-                params.put("alarmType", warningMsg);
-                // 经纬度处理(为执行信息处理)
+                params.put("alarmType", warningType);
                 double lng = nodeData.getLng();
                 double lat = nodeData.getLat();
                 params.put("location", String.format("经纬度:%.6f,%.8f", lng, lat));
@@ -206,19 +226,56 @@ public class SmsUtil {
     }
 
     /**
-     * 根据nodeId获取对应的预警类型
+     * 保存告警数据到 alarm_data 表
+     */
+    private void saveAlarmData(String deviceCode, String warningType, String warningCode,
+                               BigDecimal minValue, BigDecimal maxValue, BigDecimal actualValue, String remark) {
+        try {
+            AlarmData alarmData = new AlarmData();
+            alarmData.setDeviceCode(deviceCode);
+            alarmData.setWarningType(warningType);
+            alarmData.setWarningCode(warningCode);
+            alarmData.setMinValue(minValue);
+            alarmData.setMaxValue(maxValue);
+            alarmData.setActualValue(actualValue);
+            alarmData.setAlarmStatus(0);
+            alarmData.setAlarmTime(LocalDateTime.now());
+            alarmData.setRemark(remark);
+            alarmData.setCreateTime(LocalDateTime.now());
+            alarmDataService.saveAlarmData(alarmData);
+        } catch (Exception e) {
+            log.error("保存告警数据失败", e);
+        }
+    }
+
+    /**
+     * 根据nodeId获取对应的预警编码(自定义写死)
      */
-    private WarningCodeEnum getWarningTypeByNodeId(int nodeId) {
+    private String getWarningCodeByNodeId(int nodeId) {
         switch (nodeId) {
-            case 1: return WarningCodeEnum.SUSPENDED_SOLIDS;
-            case 2: return WarningCodeEnum.COD;
-            case 3: return WarningCodeEnum.AMMONIA_NITROGEN;
-            case 4: return WarningCodeEnum.CONDUCTIVITY;
-            case 5: return WarningCodeEnum.PH;
+            case 1: return "WARN_SUSPENDED_SOLIDS";
+            case 2: return "WARN_COD";
+            case 3: return "WARN_AMMONIA_NITROGEN";
+            case 4: return "WARN_CONDUCTIVITY";
+            case 5: return "WARN_PH";
             default: return null;
         }
     }
 
+    /**
+     * 根据nodeId获取对应的预警类型名称
+     */
+    private String getWarningTypeNameByNodeId(int nodeId) {
+        switch (nodeId) {
+            case 1: return "悬浮物";
+            case 2: return "COD";
+            case 3: return "氨氮";
+            case 4: return "电导率";
+            case 5: return "pH值";
+            default: return "未知预警";
+        }
+    }
+
     /**
      * 根据nodeId获取对应的指标数值
      */