Bladeren bron

Merge commit 'ae06a55ba8a36708d2a5beabc7f96a4cd79096b4' into HEAD

Kazerin 1 maand geleden
bovenliggende
commit
4ec5f103b1

+ 12 - 64
manhole-service/src/main/java/com/zksy/manhole/service/impl/ManholeDataServiceImpl.java

@@ -1,7 +1,6 @@
 package com.zksy.manhole.service.impl;
 
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
-import com.zksy.api.utils.AlarmLevelUtil;
 import com.zksy.manhole.domain.ManholeData;
 import com.zksy.manhole.mapper.ManholeDataMapper;
 import com.zksy.manhole.service.ManholeDataService;
@@ -10,8 +9,6 @@ import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
-import java.math.BigDecimal;
-
 /**
  * 井盖数据Service业务层处理
  * 
@@ -28,12 +25,10 @@ public class ManholeDataServiceImpl extends ServiceImpl<ManholeDataMapper, Manho
 
     /** 倾斜角度告警编码 */
     private static final String WARN_CODE_TILT = "WARN-TILT";
-    /** 设备报警编码 */
-    private static final String WARN_CODE_DEVICE = "WARN-DEVICE-ALARM";
     /** 水浸告警编码 */
     private static final String WARN_CODE_WATER_INFILTRATION = "WARN-WATER-INFILTRATION";
     /** 水位告警编码 */
-    private static final String WARN_CODE_WATER_LEVEL = "WARN-WATER-LEVEL";
+    private static final String WARN_WATER_MANHOLE_LEVEL = "WARN-WATER-MANHOLE-LEVEL";
 
     @Override
     public Integer saveManholeData(ManholeData result) {
@@ -48,36 +43,34 @@ public class ManholeDataServiceImpl extends ServiceImpl<ManholeDataMapper, Manho
 
     /**
      * 检查并保存告警数据
-     * - 倾斜角度:阈值来自采集数据字段 angleAlarmThreshold,根据偏差率计算告警等级
-     * - 设备报警/水浸/水位:状态型告警,告警即为1级
+     * 井盖的报警全部由采集过来的数据字段直接判断,无需查询阈值表:
+     * - alarmStatus:倾斜角度报警状态(0正常,1报警)
+     * - waterInfiltrationAlarmStatus:水浸报警状态(0正常,1报警)
+     * - waterLevelAlarmStatus:水位报警状态(0正常,1报警)
+     * 均为状态型告警,告警即为1级
      */
     private void checkAndSaveAlarm(ManholeData result) {
         String deviceCode = result.getImeiCardNumber();
         boolean hasAlarm = false;
         boolean evaluationCompleted = false;
         try {
-            // 1. 倾斜角度告警:阈值从采集数据字段 angleAlarmThreshold 获取
-            if (checkTiltAlarm(result, deviceCode)) {
-                hasAlarm = true;
-            }
-
-            // 2. 设备报警状态:告警即为1级
+            // 1. 倾斜角度报警状态:直接由采集数据判断
             if ("1".equals(result.getAlarmStatus())) {
-                alarmUtil.saveAlarmWithLevel(deviceCode, "设备报警", WARN_CODE_DEVICE,
-                        null, 1, "井盖设备状态报警");
+                alarmUtil.saveAlarmWithLevel(deviceCode, "倾斜预警", WARN_CODE_TILT,
+                        null, 1, "井盖倾斜报警");
                 hasAlarm = true;
             }
 
-            // 3. 水浸报警状态:告警即为1级
+            // 2. 水浸报警状态:直接由采集数据判断
             if ("1".equals(result.getWaterInfiltrationAlarmStatus())) {
                 alarmUtil.saveAlarmWithLevel(deviceCode, "水浸预警", WARN_CODE_WATER_INFILTRATION,
                         null, 1, "井盖水浸报警");
                 hasAlarm = true;
             }
 
-            // 4. 水位报警状态:告警即为1级
+            // 3. 水位报警状态:直接由采集数据判断
             if ("1".equals(result.getWaterLevelAlarmStatus())) {
-                alarmUtil.saveAlarmWithLevel(deviceCode, "水位预警", WARN_CODE_WATER_LEVEL,
+                alarmUtil.saveAlarmWithLevel(deviceCode, "窨井水位预警", WARN_WATER_MANHOLE_LEVEL,
                         null, 1, "井盖水位报警");
                 hasAlarm = true;
             }
@@ -89,49 +82,4 @@ public class ManholeDataServiceImpl extends ServiceImpl<ManholeDataMapper, Manho
             }
         }
     }
-
-    /**
-     * 倾斜角度告警检查
-     * 阈值直接从采集数据字段 angleAlarmThreshold 获取,不再查询阈值表
-     * 根据实际值和阈值的偏差率计算告警等级
-     * @return 是否触发告警
-     */
-    private boolean checkTiltAlarm(ManholeData result, String deviceCode) {
-        String tiltAngleStr = result.getTiltAngle();
-        String angleThresholdStr = result.getAngleAlarmThreshold();
-
-        if (tiltAngleStr == null || tiltAngleStr.isEmpty()
-                || angleThresholdStr == null || angleThresholdStr.isEmpty()) {
-            return false;
-        }
-
-        try {
-            BigDecimal tiltAngle = new BigDecimal(tiltAngleStr);
-            BigDecimal angleThreshold = new BigDecimal(angleThresholdStr);
-
-            // 倾斜角度超过阈值才告警
-            if (tiltAngle.compareTo(angleThreshold) < 0) {
-                return false;
-            }
-
-            // 使用 AlarmLevelUtil 计算告警等级
-            // minValue=0(正常角度为0),maxValue=angleThreshold(阈值作为上限)
-            BigDecimal minValue = BigDecimal.ZERO;
-            int alarmLevel = AlarmLevelUtil.calculateLevel(tiltAngle, minValue, angleThreshold);
-            BigDecimal deviationRatio = AlarmLevelUtil.calculateDeviationRatio(tiltAngle, minValue, angleThreshold);
-
-            String remark = String.format("井盖倾斜报警,当前角度:%s°,阈值:%s°",
-                    tiltAngle, angleThreshold);
-
-            alarmUtil.saveAlarm(deviceCode, "倾斜预警", WARN_CODE_TILT,
-                    minValue, angleThreshold, tiltAngle, remark);
-
-            log.info("倾斜告警入库: deviceCode={}, tiltAngle={}°, threshold={}°, level={}级, deviationRatio={}%",
-                    deviceCode, tiltAngle, angleThreshold, alarmLevel, deviationRatio);
-            return true;
-        } catch (NumberFormatException e) {
-            log.error("倾斜角度或阈值解析失败: tiltAngle={}, threshold={}", tiltAngleStr, angleThresholdStr, e);
-            return false;
-        }
-    }
 }

