| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147 |
- <?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.warning.mapper.EarlyWarningMapper">
- <resultMap id="BaseResultMap" type="com.zksy.base.warning.domain.EarlyWarning">
- <id column="warning_id" property="warningId"/>
- <result column="warning_no" property="warningNo"/>
- <result column="warning_type" property="warningType"/>
- <result column="warning_level" property="warningLevel"/>
- <result column="warning_special" property="warningSpecial"/>
- <result column="disposal_deadline" property="disposalDeadline"/>
- <result column="stage_deadline" property="stageDeadline"/>
- <result column="item_id" property="itemId"/>
- <result column="item_snapshot" property="itemSnapshot"/>
- <result column="device_code" property="deviceCode"/>
- <result column="device_name" property="deviceName"/>
- <result column="location" property="location"/>
- <result column="ownership_unit" property="ownershipUnit"/>
- <result column="publisher" property="publisher"/>
- <result column="publish_time" property="publishTime"/>
- <result column="handler" property="handler"/>
- <result column="reviewer" property="reviewer"/>
- <result column="status" property="status"/>
- <result column="warning_content" property="warningContent"/>
- <result column="process_instance_id" property="processInstanceId"/>
- <result column="create_by" property="createBy"/>
- <result column="create_time" property="createTime"/>
- <result column="update_by" property="updateBy"/>
- <result column="update_time" property="updateTime"/>
- <result column="remark" property="remark"/>
- </resultMap>
- <sql id="Base_Column_List">
- warning_id, warning_no, warning_type, warning_level, warning_special,
- disposal_deadline, stage_deadline, item_id, item_snapshot, device_code, device_name,
- location, ownership_unit, publisher, publish_time, handler, reviewer,
- status, warning_content, process_instance_id, create_by, create_time, update_by,
- update_time, remark
- </sql>
- <!-- The city-life project only contains water supply, drainage, gas and manhole warnings. -->
- <sql id="SupportedDashboardWarningTypes">
- AND EXISTS (SELECT 1 FROM app_user.warning_type wt WHERE wt.warning_code = w.warning_type)
- </sql>
- <sql id="DashboardWarningTypeFilter">
- <if test="warningType != null and warningType != ''">AND w.warning_type = #{warningType}</if>
- </sql>
- <sql id="DashboardWarningLevelFilter">
- <if test="warningLevel != null and warningLevel != ''">AND w.warning_level = #{warningLevel}</if>
- </sql>
- <sql id="DashboardWarningColumns">
- w.warning_id,
- w.warning_no,
- w.warning_type,
- (SELECT wt.warning_name FROM app_user.warning_type wt WHERE wt.warning_code=w.warning_type ORDER BY wt.id LIMIT 1) AS warning_type_name,
- (SELECT dict_label FROM app_user.sys_dict_data WHERE dict_type='alert_level' AND dict_value=w.warning_level AND status='0' ORDER BY dict_sort LIMIT 1) AS warning_level_name,
- (SELECT dict_label FROM app_user.sys_dict_data WHERE dict_type='pre_alarm_status' AND dict_value=w.status AND status='0' ORDER BY dict_sort LIMIT 1) AS status_name,
- w.warning_level,
- w.warning_special,
- w.location,
- 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', 'AUTO_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 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 >= CURRENT_DATE
- AND w.publish_time < CAST(CURRENT_DATE AS TIMESTAMP) + CAST('1 day' AS INTERVAL)
- AND w.publish_time <= CURRENT_TIMESTAMP
- <include refid="SupportedDashboardWarningTypes"/>
- </select>
- <!-- 查询今日预警列表 -->
- <select id="selectTodayWarningList" resultMap="BaseResultMap">
- SELECT <include refid="Base_Column_List"/>
- FROM app_user.early_warning w
- WHERE 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
- <include refid="SupportedDashboardWarningTypes"/>
- <choose>
- <when test="status != null and status != ''">
- AND w.status = #{status}
- </when>
- <otherwise>
- AND w.status != 'DRAFT'
- </otherwise>
- </choose>
- 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(NULLIF(warning_special, ''), '其他') AS warning_special,
- COUNT(*) AS warning_count
- FROM app_user.early_warning
- WHERE status != 'DRAFT'
- AND EXISTS (SELECT 1 FROM app_user.warning_type wt WHERE wt.warning_code = early_warning.warning_type)
- <if test="startTime != null">
- AND publish_time >= #{startTime}
- </if>
- <if test="endTime != null">
- AND publish_time < #{endTime}
- </if>
- <if test="warningSpecial != null and warningSpecial != ''">
- AND COALESCE(NULLIF(warning_special, ''), '其他') = #{warningSpecial}
- </if>
- GROUP BY TO_CHAR(publish_time, 'YYYY-MM-DD'), COALESCE(NULLIF(warning_special, ''), '其他')
- ORDER BY stat_date ASC, warning_special ASC
- </select>
- <!-- 按月统计预警发展趋势 -->
- <select id="selectWarningTrendByMonth" resultType="java.util.Map">
- SELECT
- TO_CHAR(publish_time, 'YYYY-MM') AS stat_month,
- COALESCE(NULLIF(warning_special, ''), '其他') AS warning_special,
- COUNT(*) AS warning_count
- FROM app_user.early_warning
- WHERE status != 'DRAFT'
- AND EXISTS (SELECT 1 FROM app_user.warning_type wt WHERE wt.warning_code = early_warning.warning_type)
- <if test="startTime != null">
- AND publish_time >= #{startTime}
- </if>
- <if test="endTime != null">
- AND publish_time < #{endTime}
- </if>
- <if test="warningSpecial != null and warningSpecial != ''">
- AND COALESCE(NULLIF(warning_special, ''), '其他') = #{warningSpecial}
- </if>
- GROUP BY TO_CHAR(publish_time, 'YYYY-MM'), COALESCE(NULLIF(warning_special, ''), '其他')
- ORDER BY stat_month ASC, warning_special ASC
- </select>
- <!-- 处置状态分析:按预警状态分组统计数量 -->
- <select id="selectWarningGroupByStatus" resultType="java.util.Map">
- SELECT
- status,
- COUNT(warning_id) AS status_count
- FROM app_user.early_warning
- WHERE status != 'DRAFT'
- AND EXISTS (SELECT 1 FROM app_user.warning_type wt WHERE wt.warning_code = early_warning.warning_type)
- <if test="startTime != null">
- AND publish_time >= #{startTime}
- </if>
- <if test="endTime != null">
- AND publish_time < #{endTime}
- </if>
- <if test="warningSpecial != null and warningSpecial != ''">
- AND warning_special = #{warningSpecial}
- </if>
- GROUP BY status
- 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'
- <include refid="SupportedDashboardWarningTypes"/>
- <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
- ROUND(AVG(dispose_hours), 2) AS avg_hours,
- ROUND(MAX(dispose_hours), 2) AS max_hours,
- ROUND(MIN(dispose_hours), 2) AS min_hours,
- COUNT(*) AS total_count
- FROM (
- 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
- AND d.disposal_type IN ('HANDLE', 'RESOLVE', 'CLEAR', 'CLOSE', 'MISREPORT', 'AUTO_CLEAR')
- WHERE w.status IN ('HANDLED', 'CLOSED')
- <include refid="SupportedDashboardWarningTypes"/>
- <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 w.warning_id, w.publish_time
- HAVING MAX(d.create_time) >= w.publish_time
- ) AS temp
- </select>
- <!-- 处置时效分析-时效区间分布统计 -->
- <select id="selectDisposeEfficiencyRange" resultType="java.util.Map">
- SELECT
- CASE
- WHEN dispose_hours <= 2 THEN '0-2小时'
- WHEN dispose_hours <= 6 THEN '2-6小时'
- WHEN dispose_hours <= 24 THEN '6-24小时'
- ELSE '24小时以上'
- END AS time_range,
- COUNT(*) AS warning_count
- FROM (
- 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
- AND d.disposal_type IN ('HANDLE', 'RESOLVE', 'CLEAR', 'CLOSE', 'MISREPORT', 'AUTO_CLEAR')
- WHERE w.status IN ('HANDLED', 'CLOSED')
- <include refid="SupportedDashboardWarningTypes"/>
- <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 w.warning_id, w.publish_time
- HAVING MAX(d.create_time) >= w.publish_time
- ) AS temp
- GROUP BY time_range
- ORDER BY
- CASE time_range
- WHEN '0-2小时' THEN 1
- WHEN '2-6小时' THEN 2
- WHEN '6-24小时' THEN 3
- ELSE 4
- END ASC
- </select>
- <!-- 处置时效分析-按预警专项统计平均时效 -->
- <select id="selectDisposeEfficiencyBySpecial" resultType="java.util.Map">
- SELECT
- COALESCE(NULLIF(warning_special, ''), '其他') AS warning_special,
- COUNT(*) AS warning_count,
- ROUND(AVG(dispose_hours), 2) AS avg_dispose_hours
- FROM (
- SELECT
- 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
- AND d.disposal_type IN ('HANDLE', 'RESOLVE', 'CLEAR', 'CLOSE', 'MISREPORT', 'AUTO_CLEAR')
- WHERE w.status IN ('HANDLED', 'CLOSED')
- <include refid="SupportedDashboardWarningTypes"/>
- <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 COALESCE(NULLIF(w.warning_special, ''), '其他') = #{warningSpecial}
- </if>
- GROUP BY w.warning_id, COALESCE(NULLIF(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
- </select>
- <!-- 处置时效分析-明细列表 -->
- <select id="selectDisposeEfficiencyList" resultType="java.util.Map">
- SELECT
- w.warning_id,
- w.warning_no,
- COALESCE(w.warning_special, '其他') AS warning_special,
- w.publish_time,
- MAX(d.create_time) AS dispose_time,
- 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
- AND d.disposal_type IN ('HANDLE', 'RESOLVE', 'CLEAR', 'CLOSE', 'MISREPORT', 'AUTO_CLEAR')
- WHERE w.status IN ('HANDLED', 'CLOSED')
- <include refid="SupportedDashboardWarningTypes"/>
- <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 w.warning_id, w.warning_no, 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
- </if>
- <if test="sortType == null or sortType == 'asc'">
- ASC
- </if>
- </select>
- <!-- 接警效率分析-概览指标统计 -->
- <select id="selectReceiveEfficiencyOverview" resultType="java.util.Map">
- SELECT
- ROUND(AVG(receive_hours), 2) AS avg_hours,
- ROUND(MAX(receive_hours), 2) AS max_hours,
- ROUND(MIN(receive_hours), 2) AS min_hours,
- COUNT(*) AS total_count
- FROM (
- SELECT
- 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'
- <include refid="SupportedDashboardWarningTypes"/>
- <if test="startTime != null">
- AND w.publish_time >= #{startTime}
- </if>
- <if test="endTime != null">
- AND w.publish_time < #{endTime}
- </if>
- <include refid="DashboardWarningTypeFilter"/>
- <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.publish_time
- HAVING MIN(d.create_time) >= w.publish_time
- ) AS temp
- </select>
- <!-- 接警效率分析-时效区间分布统计 -->
- <select id="selectReceiveEfficiencyRange" resultType="java.util.Map">
- SELECT
- CASE
- WHEN receive_hours <= 0.5 THEN '0-30分钟'
- WHEN receive_hours <= 2 THEN '30分钟-2小时'
- WHEN receive_hours <= 6 THEN '2-6小时'
- ELSE '6小时以上'
- END AS time_range,
- COUNT(*) AS warning_count
- FROM (
- SELECT
- 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'
- <include refid="SupportedDashboardWarningTypes"/>
- <if test="startTime != null">
- AND w.publish_time >= #{startTime}
- </if>
- <if test="endTime != null">
- AND w.publish_time < #{endTime}
- </if>
- <include refid="DashboardWarningTypeFilter"/>
- <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.publish_time
- HAVING MIN(d.create_time) >= w.publish_time
- ) AS temp
- GROUP BY time_range
- ORDER BY
- CASE time_range
- WHEN '0-30分钟' THEN 1
- WHEN '30分钟-2小时' THEN 2
- WHEN '2-6小时' THEN 3
- ELSE 4
- END ASC
- </select>
- <!-- 接警效率分析-按预警类型统计平均时效 -->
- <select id="selectReceiveEfficiencyByType" resultType="java.util.Map">
- SELECT
- COALESCE(warning_type, '其他') AS warning_type,
- COUNT(*) AS warning_count,
- ROUND(AVG(receive_hours), 2) AS avg_receive_hours
- FROM (
- SELECT
- w.warning_type,
- 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'
- <include refid="SupportedDashboardWarningTypes"/>
- <if test="startTime != null">
- AND w.publish_time >= #{startTime}
- </if>
- <if test="endTime != null">
- AND w.publish_time < #{endTime}
- </if>
- <include refid="DashboardWarningTypeFilter"/>
- <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
- </select>
- <!-- 接警效率分析-明细列表 -->
- <select id="selectReceiveEfficiencyList" resultType="java.util.Map">
- SELECT
- w.warning_id,
- w.warning_no,
- COALESCE(w.warning_type, '其他') AS warning_type,
- COALESCE(w.warning_special, '其他') AS warning_special,
- w.publish_time,
- MIN(d.create_time) AS receive_time,
- 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 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 >= #{startTime}
- </if>
- <if test="endTime != null">
- AND w.publish_time < #{endTime}
- </if>
- <include refid="DashboardWarningTypeFilter"/>
- <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_no, 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
- </if>
- <if test="sortType == null or sortType == 'asc'">
- ASC
- </if>
- </select>
- <!-- ————————————————————————————————————————————————————————————— -->
- <!-- 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')
- THEN 1 END) AS unresolved_count,
- COUNT(CASE
- WHEN w.status IN ('CLOSED')
- 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')
- 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')
- 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')
- 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')
- </otherwise>
- </choose>
- <include refid="DashboardWarningTypeFilter"/>
- <include refid="DashboardWarningLevelFilter"/>
- <if test="keyword != null and keyword != ''">
- AND (
- w.warning_no LIKE CONCAT('%', #{keyword}, '%')
- OR w.warning_special 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') THEN 1 END) AS resolved_count,
- COUNT(CASE WHEN w.status NOT IN ('CLOSED') 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.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', 'RECEIVED', 'PROCESSING')
- <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_special 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,
- MIN(CASE WHEN w.warning_level IN ('1', '2', '3', '4') THEN CAST(w.warning_level AS integer) END) AS highest_level
- FROM app_user.early_warning w
- <where>
- AND w.publish_time <= CURRENT_TIMESTAMP
- AND w.status IN ('PENDING', 'RECEIVED', 'PROCESSING')
- <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_special LIKE CONCAT('%', #{keyword}, '%')
- OR w.ownership_unit LIKE CONCAT('%', #{keyword}, '%')
- )
- </if>
- </where>
- </select>
- <select id="selectWarningList" resultType="java.util.Map">
- SELECT w.*, (SELECT wt.warning_name FROM app_user.warning_type wt WHERE wt.warning_code=w.warning_type ORDER BY wt.id LIMIT 1) AS warning_type_name,
- (SELECT dict_label FROM app_user.sys_dict_data WHERE dict_type='alert_level' AND dict_value=w.warning_level AND status='0' ORDER BY dict_sort LIMIT 1) AS warning_level_name,
- (SELECT dict_label FROM app_user.sys_dict_data WHERE dict_type='pre_alarm_status' AND dict_value=w.status AND status='0' ORDER BY dict_sort LIMIT 1) AS status_name
- FROM early_warning w
- <where>
- <if test="warningNo != null and warningNo != ''">AND w.warning_no LIKE CONCAT('%',#{warningNo},'%')</if>
- <if test="warningType != null and warningType != ''">
- AND w.warning_type = #{warningType}
- </if>
- <if test="warningLevel != null and warningLevel != ''">
- AND w.warning_level = #{warningLevel}
- </if>
- <if test="status != null and status != ''">
- AND w.status = #{status}
- </if>
- </where>
- ORDER BY w.create_time DESC
- </select>
- <select id="searchWarnings" resultType="java.util.Map">
- SELECT w.*, (SELECT wt.warning_name FROM app_user.warning_type wt WHERE wt.warning_code=w.warning_type ORDER BY wt.id LIMIT 1) AS warning_type_name,
- (SELECT dict_label FROM app_user.sys_dict_data WHERE dict_type='alert_level' AND dict_value=w.warning_level AND status='0' ORDER BY dict_sort LIMIT 1) AS warning_level_name,
- (SELECT dict_label FROM app_user.sys_dict_data WHERE dict_type='pre_alarm_status' AND dict_value=w.status AND status='0' ORDER BY dict_sort LIMIT 1) AS status_name
- FROM early_warning w
- <where>
- <if test="warningNo != null and warningNo != ''">
- AND w.warning_no LIKE CONCAT('%', #{warningNo}, '%')
- </if>
- <if test="warningType != null and warningType != ''">
- AND w.warning_type = #{warningType}
- </if>
- <if test="warningLevel != null and warningLevel != ''">
- AND w.warning_level = #{warningLevel}
- </if>
- <if test="status != null and status != ''">
- AND w.status = #{status}
- </if>
- <if test="publisher != null and publisher != ''">
- AND w.publisher LIKE CONCAT('%', #{publisher}, '%')
- </if>
- <if test="excludePublisher != null and excludePublisher != ''">
- AND (w.publisher IS NULL OR w.publisher NOT LIKE CONCAT('%', #{excludePublisher}, '%'))
- </if>
- <if test="ownershipUnit != null and ownershipUnit != ''">
- AND w.ownership_unit LIKE CONCAT('%', #{ownershipUnit}, '%')
- </if>
- <if test="deviceCode != null and deviceCode != ''">
- AND w.device_code LIKE CONCAT('%', #{deviceCode}, '%')
- </if>
- <if test="deviceName != null and deviceName != ''">
- AND w.device_name LIKE CONCAT('%', #{deviceName}, '%')
- </if>
- <if test="startTime != null">
- AND w.create_time >= #{startTime}
- </if>
- <if test="endTime != null">
- AND w.create_time <= #{endTime}
- </if>
- </where>
- <choose>
- <when test="releaseOrder">
- ORDER BY CASE w.status
- WHEN 'DRAFT' THEN 0
- WHEN 'PENDING' THEN 1
- WHEN 'RECEIVED' THEN 2
- WHEN 'PROCESSING' THEN 3
- WHEN 'HANDLED' THEN 4
- WHEN 'CLOSED' THEN 5
- ELSE 6 END,
- COALESCE(w.update_time, w.create_time) DESC NULLS LAST,
- w.create_time DESC NULLS LAST, w.warning_id DESC
- </when>
- <otherwise>ORDER BY w.create_time DESC</otherwise>
- </choose>
- </select>
- <select id="selectTodoList" resultType="java.util.Map">
- SELECT
- t.*,
- w.warning_no,
- w.warning_type,
- w.warning_level,
- w.handler,
- w.publisher,
- w.location,
- w.ownership_unit,
- w.publish_time
- FROM warning_todo t
- LEFT JOIN early_warning w ON t.warning_id = w.warning_id
- <where>
- t.user_id = #{userId}
- <if test="warningNo != null and warningNo != ''">AND w.warning_no LIKE CONCAT('%',#{warningNo},'%')</if>
- <if test="todoType != null and todoType != ''">
- AND t.todo_type = #{todoType}
- </if>
- </where>
- ORDER BY t.create_time DESC
- </select>
- <!-- 身份由服务端登录上下文传入,禁止使用请求中的 userName。 -->
- <select id="selectMyTasks" resultType="java.util.Map">
- SELECT w.*, (SELECT wt.warning_name FROM app_user.warning_type wt WHERE wt.warning_code=w.warning_type ORDER BY wt.id LIMIT 1) AS warning_type_name,
- (SELECT dict_label FROM app_user.sys_dict_data WHERE dict_type='alert_level' AND dict_value=w.warning_level AND status='0' ORDER BY dict_sort LIMIT 1) AS warning_level_name,
- (SELECT dict_label FROM app_user.sys_dict_data WHERE dict_type='pre_alarm_status' AND dict_value=w.status AND status='0' ORDER BY dict_sort LIMIT 1) AS status_name, t.todo_id, t.todo_type, t.action_type, t.task_name, t.read_status,
- t.create_time AS task_create_time, t.complete_time,
- (SELECT STRING_AGG(DISTINCT a.alarm_no, ',')
- FROM alarm_warning_rel rel JOIN alarm_data a ON a.id = rel.alarm_id
- WHERE rel.warning_id = w.warning_id) AS alarm_numbers
- FROM (
- SELECT task.*, ROW_NUMBER() OVER (
- PARTITION BY CASE WHEN task.todo_type = 'NOTICE' THEN task.todo_id ELSE task.warning_id END
- ORDER BY task.complete_time DESC NULLS LAST, task.create_time DESC, task.todo_id DESC
- ) AS task_rank
- FROM warning_todo task
- WHERE (task.user_name = #{username} OR task.user_id = #{userId}
- OR (task.user_name IS NULL AND task.user_id = #{username}))
- <if test="q.todoType != null and q.todoType != ''">AND task.todo_type = #{q.todoType}</if>
- <if test="q.todoType == null or q.todoType == ''">AND task.todo_type IN ('TODO', 'DONE')</if>
- ) t JOIN early_warning w ON w.warning_id = t.warning_id
- WHERE t.task_rank = 1
- <if test="q.warningNo != null and q.warningNo != ''">AND w.warning_no LIKE CONCAT('%',#{q.warningNo},'%')</if>
- <if test="q.warningSpecial != null and q.warningSpecial != ''">AND w.warning_special LIKE CONCAT('%',#{q.warningSpecial},'%')</if>
- <if test="q.warningType != null and q.warningType != ''">AND w.warning_type = #{q.warningType}</if>
- <if test="q.warningLevel != null and q.warningLevel != ''">AND w.warning_level = #{q.warningLevel}</if>
- <if test="q.status != null and q.status != ''">AND w.status = #{q.status}</if>
- <if test="q.handler != null and q.handler != ''">AND w.handler LIKE CONCAT('%',#{q.handler},'%')</if>
- <if test="q.publisher != null and q.publisher != ''">AND w.publisher LIKE CONCAT('%',#{q.publisher},'%')</if>
- <if test="q.ownershipUnit != null and q.ownershipUnit != ''">AND w.ownership_unit LIKE CONCAT('%',#{q.ownershipUnit},'%')</if>
- <if test="q.startTime != null and q.startTime != ''">AND w.publish_time >= CAST(#{q.startTime} AS TIMESTAMP)</if>
- <if test="q.endTime != null and q.endTime != ''">AND w.publish_time <= CAST(#{q.endTime} AS TIMESTAMP)</if>
- <if test="q.alarmCode != null and q.alarmCode != ''">
- AND EXISTS (SELECT 1 FROM alarm_warning_rel r JOIN alarm_data a ON a.id = r.alarm_id
- WHERE r.warning_id = w.warning_id AND a.alarm_no LIKE CONCAT('%',#{q.alarmCode},'%'))
- </if>
- ORDER BY t.create_time DESC, t.todo_id DESC
- </select>
- <select id="selectProcessingWarnings" resultType="java.util.Map">
- SELECT w.*, (SELECT wt.warning_name FROM app_user.warning_type wt WHERE wt.warning_code=w.warning_type ORDER BY wt.id LIMIT 1) AS warning_type_name,
- (SELECT dict_label FROM app_user.sys_dict_data WHERE dict_type='alert_level' AND dict_value=w.warning_level AND status='0' ORDER BY dict_sort LIMIT 1) AS warning_level_name,
- (SELECT dict_label FROM app_user.sys_dict_data WHERE dict_type='pre_alarm_status' AND dict_value=w.status AND status='0' ORDER BY dict_sort LIMIT 1) AS status_name
- FROM early_warning w
- <where>
- AND w.status IN ('PENDING', 'RECEIVED', 'PROCESSING', 'HANDLED')
- <if test="warningType != null and warningType != ''">
- AND w.warning_type = #{warningType}
- </if>
- <if test="warningLevel != null and warningLevel != ''">
- AND w.warning_level = #{warningLevel}
- </if>
- </where>
- ORDER BY w.publish_time DESC
- </select>
- <select id="selectCompletedWarnings" resultType="java.util.Map">
- SELECT w.*, (SELECT wt.warning_name FROM app_user.warning_type wt WHERE wt.warning_code=w.warning_type ORDER BY wt.id LIMIT 1) AS warning_type_name,
- (SELECT dict_label FROM app_user.sys_dict_data WHERE dict_type='alert_level' AND dict_value=w.warning_level AND status='0' ORDER BY dict_sort LIMIT 1) AS warning_level_name,
- (SELECT dict_label FROM app_user.sys_dict_data WHERE dict_type='pre_alarm_status' AND dict_value=w.status AND status='0' ORDER BY dict_sort LIMIT 1) AS status_name
- FROM early_warning w
- <where>
- AND w.status = 'CLOSED'
- <if test="warningType != null and warningType != ''">
- AND w.warning_type = #{warningType}
- </if>
- <if test="warningLevel != null and warningLevel != ''">
- AND w.warning_level = #{warningLevel}
- </if>
- <if test="startTime != null">
- AND w.update_time >= #{startTime}
- </if>
- <if test="endTime != null">
- AND w.update_time <= #{endTime}
- </if>
- </where>
- ORDER BY w.update_time DESC
- </select>
- <select id="selectWarningDetail" resultType="java.util.Map">
- SELECT w.*, (SELECT wt.warning_name FROM app_user.warning_type wt WHERE wt.warning_code=w.warning_type ORDER BY wt.id LIMIT 1) AS warning_type_name,
- (SELECT dict_label FROM app_user.sys_dict_data WHERE dict_type='alert_level' AND dict_value=w.warning_level AND status='0' ORDER BY dict_sort LIMIT 1) AS warning_level_name,
- (SELECT dict_label FROM app_user.sys_dict_data WHERE dict_type='pre_alarm_status' AND dict_value=w.status AND status='0' ORDER BY dict_sort LIMIT 1) AS status_name
- FROM early_warning w
- WHERE w.warning_id = #{warningId}
- </select>
- <select id="selectStatistics" resultType="java.util.Map">
- SELECT
- COUNT(*) AS total,
- SUM(CASE WHEN status = 'DRAFT' THEN 1 ELSE 0 END) AS draftCount,
- SUM(CASE WHEN status = 'PENDING' THEN 1 ELSE 0 END) AS pendingCount,
- SUM(CASE WHEN status = 'PROCESSING' THEN 1 ELSE 0 END) AS processingCount,
- SUM(CASE WHEN status = 'RECEIVED' THEN 1 ELSE 0 END) AS receivedCount,
- SUM(CASE WHEN status = 'HANDLED' THEN 1 ELSE 0 END) AS handledCount,
- SUM(CASE WHEN status = 'CLOSED' THEN 1 ELSE 0 END) AS closedCount,
- SUM(CASE WHEN warning_level = '1' THEN 1 ELSE 0 END) AS level1Count,
- SUM(CASE WHEN warning_level = '2' THEN 1 ELSE 0 END) AS level2Count,
- SUM(CASE WHEN warning_level = '3' THEN 1 ELSE 0 END) AS level3Count,
- SUM(CASE WHEN warning_level = '4' THEN 1 ELSE 0 END) AS level4Count
- FROM early_warning
- </select>
- <!-- 行业处置分析:兼容 device_code 存设备实例编码或设备类别主键两种历史格式。
- 设备类别主键改为整数后,业态由根节点 id 决定:1=供水 2=排水 3=燃气 4=窨井,
- 对外仍以 water_supply/drainage/gas/manhole 作为 industry_code,保持接口契约不变。 -->
- <sql id="IndustryWarningCte">
- WITH RECURSIVE type_tree AS (
- SELECT et.id AS leaf_id, et.id AS current_id,
- et.type_name AS current_name, et.parent_id, CAST(0 AS bigint) AS depth
- FROM app_user.equipment_type et
- UNION ALL
- SELECT tree.leaf_id, parent.id, parent.type_name,
- parent.parent_id, tree.depth + 1
- FROM type_tree tree
- INNER JOIN app_user.equipment_type parent ON parent.id = tree.parent_id
- ),
- root_ranked AS (
- SELECT leaf_id, current_id AS industry_id, current_name AS industry_name,
- ROW_NUMBER() OVER (PARTITION BY leaf_id ORDER BY depth DESC) AS row_num
- FROM type_tree
- ),
- type_roots AS (
- SELECT leaf_id,
- CASE industry_id
- WHEN 1 THEN 'water_supply'
- WHEN 2 THEN 'drainage'
- WHEN 3 THEN 'gas'
- WHEN 4 THEN 'manhole'
- END AS industry_code,
- industry_name
- FROM root_ranked
- WHERE row_num = 1
- AND industry_id IN (1, 2, 3, 4)
- ),
- equipment_map AS (
- SELECT equipment_code, MIN(equipment_type_id) AS equipment_type_id
- FROM app_user.equipment_base
- WHERE del_flag = '0'
- GROUP BY equipment_code
- ),
- warning_industry AS (
- SELECT w.*, (SELECT wt.warning_name FROM app_user.warning_type wt WHERE wt.warning_code=w.warning_type ORDER BY wt.id LIMIT 1) AS warning_type_name,
- (SELECT dict_label FROM app_user.sys_dict_data WHERE dict_type='alert_level' AND dict_value=w.warning_level AND status='0' ORDER BY dict_sort LIMIT 1) AS warning_level_name,
- (SELECT dict_label FROM app_user.sys_dict_data WHERE dict_type='pre_alarm_status' AND dict_value=w.status AND status='0' ORDER BY dict_sort LIMIT 1) AS status_name, roots.industry_code, roots.industry_name
- FROM app_user.early_warning w
- LEFT JOIN equipment_map equipment ON equipment.equipment_code = w.device_code
- LEFT JOIN app_user.equipment_type direct_type
- ON CAST(direct_type.id AS varchar) = w.device_code
- INNER JOIN type_roots roots
- ON CAST(roots.leaf_id AS varchar) =
- COALESCE(equipment.equipment_type_id, CAST(direct_type.id AS varchar))
- 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="industryCode != null and industryCode != ''">
- AND roots.industry_code = #{industryCode}
- </if>
- ),
- completed_actions AS (
- SELECT disposal.warning_id, MAX(disposal.create_time) AS dispose_time
- FROM app_user.warning_disposal disposal
- WHERE disposal.disposal_type IN ('HANDLE', 'RESOLVE', 'CLEAR', 'CLOSE', 'MISREPORT', 'AUTO_CLEAR')
- GROUP BY disposal.warning_id
- )
- </sql>
- <select id="selectIndustryAnalysisSummary" resultType="java.util.Map">
- <include refid="IndustryWarningCte"/>
- SELECT warning.industry_code,
- warning.industry_name,
- COUNT(*) AS total_count,
- SUM(CASE WHEN warning.status IN ('PENDING', 'RECEIVED') THEN 1 ELSE 0 END) AS pending_count,
- SUM(CASE WHEN warning.status = 'PROCESSING' THEN 1 ELSE 0 END) AS processing_count,
- SUM(CASE WHEN warning.status IN ('HANDLED', 'CLOSED') THEN 1 ELSE 0 END) AS completed_count,
- ROUND(100.0 * SUM(CASE WHEN warning.status IN ('HANDLED', 'CLOSED') THEN 1 ELSE 0 END)
- / NULLIF(COUNT(*), 0), 2) AS completion_rate,
- ROUND(AVG(CASE
- WHEN warning.status IN ('HANDLED', 'CLOSED')
- AND action.dispose_time >= warning.publish_time
- THEN EXTRACT(EPOCH FROM (CAST(action.dispose_time AS TIMESTAMPTZ)
- - CAST(warning.publish_time AS TIMESTAMPTZ))) / 3600
- END), 2) AS avg_dispose_hours,
- SUM(CASE
- WHEN warning.status IN ('HANDLED', 'CLOSED')
- AND action.dispose_time >= warning.publish_time
- AND EXTRACT(EPOCH FROM (CAST(action.dispose_time AS TIMESTAMPTZ)
- - CAST(warning.publish_time AS TIMESTAMPTZ))) / 3600 > 24
- THEN 1 ELSE 0 END) AS over_24h_count
- FROM warning_industry warning
- LEFT JOIN completed_actions action ON action.warning_id = warning.warning_id
- GROUP BY warning.industry_code, warning.industry_name
- ORDER BY CASE warning.industry_code
- WHEN 'gas' THEN 1 WHEN 'water_supply' THEN 2
- WHEN 'drainage' THEN 3 WHEN 'manhole' THEN 4 ELSE 5 END
- </select>
- <select id="selectIndustryStatusDistribution" resultType="java.util.Map">
- <include refid="IndustryWarningCte"/>
- <!-- 处置统计只使用 pre_alarm_status 字典中的 CLOSED 终态。 -->
- SELECT industry_code,
- industry_name,
- CASE WHEN status IN ('CLOSED') THEN 'CLOSED' ELSE status END AS status,
- COUNT(*) AS warning_count
- FROM warning_industry
- GROUP BY industry_code,
- industry_name,
- CASE WHEN status IN ('CLOSED') THEN 'CLOSED' ELSE status END
- ORDER BY industry_name,
- CASE WHEN status IN ('CLOSED') THEN 'CLOSED' ELSE status END
- </select>
- <select id="selectIndustryEfficiencyComparison" resultType="java.util.Map">
- <include refid="IndustryWarningCte"/>
- SELECT warning.industry_code,
- warning.industry_name,
- COUNT(*) AS completed_count,
- ROUND(AVG(EXTRACT(EPOCH FROM (CAST(action.dispose_time AS TIMESTAMPTZ)
- - CAST(warning.publish_time AS TIMESTAMPTZ))) / 3600), 2) AS avg_dispose_hours,
- ROUND(MAX(EXTRACT(EPOCH FROM (CAST(action.dispose_time AS TIMESTAMPTZ)
- - CAST(warning.publish_time AS TIMESTAMPTZ))) / 3600), 2) AS max_dispose_hours,
- ROUND(MIN(EXTRACT(EPOCH FROM (CAST(action.dispose_time AS TIMESTAMPTZ)
- - CAST(warning.publish_time AS TIMESTAMPTZ))) / 3600), 2) AS min_dispose_hours,
- ROUND(100.0 * SUM(CASE WHEN EXTRACT(EPOCH FROM (CAST(action.dispose_time AS TIMESTAMPTZ)
- - CAST(warning.publish_time AS TIMESTAMPTZ))) / 3600 <= 24
- THEN 1 ELSE 0 END) / NULLIF(COUNT(*), 0), 2) AS within_24h_rate
- FROM warning_industry warning
- INNER JOIN completed_actions action ON action.warning_id = warning.warning_id
- WHERE warning.status IN ('HANDLED', 'CLOSED')
- AND action.dispose_time >= warning.publish_time
- GROUP BY warning.industry_code, warning.industry_name
- ORDER BY avg_dispose_hours DESC
- </select>
- <select id="selectIndustryAnalysisList" resultType="java.util.Map">
- <include refid="IndustryWarningCte"/>
- SELECT warning.warning_id,
- warning.warning_no,
- warning.device_code,
- warning.device_name,
- warning.industry_code,
- warning.industry_name,
- warning.warning_level,
- warning.publish_time,
- warning.status,
- action.dispose_time,
- CASE WHEN action.dispose_time >= warning.publish_time
- THEN ROUND(EXTRACT(EPOCH FROM (CAST(action.dispose_time AS TIMESTAMPTZ)
- - CAST(warning.publish_time AS TIMESTAMPTZ))) / 3600, 2)
- ELSE NULL END AS dispose_hours
- FROM warning_industry warning
- LEFT JOIN completed_actions action ON action.warning_id = warning.warning_id
- <where>
- <if test="status != null and status != ''">
- <choose>
- <!-- 页面只提供一个“已解除”筛选项,但兼容两种历史状态值。 -->
- <when test="status == 'CLOSED'">
- warning.status IN ('CLOSED')
- </when>
- <otherwise>
- warning.status = #{status}
- </otherwise>
- </choose>
- </if>
- </where>
- ORDER BY dispose_hours
- <if test="sortType != null and sortType == 'desc'">DESC</if>
- <if test="sortType == null or sortType == 'asc'">ASC</if>
- NULLS LAST, warning.publish_time DESC
- </select>
- </mapper>
|