Ver código fonte

Merge remote-tracking branch 'origin/master'

zengy 1 semana atrás
pai
commit
596d5f9a22

+ 33 - 4
pipe-network-service/zksy-system/src/main/resources/mapper/cockpit/CockpitOverviewModulesMapper.xml

@@ -233,7 +233,15 @@
 
     <!-- 按日两个读数(维护者 2026-10-23):
            · daily_count     —— 当天新增(create_time 落在该日),走面板基础集合 audit_status = 1;
-           · unhandled_total —— 截至当天仍未处理的累计条数(alarm_status = 0,0 未处理 / 1 已处理)。
+           · unhandled_total —— **截至当天结束时仍未处置**的累计条数(按「首次被处置的时刻」判定)。
+
+             **口径修正(票 97,2026-10-28)**:旧实现用**当前** alarm_status = 0 过滤历史日,等于
+             「按今天的状态回溯过去」—— 今天处置一条,过去几天的值会一起变(维护者实测:处置后七天从
+             1,2,2,2,2,2,2 整体塌成 1,1,1,1,1,1,1),且历史值系统性偏低(10-22 那天真实积压 2:一条
+             10-16 创建的报警 10-23 才处置,旧实现对 10-22 只记 1)。现在改为:
+             backlog(D) = #{ create_time ≤ D 结束 且 ( 首次处置时刻为空 或 首次处置时刻 > D 结束 ) },
+             首次处置时刻取 MIN(alarm_log.oper_time) WHERE oper_type IN (1,3)(见下方 oper_type 语义);
+             没有 type 1/3 日志的 HANDLED 报警退回 update_time 兜底(略偏高,已记票 97)。
 
          **两条线口径不同,是刻意如此**:
          · 新增按面板基础集合(已核实报警),与上方「今日新增」等读数同口径;
@@ -242,6 +250,13 @@
            这条线会画成一条恒零的直线,"积压还在"的意思就丢了。
          累计必须从**入库最早一条**起算,不能只用窗口内数据 —— 否则窗口之前的积压会漏掉。
          票 81:片区/行业筛选对两条线**都**生效(同一个「范围内」定义),否则新增与积压会互相打架。 -->
+    <!-- 首次处置时刻(票 97,2026-10-28 在真实库上核验过 alarm_log.oper_type 语义):
+         0 = 报警产生(实测其 oper_time 与 alarm_data.create_time 完全相等,不能当处置时刻!);
+         1 = 人工确认/转工单;3 = 自动恢复("报警恢复,自动处理")。
+         所以处置时刻 = MIN(oper_time) WHERE oper_type IN (1, 3);对同一报警取**最早**一条
+         (取最后一条会把"处置后又更新"误当成处置时刻,积压会算得偏低)。
+         实测:184 条报警里 92 条有日志、其中大量是 type 0 的产生记录 —— 若不过滤 oper_type,
+         MIN(oper_time) 恒等于 create_time,整条积压线会被算成 0。 -->
     <select id="selectAlarmDailyCounts" resultType="java.util.LinkedHashMap">
         <include refid="typeTree"/>,
         days AS (
@@ -259,12 +274,26 @@
               AND a.create_time &gt;= #{startInclusive} AND a.create_time &lt; #{endExclusive}
         <include refid="alarmDeviceFilter"/>
             GROUP BY 1
+        ),
+        handled AS (
+            SELECT l.alarm_id AS alarm_id, MIN(l.oper_time) AS handled_at
+            FROM app_user.alarm_log l
+            WHERE l.oper_time IS NOT NULL
+              AND l.oper_type IN (1, 3)
+            GROUP BY l.alarm_id
         )
         SELECT d.day AS day,
                COALESCE(cr.c, 0) AS daily_count,
-               (SELECT COUNT(*) FROM app_user.alarm_data a2
-                 WHERE a2.alarm_status = 0
-                   AND a2.create_time &lt; (d.day_date + interval '1 day')
+               (SELECT COUNT(*)
+                  FROM app_user.alarm_data a2
+                  LEFT JOIN handled h2 ON h2.alarm_id = a2.id
+                 WHERE a2.create_time &lt; (d.day_date + interval '1 day')
+                   AND CASE
+                         WHEN h2.handled_at IS NOT NULL
+                             THEN h2.handled_at &gt;= (d.day_date + interval '1 day')
+                         WHEN a2.alarm_status = 0 THEN TRUE
+                         ELSE COALESCE(a2.update_time, a2.create_time) &gt;= (d.day_date + interval '1 day')
+                       END
                    <if test="district != null or unassigned">
                        AND <choose>
                            <when test="unassigned">