Przeglądaj źródła

feat(utils): 添加告警等级计算工具类

- 实现了基于偏差率的告警等级计算功能
- 提供实际值与正常范围比较的偏差率计算方法
- 支持将偏差率映射到1-4级告警等级(1级最高)
- 添加了等级名称获取功能
- 包含完整的参数校验和边界情况处理
- 实现了偏差率百分比的精确计算和范围限制
林仔 4 dni temu
rodzic
commit
b390fe7092

+ 36 - 4
environment-service/src/main/java/com/zksy/environment/utils/AlarmUtil.java

@@ -1,8 +1,11 @@
 package com.zksy.environment.utils;
 
+import com.alibaba.fastjson.JSONObject;
 import com.zksy.api.domain.AlarmData;
 import com.zksy.api.service.AlarmDataService;
 import com.zksy.api.utils.AlarmLevelUtil;
+import com.zksy.api.utils.SmsUtil;
+import com.zksy.utils.DevicePhoneFetchUtil;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -10,6 +13,8 @@ import org.springframework.stereotype.Component;
 
 import java.math.BigDecimal;
 import java.time.LocalDateTime;
+import java.util.List;
+import java.util.Map;
 
 @Component
 public class AlarmUtil {
@@ -18,6 +23,10 @@ public class AlarmUtil {
 
     @Autowired
     private AlarmDataService alarmDataService;
+    @Autowired
+    private SmsUtil smsUtil;
+    @Autowired
+    private DevicePhoneFetchUtil devicePhoneFetchUtil;
 
     public void checkAndSaveAlarm(String deviceCode,
                                     String warningType, String warningCode, Double minValue, Double maxValue,
@@ -42,9 +51,10 @@ public class AlarmUtil {
         }
     }
 
-    public void saveAlarm(String deviceCode,
+    public int saveAlarm(String deviceCode,
                            String warningType, String warningCode, BigDecimal minValue, BigDecimal maxValue,
                            BigDecimal actualValue, String remark) {
+        int alarmLevel = 4;
         try {
             AlarmData alarmData = new AlarmData();
             alarmData.setDeviceCode(deviceCode);
@@ -54,8 +64,7 @@ public class AlarmUtil {
             alarmData.setMaxValue(maxValue);
             alarmData.setActualValue(actualValue);
 
-            // 计算告警等级和偏差率
-            int alarmLevel = AlarmLevelUtil.calculateLevel(actualValue, minValue, maxValue);
+            alarmLevel = AlarmLevelUtil.calculateLevel(actualValue, minValue, maxValue);
             BigDecimal deviationRatio = AlarmLevelUtil.calculateDeviationRatio(actualValue, minValue, maxValue);
             alarmData.setAlarmLevel(alarmLevel);
             alarmData.setDeviationRatio(deviationRatio);
@@ -67,13 +76,36 @@ public class AlarmUtil {
 
             alarmDataService.saveAlarmData(alarmData);
 
-            // 1级告警特殊处理(TODO:调用短信接口或发送特殊通知)
             if (alarmLevel == 1) {
                 log.warn("【1级紧急告警】deviceCode={}, warningCode={}, deviationRatio={}%",
                         deviceCode, warningCode, deviationRatio);
+                sendAlarmSms(deviceCode, warningType, actualValue, minValue, maxValue);
             }
+            log.info("告警数据入库成功: deviceCode={}, warningCode={}, level={}级", deviceCode, warningCode, alarmLevel);
         } catch (Exception e) {
             e.printStackTrace();
         }
+        return alarmLevel;
+    }
+
+    private void sendAlarmSms(String deviceCode, String warningType, BigDecimal actualValue,
+                              BigDecimal minValue, BigDecimal maxValue) {
+        try {
+            List<String> phoneList = devicePhoneFetchUtil.getPhoneListByDeviceId(deviceCode);
+            if (phoneList == null || phoneList.isEmpty()) {
+                log.warn("报警短信发送失败:未找到设备{}的联系人手机号", deviceCode);
+                return;
+            }
+            JSONObject params = new JSONObject();
+            params.put("deviceNo", deviceCode);
+            params.put("alarmType", warningType);
+            params.put("location", "当前值:" + actualValue + ",正常范围:" + minValue + "~" + maxValue);
+
+            Map<String, Boolean> result = smsUtil.sendBatchSms(phoneList, params.toJSONString());
+            long successCount = result.values().stream().filter(Boolean::booleanValue).count();
+            log.info("1级告警短信发送完成,成功{}条,失败{}条", successCount, phoneList.size() - successCount);
+        } catch (Exception e) {
+            log.error("发送报警短信异常: {}", e.getMessage());
+        }
     }
 }

+ 35 - 4
manhole-service/src/main/java/com/zksy/manhole/utils/AlarmUtil.java

@@ -1,7 +1,10 @@
 package com.zksy.manhole.utils;
 
+import com.alibaba.fastjson.JSONObject;
 import com.zksy.api.utils.AlarmLevelUtil;
+import com.zksy.api.utils.SmsUtil;
 import com.zksy.common.utils.AjaxResult;
+import com.zksy.utils.DevicePhoneFetchUtil;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -15,6 +18,7 @@ import org.springframework.web.client.RestTemplate;
 import java.math.BigDecimal;
 import java.time.LocalDateTime;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 
 @Component
@@ -24,6 +28,10 @@ public class AlarmUtil {
 
     @Autowired
     private RestTemplate restTemplate;
+    @Autowired
+    private SmsUtil smsUtil;
+    @Autowired
+    private DevicePhoneFetchUtil devicePhoneFetchUtil;
 
     @Value("${alarm.api.url:http://zk-api-service/alarmData/save}")
     private String alarmApiUrl;
@@ -51,9 +59,10 @@ public class AlarmUtil {
         }
     }
 
-    public void saveAlarm(String deviceCode,
+    public int saveAlarm(String deviceCode,
                            String warningType, String warningCode, BigDecimal minValue, BigDecimal maxValue,
                            BigDecimal actualValue, String remark) {
+        int alarmLevel = 4;
         try {
             Map<String, Object> alarmData = new HashMap<>();
             alarmData.put("deviceCode", deviceCode);
@@ -63,8 +72,7 @@ public class AlarmUtil {
             alarmData.put("maxValue", maxValue);
             alarmData.put("actualValue", actualValue);
 
-            // 计算告警等级和偏差率
-            int alarmLevel = AlarmLevelUtil.calculateLevel(actualValue, minValue, maxValue);
+            alarmLevel = AlarmLevelUtil.calculateLevel(actualValue, minValue, maxValue);
             BigDecimal deviationRatio = AlarmLevelUtil.calculateDeviationRatio(actualValue, minValue, maxValue);
             alarmData.put("alarmLevel", alarmLevel);
             alarmData.put("deviationRatio", deviationRatio);
@@ -79,13 +87,36 @@ public class AlarmUtil {
 
             restTemplate.postForObject(alarmApiUrl, request, AjaxResult.class);
 
-            // 1级告警特殊处理(TODO:调用短信接口或发送特殊通知)
             if (alarmLevel == 1) {
                 log.warn("【1级紧急告警】deviceCode={}, warningCode={}, deviationRatio={}%",
                         deviceCode, warningCode, deviationRatio);
+                sendAlarmSms(deviceCode, warningType, actualValue, minValue, maxValue);
             }
+            log.info("告警数据入库成功: deviceCode={}, warningCode={}, level={}级", deviceCode, warningCode, alarmLevel);
         } catch (Exception e) {
             e.printStackTrace();
         }
+        return alarmLevel;
+    }
+
+    private void sendAlarmSms(String deviceCode, String warningType, BigDecimal actualValue,
+                              BigDecimal minValue, BigDecimal maxValue) {
+        try {
+            List<String> phoneList = devicePhoneFetchUtil.getPhoneListByDeviceId(deviceCode);
+            if (phoneList == null || phoneList.isEmpty()) {
+                log.warn("报警短信发送失败:未找到设备{}的联系人手机号", deviceCode);
+                return;
+            }
+            JSONObject params = new JSONObject();
+            params.put("deviceNo", deviceCode);
+            params.put("alarmType", warningType);
+            params.put("location", "当前值:" + actualValue + ",正常范围:" + minValue + "~" + maxValue);
+
+            Map<String, Boolean> result = smsUtil.sendBatchSms(phoneList, params.toJSONString());
+            long successCount = result.values().stream().filter(Boolean::booleanValue).count();
+            log.info("1级告警短信发送完成,成功{}条,失败{}条", successCount, phoneList.size() - successCount);
+        } catch (Exception e) {
+            log.error("发送报警短信异常: {}", e.getMessage());
+        }
     }
 }