Просмотр исходного кода

fix(warning): 优化预警统计数据查询逻辑

- 为预警表添加别名避免字段冲突
- 增加时间戳过滤条件确保数据实时性
- 添加预警类型白名单过滤支持
- 优化处置时效计算逻辑增加处置类型限制
- 修复空字符串特殊字段的分组统计问题
- 标准化所有查询的时间范围和状态过滤条件
- 重构重复的警告类型枚举定义统一管理
- 优化多处SQL查询的性能和准确性
林仔 1 неделя назад
Родитель
Сommit
d7a299b029

+ 71 - 44
pipe-network-service/zksy-system/src/main/resources/mapper/warning/EarlyWarningMapper.xml

@@ -132,40 +132,51 @@
     <!-- 统计今日预警核心指标 -->
     <select id="selectTodayWarningStats" resultType="java.util.Map">
         SELECT
-        COUNT(CASE WHEN status != 'DRAFT' THEN 1 END) AS today_total,
-        COUNT(CASE WHEN status = 'HANDLED' THEN 1 END) AS handled_today,
-        COUNT(CASE WHEN status = 'CLOSED' THEN 1 END) AS closed_today
-        FROM app_user.early_warning
-        WHERE publish_time &gt;= CURRENT_DATE
-        AND publish_time &lt; CAST(CURRENT_DATE AS TIMESTAMP) + CAST('1 day' AS INTERVAL)
+        COUNT(CASE WHEN w.status != 'DRAFT' THEN 1 END) AS today_total,
+        COUNT(CASE WHEN w.status = 'HANDLED' THEN 1 END) AS handled_today,
+        COUNT(CASE WHEN w.status = 'CLOSED' THEN 1 END) AS closed_today
+        FROM app_user.early_warning w
+        WHERE w.publish_time &gt;= CURRENT_DATE
+        AND w.publish_time &lt; CAST(CURRENT_DATE AS TIMESTAMP) + CAST('1 day' AS INTERVAL)
+        AND w.publish_time &lt;= CURRENT_TIMESTAMP
+        <include refid="SupportedDashboardWarningTypes"/>
     </select>
 
     <!-- 查询今日预警列表 -->
     <select id="selectTodayWarningList" resultMap="BaseResultMap">
         SELECT <include refid="Base_Column_List"/>
-        FROM app_user.early_warning
-        WHERE publish_time &gt;= CURRENT_DATE
-        AND publish_time &lt; CAST(CURRENT_DATE AS TIMESTAMP) + CAST('1 day' AS INTERVAL)
+        FROM app_user.early_warning w
+        WHERE w.publish_time &gt;= CURRENT_DATE
+        AND w.publish_time &lt; CAST(CURRENT_DATE AS TIMESTAMP) + CAST('1 day' AS INTERVAL)
+        AND w.publish_time &lt;= CURRENT_TIMESTAMP
+        <include refid="SupportedDashboardWarningTypes"/>
         <choose>
             <when test="status != null and status != ''">
-                AND status = #{status}
+                AND w.status = #{status}
             </when>
             <otherwise>
-                AND status != 'DRAFT'
+                AND w.status != 'DRAFT'
             </otherwise>
         </choose>
-        ORDER BY publish_time DESC
+        ORDER BY w.publish_time DESC
     </select>
 
     <!-- 按日统计预警发展趋势 -->
     <select id="selectWarningTrendByDay" resultType="java.util.Map">
         SELECT
         TO_CHAR(publish_time, 'YYYY-MM-DD') AS stat_date,
-        COALESCE(warning_special, '其他') AS warning_special,
+        COALESCE(NULLIF(warning_special, ''), '其他') AS warning_special,
         COUNT(*) AS warning_count
         FROM app_user.early_warning
         WHERE status != 'DRAFT'
-        AND warning_type IN ('WATER_PIPE', 'SEWER_PIPE', 'GAS_PIPE', 'MANHOLE', '1', '2', '3', '4', '供水', '排水', '燃气', '窨井')
+        AND warning_type IN (
+            'WATER_PIPE', 'SEWER_PIPE', 'GAS_PIPE', 'MANHOLE',
+            '1', '2', '3', '4',
+            '供水', '供水管网', '供水管网预警',
+            '排水', '排水管网', '排水管网预警',
+            '燃气', '燃气管网', '燃气管网预警',
+            '窨井', '窨井预警'
+        )
         <if test="startTime != null">
             AND publish_time &gt;= #{startTime}
         </if>
@@ -173,9 +184,9 @@
             AND publish_time &lt; #{endTime}
         </if>
         <if test="warningSpecial != null and warningSpecial != ''">
-            AND warning_special = #{warningSpecial}
+            AND COALESCE(NULLIF(warning_special, ''), '其他') = #{warningSpecial}
         </if>
-        GROUP BY stat_date, warning_special
+        GROUP BY TO_CHAR(publish_time, 'YYYY-MM-DD'), COALESCE(NULLIF(warning_special, ''), '其他')
         ORDER BY stat_date ASC, warning_special ASC
     </select>
 
