<?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.qmth.themis.business.dao.TOeExamRecordMapper">

    <sql id="invigilatePageHead">
        select t.exam_id          examId,
               tee.name  as       examName,
               t.exam_activity_id examActivityId,
               teea.code as       examActivityCode,
               t.exam_student_id  examStudentId,
               t.id               examRecordId,
        INSERT(rpad(substring(s.identity, 1, 2), char_length(s.identity), '*'),char_length(s.identity)-1,char_length(s.identity),substring(s.identity, char_length(s.identity) - 1 , char_length(s.identity) - 2)) as identity,
        s.room_code roomCode,
        s.room_name roomName,
        s.name name,
        s.course_name courseName,
        s.course_code courseCode,
        IFNULL (t.paper_download ,1) paperDownload,
        t.status statusCode,
        TRUNCATE (t.answer_progress ,2) progress,
        IFNULL (t.client_current_ip ,'无' ) clientCurrentIp,
        IFNULL (t.warning_count ,0) as warningCount,
        IFNULL (t.breach_status ,1) as breachStatus,
        IFNULL (t.client_websocket_status ,'OFF_LINE') as clientWebsocketStatus,
        t.client_last_sync_time as updateTime,
        t.monitor_video_source as monitorVideoSource,
        t.monitor_record as monitorRecord
    </sql>

    <sql id="invigilatePageMiddle">
        from t_e_exam_student s
		left join t_e_exam tee on tee.id = s.exam_id
		left join t_e_exam_activity teea on teea.id = s.exam_activity_id
        left join t_oe_exam_record t on t.id = s.current_record_id
    </sql>

    <select id="invigilatePageListVideo" resultType="com.qmth.themis.business.bean.admin.InvigilateListVideoBean">
        select s.exam_id as examId,
        tee.name as examName,
        s.exam_activity_id as examActivityId,
        teea.code as examActivityCode,
        s.id as examStudentId,
        s.identity,
        s.room_code as roomCode,
        s.room_name as roomName,
        s.name,
        s.course_name as courseName,
        s.course_code as courseCode,
        tes.mobile_number as mobileNumber,
        tes.base_photo_path as basePhotoPath,
        toer.id as examRecordId,
        IFNULL(toer.paper_download,1) as paperDownload,
        toer.status as statusCode,
        TRUNCATE(toer.answer_progress,2) as progress,
        IFNULL(toer.client_current_ip,'无') as clientCurrentIp,
        IFNULL(toer.warning_count,0) as warningCount,
        IFNULL(toer.breach_status,1) as breachStatus,
        IFNULL(toer.client_websocket_status,'OFF_LINE') as clientWebsocketStatus,
        toer.client_last_sync_time as updateTime,
        toer.monitor_video_source as monitorVideoSource,
        toer.monitor_record as monitorRecord,
        toer.finish_type as finishType,
        IFNULL(toer.warning_count,0) as warningNew
        from
        t_e_exam_student s
        left join t_e_exam tee on tee.id = s.exam_id
        left join t_e_exam_activity teea on teea.id = s.exam_activity_id
        left join t_e_student tes on s.student_id = tes.id
        left join t_oe_exam_record toer on toer.id = s.current_record_id
        <if test="markStatus != null and markStatus != '' and markStatus == 'MARK'">
            join t_e_exam_mark_log teeml on teeml.exam_record_id = toer.id and teeml.status = #{markStatus}
        </if>
        WHERE 1 = 1
        <choose>
            <when test="status != null and status != '' and status == 'UN_FINISH'">
                and toer.id is null
            </when>
            <otherwise>
                and toer.id is not null
            </otherwise>
        </choose>
        <if test="orgId != null and orgId != ''">
            and tee.org_id = #{orgId}
        </if>
        <if test="examId != null and examId != ''">
            and s.exam_id = #{examId}
        </if>
        <if test="examActivityId != null and examActivityId != ''">
            and s.exam_activity_id = #{examActivityId}
        </if>
        <if test="roomCodeList != null and roomCodeList != '' and roomCodeList.size > 0">
            and s.room_code in
            <foreach collection="roomCodeList" item="roomCode" index="index" open="(" close=")" separator=",">
                #{roomCode}
            </foreach>
        </if>
        <if test="name != null and name !=''">
            and s.name like CONCAT('%', #{name},'%')
        </if>
        <if test="identity != null and identity !=''">
            and s.identity like CONCAT('%', #{identity},'%')
        </if>
        and teea.finish_time > unix_timestamp(current_timestamp()) * 1000
        <if test="status != null and status != '' and status != 'UN_FINISH'">
            <choose>
                <when test="status == 'EXAMING'">
                    and toer.status in ('ANSWERING','RESUME_PREPARE','BREAK_OFF')
                </when>
                <otherwise>
                    and toer.status = #{status}
                </otherwise>
            </choose>
        </if>
        <if test="maxWarningCount != null and maxWarningCount != '' or maxWarningCount == 0">
            and toer.warning_count &lt;= #{maxWarningCount}
        </if>
        <if test="minWarningCount != null and minWarningCount != '' or minWarningCount == 0">
            and toer.warning_count &gt;= #{minWarningCount}
        </if>
        <if test="clientWebsocketStatus != null and clientWebsocketStatus != ''">
            and toer.client_websocket_status = #{clientWebsocketStatus}
        </if>
        <if test="paperDownload != null and paperDownload != '' or paperDownload == 0">
            and toer.paper_download = #{paperDownload}
        </if>
        <if test="status == null or status == ''">
            and ((toer.status = 'FIRST_PREPARE' and toer.client_websocket_status = 'ON_LINE') or toer.status in
            ('ANSWERING', 'BREAK_OFF', 'RESUME_PREPARE'))
        </if>
        <if test="cameraMonitorStatus != null and cameraMonitorStatus != ''">
            and toer.camera_monitor_status = upper(#{cameraMonitorStatus})
        </if>
        <if test="screenMonitorStatus != null and screenMonitorStatus != ''">
            and toer.screen_monitor_status = upper(#{screenMonitorStatus})
        </if>
        <if test="mobileFirstMonitorStatus != null and mobileFirstMonitorStatus != ''">
            and toer.mobile_first_monitor_status = upper(#{mobileFirstMonitorStatus})
        </if>
        <if test="mobileSecondMonitorStatus != null and mobileSecondMonitorStatus != ''">
            and toer.mobile_second_monitor_status = upper(#{mobileSecondMonitorStatus})
        </if>
        order by s.identity desc
    </select>

    <select id="invigilatePageListVideoRandom" resultType="com.qmth.themis.business.bean.admin.InvigilateListVideoBean">
        <include refid="invigilatePageHead"/>
        <!--,t.monitor_live_url as monitorLiveUrl-->
        ,IFNULL(t.warning_count,0) as warningNew
        <include refid="invigilatePageMiddle"/>
        <where> 1 = 1
            <if test="orgId != null and orgId != ''">
                and tee.org_id = #{orgId}
            </if>
            <if test="examId != null and examId != ''">
                and s.exam_id = #{examId}
            </if>
            <if test="roomCodeList != null and roomCodeList != '' and roomCodeList.size > 0">
                and s.room_code in
                <foreach collection="roomCodeList" item="roomCode" index="index" open="(" close=")" separator=",">
                    #{roomCode}
                </foreach>
            </if>
            and ((t.status = 'FIRST_PREPARE' and t.client_websocket_status = 'ON_LINE') or t.status in ('ANSWERING',
            'BREAK_OFF', 'RESUME_PREPARE'))
        </where>
        ORDER BY RAND() LIMIT #{randomNum}
    </select>

    <select id="invigilatePagePatrolList" resultType="com.qmth.themis.business.bean.admin.InvigilateListPatrolBean">
        select s.exam_id as examId,
        tee.name as examName,
        s.exam_activity_id as examActivityId,
        teea.code as examActivityCode,
        s.id as examStudentId,
        s.identity,
        s.room_code as roomCode,
        s.room_name as roomName,
        s.name,
        s.course_name as courseName,
        s.course_code as courseCode,
        tes.mobile_number as mobileNumber,
        toer.id as examRecordId,
        IFNULL(toer.paper_download,1) as paperDownload,
        toer.status as statusCode,
        TRUNCATE(toer.answer_progress,2) as progress,
        IFNULL(toer.client_current_ip,'无') as clientCurrentIp,
        IFNULL(toer.warning_count,0) as warningCount,
        IFNULL(toer.breach_status,1) as breachStatus,
        IFNULL(toer.client_websocket_status,'OFF_LINE') as clientWebsocketStatus,
        toer.client_last_sync_time as updateTime,
        toer.monitor_video_source as monitorVideoSource,
        toer.monitor_record as monitorRecord,
        toer.finish_type as finishType,
        IFNULL(toer.exception_count,0) as exceptionCount,
        IFNULL(toer.warning_multiple_face_count,0) as multipleFaceCount
        from t_e_exam_student s
        left join t_e_exam tee on tee.id = s.exam_id
        left join t_e_exam_activity teea on teea.id = s.exam_activity_id
        left join t_e_student tes on s.student_id = tes.id
        left join t_oe_exam_record toer on toer.exam_student_id = s.id
        <where> 1 = 1
            <if test="orgId != null and orgId != ''">
                and tee.org_id = #{orgId}
            </if>
            <choose>
                <when test="status != null and status != '' and status == 'UN_FINISH'">
                    and toer.id is null
                </when>
                <otherwise>
                    and toer.id is not null
                </otherwise>
            </choose>
            <if test="examId != null and examId != ''">
                and s.exam_id = #{examId}
            </if>
            <if test="examActivityId != null and examActivityId != ''">
                and s.exam_activity_id = #{examActivityId}
            </if>
            <if test="roomCodeList != null and roomCodeList != '' and roomCodeList.size > 0">
                and s.room_code in
                <foreach collection="roomCodeList" item="roomCode" index="index" open="(" close=")" separator=",">
                    #{roomCode}
                </foreach>
            </if>
            <if test="name != null and name !=''">
                and s.name like CONCAT('%', #{name},'%')
            </if>
            <if test="identity != null and identity !=''">
                and s.identity like CONCAT('%', #{identity},'%')
            </if>
            and teea.finish_time > unix_timestamp(current_timestamp()) * 1000
            <if test="status != null and status != '' and status != 'UN_FINISH'">
                <choose>
                    <when test="status == 'EXAMING'">
                        and toer.status in ('ANSWERING','RESUME_PREPARE','BREAK_OFF')
                    </when>
                    <otherwise>
                        and toer.status = #{status}
                    </otherwise>
                </choose>
            </if>
            <if test="maxWarningCount != null and maxWarningCount != '' or maxWarningCount == 0">
                and toer.warning_count &lt;= #{maxWarningCount}
            </if>
            <if test="minWarningCount != null and minWarningCount != '' or minWarningCount == 0">
                and toer.warning_count &gt;= #{minWarningCount}
            </if>
            <if test="clientWebsocketStatus != null and clientWebsocketStatus != ''">
                and toer.client_websocket_status = #{clientWebsocketStatus}
            </if>
            <if test="status == null or status == ''">
                and toer.status in ('FIRST_PREPARE','ANSWERING','BREAK_OFF','RESUME_PREPARE')
            </if>
            <if test="minMultipleFaceCount != null and minMultipleFaceCount != '' or minMultipleFaceCount == 0">
                and toer.warning_multiple_face_count &gt;= #{minMultipleFaceCount}
            </if>
            <if test="maxMultipleFaceCount != null and maxMultipleFaceCount != '' or maxMultipleFaceCount == 0">
                and toer.warning_multiple_face_count &lt;= #{maxMultipleFaceCount}
            </if>
            <if test="minExceptionCount != null and minExceptionCount != '' or minExceptionCount == 0">
                and toer.exception_count &gt;= #{minExceptionCount}
            </if>
            <if test="maxExceptionCount != null and maxExceptionCount != '' or maxExceptionCount == 0">
                and toer.exception_count &lt;= #{maxExceptionCount}
            </if>
        </where>
        <if test="(examActivityId != null and examActivityId != '') or (roomCodeList != null and roomCodeList != '' and roomCodeList.size > 0)">
            order by CAST(teea.code AS UNSIGNED),CAST(s.room_code AS UNSIGNED)
        </if>
    </select>

    <select id="invigilatePageWarningList" resultType="com.qmth.themis.business.bean.admin.InvigilateListWarningBean">
        select distinct
        tee.id as examId,
        tee.name as examName,
        teea.id as examActivityId,
        tees.id as examStudentId,
        teea.code as examActivityCode,
        tees.room_code as roomCode,
        tees.room_name as roomName,
        toer.id as examRecordId,
        tees.`identity`,
        tees.name,
        tees.course_code as courseCode,
        tees.course_name as courseName,
        toer.status as statusCode,
        IFNULL(toer.warning_count,0) as warningCount,
        IFNULL(toer.breach_status,1) as breachStatus,
        toer.client_last_sync_time as updateTime,
        tiiwi.approve_status as approveStatus,
        IFNULL(toer.exception_count,0) as exceptionCount,
        IFNULL(toer.warning_multiple_face_count,0) as multipleFaceCount
        from t_e_exam_student tees
        left join t_ie_invigilate_warn_info tiiwi on tees.id = tiiwi.exam_student_id
        left join t_e_exam tee on tee.id = tiiwi.exam_id
        left join t_e_exam_activity teea on teea.id = tiiwi.exam_activity_id
        left join t_oe_exam_record toer on toer.id = tiiwi.exam_record_id
        <if test="markStatus != null and markStatus != ''">
            join t_e_exam_mark_log teeml on teeml.exam_record_id = toer.id and teeml.status = #{markStatus}
        </if>
        <where> 1 = 1
            <if test="orgId != null and orgId != ''">
                and tee.org_id = #{orgId}
            </if>
            <if test="examId != null and examId != ''">
                and tees.exam_id = #{examId}
            </if>
            <if test="examActivityId != null and examActivityId != ''">
                and tees.exam_activity_id = #{examActivityId}
            </if>
            <if test="roomCodeList != null and roomCodeList != '' and roomCodeList.size > 0">
                and tees.room_code in
                <foreach collection="roomCodeList" item="roomCode" index="index" open="(" close=")" separator=",">
                    #{roomCode}
                </foreach>
            </if>
            <if test="approveStatus != null and approveStatus != '' or approveStatus == 0">
                and tiiwi.approve_status = #{approveStatus}
            </if>
            <if test="name != null and name !=''">
                and tees.name like CONCAT('%', #{name},'%')
            </if>
            <if test="identity != null and identity !=''">
                and tees.identity like CONCAT('%', #{identity},'%')
            </if>
            <if test="maxWarningCount != null and maxWarningCount != '' or maxWarningCount == 0">
                and toer.warning_count &lt;= #{maxWarningCount}
            </if>
            <if test="minWarningCount != null and minWarningCount != '' or minWarningCount == 0">
                and toer.warning_count &gt;= #{minWarningCount}
            </if>
            <if test="minMultipleFaceCount != null and minMultipleFaceCount != '' or minMultipleFaceCount == 0">
                and toer.warning_multiple_face_count &gt;= #{minMultipleFaceCount}
            </if>
            <if test="maxMultipleFaceCount != null and maxMultipleFaceCount != '' or maxMultipleFaceCount == 0">
                and toer.warning_multiple_face_count &lt;= #{maxMultipleFaceCount}
            </if>
            <if test="minExceptionCount != null and minExceptionCount != '' or minExceptionCount == 0">
                and toer.exception_count &gt;= #{minExceptionCount}
            </if>
            <if test="maxExceptionCount != null and maxExceptionCount != '' or maxExceptionCount == 0">
                and toer.exception_count &lt;= #{maxExceptionCount}
            </if>
            and tee.monitor_status <![CDATA[ <> ]]> 'FINISHED'
        </where>
        order by tiiwi.approve_status
        <if test="(examActivityId != null and examActivityId != '') or (roomCodeList != null and roomCodeList != '' and roomCodeList.size > 0)">
            ,CAST(teea.code AS UNSIGNED),CAST(tees.room_code AS UNSIGNED)
        </if>
    </select>

    <update id="approveStatusListUpdate">
        update t_ie_invigilate_warn_info tiiwi set tiiwi.approve_status = 1
        where exists(
        select t.warningId from(select
        tiiwi.id as warningId
        from t_ie_invigilate_warn_info tiiwi
        left join t_e_exam tee on tee.id = tiiwi.exam_id
        left join t_e_exam_activity teea on teea.id = tiiwi.exam_activity_id
        left join t_oe_exam_record toer on toer.id = tiiwi.exam_record_id
        left join t_e_exam_student tees on tees.id = tiiwi.exam_student_id
        <where> 1 = 1
            <if test="orgId != null and orgId != ''">
                and tee.org_id = #{orgId}
            </if>
            <if test="examId != null and examId != ''">
                and toer.exam_id = #{examId}
            </if>
            <if test="examActivityId != null and examActivityId != ''">
                and toer.exam_activity_id = #{examActivityId}
            </if>
            <if test="roomCodeList != null and roomCodeList != '' and roomCodeList.size > 0">
                and tees.room_code in
                <foreach collection="roomCodeList" item="roomCode" index="index" open="(" close=")" separator=",">
                    #{roomCode}
                </foreach>
            </if>
            <if test="approveStatus != null and approveStatus != '' or approveStatus == 0">
                and tiiwi.approve_status = #{approveStatus}
            </if>
            <if test="name != null and name !=''">
                and tees.name like CONCAT('%', #{name},'%')
            </if>
            <if test="identity != null and identity !=''">
                and tees.identity like CONCAT('%', #{identity},'%')
            </if>
            <if test="maxWarningCount != null and maxWarningCount != '' or maxWarningCount == 0">
                and toer.warning_count &lt;= #{maxWarningCount}
            </if>
            <if test="minWarningCount != null and minWarningCount != '' or minWarningCount == 0">
                and toer.warning_count &gt;= #{minWarningCount}
            </if>
            <if test="minMultipleFaceCount != null and minMultipleFaceCount != '' or minMultipleFaceCount == 0">
                and toer.warning_multiple_face_count &gt;= #{minMultipleFaceCount}
            </if>
            <if test="maxMultipleFaceCount != null and maxMultipleFaceCount != '' or maxMultipleFaceCount == 0">
                and toer.warning_multiple_face_count &lt;= #{maxMultipleFaceCount}
            </if>
            <if test="minExceptionCount != null and minExceptionCount != '' or minExceptionCount == 0">
                and toer.exception_count &gt;= #{minExceptionCount}
            </if>
            <if test="maxExceptionCount != null and maxExceptionCount != '' or maxExceptionCount == 0">
                and toer.exception_count &lt;= #{maxExceptionCount}
            </if>
        </where>
        ) t
        <where>1 = 1
            and t.warningId = tiiwi.id
        </where>)
    </update>

    <select id="invigilatePageProgressList" resultType="com.qmth.themis.business.bean.admin.InvigilateListProgressBean">
        select tee.id as examId,
        tee.name as examName,
        teea.id as examActivityId,
        teea.code as examActivityCode,
        tees.room_code as roomCode,
        tees.room_name as roomName,
        tees.`identity`,
        tees.name,
        tees.course_code as courseCode,
        tees.course_name as courseName,
        if(tee.exam_count - tees.already_exam_count <![CDATA[ < ]]> 0,0,tee.exam_count - tees.already_exam_count) as
        leftExamCount,
        if(tees.already_exam_count > 0,'已完成','未完成') as status,
        t.id as examRecordId,
        IFNULL(IF(t.tencent_video_url is not null, 1, null),( select count(1) from t_m_tencent_video_message tmtvm where
        tmtvm.exam_record_id = t.id)) as videoCount,
        t.monitor_record as monitorRecord,
        t.tencent_video_url as tencentVideoUrl,
        IFNULL(t.breach_status,1) as breachStatus,
        tees.class_no as classNo
        from
        t_e_exam_student tees
        left join t_e_exam tee on tee.id = tees.exam_id
        left join t_e_exam_activity teea on teea.id = tees.exam_activity_id
        left join t_oe_exam_record t on t.exam_student_id = tees.id
        <where> 1 = 1
            <if test="orgId != null and orgId != ''">
                and tee.org_id = #{orgId}
            </if>
            <if test="examId != null and examId != ''">
                and tees.exam_id = #{examId}
            </if>
            <if test="examActivityId != null and examActivityId != ''">
                and tees.exam_activity_id = #{examActivityId}
            </if>
            <if test="roomCodeList != null and roomCodeList != '' and roomCodeList.size > 0">
                and tees.room_code in
                <foreach collection="roomCodeList" item="roomCode" index="index" open="(" close=")" separator=",">
                    #{roomCode}
                </foreach>
            </if>
            <if test="courseCode != null and courseCode != ''">
                and tees.course_code = #{courseCode}
            </if>
            <if test="name != null and name !=''">
                and tees.name like CONCAT('%', #{name},'%')
            </if>
            <if test="identity != null and identity !=''">
                and tees.identity like CONCAT('%', #{identity},'%')
            </if>
            <if test="status != null and status != '' or status == 0">
                <choose>
                    <when test="status == 0">
                        and tees.already_exam_count = 0
                    </when>
                    <otherwise>
                        and tees.already_exam_count <![CDATA[ > ]]> 0
                    </otherwise>
                </choose>
            </if>
            <if test="breachStatus != null and breachStatus != '' or breachStatus == 0">
                <if test="breachStatus == 0">
                    and t.breach_status = #{breachStatus}
                </if>
                <if test="breachStatus == 1">
                    and (t.breach_status = #{breachStatus} or t.breach_status is null)
                </if>
            </if>
            and tee.monitor_status <![CDATA[ <> ]]> 'FINISHED'
        </where>
        <if test="(examActivityId != null and examActivityId != '') or (roomCodeList != null and roomCodeList != '' and roomCodeList.size > 0)">
            order by CAST(teea.code AS UNSIGNED),CAST(tees.room_code AS UNSIGNED)
        </if>
    </select>

    <select id="invigilatePageProgressListExport"
            resultType="com.qmth.themis.business.bean.admin.InvigilateListProgressExcelBean">
        select tee.id as examId,
        tee.name as examName,
        teea.id as examActivityId,
        teea.code as examActivityCode,
        tees.room_name as roomName,
        tees.room_code as roomCode,
        tees.course_name as courseName,
        tees.course_code as courseCode,
        <!--group_concat(tees.room_name,CONCAT(CONCAT('(',tees.room_code),')')) as roomName,-->
        tees.`identity`,
        tees.name,
        <!--group_concat(tees.course_name,CONCAT(CONCAT('(',tees.course_code),')')) as courseName,-->
        if(tee.exam_count - tees.already_exam_count <![CDATA[ < ]]> 0,0,tee.exam_count - tees.already_exam_count) as
        leftExamCount,
        if(tees.already_exam_count > 0,'已完成','未完成') as status,
        if(t.breach_status = 0,'违纪','正常') as breachStatus,
        tees.class_no as classNo
        from t_e_exam_student tees
        left join t_e_exam tee on tee.id = tees.exam_id
        left join t_e_exam_activity teea on teea.id = tees.exam_activity_id
        left join t_oe_exam_record t on t.exam_student_id = tees.id
        <where> 1 = 1
            <if test="orgId != null and orgId != ''">
                and tee.org_id = #{orgId}
            </if>
            <if test="examId != null and examId != ''">
                and tees.exam_id = #{examId}
            </if>
            <if test="examActivityId != null and examActivityId != ''">
                and tees.exam_activity_id = #{examActivityId}
            </if>
            <if test="roomCodeList != null and roomCodeList != '' and roomCodeList.size > 0">
                and tees.room_code in
                <foreach collection="roomCodeList" item="roomCode" index="index" open="(" close=")" separator=",">
                    #{roomCode}
                </foreach>
            </if>
            <if test="courseCode != null and courseCode != ''">
                and tees.course_code = #{courseCode}
            </if>
            <if test="name != null and name !=''">
                and tees.name like CONCAT('%', #{name},'%')
            </if>
            <if test="identity != null and identity !=''">
                and tees.identity like CONCAT('%', #{identity},'%')
            </if>
            <if test="status != null and status != '' or status == 0">
                <choose>
                    <when test="status == 0">
                        and tees.already_exam_count = 0
                    </when>
                    <otherwise>
                        and tees.already_exam_count <![CDATA[ > ]]> 0
                    </otherwise>
                </choose>
            </if>
            <if test="breachStatus != null and breachStatus != '' or breachStatus == 0">
                <if test="breachStatus == 0">
                    and t.breach_status = #{breachStatus}
                </if>
                <if test="breachStatus == 1">
                    and (t.breach_status = #{breachStatus} or t.breach_status is null)
                </if>
            </if>
            and tee.monitor_status <![CDATA[ <> ]]> 'FINISHED'
        </where>
        <if test="(examActivityId != null and examActivityId != '') or (roomCodeList != null and roomCodeList != '' and roomCodeList.size > 0)">
            order by CAST(teea.code AS UNSIGNED),CAST(tees.room_code AS UNSIGNED)
        </if>
    </select>

    <select id="invigilatePageListHistory" resultType="com.qmth.themis.business.bean.admin.InvigilateListHistoryBean">
        <include refid="invigilatePageListHistorySql"/>
        <if test="(examActivityId != null and examActivityId != '') or (roomCodeList != null and roomCodeList != '' and roomCodeList.size > 0)">
            order by CAST(teea.code AS UNSIGNED),CAST(s.room_code AS UNSIGNED)
        </if>
    </select>

    <sql id="invigilatePageListHistorySql">
        select s.exam_id as examId,
        tee.name as examName,
        s.exam_activity_id as examActivityId,
        teea.code as examActivityCode,
        s.id as examStudentId,
        s.identity,
        s.room_code as roomCode,
        s.room_name as roomName,
        s.name,
        s.course_name as courseName,
        s.course_code as courseCode,
        tes.mobile_number as mobileNumber,
        toer.id as examRecordId,
        IFNULL(toer.paper_download,1) as paperDownload,
        toer.status as statusCode,
        TRUNCATE(toer.answer_progress,2) as progress,
        IFNULL(toer.client_current_ip,'无') as clientCurrentIp,
        IFNULL(toer.warning_count,0) as warningCount,
        IFNULL(toer.breach_status,1) as breachStatus,
        IFNULL(toer.client_websocket_status,'OFF_LINE') as clientWebsocketStatus,
        toer.client_last_sync_time as updateTime,
        toer.monitor_video_source as monitorVideoSource,
        toer.monitor_record as monitorRecord,
        toer.finish_type as finishType,
        s.class_no as classNo,
        IFNULL(toer.exception_count,0) as exceptionCount,
        IFNULL(toer.warning_multiple_face_count,0) as multipleFaceCount
        from t_e_exam_student s
        left join t_e_exam tee on tee.id = s.exam_id
        left join t_e_exam_activity teea on teea.id = s.exam_activity_id
        left join t_e_student tes on s.student_id = tes.id
        left join t_oe_exam_record toer on toer.exam_student_id = s.id
        <where> 1 = 1
            <choose>
                <when test="status != null and status != '' and status == 'UN_FINISH'">
                    and toer.id is null
                </when>
                <otherwise>
                    and toer.id is not null
                </otherwise>
            </choose>
            <if test="orgId != null and orgId != ''">
                and tee.org_id = #{orgId}
            </if>
            <if test="examId != null and examId != ''">
                and s.exam_id = #{examId}
            </if>
            <if test="examActivityId != null and examActivityId != ''">
                and s.exam_activity_id = #{examActivityId}
            </if>
            <if test="roomCodeList != null and roomCodeList != '' and roomCodeList.size > 0">
                and s.room_code in
                <foreach collection="roomCodeList" item="roomCode" index="index" open="(" close=")" separator=",">
                    #{roomCode}
                </foreach>
            </if>
            <if test="name != null and name !=''">
                and s.name like CONCAT('%', #{name},'%')
            </if>
            <if test="identity != null and identity !=''">
                and s.identity like CONCAT('%', #{identity},'%')
            </if>
            <if test="courseCode != null and courseCode != ''">
                and s.course_code = #{courseCode}
            </if>
            <choose>
                <when test="status == null">
                    and toer.status <![CDATA[ <> ]]> 'JUNK'
                </when>
                <when test="status != null and status != '' and status != 'UN_FINISH'">
                    <choose>
                        <when test="status == 'EXAMING'">
                            and toer.status in ('ANSWERING','RESUME_PREPARE','BREAK_OFF')
                        </when>
                        <otherwise>
                            and toer.status = #{status}
                        </otherwise>
                    </choose>
                </when>
            </choose>
            <if test="maxWarningCount != null and maxWarningCount != '' or maxWarningCount == 0">
                and toer.warning_count &lt;= #{maxWarningCount}
            </if>
            <if test="minWarningCount != null and minWarningCount != '' or minWarningCount == 0">
                and toer.warning_count &gt;= #{minWarningCount}
            </if>
            <if test="breachStatus != null and breachStatus != '' or breachStatus == 0">
                <if test="breachStatus == 0">
                    and toer.breach_status = #{breachStatus}
                </if>
                <if test="breachStatus == 1">
                    and (toer.breach_status = #{breachStatus} or toer.breach_status is null)
                </if>
            </if>
            <if test="finishType != null and finishType != ''">
                <choose>
                    <when test="finishType == 'ALL'">
                        and toer.finish_type in ('MANUAL','AUTO','BREACH','INTERRUPT')
                    </when>
                    <otherwise>
                        and toer.finish_type = #{finishType}
                    </otherwise>
                </choose>
            </if>
            <if test="minMultipleFaceCount != null and minMultipleFaceCount != '' or minMultipleFaceCount == 0">
                and toer.warning_multiple_face_count &gt;= #{minMultipleFaceCount}
            </if>
            <if test="maxMultipleFaceCount != null and maxMultipleFaceCount != '' or maxMultipleFaceCount == 0">
                and toer.warning_multiple_face_count &lt;= #{maxMultipleFaceCount}
            </if>
            <if test="minExceptionCount != null and minExceptionCount != '' or minExceptionCount == 0">
                and toer.exception_count &gt;= #{minExceptionCount}
            </if>
            <if test="maxExceptionCount != null and maxExceptionCount != '' or maxExceptionCount == 0">
                and toer.exception_count &lt;= #{maxExceptionCount}
            </if>
        </where>
    </sql>

    <select id="invigilatePageListHistoryExport"
            resultType="com.qmth.themis.business.bean.admin.InvigilateListHistoryBean">
        <include refid="invigilatePageListHistorySql"/>
        <if test="(examActivityId != null and examActivityId != '') or (roomCodeList != null and roomCodeList != '' and roomCodeList.size > 0)">
            order by CAST(teea.code AS UNSIGNED),CAST(s.room_code AS UNSIGNED)
        </if>
    </select>

    <select id="getDoneCountByDay" resultType="java.util.Map">
        select
        FROM_UNIXTIME(f.first_prepare_time / 1000,'%Y-%m-%d') AS day,
        count(DISTINCT(f.exam_student_id)) count from t_oe_exam_record f
        left join t_e_exam_student t on f.exam_student_id=t.id
        left join t_e_student h on t.student_id=h.id
        where f.exam_id = #{examId}
        <if test="orgId != null and orgId != ''">
            and h.org_id=#{orgId}
        </if>
        <if test="activityId != null and activityId != ''">
            and f.exam_activity_id = #{activityId}
        </if>
        <if test="roomCode != null and roomCode != ''">
            and t.room_code =#{roomCode}
        </if>
        <if test="courseCode != null and courseCode != ''">
            and t.course_code = #{courseCode}
        </if>
        group by day
        ORDER BY day
    </select>

    <select id="getCountByExamId" resultType="java.lang.Long">
        select count(1)
        from t_oe_exam_record f
        where f.exam_id = #{examId}
    </select>

    <select id="findOneByExamId" resultType="com.qmth.themis.business.entity.TOeExamRecord">
        select f.* from t_oe_exam_record f
        <where>
            <if test="examId != null and examId != ''">
                and f.exam_id = #{examId}
            </if>
            <if test="status != null and status != ''">
                and f.status = #{status}
            </if>
        </where>
        limit 1
    </select>

    <select id="getListByExamIdAndStartId" resultType="com.qmth.themis.business.entity.TOeExamRecord">
        select f.*
        from t_oe_exam_record f
        where f.exam_id = #{examId}
          and f.id > #{startId}
        order by f.id limit 500
    </select>

    <update id="updateObjectiveScore">
        update t_oe_exam_record t
        set t.objective_score=#{score}
        where t.id = #{recordId}
    </update>

    <select id="findOneByPaperId" resultType="com.qmth.themis.business.entity.TOeExamRecord">
        select f.*
        from t_oe_exam_record f
        where f.paper_id = #{paperId} limit 1
    </select>

    <select id="patrolReport" resultType="com.qmth.themis.business.bean.admin.InvigilateListPatrolReportBean">
        select
        s.room_code roomCode, s.room_name roomName, sum(IFNULL(t.warning_count, 0)) as warningCount,
        count((t.client_websocket_status = 'OFF_LINE' or t.client_websocket_status is null) or null) as
        clientWebsocketStatusCount
        from
        t_oe_exam_record t
        left join t_e_exam_student s on
        t.exam_student_id = s.id
        left join t_e_exam tee on
        tee.id = t.exam_id
        left join t_e_exam_activity teea on
        teea.id = t.exam_activity_id
        <if test="userId != null and userId != ''">
            left join t_b_exam_invigilate_user tbeiu on tbeiu.exam_id = t.exam_id
        </if>
        <where>
            <if test="examId != null and examId != ''">
                and t.exam_id = #{examId}
            </if>
            <if test="userId != null and userId != ''">
                and tbeiu.user_id = #{userId}
            </if>
            and t.STATUS in ('FIRST_PREPARE','ANSWERING','BREAK_OFF','RESUME_PREPARE')
        </where>
        group by s.room_code,s.room_name
        order by s.room_code
    </select>

    <select id="getOnlineCount" resultType="java.lang.Long">
        select count(1) from t_oe_exam_record f
        left join t_e_exam h on f.exam_id=h.id
        where f.client_websocket_status='ON_LINE'
        <if test="orgId != null and orgId != ''">
            and h.org_id=#{orgId}
        </if>
    </select>

    <select id="getExceptionCount" resultType="java.lang.Long">
        SELECT
        count(DISTINCT(f.id))
        FROM
        t_oe_exam_record f
        LEFT JOIN t_ie_invigilate_exception_info t ON f.id = t.exam_record_id
        left join t_e_exam h on f.exam_id=h.id
        WHERE 1 = 1
        <if test="orgId != null and orgId != ''">
            and h.org_id=#{orgId}
        </if>
        and f.STATUS in ('FIRST_PREPARE','ANSWERING','BREAK_OFF','RESUME_PREPARE')
        AND t.id IS NOT NULL
    </select>

    <select id="getWarnCount" resultType="java.lang.Long">
        SELECT
        count(f.id)
        FROM
        t_oe_exam_record f
        LEFT JOIN t_ie_invigilate_warn_info t ON f.id = t.exam_record_id
        left join t_e_exam h on f.exam_id=h.id
        WHERE 1 = 1
        <if test="orgId != null and orgId != ''">
            and h.org_id=#{orgId}
        </if>
        and h.monitor_status <![CDATA[ <> ]]> 'FINISHED'
        and f.STATUS in ('FIRST_PREPARE','ANSWERING','BREAK_OFF','RESUME_PREPARE')
        AND t.type!='NONE'
        AND t.id IS NOT NULL
    </select>

    <select id="getBreachCount" resultType="java.lang.Long">
        SELECT
        count(f.id)
        FROM
        t_oe_exam_record f
        LEFT JOIN t_e_exam_breach_log t ON f.id = t.exam_record_id
        left join t_e_exam h on f.exam_id=h.id
        WHERE 1 = 1
        <if test="orgId != null and orgId != ''">
            and h.org_id=#{orgId}
        </if>
        and h.monitor_status <![CDATA[ <> ]]> 'FINISHED'
        and f.STATUS in ('FIRST_PREPARE','ANSWERING','BREAK_OFF','RESUME_PREPARE')
        AND t.status = 0
        AND t.id IS NOT NULL
    </select>

    <select id="getWarnDistribution"
            resultType="com.qmth.themis.business.bean.admin.ExaminationMonitorWarnDistributionBean">
        select
        if(tiiwi.info is not null,substring_index(substring_index(tiiwi.info,'】',1),'【',-1),null) as type,
        count(tiiwi.exam_record_id) as warnCount
        from
        t_ie_invigilate_warn_info tiiwi
        join t_oe_exam_record toer on tiiwi.exam_record_id = toer.id
        join t_e_exam tee on toer.exam_id = tee.id
        WHERE 1 = 1
        <if test="orgId != null and orgId != ''">
            and tee.org_id = #{orgId}
        </if>
        and tee.monitor_status <![CDATA[ <> ]]> 'FINISHED'
        and toer.STATUS in ('FIRST_PREPARE','ANSWERING','BREAK_OFF','RESUME_PREPARE')
        group by
        tiiwi.`info`
    </select>

    <select id="getWarnRegionDistribution"
            resultType="com.qmth.themis.business.bean.admin.ExaminationMonitorWarnRegionDistributionBean">
        select
        tir.country,
        tir.province,
        count(tiiwi.exam_record_id) as warnCount
        from
        t_ip_region tir
        join t_oe_exam_record toer on
        tir.exam_record_id = toer.id
        left join t_ie_invigilate_warn_info tiiwi on
        tiiwi.exam_record_id = toer.id
        join t_e_exam tee on toer.exam_id = tee.id
        WHERE 1 = 1
        <if test="orgId != null and orgId != ''">
            and tee.org_id = #{orgId}
        </if>
        and tee.monitor_status <![CDATA[ <> ]]> 'FINISHED'
        and toer.STATUS in ('FIRST_PREPARE','ANSWERING','BREAK_OFF','RESUME_PREPARE')
        and tir.country != '0' and tir.province != '0'
        group by
        tir.country,
        tir.province
    </select>

    <select id="getMap" resultType="com.qmth.themis.business.bean.admin.ExaminationMonitorMapBean">
        select
        t.country,
        t.province,
        sum(t.onlineCount) as onlineCount,
        sum(t.warnCount) as warnCount
        from
        (
        select
        tir.country,
        tir.province,
        count(toer.id) as onlineCount,
        0 as warnCount
        from
        t_ip_region tir
        join t_oe_exam_record toer on
        tir.exam_record_id = toer.id
        join t_e_exam tee on
        toer.exam_id = tee.id
        WHERE 1 = 1
        <if test="orgId != null and orgId != ''">
            and tee.org_id = #{orgId}
        </if>
        and tee.monitor_status <![CDATA[ <> ]]> 'FINISHED'
        and toer.client_websocket_status = 'ON_LINE'
        and toer.STATUS in ('FIRST_PREPARE','ANSWERING','BREAK_OFF','RESUME_PREPARE')
        and tir.country != '0' and tir.province != '0'
        group by
        tir.country,
        tir.province
        union all
        select
        tir.country,
        tir.province,
        0 as onlineCount,
        count(tiiwi.exam_record_id) as warnCount
        from
        t_ip_region tir
        join t_oe_exam_record toer on
        tir.exam_record_id = toer.id
        left join t_ie_invigilate_warn_info tiiwi on
        tiiwi.exam_record_id = tir.exam_record_id
        join t_e_exam tee on
        toer.exam_id = tee.id
        WHERE 1 = 1
        <if test="orgId != null and orgId != ''">
            and tee.org_id = #{orgId}
        </if>
        and tee.monitor_status <![CDATA[ <> ]]> 'FINISHED'
        and toer.STATUS in ('FIRST_PREPARE','ANSWERING','BREAK_OFF','RESUME_PREPARE')
        and tir.country != '0' and tir.province != '0'
        group by
        tir.country,
        tir.province) t
        group by
        t.country,
        t.province
    </select>

    <select id="getWarnTrend" resultType="com.qmth.themis.business.bean.result.TimeScaleDataResult">
        select
        t.hour,
        sum(t.warnCount) as warnCount
        from
        (
        <foreach collection="timeData" item="item" index="index">
            <choose>
                <when test="index == 0">
                    <include refid="getWarnTrendCommon"/>
                </when>
                <otherwise>
                    union all
                    <include refid="getWarnTrendCommon"/>
                </otherwise>
            </choose>
        </foreach>
        ) t
        group by
        t.hour
        order by
        t.hour
    </select>

    <update id="updateHasAnswerFile">
        update t_oe_exam_record t
        set t.has_answer_file=#{hasAnswerFile}
        where t.id = #{recordId}
    </update>

    <select id="findExamRecordNeedMark" resultType="com.qmth.themis.business.bean.admin.OpenRecordNeedMarkBean">
        SELECT t.id                                      as id,
               t.paper_id                                as paperId,
               cast(t.objective_score as DECIMAL(10, 2)) as objectiveScore,
               t.finish_time                             as finishTime
        FROM t_oe_exam_record t
        where t.exam_student_id = #{examStudentId}
          and t.finish_time is not null
          and (t.breach_status is null or t.breach_status = 1)
    </select>

    <select id="findMaxObjectiveScore" resultType="com.qmth.themis.business.entity.TOeExamRecord">
        select
        cast(max(toer.objective_score) as DECIMAL(10,2)) as objectiveScore,
        toer.id,toer.paper_id as paperId,toer.finish_time as finishTime,toer.first_start_time as firstStartTime
        from
        t_oe_exam_record toer
        <where>1 = 1
            <if test="examStudentBreachPush != null and (examStudentBreachPush == false or examStudentBreachPush == 0)">
                and (toer.breach_status = 1 or breach_status is null)
            </if>
            and toer.status in ('FINISHED','PERSISTED')
            <if test="examId != null and examId != ''">
                and toer.exam_id = #{examId}
            </if>
            <if test="examStudentId != null and examStudentId != ''">
                and toer.exam_student_id = #{examStudentId}
            </if>
        </where>
        group by
        toer.id,toer.paper_id,toer.finish_time order by toer.objective_score desc,toer.finish_time desc
    </select>

    <select id="findByOrgId" resultType="java.lang.Long">
        select count(1) as c
        from t_oe_exam_record toer
                 join t_e_exam tee on tee.id = toer.exam_id
        where 1 = 1
          and tee.org_id = #{orgId}
          and tee.monitor_status <![CDATA[ <> ]]> 'FINISHED'
          and toer.STATUS in ('FIRST_PREPARE', 'ANSWERING', 'BREAK_OFF', 'RESUME_PREPARE')
          and toer.client_websocket_status = 'ON_LINE'
        union all
        select count(1) as c
        from t_oe_exam_record toer
                 join t_e_exam tee on tee.id = toer.exam_id
        where 1 = 1
          and tee.org_id = #{orgId}
          and tee.monitor_status <![CDATA[ <> ]]> 'FINISHED'
          and toer.STATUS = 'FIRST_PREPARE'
          and toer.client_websocket_status = 'ON_LINE'
        union all
        select count(1) as c
        from t_oe_exam_record toer
                 join t_e_exam tee on tee.id = toer.exam_id
        where 1 = 1
          and tee.org_id = #{orgId}
          and toer.exam_id = tee.id
          and tee.monitor_status <![CDATA[ <> ]]> 'FINISHED'
          and toer.STATUS = 'ANSWERING'
          and toer.client_websocket_status = 'ON_LINE'
    </select>

    <select id="findByStopInfo" resultType="com.qmth.themis.business.bean.admin.CountStopBean">
        <!--select
        sum(t.clientWebsocketStatusOffCount) as offCount,
        sum(t.cameraMonitorStatusStop + t.screenMonitorStatusStop + t.mobileFirstMonitorStatusStop +
        t.mobileSecondMonitorStatusStop) as stopCount,
        sum(t.allCount) as allCount
        from
        (select
        count((t.client_websocket_status = 'OFF_LINE' or t.client_websocket_status is null) or null) as
        clientWebsocketStatusOffCount,
        count(t.client_websocket_status = 'ON_LINE') as clientWebsocketStatusOnCount,
        count(t.camera_monitor_status = 'STOP') as cameraMonitorStatusStop,
        count(t.screen_monitor_status = 'STOP') as screenMonitorStatusStop,
        count(t.mobile_first_monitor_status = 'STOP') as mobileFirstMonitorStatusStop,
        count(t.mobile_second_monitor_status = 'STOP') as mobileSecondMonitorStatusStop,
        0 as allCount
        from
        t_oe_exam_record t
        left join t_e_exam_student s on
        t.exam_student_id = s.id
        <where>
            t.exam_id = #{examId}
            and s.room_code in
            <foreach collection="roomCodeSet" item="roomCode" index="index" open="(" close=")" separator=",">
                #{roomCode}
            </foreach>
            <if test="examActivityId != null and examActivityId != ''">
                and t.exam_activity_id = #{examActivityId}
            </if>
            and t.STATUS in ('FIRST_PREPARE','ANSWERING','BREAK_OFF','RESUME_PREPARE')
        </where>
        UNION all-->
        select
        <!--0 as clientWebsocketStatusOffCount,
        0 as clientWebsocketStatusOnCount,
        0 as cameraMonitorStatusStop,
        0 as screenMonitorStatusStop,
        0 as mobileFirstMonitorStatusStop,
        0 as mobileSecondMonitorStatusStop,-->
        count(1) as allCount
        from
        t_e_exam_student t
        <where>
            t.exam_id = #{examId}
            and t.room_code in
            <foreach collection="roomCodeSet" item="roomCode" index="index" open="(" close=")" separator=",">
                #{roomCode}
            </foreach>
            <if test="examActivityId != null and examActivityId != ''">
                and t.exam_activity_id = #{examActivityId}
            </if>
        </where>
        <!--) t-->
    </select>

    <select id="findByOnlineInfo" resultType="java.lang.Integer">
        select
        count(1) as c
        from
        t_oe_exam_record t
        left join t_e_exam_student s on
        t.exam_student_id = s.id
        <where>
            t.exam_id = #{examId}
            and s.room_code in
            <foreach collection="roomCodeSet" item="roomCode" index="index" open="(" close=")" separator=",">
                #{roomCode}
            </foreach>
            <if test="examActivityId != null and examActivityId != ''">
                and t.exam_activity_id = #{examActivityId}
            </if>
            and t.STATUS = 'FIRST_PREPARE'
        </where>
        union all
        select
        count(1) as c
        from
        t_oe_exam_record t
        left join t_e_exam_student s on
        t.exam_student_id = s.id
        <where>
            t.exam_id = #{examId}
            and s.room_code in
            <foreach collection="roomCodeSet" item="roomCode" index="index" open="(" close=")" separator=",">
                #{roomCode}
            </foreach>
            <if test="examActivityId != null and examActivityId != ''">
                and t.exam_activity_id = #{examActivityId}
            </if>
            and ((t.STATUS = 'ANSWERING' and t.client_websocket_status = 'ON_LINE')
            or t.STATUS in ('RESUME_PREPARE','BREAK_OFF'))
        </where>
        union all
        select
        count(distinct t.exam_student_id) as c
        from
        t_oe_exam_record t
        left join t_e_exam_student s on
        t.exam_student_id = s.id
        <where>
            t.exam_id = #{examId}
            and s.room_code in
            <foreach collection="roomCodeSet" item="roomCode" index="index" open="(" close=")" separator=",">
                #{roomCode}
            </foreach>
            <if test="examActivityId != null and examActivityId != ''">
                and t.exam_activity_id = #{examActivityId}
            </if>
            and t.STATUS in ('FINISHED','PERSISTED') and t.first_start_time is not null
        </where>
    </select>

    <select id="findByViewAdmin" resultType="java.lang.Integer">
        select
        count(1) as c
        from
        t_e_exam_student tees
        where 1 = 1
        <if test="examId != null and examId != ''">
            and tees.exam_id = #{examId}
        </if>
        <if test="examActivityId != null and examActivityId != ''">
            and tees.exam_activity_id = #{examActivityId}
        </if>
        <if test="roomCode != null and roomCode != ''">
            and tees.room_code = #{roomCode}
        </if>
        <if test="courseCode != null and courseCode != ''">
            and tees.course_code = #{courseCode}
        </if>
        union all
        select
        count(distinct toer.exam_student_id) as c
        from
        t_oe_exam_record toer
        where 1 = 1
        <if test="examId != null and examId != ''">
            and toer.exam_id = #{examId}
        </if>
        and exists (select
        tees.id
        from
        t_e_exam_student tees
        where 1 = 1
        <if test="examId != null and examId != ''">
            and tees.exam_id = #{examId}
        </if>
        <if test="examActivityId != null and examActivityId != ''">
            and tees.exam_activity_id = #{examActivityId}
        </if>
        <if test="roomCode != null and roomCode != ''">
            and tees.room_code = #{roomCode}
        </if>
        <if test="courseCode != null and courseCode != ''">
            and tees.course_code = #{courseCode}
        </if>
        and toer.exam_student_id = tees.id
        )
        <if test="monitorStatus != null and monitorStatus != '' and monitorStatus == 'FINISHED'">
            and toer.first_start_time is not null
        </if>
        union all
        select
        count(1)
        from
        t_e_exam_student tees
        join t_e_exam tee on
        tees.exam_id = tee.id
        where
        NOT EXISTS(
        select
        toer.exam_student_id
        from
        t_oe_exam_record toer
        where
        tees.id = toer.exam_student_id)
        <if test="orgId != null and orgId != ''">
            and tee.org_id = #{orgId}
        </if>
        <if test="examId != null and examId != ''">
            and tees.exam_id = #{examId}
        </if>
        <if test="examActivityId != null and examActivityId != ''">
            and tees.exam_activity_id = #{examActivityId}
        </if>
        <if test="roomCode != null and roomCode != ''">
            and tees.room_code = #{roomCode}
        </if>
        <if test="courseCode != null and courseCode != ''">
            and tees.course_code = #{courseCode}
        </if>
    </select>

    <select id="examRecordDetailQuery" resultType="com.qmth.themis.business.cache.bean.ExamRecordDetailBean">
        select
        toer.id as examRecordId,
        tee.id as examId,
        tee.name,
        teea.code,
        teea.id as examActivityId,
        tees.name as examStudentName,
        tees.`identity`,
        tees.course_code as courseCode,
        tees.course_name as courseName,
        tees.room_code as roomCode,
        tees.room_name as roomName,
        toer.first_start_time as firstStartTime,
        toer.finish_time as finishTime,
        toer.finish_type as finishType
        from t_oe_exam_record toer
        join t_e_exam tee on tee.id = toer.exam_id
        join t_e_exam_activity teea on teea.exam_id = toer.exam_id and teea.id = toer.exam_activity_id
        join t_e_exam_student tees on tees.exam_id = toer.exam_id and tees.exam_activity_id = toer.exam_activity_id and
        tees.id = toer.exam_student_id
        <where>
            toer.first_start_time is not null
            <if test="examId != null and examId != ''">
                and toer.exam_id = #{examId}
            </if>
            <if test="examActivityId != null and examActivityId != ''">
                and teea.id = #{examActivityId}
            </if>
            <if test="courseCode != null and courseCode != ''">
                and tees.course_code = #{courseCode}
            </if>
            <if test="roomCode != null and roomCode != ''">
                and tees.room_code = #{roomCode}
            </if>
            <if test="finishType != null and finishType != ''">
                <choose>
                    <when test="finishType == 'ALL'">
                        and toer.finish_type in ('MANUAL','AUTO','BREACH','INTERRUPT')
                    </when>
                    <otherwise>
                        and toer.finish_type = #{finishType}
                    </otherwise>
                </choose>
            </if>
            <if test="name != null and name !=''">
                and tees.name like CONCAT('%', #{name},'%')
            </if>
            <if test="identity != null and identity !=''">
                and tees.identity like CONCAT('%', #{identity},'%')
            </if>
        </where>
        <if test="(examActivityId != null and examActivityId != '') or (roomCode != null and roomCode != '')">
            order by CAST(teea.code AS UNSIGNED),CAST(tees.room_code AS UNSIGNED)
        </if>
    </select>

    <select id="examRecordDetailListQuery" resultType="java.lang.String">
        select
        toer.id as examRecordId
        from t_oe_exam_record toer
        join t_e_exam tee on tee.id = toer.exam_id
        join t_e_exam_activity teea on teea.exam_id = toer.exam_id and teea.id = toer.exam_activity_id
        join t_e_exam_student tees on tees.exam_id = toer.exam_id and tees.exam_activity_id = toer.exam_activity_id and
        tees.id = toer.exam_student_id
        <where>
            toer.first_start_time is not null
            <if test="examId != null and examId != ''">
                and toer.exam_id = #{examId}
            </if>
            <if test="courseCodeList != null and courseCodeList != '' and courseCodeList.size > 0">
                and tees.course_code in
                <foreach collection="courseCodeList" item="courseCode" index="index" open="(" close=")" separator=",">
                    #{courseCode}
                </foreach>
            </if>
            <if test="identityList != null and identityList != '' and identityList.size > 0">
                and tees.identity in
                <foreach collection="identityList" item="identity" index="index" open="(" close=")" separator=",">
                    #{identity}
                </foreach>
            </if>
        </where>
        order by tees.id
    </select>

    <select id="getTimeScale" resultType="java.util.Map">
        select
        <foreach collection="timeSize" item="item" index="index" separator=",">
            DATE_FORMAT(date_sub(#{currentDate}, interval #{item} minute),'%Y-%m-%d %H:%i:00') as '${item}'
        </foreach>
    </select>

    <sql id="getWarnTrendCommon">
        select
        t.hour,
        count(t.examRecordId) as warnCount
        from
        (
        select
        DATE_FORMAT(#{item}, '%H:%i') as hour,
        date_add(#{item}, interval #{interval} minute) as minute,
        tiiwi.exam_record_id as examRecordId,
        DATE_FORMAT(FROM_UNIXTIME(tiiwi.create_time / 1000), '%Y-%m-%d %H:%i:00') as createTime
        from
        t_oe_exam_record toer
        join t_ie_invigilate_warn_info tiiwi on
        tiiwi.exam_record_id = toer.id
        join t_e_exam tee on toer.exam_id = tee.id
        WHERE 1 = 1
        <if test="orgId != null and orgId != ''">
            and tee.org_id = #{orgId}
        </if>
        and (tiiwi.create_time <![CDATA[ >= ]]> #{minusTime}
        and tiiwi.create_time <![CDATA[ <= ]]> #{currentTime})) t
        where
        (t.createTime <![CDATA[ >= ]]> #{item} and t.createTime <![CDATA[ < ]]> t.minute)
    </sql>

    <select id="getTimeOnlineData" resultType="com.qmth.themis.business.bean.result.TimeOnlineDataResult">
        select
        t.hour,
        sum(t.onlineCount) as onlineCount,
        sum(t.offlineCount) as offlineCount
        from
        (
        <foreach collection="timeData" item="item" index="index">
            <choose>
                <when test="index == 0">
                    <include refid="getTimeOnlineDataCommon"/>
                </when>
                <otherwise>
                    union all
                    <include refid="getTimeOnlineDataCommon"/>
                </otherwise>
            </choose>
        </foreach>
        ) t
        group by
        t.hour
        order by
        t.hour
    </select>

    <sql id="getTimeOnlineDataCommon">
        select
        t.hour,
        count(t.examRecordId) as onlineCount,
        0 as offlineCount
        from
        (
        select
        DATE_FORMAT(#{item}, '%H:%i') as hour,
        teesol.exam_record_id as examRecordId,
        DATE_FORMAT(FROM_UNIXTIME(teesol.create_time / 1000), '%Y-%m-%d %H:%i:00') as createTime
        from
        t_e_exam_student_online_log teesol
        join t_oe_exam_record toer on
        toer.id = teesol.exam_record_id
        join t_e_exam tee on
        toer.exam_id = tee.id
        where 1 = 1
        <if test="orgId != null and orgId != ''">
            and tee.org_id = #{orgId}
        </if>
        and tee.monitor_status <![CDATA[ <> ]]> 'FINISHED'
        and (teesol.create_time <![CDATA[ >= ]]> #{minusTime}
        and teesol.create_time <![CDATA[ <= ]]> #{currentTime})
        and teesol.`type` = 'ON_LINE') t where t.createTime <![CDATA[ <= ]]> #{item}
        union all
        select
        t.hour,
        0 as onlineCount,
        count(t.examRecordId) as offlineCount
        from
        (
        select
        DATE_FORMAT(#{item}, '%H:%i') as hour,
        teesol.exam_record_id as examRecordId,
        DATE_FORMAT(FROM_UNIXTIME(teesol.create_time / 1000), '%Y-%m-%d %H:%i:00') as createTime
        from
        t_e_exam_student_online_log teesol
        join t_oe_exam_record toer on
        toer.id = teesol.exam_record_id
        join t_e_exam tee on
        toer.exam_id = tee.id
        where 1 = 1
        <if test="orgId != null and orgId != ''">
            and tee.org_id = #{orgId}
        </if>
        and tee.monitor_status <![CDATA[ <> ]]> 'FINISHED'
        and (teesol.create_time <![CDATA[ >= ]]> #{minusTime}
        and teesol.create_time <![CDATA[ <= ]]> #{currentTime})
        and teesol.`type` = 'OFF_LINE') t where t.createTime <![CDATA[ <= ]]> #{item}
    </sql>

    <select id="findExamRecordByNotVideoUrl" resultType="com.qmth.themis.business.entity.TOeExamRecord">
        select toer.*
        from t_oe_exam_record toer
        where not EXISTS(
                select tmtvm.exam_record_id
                from t_m_tencent_video_message tmtvm
                where tmtvm.exam_record_id = toer.id
            )
          and toer.exam_id = #{examId}
    </select>

    <select id="findExamRecordByExamIdAndExamActivityId" resultType="com.qmth.themis.business.entity.TOeExamRecord">
        select *
        from t_oe_exam_record toer
        where toer.exam_id = #{examId}
          and toer.exam_activity_id = #{examActivityId}
          and toer.status in ('FIRST_PREPARE', 'ANSWERING', 'BREAK_OFF', 'RESUME_PREPARE')
    </select>

    <select id="findByExamIdOrExamActivityIdCount" resultType="java.lang.Integer">
        select count(1) from t_oe_exam_record toer
        <where>
            <if test="examId != null and examId != ''">
                and toer.exam_id = #{examId}
            </if>
            <if test="examActivityId != null and examActivityId != ''">
                and toer.exam_activity_id = #{examActivityId}
            </if>
            and toer.status in ('FIRST_PREPARE','ANSWERING','BREAK_OFF','RESUME_PREPARE')
        </where>
    </select>

    <select id="findExamRecordNeedMarkAll" resultType="com.qmth.themis.business.entity.TOeExamRecord">
        select
        t1.*
        from
        (
        select
        t.exam_student_id
        from
        t_oe_exam_record t
        where
        exists(
        select
        tees.id
        from
        t_e_exam_student tees
        join t_oe_exam_record toer on
        toer.exam_id = tees.exam_id
        and toer.exam_activity_id = tees.exam_activity_id
        and toer.exam_student_id = tees.id
        <where>
            <if test="examId != null and examId != ''">
                and tees.exam_id = #{examId}
            </if>
            and tees.enable = 1
            and tees.already_exam_count is not null
            and tees.already_exam_count <![CDATA[ > ]]> 0
            <if test="examPaperIdSet != null and examPaperIdSet != '' and examPaperIdSet.size > 0">
                and toer.paper_id in
                <foreach collection="examPaperIdSet" item="paperId" index="index" open="(" close=")" separator=",">
                    #{paperId}
                </foreach>
            </if>
            and toer.status in ('FINISHED','PERSISTED')
            and toer.first_start_time is not null
            and toer.finish_time is not null
            <if test="examStudentBreachPush != null and (examStudentBreachPush == false or examStudentBreachPush == 0)">
                and (toer.breach_status is null or toer.breach_status = 1)
            </if>
            and t.exam_student_id = tees.id
        </where>
        )
        group by
        t.exam_student_id
        <if test="many != null and many != '' or many == 0">
            <choose>
                <when test="many == true">
                    HAVING count(t.exam_student_id) <![CDATA[ > ]]> 1
                </when>
                <otherwise>
                    HAVING count(t.exam_student_id) = 1
                </otherwise>
            </choose>
        </if>
        ) t
        join t_oe_exam_record t1 on
        t1.exam_student_id = t.exam_student_id
        where t1.status in ('FINISHED','PERSISTED')
        and t1.first_start_time is not null
        and t1.finish_time is not null
        <if test="examStudentBreachPush != null and (examStudentBreachPush == false or examStudentBreachPush == 0)">
            and (t1.breach_status is null or t1.breach_status = 1)
        </if>
        <!--<if test="many != null and many != '' or many == 0">
            <choose>
                <when test="many == true">
                    order by t1.id limit 510
                </when>
                <otherwise>
                    order by t1.id limit 500
                </otherwise>
            </choose>
        </if>-->
        order by t1.id
    </select>

    <select id="persistedAnswerBatch" resultType="com.qmth.themis.business.entity.TOeExamRecord">
        select toer.* from t_oe_exam_record toer
        left join t_oe_exam_answer toea on toea.exam_record_id = toer.id
        <where>
            <if test="examId != null and examId != ''">
                and toer.exam_id = #{examId}
            </if>
            <if test="examActivityId != null and examActivityId != ''">
                and toer.exam_activity_id = #{examActivityId}
            </if>
            <if test="status != null and status != ''">
                and toer.status = #{status}
            </if>
            and toer.objective_score > 0
            and toea.id is null
            and toer.first_start_time is not null
            and toer.finish_time is not null
        </where>
        group by toer.id
        having count(toea.id) = 0
    </select>

    <select id="cleanExamFirstPrepareCache" resultType="java.util.Map">
        select
        a.*
        from
        (
        select
        tes.id as studentId,
        toer.id as examRecordId,
        DATE_FORMAT(FROM_UNIXTIME(toer.first_prepare_time / 1000), '%Y-%m-%d %H:%i:%s') as 'firstPrepareTime',
        DATE_FORMAT(FROM_UNIXTIME(toer.finish_time / 1000), '%Y-%m-%d %H:%i:%s') as 'finishTime',
        DATE_FORMAT(FROM_UNIXTIME(toer.first_start_time / 1000), '%Y-%m-%d %H:%i:%s') as 'firstStartTime',
        DATE_FORMAT(FROM_UNIXTIME(toer.start_time / 1000), '%Y-%m-%d %H:%i:%s') as 'startTime',
        DATE_FORMAT(FROM_UNIXTIME(toer.end_time / 1000), '%Y-%m-%d %H:%i:%s') as 'endTime'
        from
        t_oe_exam_record toer
        join t_e_exam_student tees on tees.id = toer.exam_student_id
        join t_e_student tes on tes.id = tees.student_id
        <where>
            toer.status = 'FIRST_PREPARE'
            <if test="examIds != null and examIds != ''">
                and toer.exam_id in
                <foreach collection="examIds" item="examId" index="index" open="(" close=")" separator=",">
                    #{examId}
                </foreach>
            </if>
            and toer.first_prepare_time is not null
            and toer.first_start_time is null
            and toer.finish_time is null
            and (toer.objective_score is null
            or toer.objective_score = 0)
        </where>
        group by
        toer.id
        having
        count(toer.id) > 0) a;
    </select>

    <!--    <select id="dataCount" resultType="java.lang.Long">-->
    <!--        select count(1) as c-->
    <!--        from t_oe_exam_record toer-->
    <!--        where toer.client_websocket_status = 'ON_LINE'-->
    <!--        union all-->
    <!--        select count(1) as c-->
    <!--        from t_oe_exam_record toer-->
    <!--        where toer.STATUS in ('ANSWERING', 'RESUME_PREPARE')-->
    <!--          and toer.client_websocket_status = 'ON_LINE'-->
    <!--        union all-->
    <!--        select count(1) as c-->
    <!--        from t_oe_exam_record toer-->
    <!--        where toer.STATUS in ('FINISHED', 'PERSISTED')-->
    <!--        union all-->
    <!--        select count(distinct tees.id) as c-->
    <!--        from t_e_exam_student tees-->
    <!--                 left join t_oe_exam_record toer on toer.exam_student_id = tees.id-->
    <!--        where toer.STATUS in ('FINISHED', 'PERSISTED')-->
    <!--    </select>-->

    <!--    <select id="orgDataCount" resultType="com.qmth.themis.business.bean.admin.OrgDataCountBean">-->
    <!--        select t.name           as name,-->
    <!--               t.code           as code,-->
    <!--               sum(onlineCount) as onlineCount,-->
    <!--               sum(examCount)   as examCount-->
    <!--        from (select tbo.name,-->
    <!--                     tbo.code,-->
    <!--                     count(toer.id) as onlineCount,-->
    <!--                     0              as examCount-->
    <!--              from t_b_org tbo-->
    <!--                       join t_e_exam tee on-->
    <!--                  tbo.id = tee.org_id-->
    <!--                       join t_oe_exam_record toer on-->
    <!--                  tee.id = toer.exam_id-->
    <!--              WHERE toer.client_websocket_status = 'ON_LINE'-->
    <!--              group by tbo.name,-->
    <!--                       tbo.code-->
    <!--              union all-->
    <!--              select tbo.name,-->
    <!--                     tbo.code,-->
    <!--                     0              as onlineCount,-->
    <!--                     count(toer.id) as examCount-->
    <!--              from t_b_org tbo-->
    <!--                       join t_e_exam tee on-->
    <!--                  tbo.id = tee.org_id-->
    <!--                       join t_oe_exam_record toer on-->
    <!--                  tee.id = toer.exam_id-->
    <!--              WHERE toer.STATUS in ('ANSWERING', 'RESUME_PREPARE')-->
    <!--                and toer.client_websocket_status = 'ON_LINE'-->
    <!--              group by tbo.name,-->
    <!--                       tbo.code) t-->
    <!--        group by t.name,-->
    <!--                 t.code-->
    <!--    </select>-->

    <!--    <select id="mapDataCount" resultType="com.qmth.themis.business.bean.admin.MapDataCountBean">-->
    <!--        select tir.country,-->
    <!--               tir.province,-->
    <!--               count(toer.id) as onlineCount-->
    <!--        from t_ip_region tir-->
    <!--                 join t_oe_exam_record toer on tir.exam_record_id = toer.id-->
    <!--        WHERE toer.client_websocket_status = 'ON_LINE'-->
    <!--          &lt;!&ndash;and tir.country != '0' and tir.province != '0'&ndash;&gt;-->
    <!--        group by-->
    <!--            tir.country,-->
    <!--            tir.province-->
    <!--    </select>-->

    <update id="updateWarningCount">
        update t_oe_exam_record
        set warning_count  = warning_count + 1,
            warning_unread = warning_unread + 1
        where id = #{id}
    </update>

    <update id="updateWarningUnread">
        update t_oe_exam_record set
        <choose>
            <when test="number != null and number != '' or number == 0">
                warning_unread = #{number}
            </when>
            <otherwise>
                warning_unread = warning_unread - #{number}
            </otherwise>
        </choose>
        where id = #{id}
    </update>

    <select id="findExamRecordByWarning" resultType="com.qmth.themis.business.entity.TOeExamRecord">
        select toer.* from t_oe_exam_record toer
        left join t_e_exam tee on tee.id = toer.exam_id
        left join t_e_exam_activity teea on teea.id = toer.exam_activity_id
        left join t_e_exam_student tees on tees.id = toer.exam_student_id
        <where> 1 = 1
            <if test="orgId != null and orgId != ''">
                and tee.org_id = #{orgId}
            </if>
            <if test="examId != null and examId != ''">
                and toer.exam_id = #{examId}
            </if>
            <if test="examActivityId != null and examActivityId != ''">
                and toer.exam_activity_id = #{examActivityId}
            </if>
            <if test="roomCodeList != null and roomCodeList != '' and roomCodeList.size > 0">
                and tees.room_code in
                <foreach collection="roomCodeList" item="roomCode" index="index" open="(" close=")" separator=",">
                    #{roomCode}
                </foreach>
            </if>
            <if test="name != null and name !=''">
                and tees.name like CONCAT('%', #{name},'%')
            </if>
            <if test="identity != null and identity !=''">
                and tees.identity like CONCAT('%', #{identity},'%')
            </if>
            <if test="maxWarningCount != null and maxWarningCount != '' or maxWarningCount == 0">
                and toer.warning_count &lt;= #{maxWarningCount}
            </if>
            <if test="minWarningCount != null and minWarningCount != '' or minWarningCount == 0">
                and toer.warning_count &gt;= #{minWarningCount}
            </if>
            <if test="minMultipleFaceCount != null and minMultipleFaceCount != '' or minMultipleFaceCount == 0">
                and toer.warning_multiple_face_count &gt;= #{minMultipleFaceCount}
            </if>
            <if test="maxMultipleFaceCount != null and maxMultipleFaceCount != '' or maxMultipleFaceCount == 0">
                and toer.warning_multiple_face_count &lt;= #{maxMultipleFaceCount}
            </if>
            <if test="minExceptionCount != null and minExceptionCount != '' or minExceptionCount == 0">
                and toer.exception_count &gt;= #{minExceptionCount}
            </if>
            <if test="maxExceptionCount != null and maxExceptionCount != '' or maxExceptionCount == 0">
                and toer.exception_count &lt;= #{maxExceptionCount}
            </if>
        </where>
    </select>

    <select id="findExamRecordByFinish" resultType="java.lang.Integer">
        select count(distinct t.exam_student_id) from t_oe_exam_record t
        left join t_e_exam_student tees on tees.id = t.exam_student_id
        <where> 1 = 1
            <if test="examId != null and examId != ''">
                and t.exam_id = #{examId}
            </if>
            <if test="examActivityId != null and examActivityId != ''">
                and t.exam_activity_id = #{examActivityId}
            </if>
            <if test="roomCode != null and roomCode != ''">
                and tees.room_code = #{roomCode}
            </if>
            and (t.status = 'FINISHED' or t.status = 'PERSISTED') and t.first_start_time is not null
        </where>
    </select>
</mapper>