Przeglądaj źródła

排水报警修复

LAPTOP-JI2IUVG1\26646 4 tygodni temu
rodzic
commit
260bca5e6b

+ 13 - 0
pipe-network-service/zksy-system/src/main/java/com/zksy/base/alarm/mapper/AlarmDataMapper.java

@@ -1,10 +1,23 @@
 package com.zksy.base.alarm.mapper;
 package com.zksy.base.alarm.mapper;
 
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.zksy.base.alarm.domain.AlarmData;
 import com.zksy.base.alarm.domain.AlarmData;
 import org.apache.ibatis.annotations.Mapper;
 import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
 
 
 @Mapper
 @Mapper
 public interface AlarmDataMapper extends BaseMapper<AlarmData> {
 public interface AlarmDataMapper extends BaseMapper<AlarmData> {
 
 
+    IPage<AlarmData> selectLatestPage(Page<AlarmData> page,
+                                      @Param("deviceCodes") List<String> deviceCodes,
+                                      @Param("deviceCode") String deviceCode,
+                                      @Param("warningType") String warningType,
+                                      @Param("warningCode") String warningCode,
+                                      @Param("alarmStatus") Integer alarmStatus,
+                                      @Param("startTime") java.time.LocalDateTime startTime,
+                                      @Param("endTime") java.time.LocalDateTime endTime);
 }
 }

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

@@ -40,42 +40,18 @@ public class AlarmDataServiceImpl extends ServiceImpl<AlarmDataMapper, AlarmData
                                         Integer alarmStatus, String equipmentType,
                                         Integer alarmStatus, String equipmentType,
                                         String startTime, String endTime) {
                                         String startTime, String endTime) {
         Page<AlarmData> page = new Page<>(pageNum, pageSize);
         Page<AlarmData> page = new Page<>(pageNum, pageSize);
-        LambdaQueryWrapper<AlarmData> queryWrapper = new LambdaQueryWrapper<>();
 
 
         // 当传入 equipmentType='drainage' 时,通过设备类型树关联查询排水类设备编码列表。
         // 当传入 equipmentType='drainage' 时,通过设备类型树关联查询排水类设备编码列表。
         // 不能再写死历史类型 ID:当前排水根类型为 2,子类型由 equipment_type.parent_id 维护。
         // 不能再写死历史类型 ID:当前排水根类型为 2,子类型由 equipment_type.parent_id 维护。
-        if ("drainage".equals(equipmentType)) {
-            List<String> drainageTypeIds = findDrainageTypeIds();
-            if (drainageTypeIds.isEmpty()) {
-                return new Page<>(pageNum, pageSize);
-            }
-            LambdaQueryWrapper<EquipmentBase> eqQuery = new LambdaQueryWrapper<>();
-            eqQuery.in(EquipmentBase::getEquipmentTypeId, drainageTypeIds)
-                   .select(EquipmentBase::getEquipmentCode);
-            List<EquipmentBase> devices = equipmentBaseMapper.selectList(eqQuery);
-            List<String> deviceCodes = devices.stream()
-                    .map(EquipmentBase::getEquipmentCode)
-                    .filter(code -> code != null && !code.isEmpty())
-                    .collect(Collectors.toList());
-            if (deviceCodes.isEmpty()) {
-                // 没有排水类设备,直接返回空结果
+        List<String> deviceCodes = deviceCodesForQuery(equipmentType);
+        if ("drainage".equals(equipmentType) && (deviceCodes == null || deviceCodes.isEmpty())) {
                 return new Page<>(pageNum, pageSize);
                 return new Page<>(pageNum, pageSize);
-            }
-            queryWrapper.in(AlarmData::getDeviceCode, deviceCodes);
         }
         }
 
 
-        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);
-        if (startTime != null && !startTime.isEmpty()) {
-            queryWrapper.ge(AlarmData::getAlarmTime, parseDateTime(startTime));
-        }
-        if (endTime != null && !endTime.isEmpty()) {
-            queryWrapper.le(AlarmData::getAlarmTime, parseDateTime(endTime));
-        }
-        queryWrapper.orderByDesc(AlarmData::getAlarmTime);
-        Page<AlarmData> result = this.page(page, queryWrapper);
+        // 数据库先按设备编码保留最新一条,再执行分页,避免内存去重造成分页漏数据。
+        Page<AlarmData> result = (Page<AlarmData>) baseMapper.selectLatestPage(
+                page, deviceCodes, deviceCode, warningType,
+                warningCode, alarmStatus, parseStartTime(startTime), parseEndTime(endTime));
 
 
         // 填充 deviceName/longitude/latitude:通过 device_code 从 equipment_base 表关联查询
         // 填充 deviceName/longitude/latitude:通过 device_code 从 equipment_base 表关联查询
         fillDeviceInfo(result.getRecords());
         fillDeviceInfo(result.getRecords());