@@ -183,11 +194,18 @@
     <select id="selectWarningTrendByMonth" resultType="java.util.Map">
         SELECT
         TO_CHAR(publish_time, 'YYYY-MM') AS stat_month,
-        COALESCE(warning_special, '其他') AS warning_special,
+        COALESCE(NULLIF(warning_special, ''), '其他') AS warning_special,
         COUNT(*) AS warning_count
         FROM app_user.early_warning
         WHERE status != 'DRAFT'
-        AND warning_type IN ('WATER_PIPE', 'SEWER_PIPE', 'GAS_PIPE', 'MANHOLE', '1', '2', '3', '4', '供水', '排水', '燃气', '窨井')
+        AND warning_type IN (
+            'WATER_PIPE', 'SEWER_PIPE', 'GAS_PIPE', 'MANHOLE',
+            '1', '2', '3', '4',
+            '供水', '供水管网', '供水管网预警',
+            '排水', '排水管网', '排水管网预警',
+            '燃气', '燃气管网', '燃气管网预警',
+            '窨井', '窨井预警'
+        )
         <if test="startTime != null">
             AND publish_time &gt;= #{startTime}
         </if>
@@ -195,9 +213,9 @@
             AND publish_time &lt; #{endTime}
         </if>
         <if test="warningSpecial != null and warningSpecial != ''">
-            AND warning_special = #{warningSpecial}
+            AND COALESCE(NULLIF(warning_special, ''), '其他') = #{warningSpecial}
         </if>
-        GROUP BY stat_month, warning_special
+        GROUP BY TO_CHAR(publish_time, 'YYYY-MM'), COALESCE(NULLIF(warning_special, ''), '其他')
         ORDER BY stat_month ASC, warning_special ASC
     </select>
 
@@ -234,6 +252,7 @@
         FROM app_user.warning_disposal d
         INNER JOIN app_user.early_warning w ON w.warning_id = d.warning_id
         WHERE w.status != 'DRAFT'
+        <include refid="SupportedDashboardWarningTypes"/>
         <if test="startTime != null">
             AND w.publish_time &gt;= #{startTime}
         </if>
@@ -258,8 +277,11 @@
         SELECT
         EXTRACT(EPOCH FROM (CAST(MAX(d.create_time) AS TIMESTAMPTZ) - CAST(w.publish_time AS TIMESTAMPTZ))) / 3600 AS dispose_hours
         FROM app_user.early_warning w
-        INNER JOIN app_user.warning_disposal d ON w.warning_id = d.warning_id
-        WHERE w.status IN ('HANDLED', 'CLOSED')
+        INNER JOIN app_user.warning_disposal d
+            ON w.warning_id = d.warning_id
+           AND d.disposal_type IN ('HANDLE', 'RESOLVE', 'CLEAR', 'CLOSE', 'MISREPORT')
+        WHERE w.status IN ('HANDLED', 'CLOSED', 'RESOLVED')
+        <include refid="SupportedDashboardWarningTypes"/>
         <if test="startTime != null">
             AND w.publish_time &gt;= #{startTime}
         </if>
@@ -288,8 +310,11 @@
         SELECT
         EXTRACT(EPOCH FROM (CAST(MAX(d.create_time) AS TIMESTAMPTZ) - CAST(w.publish_time AS TIMESTAMPTZ))) / 3600 AS dispose_hours
         FROM app_user.early_warning w
-        INNER JOIN app_user.warning_disposal d ON w.warning_id = d.warning_id
-        WHERE w.status IN ('HANDLED', 'CLOSED')
+        INNER JOIN app_user.warning_disposal d
+            ON w.warning_id = d.warning_id
+           AND d.disposal_type IN ('HANDLE', 'RESOLVE', 'CLEAR', 'CLOSE', 'MISREPORT')
+        WHERE w.status IN ('HANDLED', 'CLOSED', 'RESOLVED')
+        <include refid="SupportedDashboardWarningTypes"/>
         <if test="startTime != null">
             AND w.publish_time &gt;= #{startTime}
         </if>
@@ -315,16 +340,19 @@
     <!-- 处置时效分析-按预警专项统计平均时效 -->
     <select id="selectDisposeEfficiencyBySpecial" resultType="java.util.Map">
         SELECT
