<?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.pm.subsystem.mapper.IntrusionAlarmMapper">

    <!-- ==================== 报警点相关查询 ==================== -->
    <resultMap type="pd" id="AlarmPointResult">
        <result property="id"    column="id"    />
        <result property="deviceCode"    column="device_code"    />
        <result property="deviceName"    column="device_name"    />
        <result property="alarmType"    column="alarm_type"    />
        <result property="zoneCode"    column="zone_code"    />
        <result property="zoneName"    column="zone_name"    />
        <result property="building"    column="building"    />
        <result property="floor"    column="floor"    />
        <result property="locationDetail"    column="location_detail"    />
        <result property="brand"    column="brand"    />
        <result property="model"    column="model"    />
        <result property="deviceStatus"    column="device_status"    />
        <result property="armStatus"    column="arm_status"    />
        <result property="sensitivity"    column="sensitivity"    />
        <result property="delayTime"    column="delay_time"    />
        <result property="linkageCameras"    column="linkage_cameras"    />
        <result property="lastAlarmTime"    column="last_alarm_time"    />
        <result property="installTime"    column="install_time"    />
        <result property="lastMaintainTime"    column="last_maintain_time"    />
        <result property="createTime"    column="create_time"    />
        <result property="updateTime"    column="update_time"    />
    </resultMap>

    <sql id="selectAlarmPointVo">
        select id, device_code, device_name, alarm_type, zone_code, zone_name, building, floor,
               location_detail, brand, model, device_status, arm_status, sensitivity, delay_time,
               linkage_cameras, last_alarm_time, install_time, last_maintain_time, create_time, update_time
        from alarm_point
    </sql>

    <select id="selectAlarmPointList" parameterType="pd" resultMap="AlarmPointResult">
        <include refid="selectAlarmPointVo"/>
        <where>
            <if test="deviceCode != null and deviceCode != ''"> and device_code like concat('%', #{deviceCode}, '%')</if>
            <if test="deviceName != null and deviceName != ''"> and device_name like concat('%', #{deviceName}, '%')</if>
            <if test="alarmType != null and alarmType != ''"> and alarm_type = #{alarmType}</if>
            <if test="zone != null and zone != ''"> and zone_code = #{zone}</if>
            <if test="building != null and building != ''"> and building = #{building}</if>
            <if test="floor != null and floor != ''"> and floor = #{floor}</if>
            <if test="deviceStatus != null"> and device_status = #{deviceStatus}</if>
            <if test="armStatus != null"> and arm_status = #{armStatus}</if>
            <if test="beginTime != null and beginTime != ''"> and date_format(create_time,'%y%m%d') &gt;= date_format(#{beginTime},'%y%m%d')</if>
            <if test="endTime != null and endTime != ''"> and date_format(create_time,'%y%m%d') &lt;= date_format(#{endTime},'%y%m%d')</if>
        </where>
        order by create_time desc
    </select>

    <select id="selectAlarmPointById" parameterType="pd" resultMap="AlarmPointResult">
        <include refid="selectAlarmPointVo"/>
        where id = #{id}
    </select>

    <insert id="insertAlarmPoint" parameterType="pd" useGeneratedKeys="true" keyProperty="id">
        insert into alarm_point
        <trim prefix="(" suffix=")" suffixOverrides=",">
            <if test="deviceCode != null and deviceCode != ''">device_code,</if>
            <if test="deviceName != null and deviceName != ''">device_name,</if>
            <if test="alarmType != null and alarmType != ''">alarm_type,</if>
            <if test="zoneCode != null and zoneCode != ''">zone_code,</if>
            <if test="zoneName != null and zoneName != ''">zone_name,</if>
            <if test="building != null and building != ''">building,</if>
            <if test="floor != null and floor != ''">floor,</if>
            <if test="locationDetail != null and locationDetail != ''">location_detail,</if>
            <if test="brand != null and brand != ''">brand,</if>
            <if test="model != null and model != ''">model,</if>
            <if test="deviceStatus != null">device_status,</if>
            <if test="armStatus != null">arm_status,</if>
            <if test="sensitivity != null">sensitivity,</if>
            <if test="delayTime != null">delay_time,</if>
            <if test="linkageCameras != null and linkageCameras != ''">linkage_cameras,</if>
            <if test="lastAlarmTime != null">last_alarm_time,</if>
            <if test="installTime != null">install_time,</if>
            <if test="lastMaintainTime != null">last_maintain_time,</if>
            <if test="createTime != null">create_time,</if>
            <if test="updateTime != null">update_time,</if>
        </trim>
        <trim prefix="values (" suffix=")" suffixOverrides=",">
            <if test="deviceCode != null and deviceCode != ''">#{deviceCode},</if>
            <if test="deviceName != null and deviceName != ''">#{deviceName},</if>
            <if test="alarmType != null and alarmType != ''">#{alarmType},</if>
            <if test="zoneCode != null and zoneCode != ''">#{zoneCode},</if>
            <if test="zoneName != null and zoneName != ''">#{zoneName},</if>
            <if test="building != null and building != ''">#{building},</if>
            <if test="floor != null and floor != ''">#{floor},</if>
            <if test="locationDetail != null and locationDetail != ''">#{locationDetail},</if>
            <if test="brand != null and brand != ''">#{brand},</if>
            <if test="model != null and model != ''">#{model},</if>
            <if test="deviceStatus != null">#{deviceStatus},</if>
            <if test="armStatus != null">#{armStatus},</if>
            <if test="sensitivity != null">#{sensitivity},</if>
            <if test="delayTime != null">#{delayTime},</if>
            <if test="linkageCameras != null and linkageCameras != ''">#{linkageCameras},</if>
            <if test="lastAlarmTime != null">#{lastAlarmTime},</if>
            <if test="installTime != null">#{installTime},</if>
            <if test="lastMaintainTime != null">#{lastMaintainTime},</if>
            <if test="createTime != null">#{createTime},</if>
            <if test="updateTime != null">#{updateTime},</if>
        </trim>
    </insert>

    <update id="updateAlarmPoint" parameterType="pd">
        update alarm_point
        <trim prefix="SET" suffixOverrides=",">
            <if test="deviceName != null and deviceName != ''">device_name = #{deviceName},</if>
            <if test="alarmType != null and alarmType != ''">alarm_type = #{alarmType},</if>
            <if test="zoneCode != null and zoneCode != ''">zone_code = #{zoneCode},</if>
            <if test="zoneName != null and zoneName != ''">zone_name = #{zoneName},</if>
            <if test="building != null and building != ''">building = #{building},</if>
            <if test="floor != null and floor != ''">floor = #{floor},</if>
            <if test="locationDetail != null and locationDetail != ''">location_detail = #{locationDetail},</if>
            <if test="brand != null and brand != ''">brand = #{brand},</if>
            <if test="model != null and model != ''">model = #{model},</if>
            <if test="deviceStatus != null">device_status = #{deviceStatus},</if>
            <if test="armStatus != null">arm_status = #{armStatus},</if>
            <if test="sensitivity != null">sensitivity = #{sensitivity},</if>
            <if test="delayTime != null">delay_time = #{delayTime},</if>
            <if test="linkageCameras != null">linkage_cameras = #{linkageCameras},</if>
            <if test="lastAlarmTime != null">last_alarm_time = #{lastAlarmTime},</if>
            <if test="installTime != null">install_time = #{installTime},</if>
            <if test="lastMaintainTime != null">last_maintain_time = #{lastMaintainTime},</if>
            <if test="updateTime != null">update_time = #{updateTime},</if>
        </trim>
        <where>
            <if test="id != null">id = #{id}</if>
            <if test="deviceCode != null and deviceCode != ''">or device_code = #{deviceCode}</if>
        </where>
    </update>

    <delete id="deleteAlarmPointById" parameterType="Long">
        delete from alarm_point where id = #{id}
    </delete>

    <delete id="deleteAlarmPointByIds" parameterType="String">
        delete from alarm_point where id in
        <foreach item="id" collection="array" open="(" separator="," close=")">
            #{id}
        </foreach>
    </delete>

    <!-- ==================== 报警记录相关查询 ==================== -->
    <select id="selectAlarmList" parameterType="pd" resultType="pd">
        select id, device_code, device_name, alarm_type, alarm_level, alarm_message, building, floor,
        zone_code, zone_name, alarm_time, handle_status, handle_user, handle_time, handle_remark,
        linkage_status, linkage_result, create_time
        from alarm_record
        <where>
            <if test="deviceCode != null and deviceCode != ''"> and device_code like concat('%', #{deviceCode}, '%')</if>
            <if test="deviceName != null and deviceName != ''"> and device_name like concat('%', #{deviceName}, '%')</if>
            <if test="alarmType != null and alarmType != ''"> and alarm_type = #{alarmType}</if>
            <if test="alarmLevel != null"> and alarm_level = #{alarmLevel}</if>
            <if test="handleStatus != null"> and handle_status = #{handleStatus}</if>
            <if test="zone != null and zone != ''"> and zone_code = #{zone}</if>
            <if test="building != null and building != ''"> and building = #{building}</if>
            <if test="linkageStatus != null"> and linkage_status = #{linkageStatus}</if>
            <if test="beginTime != null and beginTime != ''"> and date_format(alarm_time,'%y%m%d') &gt;= date_format(#{beginTime},'%y%m%d')</if>
            <if test="endTime != null and endTime != ''"> and date_format(alarm_time,'%y%m%d') &lt;= date_format(#{endTime},'%y%m%d')</if>
        </where>
        order by alarm_time desc
    </select>

    <select id="selectAlarmById" parameterType="pd" resultType="pd">
        select id, device_code, device_name, alarm_type, alarm_level, alarm_message, building, floor,
               zone_code, zone_name, alarm_time, handle_status, handle_user, handle_time, handle_remark,
               linkage_status, linkage_result, create_time
        from alarm_record
        where id = #{id}
    </select>

    <insert id="insertAlarm" parameterType="pd" useGeneratedKeys="true" keyProperty="id">
        insert into alarm_record (device_code, device_name, alarm_type, alarm_level, alarm_message, building, floor,
                                  zone_code, zone_name, alarm_time, handle_status, linkage_status, create_time)
        values (#{deviceCode}, #{deviceName}, #{alarmType}, #{alarmLevel}, #{alarmMessage}, #{building}, #{floor},
                #{zoneCode}, #{zoneName}, #{alarmTime}, #{handleStatus}, #{linkageStatus}, #{createTime})
    </insert>

    <update id="updateAlarm" parameterType="pd">
        update alarm_record
        <trim prefix="SET" suffixOverrides=",">
            <if test="handleStatus != null">handle_status = #{handleStatus},</if>
            <if test="handleUser != null and handleUser != ''">handle_user = #{handleUser},</if>
            <if test="handleTime != null">handle_time = #{handleTime},</if>
            <if test="handleRemark != null">handle_remark = #{handleRemark},</if>
            <if test="linkageStatus != null">linkage_status = #{linkageStatus},</if>
            <if test="linkageResult != null">linkage_result = #{linkageResult},</if>
        </trim>
        where id = #{id}
    </update>

    <delete id="deleteAlarmById" parameterType="Long">
        delete from alarm_record where id = #{id}
    </delete>

    <delete id="deleteAlarmByIds" parameterType="String">
        delete from alarm_record where id in
        <foreach item="id" collection="array" open="(" separator="," close=")">
            #{id}
        </foreach>
    </delete>

    <!-- ==================== 防区相关查询 ==================== -->
    <select id="selectZoneList" parameterType="pd" resultType="pd">
        select id, zone_code, zone_name, zone_description, zone_status, device_count, online_count,
        linkage_cameras, arm_mode, arm_schedule, create_time, update_time
        from alarm_zone
        <where>
            <if test="zoneCode != null and zoneCode != ''"> and zone_code like concat('%', #{zoneCode}, '%')</if>
            <if test="zoneName != null and zoneName != ''"> and zone_name like concat('%', #{zoneName}, '%')</if>
            <if test="zoneStatus != null"> and zone_status = #{zoneStatus}</if>
        </where>
        order by zone_code
    </select>

    <select id="selectZoneById" parameterType="pd" resultType="pd">
        select id, zone_code, zone_name, zone_description, zone_status, device_count, online_count,
               linkage_cameras, arm_mode, arm_schedule, create_time, update_time
        from alarm_zone
        where id = #{id}
    </select>

    <insert id="insertZone" parameterType="pd" useGeneratedKeys="true" keyProperty="id">
        insert into alarm_zone (zone_code, zone_name, zone_description, zone_status, device_count, online_count,
                                linkage_cameras, arm_mode, arm_schedule, create_time, update_time)
        values (#{zoneCode}, #{zoneName}, #{zoneDescription}, #{zoneStatus}, #{deviceCount}, #{onlineCount},
                #{linkageCameras}, #{armMode}, #{armSchedule}, #{createTime}, #{updateTime})
    </insert>

    <update id="updateZone" parameterType="pd">
        update alarm_zone
        <trim prefix="SET" suffixOverrides=",">
            <if test="zoneName != null and zoneName != ''">zone_name = #{zoneName},</if>
            <if test="zoneDescription != null">zone_description = #{zoneDescription},</if>
            <if test="zoneStatus != null">zone_status = #{zoneStatus},</if>
            <if test="deviceCount != null">device_count = #{deviceCount},</if>
            <if test="onlineCount != null">online_count = #{onlineCount},</if>
            <if test="linkageCameras != null">linkage_cameras = #{linkageCameras},</if>
            <if test="armMode != null and armMode != ''">arm_mode = #{armMode},</if>
            <if test="armSchedule != null">arm_schedule = #{armSchedule},</if>
            <if test="updateTime != null">update_time = #{updateTime},</if>
        </trim>
        where id = #{id}
    </update>

    <delete id="deleteZoneById" parameterType="Long">
        delete from alarm_zone where id = #{id}
    </delete>

    <!-- 查询防区设备列表 -->
    <select id="selectZoneDeviceList" parameterType="pd" resultType="pd">
        select device_code, device_name, alarm_type, device_status, arm_status, sensitivity, create_time
        from alarm_point
        where zone_code = #{zoneCode}
        order by device_code
    </select>

    <!-- ==================== 联动规则相关查询 ==================== -->
    <select id="selectLinkageRuleList" parameterType="pd" resultType="pd">
        select id, rule_name, trigger_device_code, trigger_condition, target_device, linkage_action,
        delay_time, rule_status, priority, create_time, update_time
        from intrusion_linkage_rule
        <where>
            <if test="ruleName != null and ruleName != ''"> and rule_name like concat('%', #{ruleName}, '%')</if>
            <if test="triggerDeviceCode != null and triggerDeviceCode != ''"> and trigger_device_code = #{triggerDeviceCode}</if>
            <if test="targetDevice != null and targetDevice != ''"> and target_device = #{targetDevice}</if>
            <if test="ruleStatus != null"> and rule_status = #{ruleStatus}</if>
        </where>
        order by priority desc, create_time desc
    </select>

    <select id="selectLinkageRuleById" parameterType="Long" resultType="pd">
        select id, rule_name, trigger_device_code, trigger_condition, target_device, linkage_action,
               delay_time, rule_status, priority, create_time, update_time
        from intrusion_linkage_rule
        where id = #{id}
    </select>

    <insert id="insertLinkageRule" parameterType="pd" useGeneratedKeys="true" keyProperty="id">
        insert into intrusion_linkage_rule (rule_name, trigger_device_code, trigger_condition, target_device,
                                            linkage_action, delay_time, rule_status, priority, create_time, update_time)
        values (#{ruleName}, #{triggerDeviceCode}, #{triggerCondition}, #{targetDevice},
                #{linkageAction}, #{delayTime}, #{ruleStatus}, #{priority}, #{createTime}, #{updateTime})
    </insert>

    <update id="updateLinkageRule" parameterType="pd">
        update intrusion_linkage_rule
        <trim prefix="SET" suffixOverrides=",">
            <if test="ruleName != null and ruleName != ''">rule_name = #{ruleName},</if>
            <if test="triggerDeviceCode != null and triggerDeviceCode != ''">trigger_device_code = #{triggerDeviceCode},</if>
            <if test="triggerCondition != null and triggerCondition != ''">trigger_condition = #{triggerCondition},</if>
            <if test="targetDevice != null and targetDevice != ''">target_device = #{targetDevice},</if>
            <if test="linkageAction != null and linkageAction != ''">linkage_action = #{linkageAction},</if>
            <if test="delayTime != null">delay_time = #{delayTime},</if>
            <if test="ruleStatus != null">rule_status = #{ruleStatus},</if>
            <if test="priority != null">priority = #{priority},</if>
            <if test="updateTime != null">update_time = #{updateTime},</if>
        </trim>
        where id = #{id}
    </update>

    <delete id="deleteLinkageRuleById" parameterType="Long">
        delete from intrusion_linkage_rule where id = #{id}
    </delete>

    <!-- 联动执行记录查询 -->
    <select id="selectLinkageRecordList" parameterType="pd" resultType="pd">
        select r.id, r.rule_id, r.trigger_device, r.target_device, r.linkage_action,
        r.execute_time, r.execute_result, r.execute_detail, r.create_time,
        l.rule_name
        from intrusion_linkage_record r
        left join intrusion_linkage_rule l on r.rule_id = l.id
        <where>
            <if test="triggerDevice != null and triggerDevice != ''"> and r.trigger_device = #{triggerDevice}</if>
            <if test="targetDevice != null and targetDevice != ''"> and r.target_device = #{targetDevice}</if>
            <if test="executeResult != null and executeResult != ''"> and r.execute_result = #{executeResult}</if>
            <if test="beginTime != null and beginTime != ''"> and date_format(r.execute_time,'%y%m%d') &gt;= date_format(#{beginTime},'%y%m%d')</if>
            <if test="endTime != null and endTime != ''"> and date_format(r.execute_time,'%y%m%d') &lt;= date_format(#{endTime},'%y%m%d')</if>
        </where>
        order by r.execute_time desc
    </select>

    <insert id="insertLinkageRecord" parameterType="pd" useGeneratedKeys="true" keyProperty="id">
        insert into intrusion_linkage_record (rule_id, trigger_device, target_device, linkage_action,
                                              execute_time, execute_result, execute_detail, create_time)
        values (#{ruleId}, #{triggerDevice}, #{targetDevice}, #{linkageAction},
                #{executeTime}, #{executeResult}, #{executeDetail}, #{createTime})
    </insert>

    <!-- ==================== 统计查询 ==================== -->
    <select id="selectAlarmStatistics" parameterType="pd" resultType="pd">
        select
            -- 今日报警数
            coalesce(sum(case when date(alarm_time) = curdate() then 1 else 0 end), 0) as todayAlarms,
            -- 未处理报警数
            coalesce(sum(case when handle_status = 0 then 1 else 0 end), 0) as unhandledAlarms,
            -- 在线设备数（从报警点表查询）
            (select count(*) from alarm_point where device_status = 1) as onlineDevices,
            -- 总设备数
            (select count(*) from alarm_point) as totalDevices,
            -- 布防防区数
            (select count(*) from alarm_zone where zone_status = 1) as armedZones,
            -- 总防区数
            (select count(*) from alarm_zone) as totalZones
        from alarm_record
    </select>

    <select id="selectRealTimeStatus" parameterType="pd" resultType="pd">
        select
            -- 在线设备统计
            count(case when device_status = 1 then 1 end) as onlineDevices,
            count(case when device_status = 0 then 1 end) as offlineDevices,
            count(case when device_status = 2 then 1 end) as alarmDevices,
            count(case when device_status = 3 then 1 end) as faultDevices,
            -- 布防状态统计
            count(case when arm_status = 1 then 1 end) as armedDevices,
            count(case when arm_status = 0 then 1 end) as disarmedDevices,
            -- 各类型设备统计
            count(case when alarm_type = 'infrared' then 1 end) as infraredDevices,
            count(case when alarm_type = 'door_magnetic' then 1 end) as doorMagneticDevices,
            count(case when alarm_type = 'glass_break' then 1 end) as glassBreakDevices,
            count(case when alarm_type = 'vibration' then 1 end) as vibrationDevices
        from alarm_point
    </select>

    <select id="selectAlarmTrend" parameterType="pd" resultType="pd">
        select
        date_format(alarm_time, '%Y-%m-%d') as alarmDate,
        count(*) as alarmCount,
        count(case when alarm_level = 1 then 1 end) as lowLevelCount,
        count(case when alarm_level = 2 then 1 end) as mediumLevelCount,
        count(case when alarm_level = 3 then 1 end) as highLevelCount,
        count(case when alarm_level = 4 then 1 end) as emergencyLevelCount,
        count(case when handle_status = 2 then 1 end) as handledCount
        from alarm_record
        <where>
            <if test="beginTime != null and beginTime != ''"> and date_format(alarm_time,'%y%m%d') &gt;= date_format(#{beginTime},'%y%m%d')</if>
            <if test="endTime != null and endTime != ''"> and date_format(alarm_time,'%y%m%d') &lt;= date_format(#{endTime},'%y%m%d')</if>
        </where>
        group by date_format(alarm_time, '%Y-%m-%d')
        order by alarmDate desc
        limit 30
    </select>

    <!-- ==================== 维护记录相关查询 ==================== -->
    <select id="selectMaintenanceRecordList" parameterType="pd" resultType="pd">
        select id, device_code, device_name, maintenance_type, maintenance_content, maintenance_user,
        maintenance_time, maintenance_result, next_maintenance_time, create_user, create_time
        from maintenance_record
        <where>
            <if test="deviceCode != null and deviceCode != ''"> and device_code like concat('%', #{deviceCode}, '%')</if>
            <if test="deviceName != null and deviceName != ''"> and device_name like concat('%', #{deviceName}, '%')</if>
            <if test="maintenanceType != null and maintenanceType != ''"> and maintenance_type = #{maintenanceType}</if>
            <if test="maintenanceUser != null and maintenanceUser != ''"> and maintenance_user = #{maintenanceUser}</if>
            <if test="beginTime != null and beginTime != ''"> and date_format(maintenance_time,'%y%m%d') &gt;= date_format(#{beginTime},'%y%m%d')</if>
            <if test="endTime != null and endTime != ''"> and date_format(maintenance_time,'%y%m%d') &lt;= date_format(#{endTime},'%y%m%d')</if>
        </where>
        order by maintenance_time desc
    </select>

    <insert id="insertMaintenanceRecord" parameterType="pd" useGeneratedKeys="true" keyProperty="id">
        insert into maintenance_record (device_code, device_name, maintenance_type, maintenance_content,
                                        maintenance_user, maintenance_time, maintenance_result, next_maintenance_time,
                                        create_user, create_time)
        values (#{deviceCode}, #{deviceName}, #{maintenanceType}, #{maintenanceContent},
                #{maintenanceUser}, #{maintenanceTime}, #{maintenanceResult}, #{nextMaintenanceTime},
                #{createUser}, #{createTime})
    </insert>

</mapper>