@@ -85,6 +61,24 @@ public class AlarmDataServiceImpl extends ServiceImpl<AlarmDataMapper, AlarmData
         return result;
         return result;
     }
     }
 
 
+    private List<String> deviceCodesForQuery(String equipmentType) {
+        if (!"drainage".equals(equipmentType)) {
+            return null;
+        }
+        List<String> drainageTypeIds = findDrainageTypeIds();
+        if (drainageTypeIds.isEmpty()) {
+            return List.of();
+        }
+        LambdaQueryWrapper<EquipmentBase> eqQuery = new LambdaQueryWrapper<>();
+        eqQuery.in(EquipmentBase::getEquipmentTypeId, drainageTypeIds)
+                .select(EquipmentBase::getEquipmentCode);
+        return equipmentBaseMapper.selectList(eqQuery).stream()
+                .map(EquipmentBase::getEquipmentCode)
+                .filter(code -> code != null && !code.isEmpty())
+                .distinct()
+                .collect(Collectors.toList());
+    }
+
     /**
     /**
      * 读取排水设备根类型及其全部后代类型,避免设备类型调整后报警列表被错误过滤为空。
      * 读取排水设备根类型及其全部后代类型,避免设备类型调整后报警列表被错误过滤为空。
      */
      */
@@ -160,6 +154,25 @@ public class AlarmDataServiceImpl extends ServiceImpl<AlarmDataMapper, AlarmData
         return LocalDateTime.parse(value, java.time.format.DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
         return LocalDateTime.parse(value, java.time.format.DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
     }
     }
 
 
+    private LocalDateTime parseStartTime(String value) {
+        return parseDateTime(value, " 00:00:00");
+    }
+
+    private LocalDateTime parseEndTime(String value) {
+        return parseDateTime(value, " 23:59:59");
+    }
+
+    private LocalDateTime parseDateTime(String value, String dateSuffix) {
+        if (value == null || value.trim().isEmpty()) {
+            return null;
+        }
+        String normalized = value.trim();
+        if (normalized.length() == 10) {
+            normalized += dateSuffix;
+        }
+        return parseDateTime(normalized);
+    }
+
     /**
     /**
      * 根据 deviceCode 从 equipment_base 表批量填充 deviceName、longitude、latitude
      * 根据 deviceCode 从 equipment_base 表批量填充 deviceName、longitude、latitude
      */
      */

+ 49 - 0
pipe-network-service/zksy-system/src/main/resources/mapper/base/AlarmDataMapper.xml

@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.zksy.base.alarm.mapper.AlarmDataMapper">
+
+    <select id="selectLatestPage" resultType="com.zksy.base.alarm.domain.AlarmData">
+        SELECT a.*
+        FROM alarm_data a
+        <where>
+            <if test="deviceCodes != null and deviceCodes.size() > 0">
+                AND a.device_code IN
+                <foreach collection="deviceCodes" item="code" open="(" separator="," close=")">
+                    #{code}
+                </foreach>
+            </if>
+            <if test="deviceCode != null and deviceCode != ''">
+                AND a.device_code LIKE CONCAT('%', #{deviceCode}, '%')
+            </if>
+            <if test="warningType != null and warningType != ''">
+                AND a.warning_type LIKE CONCAT('%', #{warningType}, '%')
+            </if>
+            <if test="warningCode != null and warningCode != ''">
+                AND a.warning_code LIKE CONCAT('%', #{warningCode}, '%')
+            </if>
+            <if test="alarmStatus != null">
+                AND a.alarm_status = #{alarmStatus}
+            </if>
+            <if test="startTime != null">
+                AND a.alarm_time &gt;= #{startTime}
+            </if>
+            <if test="endTime != null">
+                AND a.alarm_time &lt;= #{endTime}
+            </if>
+            AND NOT EXISTS (
+                SELECT 1
+                FROM alarm_data newer
+                WHERE newer.device_code = a.device_code
+                  AND (
+                      COALESCE(newer.alarm_time, newer.create_time) &gt; COALESCE(a.alarm_time, a.create_time)
+                      OR (
+                          COALESCE(newer.alarm_time, newer.create_time) = COALESCE(a.alarm_time, a.create_time)
+                          AND newer.id &gt; a.id
+                      )
+                  )
+            )
+        </where>
+        ORDER BY a.alarm_time DESC, a.create_time DESC, a.id DESC
+    </select>
+
+</mapper>