|
|
@@ -36,23 +36,116 @@
|
|
|
update_time, remark
|
|
|
</sql>
|
|
|
|
|
|
+ <!-- The city-life project only contains water supply, drainage, gas and manhole warnings. -->
|
|
|
+ <sql id="SupportedDashboardWarningTypes">
|
|
|
+ AND w.warning_type IN (
|
|
|
+ 'WATER_PIPE', 'SEWER_PIPE', 'GAS_PIPE', 'MANHOLE',
|
|
|
+ '1', '2', '3', '4',
|
|
|
+ '供水', '供水管网', '供水管网预警',
|
|
|
+ '排水', '排水管网', '排水管网预警',
|
|
|
+ '燃气', '燃气管网', '燃气管网预警',
|
|
|
+ '窨井', '窨井预警'
|
|
|
+ )
|
|
|
+ </sql>
|
|
|
+
|
|
|
+ <sql id="DashboardWarningTypeFilter">
|
|
|
+ <if test="warningType != null and warningType != ''">
|
|
|
+ <choose>
|
|
|
+ <when test="warningType == 'WATER_PIPE' or warningType == '1'.toString()">
|
|
|
+ AND w.warning_type IN ('WATER_PIPE', '1', '供水', '供水管网', '供水管网预警')
|
|
|
+ </when>
|
|
|
+ <when test="warningType == 'SEWER_PIPE' or warningType == '2'.toString()">
|
|
|
+ AND w.warning_type IN ('SEWER_PIPE', '2', '排水', '排水管网', '排水管网预警')
|
|
|
+ </when>
|
|
|
+ <when test="warningType == 'GAS_PIPE' or warningType == '3'.toString()">
|
|
|
+ AND w.warning_type IN ('GAS_PIPE', '3', '燃气', '燃气管网', '燃气管网预警')
|
|
|
+ </when>
|
|
|
+ <when test="warningType == 'MANHOLE' or warningType == '4'.toString()">
|
|
|
+ AND w.warning_type IN ('MANHOLE', '4', '窨井', '窨井预警')
|
|
|
+ </when>
|
|
|
+ <otherwise>
|
|
|
+ AND w.warning_type = #{warningType}
|
|
|
+ </otherwise>
|
|
|
+ </choose>
|
|
|
+ </if>
|
|
|
+ </sql>
|
|
|
+
|
|
|
+ <sql id="DashboardWarningLevelFilter">
|
|
|
+ <if test="warningLevel != null and warningLevel != ''">
|
|
|
+ <choose>
|
|
|
+ <when test="warningLevel == '1'.toString()">
|
|
|
+ AND w.warning_level IN ('1', 'BLUE', 'IV')
|
|
|
+ </when>
|
|
|
+ <when test="warningLevel == '2'.toString()">
|
|
|
+ AND w.warning_level IN ('2', 'YELLOW', 'III')
|
|
|
+ </when>
|
|
|
+ <when test="warningLevel == '3'.toString()">
|
|
|
+ AND w.warning_level IN ('3', 'ORANGE', 'II')
|
|
|
+ </when>
|
|
|
+ <when test="warningLevel == '4'.toString()">
|
|
|
+ AND w.warning_level IN ('4', 'RED', 'I')
|
|
|
+ </when>
|
|
|
+ <otherwise>
|
|
|
+ AND w.warning_level = #{warningLevel}
|
|
|
+ </otherwise>
|
|
|
+ </choose>
|
|
|
+ </if>
|
|
|
+ </sql>
|
|
|
+
|
|
|
+ <sql id="DashboardWarningColumns">
|
|
|
+ w.warning_id,
|
|
|
+ w.warning_no,
|
|
|
+ w.warning_name,
|
|
|
+ w.warning_type,
|
|
|
+ CASE
|
|
|
+ WHEN w.warning_type IN ('WATER_PIPE', '1', '供水', '供水管网', '供水管网预警') THEN '供水管网'
|
|
|
+ WHEN w.warning_type IN ('SEWER_PIPE', '2', '排水', '排水管网', '排水管网预警') THEN '排水管网'
|
|
|
+ WHEN w.warning_type IN ('GAS_PIPE', '3', '燃气', '燃气管网', '燃气管网预警') THEN '燃气管网'
|
|
|
+ WHEN w.warning_type IN ('MANHOLE', '4', '窨井', '窨井预警') THEN '窨井'
|
|
|
+ END AS warning_type_name,
|
|
|
+ w.warning_level,
|
|
|
+ w.warning_special,
|
|
|
+ w.location,
|
|
|
+ w.longitude,
|
|
|
+ w.latitude,
|
|
|
+ w.ownership_unit,
|
|
|
+ w.publisher,
|
|
|
+ w.publish_time,
|
|
|
+ w.handler,
|
|
|
+ w.status,
|
|
|
+ w.warning_content,
|
|
|
+ w.create_time,
|
|
|
+ w.update_time,
|
|
|
+ w.device_code,
|
|
|
+ w.device_name
|
|
|
+ </sql>
|
|
|
+
|
|
|
+ <sql id="DashboardResolvedTimeJoin">
|
|
|
+ LEFT JOIN (
|
|
|
+ SELECT warning_id, MAX(create_time) AS resolved_time
|
|
|
+ FROM app_user.warning_disposal
|
|
|
+ WHERE disposal_type IN ('RESOLVE', 'CLOSE', 'CLEAR')
|
|
|
+ GROUP BY warning_id
|
|
|
+ ) resolved_record ON resolved_record.warning_id = w.warning_id
|
|
|
+ </sql>
|
|
|
+
|
|
|
<!-- 统计今日预警核心指标 -->
|
|
|
<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 early_warning
|
|
|
+ FROM app_user.early_warning
|
|
|
WHERE publish_time >= CURRENT_DATE
|
|
|
- AND publish_time < CURRENT_DATE + INTERVAL '1 day'
|
|
|
+ AND publish_time < CAST(CURRENT_DATE AS TIMESTAMP) + CAST('1 day' AS INTERVAL)
|
|
|
</select>
|
|
|
|
|
|
<!-- 查询今日预警列表 -->
|
|
|
<select id="selectTodayWarningList" resultMap="BaseResultMap">
|
|
|
SELECT <include refid="Base_Column_List"/>
|
|
|
- FROM early_warning
|
|
|
+ FROM app_user.early_warning
|
|
|
WHERE publish_time >= CURRENT_DATE
|
|
|
- AND publish_time < CURRENT_DATE + INTERVAL '1 day'
|
|
|
+ AND publish_time < CAST(CURRENT_DATE AS TIMESTAMP) + CAST('1 day' AS INTERVAL)
|
|
|
<choose>
|
|
|
<when test="status != null and status != ''">
|
|
|
AND status = #{status}
|
|
|
@@ -70,8 +163,9 @@
|
|
|
TO_CHAR(publish_time, 'YYYY-MM-DD') AS stat_date,
|
|
|
COALESCE(warning_special, '其他') AS warning_special,
|
|
|
COUNT(*) AS warning_count
|
|
|
- FROM early_warning
|
|
|
+ FROM app_user.early_warning
|
|
|
WHERE status != 'DRAFT'
|
|
|
+ AND warning_type IN ('WATER_PIPE', 'SEWER_PIPE', 'GAS_PIPE', 'MANHOLE', '1', '2', '3', '4', '供水', '排水', '燃气', '窨井')
|
|
|
<if test="startTime != null">
|
|
|
AND publish_time >= #{startTime}
|
|
|
</if>
|
|
|
@@ -91,8 +185,9 @@
|
|
|
TO_CHAR(publish_time, 'YYYY-MM') AS stat_month,
|
|
|
COALESCE(warning_special, '其他') AS warning_special,
|
|
|
COUNT(*) AS warning_count
|
|
|
- FROM early_warning
|
|
|
+ FROM app_user.early_warning
|
|
|
WHERE status != 'DRAFT'
|
|
|
+ AND warning_type IN ('WATER_PIPE', 'SEWER_PIPE', 'GAS_PIPE', 'MANHOLE', '1', '2', '3', '4', '供水', '排水', '燃气', '窨井')
|
|
|
<if test="startTime != null">
|
|
|
AND publish_time >= #{startTime}
|
|
|
</if>
|
|
|
@@ -111,8 +206,16 @@
|
|
|
SELECT
|
|
|
status,
|
|
|
COUNT(warning_id) AS status_count
|
|
|
- FROM early_warning
|
|
|
+ FROM app_user.early_warning
|
|
|
WHERE status != 'DRAFT'
|
|
|
+ AND warning_type IN (
|
|
|
+ 'WATER_PIPE', 'SEWER_PIPE', 'GAS_PIPE', 'MANHOLE',
|
|
|
+ '1', '2', '3', '4',
|
|
|
+ '供水', '供水管网', '供水管网预警',
|
|
|
+ '排水', '排水管网', '排水管网预警',
|
|
|
+ '燃气', '燃气管网', '燃气管网预警',
|
|
|
+ '窨井', '窨井预警'
|
|
|
+ )
|
|
|
<if test="startTime != null">
|
|
|
AND publish_time >= #{startTime}
|
|
|
</if>
|
|
|
@@ -126,6 +229,24 @@
|
|
|
ORDER BY status_count DESC
|
|
|
</select>
|
|
|
|
|
|
+ <select id="selectDisposalGroupByType" resultType="java.util.Map">
|
|
|
+ SELECT d.disposal_type, COUNT(*) AS disposal_count
|
|
|
+ FROM app_user.warning_disposal d
|
|
|
+ INNER JOIN app_user.early_warning w ON w.warning_id = d.warning_id
|
|
|
+ WHERE w.status != 'DRAFT'
|
|
|
+ <if test="startTime != null">
|
|
|
+ AND w.publish_time >= #{startTime}
|
|
|
+ </if>
|
|
|
+ <if test="endTime != null">
|
|
|
+ AND w.publish_time < #{endTime}
|
|
|
+ </if>
|
|
|
+ <if test="warningSpecial != null and warningSpecial != ''">
|
|
|
+ AND w.warning_special = #{warningSpecial}
|
|
|
+ </if>
|
|
|
+ GROUP BY d.disposal_type
|
|
|
+ ORDER BY disposal_count DESC
|
|
|
+ </select>
|
|
|
+
|
|
|
<!-- 处置时效分析-概览指标统计 -->
|
|
|
<select id="selectDisposeEfficiencyOverview" resultType="java.util.Map">
|
|
|
SELECT
|
|
|
@@ -135,9 +256,9 @@
|
|
|
COUNT(*) AS total_count
|
|
|
FROM (
|
|
|
SELECT
|
|
|
- EXTRACT(EPOCH FROM (MAX(d.create_time) - w.publish_time)) / 3600 AS dispose_hours
|
|
|
- FROM early_warning w
|
|
|
- LEFT JOIN warning_disposal d ON w.warning_id = d.warning_id
|
|
|
+ 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')
|
|
|
<if test="startTime != null">
|
|
|
AND w.publish_time >= #{startTime}
|
|
|
@@ -148,8 +269,8 @@
|
|
|
<if test="warningSpecial != null and warningSpecial != ''">
|
|
|
AND w.warning_special = #{warningSpecial}
|
|
|
</if>
|
|
|
- GROUP BY w.warning_id
|
|
|
- HAVING dispose_hours IS NOT NULL
|
|
|
+ GROUP BY w.warning_id, w.publish_time
|
|
|
+ HAVING MAX(d.create_time) >= w.publish_time
|
|
|
) AS temp
|
|
|
</select>
|
|
|
|
|
|
@@ -165,9 +286,9 @@
|
|
|
COUNT(*) AS warning_count
|
|
|
FROM (
|
|
|
SELECT
|
|
|
- EXTRACT(EPOCH FROM (MAX(d.create_time) - w.publish_time)) / 3600 AS dispose_hours
|
|
|
- FROM early_warning w
|
|
|
- LEFT JOIN warning_disposal d ON w.warning_id = d.warning_id
|
|
|
+ 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')
|
|
|
<if test="startTime != null">
|
|
|
AND w.publish_time >= #{startTime}
|
|
|
@@ -178,8 +299,8 @@
|
|
|
<if test="warningSpecial != null and warningSpecial != ''">
|
|
|
AND w.warning_special = #{warningSpecial}
|
|
|
</if>
|
|
|
- GROUP BY w.warning_id
|
|
|
- HAVING dispose_hours IS NOT NULL
|
|
|
+ GROUP BY w.warning_id, w.publish_time
|
|
|
+ HAVING MAX(d.create_time) >= w.publish_time
|
|
|
) AS temp
|
|
|
GROUP BY time_range
|
|
|
ORDER BY
|
|
|
@@ -200,9 +321,9 @@
|
|
|
FROM (
|
|
|
SELECT
|
|
|
w.warning_special,
|
|
|
- EXTRACT(EPOCH FROM (MAX(d.create_time) - w.publish_time)) / 3600 AS dispose_hours
|
|
|
- FROM early_warning w
|
|
|
- LEFT JOIN warning_disposal d ON w.warning_id = d.warning_id
|
|
|
+ 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')
|
|
|
<if test="startTime != null">
|
|
|
AND w.publish_time >= #{startTime}
|
|
|
@@ -210,8 +331,11 @@
|
|
|
<if test="endTime != null">
|
|
|
AND w.publish_time < #{endTime}
|
|
|
</if>
|
|
|
- GROUP BY w.warning_id
|
|
|
- HAVING dispose_hours IS NOT NULL
|
|
|
+ <if test="warningSpecial != null and warningSpecial != ''">
|
|
|
+ AND w.warning_special = #{warningSpecial}
|
|
|
+ </if>
|
|
|
+ GROUP BY w.warning_id, w.warning_special, w.publish_time
|
|
|
+ HAVING MAX(d.create_time) >= w.publish_time
|
|
|
) AS temp
|
|
|
GROUP BY warning_special
|
|
|
ORDER BY avg_dispose_hours DESC
|
|
|
@@ -226,10 +350,10 @@
|
|
|
COALESCE(w.warning_special, '其他') AS warning_special,
|
|
|
w.publish_time,
|
|
|
MAX(d.create_time) AS dispose_time,
|
|
|
- ROUND(EXTRACT(EPOCH FROM (MAX(d.create_time) - w.publish_time)) / 3600, 2) AS dispose_hours,
|
|
|
+ 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 early_warning w
|
|
|
- LEFT JOIN warning_disposal d ON w.warning_id = d.warning_id
|
|
|
+ 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')
|
|
|
<if test="startTime != null">
|
|
|
AND w.publish_time >= #{startTime}
|
|
|
@@ -240,8 +364,8 @@
|
|
|
<if test="warningSpecial != null and warningSpecial != ''">
|
|
|
AND w.warning_special = #{warningSpecial}
|
|
|
</if>
|
|
|
- GROUP BY w.warning_id
|
|
|
- HAVING dispose_hours IS NOT NULL
|
|
|
+ GROUP BY w.warning_id, w.warning_no, w.warning_name, w.warning_special, w.publish_time, w.status
|
|
|
+ HAVING MAX(d.create_time) >= w.publish_time
|
|
|
ORDER BY dispose_hours
|
|
|
<if test="sortType != null and sortType == 'desc'">
|
|
|
DESC
|
|
|
@@ -260,9 +384,9 @@
|
|
|
COUNT(*) AS total_count
|
|
|
FROM (
|
|
|
SELECT
|
|
|
- EXTRACT(EPOCH FROM (MIN(d.create_time) - w.publish_time)) / 3600 AS receive_hours
|
|
|
- FROM early_warning w
|
|
|
- INNER JOIN warning_disposal d ON w.warning_id = d.warning_id
|
|
|
+ EXTRACT(EPOCH FROM (CAST(MIN(d.create_time) AS TIMESTAMPTZ) - CAST(w.publish_time AS TIMESTAMPTZ))) / 3600 AS receive_hours
|
|
|
+ FROM app_user.early_warning w
|
|
|
+ INNER JOIN app_user.warning_disposal d ON w.warning_id = d.warning_id
|
|
|
WHERE w.status != 'DRAFT'
|
|
|
<if test="startTime != null">
|
|
|
AND w.publish_time >= #{startTime}
|
|
|
@@ -279,8 +403,8 @@
|
|
|
<if test="status != null and status != ''">
|
|
|
AND w.status = #{status}
|
|
|
</if>
|
|
|
- GROUP BY w.warning_id
|
|
|
- HAVING receive_hours IS NOT NULL
|
|
|
+ GROUP BY w.warning_id, w.publish_time
|
|
|
+ HAVING MIN(d.create_time) >= w.publish_time
|
|
|
) AS temp
|
|
|
</select>
|
|
|
|
|
|
@@ -296,9 +420,9 @@
|
|
|
COUNT(*) AS warning_count
|
|
|
FROM (
|
|
|
SELECT
|
|
|
- EXTRACT(EPOCH FROM (MIN(d.create_time) - w.publish_time)) / 3600 AS receive_hours
|
|
|
- FROM early_warning w
|
|
|
- INNER JOIN warning_disposal d ON w.warning_id = d.warning_id
|
|
|
+ EXTRACT(EPOCH FROM (CAST(MIN(d.create_time) AS TIMESTAMPTZ) - CAST(w.publish_time AS TIMESTAMPTZ))) / 3600 AS receive_hours
|
|
|
+ FROM app_user.early_warning w
|
|
|
+ INNER JOIN app_user.warning_disposal d ON w.warning_id = d.warning_id
|
|
|
WHERE w.status != 'DRAFT'
|
|
|
<if test="startTime != null">
|
|
|
AND w.publish_time >= #{startTime}
|
|
|
@@ -315,8 +439,8 @@
|
|
|
<if test="status != null and status != ''">
|
|
|
AND w.status = #{status}
|
|
|
</if>
|
|
|
- GROUP BY w.warning_id
|
|
|
- HAVING receive_hours IS NOT NULL
|
|
|
+ GROUP BY w.warning_id, w.publish_time
|
|
|
+ HAVING MIN(d.create_time) >= w.publish_time
|
|
|
) AS temp
|
|
|
GROUP BY time_range
|
|
|
ORDER BY
|
|
|
@@ -337,9 +461,9 @@
|
|
|
FROM (
|
|
|
SELECT
|
|
|
w.warning_type,
|
|
|
- EXTRACT(EPOCH FROM (MIN(d.create_time) - w.publish_time)) / 3600 AS receive_hours
|
|
|
- FROM early_warning w
|
|
|
- INNER JOIN warning_disposal d ON w.warning_id = d.warning_id
|
|
|
+ EXTRACT(EPOCH FROM (CAST(MIN(d.create_time) AS TIMESTAMPTZ) - CAST(w.publish_time AS TIMESTAMPTZ))) / 3600 AS receive_hours
|
|
|
+ FROM app_user.early_warning w
|
|
|
+ INNER JOIN app_user.warning_disposal d ON w.warning_id = d.warning_id
|
|
|
WHERE w.status != 'DRAFT'
|
|
|
<if test="startTime != null">
|
|
|
AND w.publish_time >= #{startTime}
|
|
|
@@ -347,8 +471,17 @@
|
|
|
<if test="endTime != null">
|
|
|
AND w.publish_time < #{endTime}
|
|
|
</if>
|
|
|
- GROUP BY w.warning_id
|
|
|
- HAVING receive_hours IS NOT NULL
|
|
|
+ <if test="warningType != null and warningType != ''">
|
|
|
+ AND w.warning_type = #{warningType}
|
|
|
+ </if>
|
|
|
+ <if test="warningSpecial != null and warningSpecial != ''">
|
|
|
+ AND w.warning_special = #{warningSpecial}
|
|
|
+ </if>
|
|
|
+ <if test="status != null and status != ''">
|
|
|
+ AND w.status = #{status}
|
|
|
+ </if>
|
|
|
+ GROUP BY w.warning_id, w.warning_type, w.publish_time
|
|
|
+ HAVING MIN(d.create_time) >= w.publish_time
|
|
|
) AS temp
|
|
|
GROUP BY warning_type
|
|
|
ORDER BY avg_receive_hours DESC
|
|
|
@@ -364,10 +497,10 @@
|
|
|
COALESCE(w.warning_special, '其他') AS warning_special,
|
|
|
w.publish_time,
|
|
|
MIN(d.create_time) AS receive_time,
|
|
|
- ROUND(EXTRACT(EPOCH FROM (MIN(d.create_time) - w.publish_time)) / 3600, 2) AS receive_hours,
|
|
|
+ ROUND(EXTRACT(EPOCH FROM (CAST(MIN(d.create_time) AS TIMESTAMPTZ) - CAST(w.publish_time AS TIMESTAMPTZ))) / 3600, 2) AS receive_hours,
|
|
|
w.status
|
|
|
- FROM early_warning w
|
|
|
- INNER JOIN warning_disposal d ON w.warning_id = d.warning_id
|
|
|
+ FROM app_user.early_warning w
|
|
|
+ INNER JOIN app_user.warning_disposal d ON w.warning_id = d.warning_id
|
|
|
WHERE w.status != 'DRAFT'
|
|
|
<if test="startTime != null">
|
|
|
AND w.publish_time >= #{startTime}
|
|
|
@@ -384,8 +517,9 @@
|
|
|
<if test="status != null and status != ''">
|
|
|
AND w.status = #{status}
|
|
|
</if>
|
|
|
- GROUP BY w.warning_id
|
|
|
- HAVING receive_hours IS NOT NULL
|
|
|
+ GROUP BY w.warning_id, w.warning_no, w.warning_name, w.warning_type,
|
|
|
+ w.warning_special, w.publish_time, w.status
|
|
|
+ HAVING MIN(d.create_time) >= w.publish_time
|
|
|
ORDER BY receive_hours
|
|
|
<if test="sortType != null and sortType == 'desc'">
|
|
|
DESC
|
|
|
@@ -397,6 +531,291 @@
|
|
|
|
|
|
<!-- ————————————————————————————————————————————————————————————— -->
|
|
|
|
|
|
+ <!-- Warning overview: headline numbers for current active and resolved-today warnings. -->
|
|
|
+ <select id="selectDashboardTodaySummary" resultType="java.util.Map">
|
|
|
+ SELECT
|
|
|
+ COUNT(CASE
|
|
|
+ WHEN w.publish_time >= CURRENT_DATE
|
|
|
+ AND w.publish_time < CAST(CURRENT_DATE AS TIMESTAMP) + CAST('1 day' AS INTERVAL)
|
|
|
+ AND w.publish_time <= CURRENT_TIMESTAMP
|
|
|
+ AND w.status != 'DRAFT'
|
|
|
+ THEN 1 END) AS today_total,
|
|
|
+ COUNT(CASE
|
|
|
+ WHEN w.publish_time <= CURRENT_TIMESTAMP
|
|
|
+ AND w.status NOT IN ('DRAFT', 'CLOSED', 'RESOLVED')
|
|
|
+ THEN 1 END) AS unresolved_count,
|
|
|
+ COUNT(CASE
|
|
|
+ WHEN w.status IN ('CLOSED', 'RESOLVED')
|
|
|
+ AND COALESCE(resolved_record.resolved_time, w.update_time, w.publish_time) >= CURRENT_DATE
|
|
|
+ AND COALESCE(resolved_record.resolved_time, w.update_time, w.publish_time)
|
|
|
+ < CAST(CURRENT_DATE AS TIMESTAMP) + CAST('1 day' AS INTERVAL)
|
|
|
+ AND COALESCE(resolved_record.resolved_time, w.update_time, w.publish_time) <= CURRENT_TIMESTAMP
|
|
|
+ THEN 1 END) AS resolved_count
|
|
|
+ FROM app_user.early_warning w
|
|
|
+ <include refid="DashboardResolvedTimeJoin"/>
|
|
|
+ WHERE 1 = 1
|
|
|
+ <include refid="SupportedDashboardWarningTypes"/>
|
|
|
+ </select>
|
|
|
+
|
|
|
+ <!-- Small detail lists returned with the today overview cards. -->
|
|
|
+ <select id="selectDashboardTodayPreview" resultType="java.util.Map">
|
|
|
+ SELECT
|
|
|
+ <include refid="DashboardWarningColumns"/>,
|
|
|
+ COALESCE(resolved_record.resolved_time, w.update_time, w.publish_time) AS resolved_time,
|
|
|
+ ROUND(
|
|
|
+ EXTRACT(EPOCH FROM (
|
|
|
+ CAST(CURRENT_TIMESTAMP AS TIMESTAMPTZ) - CAST(w.publish_time AS TIMESTAMPTZ)
|
|
|
+ )) / 3600,
|
|
|
+ 2
|
|
|
+ ) AS waiting_hours
|
|
|
+ FROM app_user.early_warning w
|
|
|
+ <include refid="DashboardResolvedTimeJoin"/>
|
|
|
+ WHERE 1 = 1
|
|
|
+ <include refid="SupportedDashboardWarningTypes"/>
|
|
|
+ <choose>
|
|
|
+ <when test="category == 'resolved'">
|
|
|
+ AND w.status IN ('CLOSED', 'RESOLVED')
|
|
|
+ AND COALESCE(resolved_record.resolved_time, w.update_time, w.publish_time) >= CURRENT_DATE
|
|
|
+ AND COALESCE(resolved_record.resolved_time, w.update_time, w.publish_time)
|
|
|
+ < CAST(CURRENT_DATE AS TIMESTAMP) + CAST('1 day' AS INTERVAL)
|
|
|
+ AND COALESCE(resolved_record.resolved_time, w.update_time, w.publish_time) <= CURRENT_TIMESTAMP
|
|
|
+ ORDER BY resolved_time DESC, w.warning_id DESC
|
|
|
+ </when>
|
|
|
+ <otherwise>
|
|
|
+ AND w.publish_time <= CURRENT_TIMESTAMP
|
|
|
+ AND w.status NOT IN ('DRAFT', 'CLOSED', 'RESOLVED')
|
|
|
+ ORDER BY
|
|
|
+ CASE w.warning_level
|
|
|
+ WHEN '4' THEN 1 WHEN 'RED' THEN 1
|
|
|
+ WHEN '3' THEN 2 WHEN 'ORANGE' THEN 2
|
|
|
+ WHEN '2' THEN 3 WHEN 'YELLOW' THEN 3
|
|
|
+ WHEN '1' THEN 4 WHEN 'BLUE' THEN 4
|
|
|
+ ELSE 5
|
|
|
+ END,
|
|
|
+ w.publish_time ASC,
|
|
|
+ w.warning_id ASC
|
|
|
+ </otherwise>
|
|
|
+ </choose>
|
|
|
+ LIMIT #{limit}
|
|
|
+ </select>
|
|
|
+
|
|
|
+ <!-- Paged detail list for the two today overview categories. -->
|
|
|
+ <select id="selectDashboardTodayPage" resultType="java.util.Map">
|
|
|
+ SELECT
|
|
|
+ <include refid="DashboardWarningColumns"/>,
|
|
|
+ COALESCE(resolved_record.resolved_time, w.update_time, w.publish_time) AS resolved_time,
|
|
|
+ ROUND(
|
|
|
+ EXTRACT(EPOCH FROM (
|
|
|
+ CAST(CURRENT_TIMESTAMP AS TIMESTAMPTZ) - CAST(w.publish_time AS TIMESTAMPTZ)
|
|
|
+ )) / 3600,
|
|
|
+ 2
|
|
|
+ ) AS waiting_hours
|
|
|
+ FROM app_user.early_warning w
|
|
|
+ <include refid="DashboardResolvedTimeJoin"/>
|
|
|
+ <where>
|
|
|
+ <include refid="SupportedDashboardWarningTypes"/>
|
|
|
+ <choose>
|
|
|
+ <when test="category == 'resolved'">
|
|
|
+ AND w.status IN ('CLOSED', 'RESOLVED')
|
|
|
+ AND COALESCE(resolved_record.resolved_time, w.update_time, w.publish_time) >= CURRENT_DATE
|
|
|
+ AND COALESCE(resolved_record.resolved_time, w.update_time, w.publish_time)
|
|
|
+ < CAST(CURRENT_DATE AS TIMESTAMP) + CAST('1 day' AS INTERVAL)
|
|
|
+ AND COALESCE(resolved_record.resolved_time, w.update_time, w.publish_time) <= CURRENT_TIMESTAMP
|
|
|
+ </when>
|
|
|
+ <when test="category == 'all'">
|
|
|
+ AND w.publish_time >= CURRENT_DATE
|
|
|
+ AND w.publish_time < CAST(CURRENT_DATE AS TIMESTAMP) + CAST('1 day' AS INTERVAL)
|
|
|
+ AND w.publish_time <= CURRENT_TIMESTAMP
|
|
|
+ AND w.status != 'DRAFT'
|
|
|
+ </when>
|
|
|
+ <otherwise>
|
|
|
+ AND w.publish_time <= CURRENT_TIMESTAMP
|
|
|
+ AND w.status NOT IN ('DRAFT', 'CLOSED', 'RESOLVED')
|
|
|
+ </otherwise>
|
|
|
+ </choose>
|
|
|
+ <include refid="DashboardWarningTypeFilter"/>
|
|
|
+ <include refid="DashboardWarningLevelFilter"/>
|
|
|
+ <if test="keyword != null and keyword != ''">
|
|
|
+ AND (
|
|
|
+ w.warning_no LIKE CONCAT('%', #{keyword}, '%')
|
|
|
+ OR w.warning_name LIKE CONCAT('%', #{keyword}, '%')
|
|
|
+ OR w.warning_special LIKE CONCAT('%', #{keyword}, '%')
|
|
|
+ OR w.location LIKE CONCAT('%', #{keyword}, '%')
|
|
|
+ OR w.ownership_unit LIKE CONCAT('%', #{keyword}, '%')
|
|
|
+ )
|
|
|
+ </if>
|
|
|
+ </where>
|
|
|
+ <choose>
|
|
|
+ <when test="category == 'resolved'">
|
|
|
+ ORDER BY resolved_time DESC, w.warning_id DESC
|
|
|
+ </when>
|
|
|
+ <when test="category == 'all'">
|
|
|
+ ORDER BY w.publish_time DESC, w.warning_id DESC
|
|
|
+ </when>
|
|
|
+ <otherwise>
|
|
|
+ ORDER BY
|
|
|
+ CASE w.warning_level
|
|
|
+ WHEN '4' THEN 1 WHEN 'RED' THEN 1
|
|
|
+ WHEN '3' THEN 2 WHEN 'ORANGE' THEN 2
|
|
|
+ WHEN '2' THEN 3 WHEN 'YELLOW' THEN 3
|
|
|
+ WHEN '1' THEN 4 WHEN 'BLUE' THEN 4
|
|
|
+ ELSE 5
|
|
|
+ END,
|
|
|
+ w.publish_time ASC,
|
|
|
+ w.warning_id ASC
|
|
|
+ </otherwise>
|
|
|
+ </choose>
|
|
|
+ </select>
|
|
|
+
|
|
|
+ <!-- Historical warning summary. Drafts and unsupported facility types are excluded. -->
|
|
|
+ <select id="selectDashboardHistorySummary" resultType="java.util.Map">
|
|
|
+ SELECT
|
|
|
+ COUNT(*) AS total_count,
|
|
|
+ COUNT(CASE WHEN w.status IN ('CLOSED', 'RESOLVED') THEN 1 END) AS resolved_count,
|
|
|
+ COUNT(CASE WHEN w.status NOT IN ('CLOSED', 'RESOLVED') THEN 1 END) AS active_count
|
|
|
+ FROM app_user.early_warning w
|
|
|
+ WHERE w.status != 'DRAFT'
|
|
|
+ AND w.publish_time <= CURRENT_TIMESTAMP
|
|
|
+ <include refid="SupportedDashboardWarningTypes"/>
|
|
|
+ </select>
|
|
|
+
|
|
|
+ <select id="selectDashboardHistorySpecialStats" resultType="java.util.Map">
|
|
|
+ WITH special_stats AS (
|
|
|
+ SELECT
|
|
|
+ COALESCE(NULLIF(w.warning_special, ''), '未分类') AS special_name,
|
|
|
+ COUNT(*) AS warning_count
|
|
|
+ FROM app_user.early_warning w
|
|
|
+ WHERE w.status != 'DRAFT'
|
|
|
+ AND w.publish_time <= CURRENT_TIMESTAMP
|
|
|
+ <include refid="SupportedDashboardWarningTypes"/>
|
|
|
+ <include refid="DashboardWarningTypeFilter"/>
|
|
|
+ GROUP BY COALESCE(NULLIF(w.warning_special, ''), '未分类')
|
|
|
+ )
|
|
|
+ SELECT
|
|
|
+ special_name,
|
|
|
+ warning_count,
|
|
|
+ ROUND(warning_count * 100.0 / NULLIF(SUM(warning_count) OVER (), 0), 2) AS percentage
|
|
|
+ FROM special_stats
|
|
|
+ ORDER BY warning_count DESC, special_name ASC
|
|
|
+ </select>
|
|
|
+
|
|
|
+ <select id="selectDashboardHistoryPage" resultType="java.util.Map">
|
|
|
+ SELECT <include refid="DashboardWarningColumns"/>
|
|
|
+ FROM app_user.early_warning w
|
|
|
+ <where>
|
|
|
+ AND w.status != 'DRAFT'
|
|
|
+ AND w.publish_time <= CURRENT_TIMESTAMP
|
|
|
+ <include refid="SupportedDashboardWarningTypes"/>
|
|
|
+ <include refid="DashboardWarningTypeFilter"/>
|
|
|
+ <if test="warningSpecial != null and warningSpecial != ''">
|
|
|
+ AND COALESCE(NULLIF(w.warning_special, ''), '未分类') = #{warningSpecial}
|
|
|
+ </if>
|
|
|
+ <if test="keyword != null and keyword != ''">
|
|
|
+ AND (
|
|
|
+ w.warning_no LIKE CONCAT('%', #{keyword}, '%')
|
|
|
+ OR w.warning_name LIKE CONCAT('%', #{keyword}, '%')
|
|
|
+ OR w.location LIKE CONCAT('%', #{keyword}, '%')
|
|
|
+ OR w.ownership_unit LIKE CONCAT('%', #{keyword}, '%')
|
|
|
+ )
|
|
|
+ </if>
|
|
|
+ </where>
|
|
|
+ ORDER BY w.publish_time DESC, w.warning_id DESC
|
|
|
+ </select>
|
|
|
+
|
|
|
+ <!-- Outstanding warning list. One most-recent open todo is attached per warning. -->
|
|
|
+ <select id="selectDashboardUnprocessedPage" resultType="java.util.Map">
|
|
|
+ SELECT
|
|
|
+ <include refid="DashboardWarningColumns"/>,
|
|
|
+ open_todo.todo_id,
|
|
|
+ open_todo.user_id AS todo_user_id,
|
|
|
+ open_todo.user_name AS todo_user_name,
|
|
|
+ open_todo.todo_type,
|
|
|
+ open_todo.read_status,
|
|
|
+ open_todo.task_name,
|
|
|
+ open_todo.create_time AS todo_create_time,
|
|
|
+ ROUND(
|
|
|
+ EXTRACT(EPOCH FROM (
|
|
|
+ CAST(CURRENT_TIMESTAMP AS TIMESTAMPTZ) - CAST(w.publish_time AS TIMESTAMPTZ)
|
|
|
+ )) / 3600,
|
|
|
+ 2
|
|
|
+ ) AS waiting_hours
|
|
|
+ FROM app_user.early_warning w
|
|
|
+ LEFT JOIN (
|
|
|
+ SELECT todo_id, warning_id, user_id, user_name, todo_type, read_status, task_name, create_time
|
|
|
+ FROM (
|
|
|
+ SELECT
|
|
|
+ t.*,
|
|
|
+ ROW_NUMBER() OVER (
|
|
|
+ PARTITION BY t.warning_id
|
|
|
+ ORDER BY t.create_time DESC, t.todo_id DESC
|
|
|
+ ) AS row_num
|
|
|
+ FROM app_user.warning_todo t
|
|
|
+ WHERE t.complete_time IS NULL
|
|
|
+ AND (t.todo_type IS NULL OR t.todo_type != 'DONE')
|
|
|
+ ) ranked_todo
|
|
|
+ WHERE row_num = 1
|
|
|
+ ) open_todo ON open_todo.warning_id = w.warning_id
|
|
|
+ <where>
|
|
|
+ AND w.publish_time <= CURRENT_TIMESTAMP
|
|
|
+ AND w.status IN ('PENDING', 'PROCESSING', 'RELEASED')
|
|
|
+ <include refid="SupportedDashboardWarningTypes"/>
|
|
|
+ <include refid="DashboardWarningTypeFilter"/>
|
|
|
+ <include refid="DashboardWarningLevelFilter"/>
|
|
|
+ <if test="keyword != null and keyword != ''">
|
|
|
+ AND (
|
|
|
+ w.warning_no LIKE CONCAT('%', #{keyword}, '%')
|
|
|
+ OR w.warning_name LIKE CONCAT('%', #{keyword}, '%')
|
|
|
+ OR w.warning_special LIKE CONCAT('%', #{keyword}, '%')
|
|
|
+ OR w.location LIKE CONCAT('%', #{keyword}, '%')
|
|
|
+ OR w.ownership_unit LIKE CONCAT('%', #{keyword}, '%')
|
|
|
+ )
|
|
|
+ </if>
|
|
|
+ </where>
|
|
|
+ ORDER BY
|
|
|
+ CASE w.warning_level
|
|
|
+ WHEN '4' THEN 1 WHEN 'RED' THEN 1
|
|
|
+ WHEN '3' THEN 2 WHEN 'ORANGE' THEN 2
|
|
|
+ WHEN '2' THEN 3 WHEN 'YELLOW' THEN 3
|
|
|
+ WHEN '1' THEN 4 WHEN 'BLUE' THEN 4
|
|
|
+ ELSE 5
|
|
|
+ END,
|
|
|
+ w.publish_time ASC,
|
|
|
+ w.warning_id ASC
|
|
|
+ </select>
|
|
|
+
|
|
|
+ <!-- Aggregate cards for the unprocessed list. The filters mirror the page
|
|
|
+ query so counts remain correct when the user searches or narrows a
|
|
|
+ warning type/level. -->
|
|
|
+ <select id="selectDashboardUnprocessedSummary" resultType="java.util.Map">
|
|
|
+ SELECT
|
|
|
+ COUNT(*) AS total,
|
|
|
+ COUNT(DISTINCT NULLIF(w.ownership_unit, '')) AS ownership_count,
|
|
|
+ MAX(CASE
|
|
|
+ WHEN w.warning_level IN ('1', 'BLUE', 'IV') THEN 1
|
|
|
+ WHEN w.warning_level IN ('2', 'YELLOW', 'III') THEN 2
|
|
|
+ WHEN w.warning_level IN ('3', 'ORANGE', 'II') THEN 3
|
|
|
+ WHEN w.warning_level IN ('4', 'RED', 'I') THEN 4
|
|
|
+ ELSE NULL
|
|
|
+ END) AS highest_level
|
|
|
+ FROM app_user.early_warning w
|
|
|
+ <where>
|
|
|
+ AND w.publish_time <= CURRENT_TIMESTAMP
|
|
|
+ AND w.status IN ('PENDING', 'PROCESSING', 'RELEASED')
|
|
|
+ <include refid="SupportedDashboardWarningTypes"/>
|
|
|
+ <include refid="DashboardWarningTypeFilter"/>
|
|
|
+ <include refid="DashboardWarningLevelFilter"/>
|
|
|
+ <if test="keyword != null and keyword != ''">
|
|
|
+ AND (
|
|
|
+ w.warning_no LIKE CONCAT('%', #{keyword}, '%')
|
|
|
+ OR w.warning_name LIKE CONCAT('%', #{keyword}, '%')
|
|
|
+ OR w.warning_special LIKE CONCAT('%', #{keyword}, '%')
|
|
|
+ OR w.location LIKE CONCAT('%', #{keyword}, '%')
|
|
|
+ OR w.ownership_unit LIKE CONCAT('%', #{keyword}, '%')
|
|
|
+ )
|
|
|
+ </if>
|
|
|
+ </where>
|
|
|
+ </select>
|
|
|
+
|
|
|
<select id="selectWarningList" resultType="java.util.Map">
|
|
|
SELECT w.*
|
|
|
FROM early_warning w
|