<?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.DeviceServiceOrderMapper">

    <resultMap type="com.pm.common.config.PageData" id="ServiceOrderResult">
    </resultMap>

    <sql id="selectServiceOrderVo">
        select id, order_id, alarm_id, device_code, device_name,
               order_type, order_title, order_content, priority, order_status,
               reporter, report_time, assignee, assign_time,
               handler, handle_time, complete_time,
               estimated_duration, actual_duration, cost,
               remark, attachments, create_time, update_time
        from device_service_order
    </sql>

    <select id="selectServiceOrderById" parameterType="Long" resultMap="ServiceOrderResult">
        <include refid="selectServiceOrderVo"/>
        where id = #{id}
    </select>

    <select id="selectServiceOrderList" parameterType="com.pm.common.config.PageData" resultMap="ServiceOrderResult">
        <include refid="selectServiceOrderVo"/>
        <where>
            <if test="orderId != null and orderId != ''"> and order_id like concat('%', #{orderId}, '%')</if>
            <if test="alarmId != null and alarmId != ''"> and alarm_id = #{alarmId}</if>
            <if test="deviceCode != null and deviceCode != ''"> and device_code = #{deviceCode}</if>
            <if test="deviceName != null and deviceName != ''"> and device_name like concat('%', #{deviceName}, '%')</if>
            <if test="orderType != null and orderType != ''"> and order_type = #{orderType}</if>
            <if test="orderTitle != null and orderTitle != ''"> and order_title like concat('%', #{orderTitle}, '%')</if>
            <if test="priority != null and priority != ''"> and priority = #{priority}</if>
            <if test="orderStatus != null and orderStatus != ''"> and order_status = #{orderStatus}</if>
            <if test="reporter != null and reporter != ''"> and reporter = #{reporter}</if>
            <if test="assignee != null and assignee != ''"> and assignee = #{assignee}</if>
            <if test="handler != null and handler != ''"> and handler = #{handler}</if>
            <if test="beginTime != null and beginTime != ''"> and create_time &gt;= #{beginTime}</if>
            <if test="endTime != null and endTime != ''"> and create_time &lt;= #{endTime}</if>
        </where>
        order by create_time desc
    </select>

    <select id="selectServiceOrderByOrderNo" parameterType="String" resultMap="ServiceOrderResult">
        <include refid="selectServiceOrderVo"/>
        where order_id = #{orderNo}
    </select>

    <insert id="insertServiceOrder" parameterType="com.pm.common.config.PageData">
        insert into device_service_order
        <trim prefix="(" suffix=")" suffixOverrides=",">
            <if test="orderId != null">order_id,</if>
            <if test="alarmId != null">alarm_id,</if>
            <if test="deviceCode != null">device_code,</if>
            <if test="deviceName != null">device_name,</if>
            <if test="orderType != null">order_type,</if>
            <if test="orderTitle != null">order_title,</if>
            <if test="orderContent != null">order_content,</if>
            <if test="priority != null">priority,</if>
            <if test="orderStatus != null">order_status,</if>
            <if test="reporter != null">reporter,</if>
            <if test="reportTime != null">report_time,</if>
            <if test="estimatedDuration != null">estimated_duration,</if>
            <if test="cost != null">cost,</if>
            <if test="remark != null">remark,</if>
            <if test="attachments != null">attachments,</if>
        </trim>
        <trim prefix="values (" suffix=")" suffixOverrides=",">
            <if test="orderId != null">#{orderId},</if>
            <if test="alarmId != null">#{alarmId},</if>
            <if test="deviceCode != null">#{deviceCode},</if>
            <if test="deviceName != null">#{deviceName},</if>
            <if test="orderType != null">#{orderType},</if>
            <if test="orderTitle != null">#{orderTitle},</if>
            <if test="orderContent != null">#{orderContent},</if>
            <if test="priority != null">#{priority},</if>
            <if test="orderStatus != null">#{orderStatus},</if>
            <if test="reporter != null">#{reporter},</if>
            <if test="reportTime != null">#{reportTime},</if>
            <if test="estimatedDuration != null">#{estimatedDuration},</if>
            <if test="cost != null">#{cost},</if>
            <if test="remark != null">#{remark},</if>
            <if test="attachments != null">#{attachments},</if>
        </trim>
    </insert>

    <update id="updateServiceOrder" parameterType="com.pm.common.config.PageData">
        update device_service_order
        <trim prefix="SET" suffixOverrides=",">
            <if test="deviceCode != null">device_code = #{deviceCode},</if>
            <if test="deviceName != null">device_name = #{deviceName},</if>
            <if test="orderType != null">order_type = #{orderType},</if>
            <if test="orderTitle != null">order_title = #{orderTitle},</if>
            <if test="orderContent != null">order_content = #{orderContent},</if>
            <if test="priority != null">priority = #{priority},</if>
            <if test="orderStatus != null">order_status = #{orderStatus},</if>
            <if test="assignee != null">assignee = #{assignee},</if>
            <if test="assignTime != null">assign_time = #{assignTime},</if>
            <if test="handler != null">handler = #{handler},</if>
            <if test="handleTime != null">handle_time = #{handleTime},</if>
            <if test="completeTime != null">complete_time = #{completeTime},</if>
            <if test="estimatedDuration != null">estimated_duration = #{estimatedDuration},</if>
            <if test="actualDuration != null">actual_duration = #{actualDuration},</if>
            <if test="cost != null">cost = #{cost},</if>
            <if test="remark != null">remark = #{remark},</if>
            <if test="attachments != null">attachments = #{attachments},</if>
        </trim>
        where id = #{id}
    </update>

    <delete id="deleteServiceOrderById" parameterType="Long">
        delete from device_service_order where id = #{id}
    </delete>

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

    <update id="assignServiceOrder" parameterType="com.pm.common.config.PageData">
        update device_service_order
        set order_status = 'PROCESSING',
            assignee = #{assignee},
            assign_time = #{assignTime},
            handler = #{handler}
        where order_id = #{orderNo}
          and order_status = 'PENDING'
    </update>

    <update id="acceptServiceOrder" parameterType="com.pm.common.config.PageData">
        update device_service_order
        set handle_time = #{handleTime}
        where order_id = #{orderNo}
          and order_status = 'PROCESSING'
          and handler = #{handler}
    </update>

    <update id="completeServiceOrder" parameterType="com.pm.common.config.PageData">
        update device_service_order
        set order_status = 'COMPLETED',
            complete_time = #{completeTime},
            actual_duration = #{actualDuration},
            remark = #{remark}
        where order_id = #{orderNo}
          and order_status = 'PROCESSING'
    </update>

    <update id="evaluateServiceOrder" parameterType="com.pm.common.config.PageData">
        <!-- 由于表结构中没有评价相关字段，这里只更新备注 -->
        update device_service_order
        set remark = concat(ifnull(remark, ''), ' 评价：', #{evaluateContent})
        where order_id = #{orderNo}
        and order_status = 'COMPLETED'
    </update>

    <update id="closeServiceOrder" parameterType="com.pm.common.config.PageData">
        update device_service_order
        set order_status = 'CANCELLED',
            remark = concat(ifnull(remark, ''), ' 关闭原因：', #{closeReason})
        where order_id = #{orderNo}
    </update>

    <select id="getOrderStatistics" parameterType="com.pm.common.config.PageData" resultType="map">
        select
        count(1) as totalCount,
        sum(case when order_status = 'PENDING' then 1 else 0 end) as pendingCount,
        sum(case when order_status = 'PROCESSING' then 1 else 0 end) as processingCount,
        sum(case when order_status = 'COMPLETED' then 1 else 0 end) as completedCount,
        sum(case when order_status = 'CANCELLED' then 1 else 0 end) as cancelledCount,
        sum(case when priority = 'URGENT' then 1 else 0 end) as urgentCount,
        sum(case when priority = 'HIGH' then 1 else 0 end) as highCount,
        sum(case when priority = 'NORMAL' then 1 else 0 end) as normalCount,
        sum(case when priority = 'LOW' then 1 else 0 end) as lowCount,
        avg(actual_duration) as avgDuration,
        sum(cost) as totalCost
        from device_service_order
        <where>
            <if test="handler != null and handler != ''"> and handler = #{handler}</if>
            <if test="deviceCode != null and deviceCode != ''"> and device_code = #{deviceCode}</if>
            <if test="beginTime != null and beginTime != ''"> and create_time &gt;= #{beginTime}</if>
            <if test="endTime != null and endTime != ''"> and create_time &lt;= #{endTime}</if>
        </where>
    </select>

    <select id="getOrderTrend" parameterType="com.pm.common.config.PageData" resultType="map">
        select
        date_format(create_time, '%Y-%m-%d') as date,
        count(1) as totalCount,
        sum(case when order_status = 'COMPLETED' then 1 else 0 end) as completedCount,
        sum(case when order_status = 'CANCELLED' then 1 else 0 end) as cancelledCount,
        order_type
        from device_service_order
        <where>
            <if test="beginTime != null and beginTime != ''"> and create_time &gt;= #{beginTime}</if>
            <if test="endTime != null and endTime != ''"> and create_time &lt;= #{endTime}</if>
        </where>
        group by date_format(create_time, '%Y-%m-%d'), order_type
        order by date
    </select>

    <select id="selectMyServiceOrderList" parameterType="com.pm.common.config.PageData" resultMap="ServiceOrderResult">
        <include refid="selectServiceOrderVo"/>
        <where>
            and (reporter = #{userId} or handler = #{userId} or assignee = #{userId})
            <if test="orderStatus != null and orderStatus != ''"> and order_status = #{orderStatus}</if>
            <if test="beginTime != null and beginTime != ''"> and create_time &gt;= #{beginTime}</if>
            <if test="endTime != null and endTime != ''"> and create_time &lt;= #{endTime}</if>
        </where>
        order by create_time desc
    </select>

    <insert id="insertOrderOperateRecord" parameterType="com.pm.common.config.PageData">
        <!-- 由于没有单独的操作记录表，这里使用更新备注的方式记录 -->
        update device_service_order
        set remark = concat(ifnull(remark, ''), ' [', #{operateTime}, '] ', #{operateUser}, ': ', #{operateContent})
        where order_id = #{orderNo}
    </insert>

    <select id="selectOrderOperateRecords" parameterType="String" resultType="map">
        <!-- 由于没有单独的操作记录表，返回工单的基本操作信息 -->
        select
        'CREATE' as operateType,
        reporter as operateUser,
        report_time as operateTime,
        '创建工单' as operateContent
        from device_service_order
        where order_id = #{orderNo}
        union all
        select
        'ASSIGN' as operateType,
        assignee as operateUser,
        assign_time as operateTime,
        concat('分配给：', handler) as operateContent
        from device_service_order
        where order_id = #{orderNo} and assign_time is not null
        union all
        select
        'COMPLETE' as operateType,
        handler as operateUser,
        complete_time as operateTime,
        '完成工单' as operateContent
        from device_service_order
        where order_id = #{orderNo} and complete_time is not null
        order by operateTime desc
    </select>

    <update id="updateOrderStatus" parameterType="com.pm.common.config.PageData">
        update device_service_order
        set order_status = #{orderStatus}
        where order_id = #{orderNo}
    </update>

    <select id="selectTimeoutOrders" parameterType="com.pm.common.config.PageData" resultMap="ServiceOrderResult">
        <include refid="selectServiceOrderVo"/>
        where order_status in ('PENDING', 'PROCESSING')
        and estimated_duration is not null
        and timestampdiff(MINUTE, create_time, now()) > estimated_duration
    </select>

    <update id="batchAssignServiceOrders" parameterType="com.pm.common.config.PageData">
        update device_service_order
        set order_status = 'PROCESSING',
        assignee = #{assignee},
        assign_time = #{assignTime},
        handler = #{handler}
        where order_id in
        <foreach item="orderId" collection="orderIds" open="(" separator="," close=")">
            #{orderId}
        </foreach>
        and order_status = 'PENDING'
    </update>

</mapper>