-        COALESCE(warning_special, '其他') AS warning_special,
+        COALESCE(NULLIF(warning_special, ''), '其他') AS warning_special,
         COUNT(*) AS warning_count,
         ROUND(AVG(dispose_hours), 2) AS avg_dispose_hours
         FROM (
         SELECT
-        w.warning_special,
+        COALESCE(NULLIF(w.warning_special, ''), '其他') AS warning_special,
         EXTRACT(EPOCH FROM (CAST(MAX(d.create_time) AS TIMESTAMPTZ) - CAST(w.publish_time AS TIMESTAMPTZ))) / 3600 AS dispose_hours
         FROM app_user.early_warning w
-        INNER JOIN app_user.warning_disposal d ON w.warning_id = d.warning_id
-        WHERE w.status IN ('HANDLED', 'CLOSED')
+        INNER JOIN app_user.warning_disposal d
+            ON w.warning_id = d.warning_id
+           AND d.disposal_type IN ('HANDLE', 'RESOLVE', 'CLEAR', 'CLOSE', 'MISREPORT')
+        WHERE w.status IN ('HANDLED', 'CLOSED', 'RESOLVED')
+        <include refid="SupportedDashboardWarningTypes"/>
         <if test="startTime != null">
             AND w.publish_time &gt;= #{startTime}
         </if>
@@ -332,9 +360,9 @@
             AND w.publish_time &lt; #{endTime}
         </if>
         <if test="warningSpecial != null and warningSpecial != ''">
-            AND w.warning_special = #{warningSpecial}
+            AND COALESCE(NULLIF(w.warning_special, ''), '其他') = #{warningSpecial}
         </if>
-        GROUP BY w.warning_id, w.warning_special, w.publish_time
+        GROUP BY w.warning_id, COALESCE(NULLIF(w.warning_special, ''), '其他'), w.publish_time
         HAVING MAX(d.create_time) &gt;= w.publish_time
         ) AS temp
         GROUP BY warning_special
@@ -353,8 +381,11 @@
         ROUND(EXTRACT(EPOCH FROM (CAST(MAX(d.create_time) AS TIMESTAMPTZ) - CAST(w.publish_time AS TIMESTAMPTZ))) / 3600, 2) AS dispose_hours,
         w.status
         FROM app_user.early_warning w
-        INNER JOIN app_user.warning_disposal d ON w.warning_id = d.warning_id
-        WHERE w.status IN ('HANDLED', 'CLOSED')
+        INNER JOIN app_user.warning_disposal d
+            ON w.warning_id = d.warning_id
+           AND d.disposal_type IN ('HANDLE', 'RESOLVE', 'CLEAR', 'CLOSE', 'MISREPORT')
+        WHERE w.status IN ('HANDLED', 'CLOSED', 'RESOLVED')
+        <include refid="SupportedDashboardWarningTypes"/>
         <if test="startTime != null">
             AND w.publish_time &gt;= #{startTime}
         </if>
@@ -388,15 +419,14 @@
         FROM app_user.early_warning w
         INNER JOIN app_user.warning_disposal d ON w.warning_id = d.warning_id
         WHERE w.status != 'DRAFT'
+        <include refid="SupportedDashboardWarningTypes"/>
         <if test="startTime != null">
             AND w.publish_time &gt;= #{startTime}
         </if>
         <if test="endTime != null">
             AND w.publish_time &lt; #{endTime}
         </if>
-        <if test="warningType != null and warningType != ''">
-            AND w.warning_type = #{warningType}
-        </if>
+        <include refid="DashboardWarningTypeFilter"/>
         <if test="warningSpecial != null and warningSpecial != ''">
             AND w.warning_special = #{warningSpecial}
         </if>
@@ -424,15 +454,14 @@
         FROM app_user.early_warning w
         INNER JOIN app_user.warning_disposal d ON w.warning_id = d.warning_id
         WHERE w.status != 'DRAFT'
+        <include refid="SupportedDashboardWarningTypes"/>
         <if test="startTime != null">
             AND w.publish_time &gt;= #{startTime}
         </if>
         <if test="endTime != null">
             AND w.publish_time &lt; #{endTime}
         </if>
-        <if test="warningType != null and warningType != ''">
-            AND w.warning_type = #{warningType}
-        </if>
+        <include refid="DashboardWarningTypeFilter"/>
         <if test="warningSpecial != null and warningSpecial != ''">
             AND w.warning_special = #{warningSpecial}
         </if>
@@ -465,15 +494,14 @@
         FROM app_user.early_warning w
         INNER JOIN app_user.warning_disposal d ON w.warning_id = d.warning_id
         WHERE w.status != 'DRAFT'
+        <include refid="SupportedDashboardWarningTypes"/>
         <if test="startTime != null">
             AND w.publish_time &gt;= #{startTime}
         </if>
         <if test="endTime != null">
             AND w.publish_time &lt; #{endTime}
         </if>
-        <if test="warningType != null and warningType != ''">
-            AND w.warning_type = #{warningType}
-        </if>
+        <include refid="DashboardWarningTypeFilter"/>
         <if test="warningSpecial != null and warningSpecial != ''">
             AND w.warning_special = #{warningSpecial}
         </if>
@@ -502,15 +530,14 @@
         FROM app_user.early_warning w
         INNER JOIN app_user.warning_disposal d ON w.warning_id = d.warning_id
         WHERE w.status != 'DRAFT'
+        <include refid="SupportedDashboardWarningTypes"/>
         <if test="startTime != null">
             AND w.publish_time &gt;= #{startTime}
         </if>
         <if test="endTime != null">
             AND w.publish_time &lt; #{endTime}
         </if>
-        <if test="warningType != null and warningType != ''">
-            AND w.warning_type = #{warningType}
-        </if>
+        <include refid="DashboardWarningTypeFilter"/>
         <if test="warningSpecial != null and warningSpecial != ''">
             AND w.warning_special = #{warningSpecial}
         </if>