<?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.ruoyi.ems.mapper.AlarmMapper">

    <resultMap type="com.ruoyi.ems.domain.Alarm" id="AlarmResult">
        <id property="id" column="id"/>
        <result property="alarmId" column="alarm_id"/>
        <result property="areaCode" column="area_code"/>
        <result property="areaName" column="area_name"/>
        <result property="subsystemCode" column="subsystem_code"/>
        <result property="subsystemName" column="subsystem_name"/>
        <result property="targetType" column="target_type"/>
        <result property="targetCode" column="target_code"/>
        <result property="targetName" column="target_name"/>
        <result property="deviceModel" column="device_model"/>
        <result property="deviceModelName" column="device_model_name"/>
        <result property="location" column="location"/>
        <result property="ruleCode" column="rule_code"/>
        <result property="ruleName" column="rule_name"/>
        <result property="attrKey" column="attr_key"/>
        <result property="attrName" column="attr_name"/>
        <result property="attrValue" column="attr_value"/>
        <result property="thresholdValue" column="threshold_value"/>
        <result property="alarmLevel" column="alarm_level"/>
        <result property="alarmCode" column="alarm_code"/>
        <result property="alarmMsg" column="alarm_msg"/>
        <result property="alarmSource" column="alarm_source"/>
        <result property="sourceRef" column="source_ref"/>
        <result property="alarmTime" column="alarm_time"/>
        <result property="alarmDate" column="alarm_date"/>
        <result property="alarmStatus" column="alarm_status"/>
        <result property="confirmTime" column="confirm_time"/>
        <result property="confirmBy" column="confirm_by"/>
        <result property="resolveTime" column="resolve_time"/>
        <result property="resolveBy" column="resolve_by"/>
        <result property="resolveRemark" column="resolve_remark"/>
        <result property="recoveryTime" column="recovery_time"/>
        <result property="duration" column="duration"/>
        <result property="repeatCount" column="repeat_count"/>
        <result property="lastOccurTime" column="last_occur_time"/>
        <result property="isNotified" column="is_notified"/>
        <result property="notifyTime" column="notify_time"/>
        <result property="createTime" column="create_time"/>
        <result property="updateTime" column="update_time"/>
    </resultMap>

    <sql id="selectVo">
        SELECT al.id, al.alarm_id, al.area_code, a.area_name, al.subsystem_code, s.system_name AS subsystem_name,
               al.target_type, al.target_code, al.target_name, al.device_model, m.model_name AS device_model_name,
               al.location, al.rule_code, al.rule_name, al.attr_key, al.attr_name, al.attr_value, al.threshold_value,
               al.alarm_level, al.alarm_code, al.alarm_msg, al.alarm_source, al.source_ref,
               al.alarm_time, al.alarm_date, al.alarm_status,
               al.confirm_time, al.confirm_by, al.resolve_time, al.resolve_by, al.resolve_remark,
               al.recovery_time, al.duration, al.repeat_count, al.last_occur_time,
               al.is_notified, al.notify_time, al.create_time, al.update_time
        FROM adm_op_alarm al
                 LEFT JOIN adm_area a ON al.area_code = a.area_code
                 LEFT JOIN adm_ems_subsystem s ON al.subsystem_code = s.system_code
                 LEFT JOIN adm_ems_obj_model m ON al.device_model = m.model_code
    </sql>

    <select id="selectById" parameterType="Long" resultMap="AlarmResult">
        <include refid="selectVo"/>
        WHERE al.id = #{id}
    </select>

    <select id="selectByAlarmId" parameterType="String" resultMap="AlarmResult">
        <include refid="selectVo"/>
        WHERE al.alarm_id = #{alarmId}
    </select>

    <select id="selectList" parameterType="com.ruoyi.ems.domain.Alarm" resultMap="AlarmResult">
        <include refid="selectVo"/>
        <where>
            <if test="alarmId != null and alarmId != ''">AND al.alarm_id = #{alarmId}</if>
            <if test="areaCode != null and areaCode != '' and areaCode != '-1'">AND al.area_code = #{areaCode}</if>
            <if test="subsystemCode != null and subsystemCode != ''">AND al.subsystem_code = #{subsystemCode}</if>
            <if test="targetType != null">AND al.target_type = #{targetType}</if>
            <if test="targetCode != null and targetCode != ''">AND al.target_code = #{targetCode}</if>
            <if test="targetName != null and targetName != ''">AND al.target_name LIKE CONCAT('%', #{targetName}, '%')</if>
            <if test="deviceModel != null and deviceModel != ''">AND al.device_model = #{deviceModel}</if>
            <if test="ruleCode != null and ruleCode != ''">AND al.rule_code = #{ruleCode}</if>
            <if test="alarmLevel != null">AND al.alarm_level = #{alarmLevel}</if>
            <if test="alarmCode != null and alarmCode != ''">AND al.alarm_code = #{alarmCode}</if>
            <if test="alarmSource != null">AND al.alarm_source = #{alarmSource}</if>
            <if test="alarmStatus != null">AND al.alarm_status = #{alarmStatus}</if>
            <if test="startRecTime != null and startRecTime != '' and endRecTime != null and endRecTime != ''">
                AND al.alarm_time >= #{startRecTime} AND al.alarm_time &lt;= #{endRecTime}
            </if>
            <if test="alarmDate != null">AND al.alarm_date = #{alarmDate}</if>
        </where>
        ORDER BY al.alarm_time DESC
    </select>

    <!-- 查询活动告警 -->
    <select id="selectActiveAlarms" parameterType="String" resultMap="AlarmResult">
        <include refid="selectVo"/>
        WHERE al.alarm_status IN (0, 1, 2)
        <if test="areaCode != null and areaCode != '' and areaCode != '-1'">
            AND al.area_code = #{areaCode}
        </if>
        ORDER BY al.alarm_level DESC, al.alarm_time DESC
    </select>

    <!-- 查询指定规则和目标的活动告警(用于聚合) -->
    <select id="selectActiveAlarm" resultMap="AlarmResult">
        <include refid="selectVo"/>
        WHERE al.rule_code = #{ruleCode}
        AND al.target_code = #{targetCode}
        AND al.alarm_status IN (0, 1, 2)
        ORDER BY al.alarm_time DESC
        LIMIT 1
    </select>

    <!-- 按告警级别统计 -->
    <select id="countByLevel" parameterType="com.ruoyi.ems.domain.Alarm" resultType="java.util.Map">
        SELECT alarm_level AS alarmLevel, COUNT(*) AS cnt
        FROM adm_op_alarm
        <where>
            <if test="areaCode != null and areaCode != '' and areaCode != '-1'">AND area_code = #{areaCode}</if>
            <if test="startRecTime != null and startRecTime != '' and endRecTime != null and endRecTime != ''">
                AND alarm_time >= #{startRecTime} AND alarm_time &lt;= #{endRecTime}
            </if>
            <if test="alarmDate != null">AND alarm_date = #{alarmDate}</if>
        </where>
        GROUP BY alarm_level
    </select>

    <!-- 按告警状态统计 -->
    <select id="countByStatus" parameterType="com.ruoyi.ems.domain.Alarm" resultType="java.util.Map">
        SELECT alarm_status AS alarmStatus, COUNT(*) AS cnt
        FROM adm_op_alarm
        <where>
            <if test="areaCode != null and areaCode != '' and areaCode != '-1'">AND area_code = #{areaCode}</if>
            <if test="startRecTime != null and startRecTime != '' and endRecTime != null and endRecTime != ''">
                AND alarm_time >= #{startRecTime} AND alarm_time &lt;= #{endRecTime}
            </if>
        </where>
        GROUP BY alarm_status
    </select>

    <!-- 按时间趋势统计(日) -->
    <select id="countByDay" parameterType="com.ruoyi.ems.domain.Alarm" resultType="java.util.Map">
        SELECT DATE_FORMAT(alarm_time, '%H:00') AS timeIndex, COUNT(*) AS cnt
        FROM adm_op_alarm
        <where>
            <if test="areaCode != null and areaCode != '' and areaCode != '-1'">AND area_code = #{areaCode}</if>
            <if test="alarmDate != null">AND alarm_date = #{alarmDate}</if>
        </where>
        GROUP BY DATE_FORMAT(alarm_time, '%H:00')
        ORDER BY timeIndex
    </select>

    <!-- 按时间趋势统计(月) -->
    <select id="countByMonth" parameterType="com.ruoyi.ems.domain.Alarm" resultType="java.util.Map">
        SELECT DATE_FORMAT(alarm_date, '%Y-%m-%d') AS timeIndex, COUNT(*) AS cnt
        FROM adm_op_alarm
        <where>
            <if test="areaCode != null and areaCode != '' and areaCode != '-1'">AND area_code = #{areaCode}</if>
            <if test="startRecTime != null and startRecTime != ''">AND alarm_date >= #{startRecTime}</if>
        </where>
        GROUP BY alarm_date
        ORDER BY timeIndex
    </select>

    <!-- 按子系统统计 -->
    <select id="countBySubsystem" parameterType="com.ruoyi.ems.domain.Alarm" resultType="java.util.Map">
        SELECT al.subsystem_code AS subsystemCode, s.system_name AS subsystemName, COUNT(*) AS cnt
        FROM adm_op_alarm al
        LEFT JOIN adm_ems_subsystem s ON al.subsystem_code = s.system_code
        <where>
            <if test="areaCode != null and areaCode != '' and areaCode != '-1'">AND al.area_code = #{areaCode}</if>
            <if test="startRecTime != null and startRecTime != '' and endRecTime != null and endRecTime != ''">
                AND al.alarm_time >= #{startRecTime} AND al.alarm_time &lt;= #{endRecTime}
            </if>
        </where>
        GROUP BY al.subsystem_code
    </select>

    <!-- 统计处理率 -->
    <select id="countHandleRate" parameterType="com.ruoyi.ems.domain.Alarm" resultType="java.util.Map">
        SELECT
        COUNT(*) AS total,
        SUM(CASE WHEN alarm_status IN (3, 4, 5) THEN 1 ELSE 0 END) AS handled,
        SUM(CASE WHEN alarm_status IN (0, 1, 2) THEN 1 ELSE 0 END) AS pending
        FROM adm_op_alarm
        <where>
            <if test="areaCode != null and areaCode != '' and areaCode != '-1'">AND area_code = #{areaCode}</if>
            <if test="startRecTime != null and startRecTime != '' and endRecTime != null and endRecTime != ''">
                AND alarm_time >= #{startRecTime} AND alarm_time &lt;= #{endRecTime}
            </if>
        </where>
    </select>

    <insert id="insert" parameterType="com.ruoyi.ems.domain.Alarm" useGeneratedKeys="true" keyProperty="id">
        INSERT INTO adm_op_alarm (
            alarm_id, area_code, subsystem_code, target_type, target_code, target_name,
            device_model, location, rule_code, rule_name, attr_key, attr_name, attr_value, threshold_value,
            alarm_level, alarm_code, alarm_msg, alarm_source, source_ref,
            alarm_time, alarm_date, alarm_status, repeat_count, last_occur_time, is_notified, create_time
        ) VALUES (
                     #{alarmId}, #{areaCode}, #{subsystemCode}, #{targetType}, #{targetCode}, #{targetName},
                     #{deviceModel}, #{location}, #{ruleCode}, #{ruleName}, #{attrKey}, #{attrName}, #{attrValue}, #{thresholdValue},
                     #{alarmLevel}, #{alarmCode}, #{alarmMsg}, #{alarmSource}, #{sourceRef},
                     #{alarmTime}, #{alarmDate}, #{alarmStatus}, #{repeatCount}, #{lastOccurTime}, #{isNotified}, NOW()
                 )
    </insert>

    <update id="update" parameterType="com.ruoyi.ems.domain.Alarm">
        UPDATE adm_op_alarm
        <set>
            <if test="alarmStatus != null">alarm_status = #{alarmStatus},</if>
            <if test="confirmTime != null">confirm_time = #{confirmTime},</if>
            <if test="confirmBy != null">confirm_by = #{confirmBy},</if>
            <if test="resolveTime != null">resolve_time = #{resolveTime},</if>
            <if test="resolveBy != null">resolve_by = #{resolveBy},</if>
            <if test="resolveRemark != null">resolve_remark = #{resolveRemark},</if>
            <if test="recoveryTime != null">recovery_time = #{recoveryTime},</if>
            <if test="duration != null">duration = #{duration},</if>
            <if test="repeatCount != null">repeat_count = #{repeatCount},</if>
            <if test="lastOccurTime != null">last_occur_time = #{lastOccurTime},</if>
            <if test="attrValue != null">attr_value = #{attrValue},</if>
            <if test="isNotified != null">is_notified = #{isNotified},</if>
            <if test="notifyTime != null">notify_time = #{notifyTime},</if>
            <if test="updateBy != null">update_by = #{updateBy},</if>
            update_time = NOW()
        </set>
        WHERE id = #{id}
    </update>

    <delete id="deleteByIds" parameterType="Long">
        DELETE FROM adm_op_alarm WHERE id IN
        <foreach item="id" collection="array" open="(" separator="," close=")">
            #{id}
        </foreach>
    </delete>
</mapper>