+ 14 - 2
pipe-network-service/zksy-admin/src/main/java/com/zksy/web/controller/warning/EarlyWarningController.java

@@ -160,8 +160,20 @@ List<String> alarmIds = alarmIdsJson != null && !alarmIdsJson.isEmpty()
     @ApiOperation("发布预警")
     @Log(title = "发布预警", businessType = BusinessType.UPDATE)
     @PreAuthorize("@ss.hasPermi('warning:warning:publish')")
-    public AjaxResult publishWarning(@PathVariable String warningId) {
-        boolean result = earlyWarningService.publishWarning(warningId);
+    public AjaxResult publishWarning(@PathVariable String warningId,
+                                     @RequestParam(required = false) String handler) {
+        // 允许草稿在编辑时先保存处置人,发布接口仍必须确认最终处置人存在。
+        if (handler == null || handler.trim().isEmpty()) {
+            EarlyWarning warning = earlyWarningService.getById(warningId);
+            if (warning == null) {
+                return AjaxResult.error("预警信息不存在");
+            }
+            handler = warning.getHandler();
+        }
+        if (handler == null || handler.trim().isEmpty()) {
+            return AjaxResult.error("发布预警前必须选择处置人");
+        }
+        boolean result = earlyWarningService.publishWarning(warningId, handler.trim());
         return result ? AjaxResult.success("发布成功") : AjaxResult.error("发布失败");
     }
 

+ 9 - 1
pipe-network-service/zksy-system/src/main/java/com/zksy/base/warning/service/EarlyWarningService.java

@@ -34,7 +34,15 @@ public interface EarlyWarningService extends IService<EarlyWarning> {
 
     boolean deleteBatchWarning(List<String> warningIds);
 
-    boolean publishWarning(String warningId);
+    /**
+     * 发布预警。发布时必须传入明确的处置人;handler 为空时仅兼容历史调用,
+     * 由实现根据草稿中已保存的处置人继续校验,绝不自动回退为当前登录用户。
+     */
+    boolean publishWarning(String warningId, String handler);
+
+    default boolean publishWarning(String warningId) {
+        return publishWarning(warningId, null);
+    }
 
     boolean confirmWarning(String warningId, String assignedUser, String confirmRemark);
 

+ 11 - 3
pipe-network-service/zksy-system/src/main/java/com/zksy/base/warning/service/impl/EarlyWarningServiceImpl.java

@@ -273,19 +273,27 @@ public class EarlyWarningServiceImpl extends ServiceImpl<EarlyWarningMapper, Ear
     @Override
     @Transactional(rollbackFor = Exception.class)
     public boolean publishWarning(String warningId) {
+        return publishWarning(warningId, null);
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean publishWarning(String warningId, String requestedHandler) {
         EarlyWarning warning = getById(warningId);
         if (warning == null) return false;
 
+        String assignee = isBlank(requestedHandler) ? warning.getHandler() : requestedHandler.trim();
+        // 发布不能再自动指派当前登录用户,处置人必须由发布人明确选择或提前保存。
+        if (isBlank(assignee)) return false;
+
         warning.setStatus("PENDING");
         warning.setPublishTime(LocalDateTime.now());
         warning.setUpdateTime(LocalDateTime.now());
+        warning.setHandler(assignee);
 
         boolean result = updateById(warning);
 
         if (result) {
-            String assignee = isBlank(warning.getHandler()) ? currentUser() : warning.getHandler();
-            warning.setHandler(assignee);
-            updateById(warning);
             addDisposalRecord(warningId, "RELEASE", null, null, assignee, "系统发布预警信息");
             createTodo(warningId, assignee, "待办预警", "TODO");
         }

+ 30 - 0
zk-api-service/src/main/java/com/zksy/api/service/impl/EquipmentStatusApiServiceImpl.java

@@ -3,7 +3,9 @@ package com.zksy.api.service.impl;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.zksy.api.domain.EquipmentBase;
 import com.zksy.api.domain.EquipmentStatus;
+import com.zksy.api.domain.AlarmData;
 import com.zksy.api.event.DeviceStatusChangePublisher;
+import com.zksy.api.mapper.AlarmDataMapper;
 import com.zksy.api.mapper.EquipmentBaseApiMapper;
 import com.zksy.api.mapper.EquipmentStatusApiMapper;
 import com.zksy.api.service.EquipmentStatusApiService;
@@ -32,6 +34,9 @@ public class EquipmentStatusApiServiceImpl implements EquipmentStatusApiService
     @Autowired
     private DeviceStatusChangePublisher deviceStatusChangePublisher;
 
+    @Autowired
+    private AlarmDataMapper alarmDataMapper;
+
     @Override
     @Transactional
     public boolean updateAlarmStatus(String deviceCode, Integer alarmStatus) {
@@ -134,6 +139,10 @@ public class EquipmentStatusApiServiceImpl implements EquipmentStatusApiService
                         existingStatus.getCurrentStatus(), existingStatus.getAlarmStatus(),
                         existingStatus.getOnlineStatus(), "zk-api:updateOnlineStatus");
             }
+            // 设备由在线转为离线时,新增离线报警记录
+            if (previousOnlineStatus != null && previousOnlineStatus == 1 && onlineStatus == 0) {
+                saveOfflineAlarm(deviceCode);
+            }
         } else {
             EquipmentStatus newStatus = new EquipmentStatus();
             newStatus.setEquipmentId(equipmentId);
@@ -155,4 +164,25 @@ public class EquipmentStatusApiServiceImpl implements EquipmentStatusApiService
 
         return true;
     }
+
+    /**
+     * 新增设备离线报警记录
+     */
+    private void saveOfflineAlarm(String deviceCode) {
+        try {
+            AlarmData alarmData = new AlarmData();
+            alarmData.setDeviceCode(deviceCode);
+            alarmData.setWarningType("设备离线");
+            alarmData.setWarningCode("OFFLINE");
+            alarmData.setAlarmLevel(4);
+            alarmData.setAlarmStatus(0);
+            alarmData.setAlarmTime(LocalDateTime.now());
+            alarmData.setRemark("设备超过设定时间未上报数据,判定为离线");
+            alarmData.setCreateTime(LocalDateTime.now());
+            alarmDataMapper.insert(alarmData);
+            log.info("设备离线报警数据入库成功: deviceCode={}, alarmId={}", deviceCode, alarmData.getId());
+        } catch (Exception e) {
+            log.error("保存设备离线报警数据失败: deviceCode={}", deviceCode, e);
+        }
+    }
 }