wangliang 4 роки тому
батько
коміт
e1d37d7b61

+ 2 - 5
themis-business/src/main/java/com/qmth/themis/business/cache/ExamActivityRecordCacheUtil.java

@@ -4,8 +4,6 @@ import com.qmth.themis.business.bean.status.ExamStatusBean;
 import com.qmth.themis.business.cache.bean.ExamActivityRecordCacheBean;
 import com.qmth.themis.business.constant.SpringContextHolder;
 import com.qmth.themis.business.util.RedisUtil;
-import com.qmth.themis.common.enums.ExceptionResultEnum;
-import com.qmth.themis.common.exception.BusinessException;
 
 import java.util.Objects;
 
@@ -21,9 +19,8 @@ public class ExamActivityRecordCacheUtil {
 
     public static void setExamRecordStatus(Long activityId, Long recordId) {
         ExamStatusBean examStatusBean = ExamRecordCacheUtil.getStatusBean(recordId);
-        if (Objects.isNull(examStatusBean) || Objects.isNull(examStatusBean.getExamRecordStatusEnum())) {
-            throw new BusinessException(ExceptionResultEnum.EXAM_STATUS_NOT_NULL);
+        if (Objects.nonNull(examStatusBean) && Objects.nonNull(examStatusBean.getExamRecordStatusEnum())) {
+            redisUtil.set(RedisKeyHelper.examActivityRecordCacheKey(activityId), recordId.toString(), new ExamActivityRecordCacheBean(ExamRecordCacheUtil.getExamStudentId(recordId), examStatusBean.getExamRecordStatusEnum()));
         }
-        redisUtil.set(RedisKeyHelper.examActivityRecordCacheKey(activityId), recordId.toString(), new ExamActivityRecordCacheBean(ExamRecordCacheUtil.getExamStudentId(recordId), examStatusBean.getExamRecordStatusEnum()));
     }
 }

+ 224 - 214
themis-business/src/main/java/com/qmth/themis/business/cache/RedisKeyHelper.java

@@ -3,218 +3,228 @@ package com.qmth.themis.business.cache;
 import com.qmth.themis.business.enums.MobileModeEnum;
 
 public class RedisKeyHelper {
-	private static String underLine = "_";
-
-	/**
-	 * 场次
-	 */
-	private static String examActivityKeyPrefix = "exam_activity::";
-	/**
-	 * 考生
-	 */
-	private static String examStudentKeyPrefix = "exam_student::";
-	/**
-	 * 考试记录
-	 */
-	private static String examRecordKeyPrefix = "exam_record::";
-	/**
-	 * 考生试卷结构
-	 */
-	private static String studentPaperStructKeyPrefix = "student_paper_struct::";
-	/**
-	 * 考生作答
-	 */
-	private static String studentAnswerKeyPrefix = "student_answer::";
-	/**
-	 * 剩余音频播放次数
-	 */
-	private static String audioLeftPlayCountKeyPrefix = "audio_left_play_count::";
-	
-	/**
-	 * 人脸验证
-	 */
-	private static String faceVerifyKeyPrefix = "face_verify::";
-	
-	/**
-	 * 断点
-	 */
-	private static String examBreakKeyPrefix = "exam_break::";
-	
-	/**
-	 * 活体验证
-	 */
-	private static String livenessVerifyKeyPrefix = "liveness_verify::";
-	
-
-	/**
-	 * 场次-考试记录
-	 */
-	private static String examActivityRecordKeyPrefix = "exam_activity_record::";
-	
-	/**
-	 * 移动端临时认证
-	 */
-	private static String mobileAuthKeyPrefix = "mobile_auth::";
-	
-	/**
-	 * 未完成考试记录id
-	 */
-	private static String unFinishedRecordIdKeyPrefix = "un_finished_record_id::student_id_";
-	
-	/**
-	 * 客观题答案
-	 */
-	private static String objectiveAnswerKeyPrefix = "objective_answer::exam_id_";
-	
-	/**
-	 * 客观题答案
-	 */
-	private static String objectiveAnswerHashKeyPrefix = "paper_id_";
-	
-	/**
-	 * 场次
-	 * 
-	 * @param activityId
-	 * @return
-	 */
-	public static String examActivityCacheKey(Long activityId) {
-		return examActivityKeyPrefix + activityId;
-	}
-
-	/**
-	 * 考生
-	 * 
-	 * @param examStudentId
-	 * @return
-	 */
-	public static String examStudentCacheKey(Long examStudentId) {
-		return examStudentKeyPrefix + examStudentId;
-	}
-
-	/**
-	 * 考试记录
-	 * 
-	 * @param examRecordId
-	 * @return
-	 */
-	public static String examRecordCacheKey(Long examRecordId) {
-		return examRecordKeyPrefix + examRecordId;
-	}
-
-	/**
-	 * 考生试卷结构
-	 * 
-	 * @param examRecordId
-	 * @return
-	 */
-	public static String studentPaperStructKey(Long examRecordId) {
-		return studentPaperStructKeyPrefix + examRecordId;
-	}
-
-	/**
-	 * 考生作答
-	 * 
-	 * @param examRecordId
-	 * @return
-	 */
-	public static String examAnswerKey(Long examRecordId) {
-		return studentAnswerKeyPrefix + examRecordId;
-	}
-
-	/**
-	 * 考生作答 hashKey
-	 * 
-	 * @param mainNumber
-	 * @param subNumber
-	 * @param subIndex
-	 * @return
-	 */
-	public static String examAnswerHashKey(Integer mainNumber, Integer subNumber, Integer subIndex) {
-		if (subIndex == null) {
-			return mainNumber + underLine + subNumber;
-		} else {
-			return mainNumber + underLine + subNumber + underLine + subIndex;
-		}
-	}
-	
-	/**
-	 * 音频剩余播放次数
-	 * 
-	 * @param examRecordId
-	 * @return
-	 */
-	public static String audioLeftPlayCountKey(Long examRecordId) {
-		return audioLeftPlayCountKeyPrefix + examRecordId;
-	}
-	
-	/**
-	 * 人脸验证 大key
-	 * 
-	 * @param examRecordId
-	 * @return
-	 */
-	public static String faceVerifyCacheKey(Long examRecordId) {
-		return faceVerifyKeyPrefix + examRecordId;
-	}
-	
-	/**
-	 * 活体验证 大key
-	 * 
-	 * @param examRecordId
-	 * @return
-	 */
-	public static String livenessVerifyCacheKey(Long examRecordId) {
-		return livenessVerifyKeyPrefix + examRecordId;
-	}
-	
-	/**断点缓存大key
-	 * @param id
-	 * @return
-	 */
-	public static String examBreakCacheKey(Long id) {
-		return examBreakKeyPrefix + id;
-	}
-	
-	/**场次-考试记录大key
-	 * @param id
-	 * @return
-	 */
-	public static String examActivityRecordCacheKey(Long activityId) {
-		return examActivityRecordKeyPrefix + activityId;
-	}
-	
-	/**移动端临时认证大key
-	 * @param mode
-	 * @param code
-	 * @return
-	 */
-	public static String mobileAuthCacheKey(MobileModeEnum mode,String code) {
-		return mobileAuthKeyPrefix + mode.name().toLowerCase()+underLine+code;
-	}
-	
-	/**未完成考试记录id key
-	 * @param studentId
-	 * @return
-	 */
-	public static String unFinishedRecordIdCacheKey(Long studentId) {
-		return unFinishedRecordIdKeyPrefix + studentId;
-	}
-	
-	/**客观题答案大key
-	 * @param examId
-	 * @return
-	 */
-	public static String objectiveAnswerCacheKey(Long examId) {
-		return objectiveAnswerKeyPrefix+examId;
-	}
-	
-	/**客观题答案小key
-	 * @param paperId
-	 * @return
-	 */
-	public static String objectiveAnswerCacheHashKey(Long paperId) {
-		return objectiveAnswerHashKeyPrefix+paperId;
-	}
-	
-	
+    private static String underLine = "_";
+
+    /**
+     * 场次
+     */
+    private static String examActivityKeyPrefix = "exam_activity";
+    /**
+     * 考生
+     */
+    private static String examStudentKeyPrefix = "exam_student";
+    /**
+     * 考试记录
+     */
+    private static String examRecordKeyPrefix = "exam_record";
+    /**
+     * 考生试卷结构
+     */
+    private static String studentPaperStructKeyPrefix = "student_paper_struct";
+    /**
+     * 考生作答
+     */
+    private static String studentAnswerKeyPrefix = "student_answer";
+    /**
+     * 剩余音频播放次数
+     */
+    private static String audioLeftPlayCountKeyPrefix = "audio_left_play_count";
+
+    /**
+     * 人脸验证
+     */
+    private static String faceVerifyKeyPrefix = "face_verify";
+
+    /**
+     * 断点
+     */
+    private static String examBreakKeyPrefix = "exam_break";
+
+    /**
+     * 活体验证
+     */
+    private static String livenessVerifyKeyPrefix = "liveness_verify";
+
+
+    /**
+     * 场次-考试记录
+     */
+    private static String examActivityRecordKeyPrefix = "exam_activity_record";
+
+    /**
+     * 移动端临时认证
+     */
+    private static String mobileAuthKeyPrefix = "mobile_auth";
+
+    /**
+     * 未完成考试记录id
+     */
+    private static String unFinishedRecordIdKeyPrefix = "un_finished_record_id:student_id_";
+
+    /**
+     * 客观题答案
+     */
+    private static String objectiveAnswerKeyPrefix = "objective_answer:exam_id_";
+
+    /**
+     * 客观题答案
+     */
+    private static String objectiveAnswerHashKeyPrefix = "paper_id_";
+
+    /**
+     * 场次
+     *
+     * @param activityId
+     * @return
+     */
+    public static String examActivityCacheKey(Long activityId) {
+        return examActivityKeyPrefix + activityId;
+    }
+
+    /**
+     * 考生
+     *
+     * @param examStudentId
+     * @return
+     */
+    public static String examStudentCacheKey(Long examStudentId) {
+        return examStudentKeyPrefix + examStudentId;
+    }
+
+    /**
+     * 考试记录
+     *
+     * @param examRecordId
+     * @return
+     */
+    public static String examRecordCacheKey(Long examRecordId) {
+        return examRecordKeyPrefix + examRecordId;
+    }
+
+    /**
+     * 考生试卷结构
+     *
+     * @param examRecordId
+     * @return
+     */
+    public static String studentPaperStructKey(Long examRecordId) {
+        return studentPaperStructKeyPrefix + examRecordId;
+    }
+
+    /**
+     * 考生作答
+     *
+     * @param examRecordId
+     * @return
+     */
+    public static String examAnswerKey(Long examRecordId) {
+        return studentAnswerKeyPrefix + examRecordId;
+    }
+
+    /**
+     * 考生作答 hashKey
+     *
+     * @param mainNumber
+     * @param subNumber
+     * @param subIndex
+     * @return
+     */
+    public static String examAnswerHashKey(Integer mainNumber, Integer subNumber, Integer subIndex) {
+        if (subIndex == null) {
+            return mainNumber + underLine + subNumber;
+        } else {
+            return mainNumber + underLine + subNumber + underLine + subIndex;
+        }
+    }
+
+    /**
+     * 音频剩余播放次数
+     *
+     * @param examRecordId
+     * @return
+     */
+    public static String audioLeftPlayCountKey(Long examRecordId) {
+        return audioLeftPlayCountKeyPrefix + examRecordId;
+    }
+
+    /**
+     * 人脸验证 大key
+     *
+     * @param examRecordId
+     * @return
+     */
+    public static String faceVerifyCacheKey(Long examRecordId) {
+        return faceVerifyKeyPrefix + examRecordId;
+    }
+
+    /**
+     * 活体验证 大key
+     *
+     * @param examRecordId
+     * @return
+     */
+    public static String livenessVerifyCacheKey(Long examRecordId) {
+        return livenessVerifyKeyPrefix + examRecordId;
+    }
+
+    /**
+     * 断点缓存大key
+     *
+     * @param id
+     * @return
+     */
+    public static String examBreakCacheKey(Long id) {
+        return examBreakKeyPrefix + id;
+    }
+
+    /**
+     * 场次-考试记录大key
+     *
+     * @param id
+     * @return
+     */
+    public static String examActivityRecordCacheKey(Long activityId) {
+        return examActivityRecordKeyPrefix + activityId;
+    }
+
+    /**
+     * 移动端临时认证大key
+     *
+     * @param mode
+     * @param code
+     * @return
+     */
+    public static String mobileAuthCacheKey(MobileModeEnum mode, String code) {
+        return mobileAuthKeyPrefix + mode.name().toLowerCase() + underLine + code;
+    }
+
+    /**
+     * 未完成考试记录id key
+     *
+     * @param studentId
+     * @return
+     */
+    public static String unFinishedRecordIdCacheKey(Long studentId) {
+        return unFinishedRecordIdKeyPrefix + studentId;
+    }
+
+    /**
+     * 客观题答案大key
+     *
+     * @param examId
+     * @return
+     */
+    public static String objectiveAnswerCacheKey(Long examId) {
+        return objectiveAnswerKeyPrefix + examId;
+    }
+
+    /**
+     * 客观题答案小key
+     *
+     * @param paperId
+     * @return
+     */
+    public static String objectiveAnswerCacheHashKey(Long paperId) {
+        return objectiveAnswerHashKeyPrefix + paperId;
+    }
 }

+ 152 - 112
themis-business/src/main/java/com/qmth/themis/business/service/impl/TIeReportServiceImpl.java

@@ -1,59 +1,36 @@
 package com.qmth.themis.business.service.impl;
 
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.stream.Collectors;
-
-import javax.annotation.Resource;
-
-import org.apache.commons.lang3.StringUtils;
-import org.apache.commons.lang3.time.DateUtils;
-import org.springframework.stereotype.Service;
-
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.metadata.OrderItem;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
-import com.qmth.themis.business.bean.admin.ExamBreachDetailListBean;
-import com.qmth.themis.business.bean.admin.ExamBreachListBean;
-import com.qmth.themis.business.bean.admin.ExamDeficiencyListBean;
-import com.qmth.themis.business.bean.admin.ExamExceptionDetailListBean;
-import com.qmth.themis.business.bean.admin.ExamExceptionListBean;
-import com.qmth.themis.business.bean.admin.ExamReexamListBean;
-import com.qmth.themis.business.bean.admin.ExamStudentLogDetailListBean;
-import com.qmth.themis.business.bean.admin.ExamStudentLogListBean;
-import com.qmth.themis.business.bean.admin.ExamViewCountListBean;
-import com.qmth.themis.business.bean.admin.ExaminationMonitorCountBean;
-import com.qmth.themis.business.bean.admin.ExaminationMonitorHourWarnCountBean;
-import com.qmth.themis.business.bean.admin.ExaminationMonitorWarnDistributionBean;
-import com.qmth.themis.business.bean.admin.ExaminationMonitorWarnMsgBean;
-import com.qmth.themis.business.bean.admin.InvigilateListPatrolReportBean;
-import com.qmth.themis.business.bean.admin.WarningNotifyBean;
+import com.qmth.themis.business.bean.admin.*;
+import com.qmth.themis.business.cache.ExamRecordCacheUtil;
+import com.qmth.themis.business.cache.RedisKeyHelper;
 import com.qmth.themis.business.cache.bean.ExamActivityCacheBean;
+import com.qmth.themis.business.cache.bean.ExamActivityRecordCacheBean;
 import com.qmth.themis.business.cache.bean.ExamCacheBean;
-import com.qmth.themis.business.dao.TBExamInvigilateUserMapper;
-import com.qmth.themis.business.dao.TEExamBreachLogMapper;
-import com.qmth.themis.business.dao.TEExamReexamMapper;
-import com.qmth.themis.business.dao.TEExamStudentLogMapper;
-import com.qmth.themis.business.dao.TEExamStudentMapper;
-import com.qmth.themis.business.dao.TIeInvigilateExceptionInfoMapper;
-import com.qmth.themis.business.dao.TIeInvigilateWarnInfoMapper;
-import com.qmth.themis.business.dao.TOeExamRecordMapper;
+import com.qmth.themis.business.cache.bean.ExamStudentCacheBean;
+import com.qmth.themis.business.dao.*;
 import com.qmth.themis.business.entity.TBUser;
+import com.qmth.themis.business.entity.TEExam;
 import com.qmth.themis.business.entity.TEExamActivity;
-import com.qmth.themis.business.enums.BreachCancelTypeEnum;
-import com.qmth.themis.business.enums.BreachTypeEnum;
-import com.qmth.themis.business.enums.ExceptionEnum;
-import com.qmth.themis.business.enums.InvigilateMonitorStatusEnum;
-import com.qmth.themis.business.enums.VerifyExceptionEnum;
+import com.qmth.themis.business.enums.*;
 import com.qmth.themis.business.service.TEExamActivityService;
 import com.qmth.themis.business.service.TEExamService;
+import com.qmth.themis.business.service.TEExamStudentService;
 import com.qmth.themis.business.service.TIeReportService;
 import com.qmth.themis.business.util.RedisUtil;
 import com.qmth.themis.business.util.ServletUtil;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.time.DateUtils;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.text.SimpleDateFormat;
+import java.util.*;
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.stream.Collectors;
 
 @Service
 public class TIeReportServiceImpl implements TIeReportService {
@@ -94,12 +71,15 @@ public class TIeReportServiceImpl implements TIeReportService {
     @Resource
     private RedisUtil redisUtil;
 
+    @Resource
+    TEExamStudentService teExamStudentService;
+
     @Override
-    public Map<String, Object> examView(Long orgId,Long examId, Long examActivityId, String roomCode, String courseCode,
+    public Map<String, Object> examView(Long orgId, Long examId, Long examActivityId, String roomCode, String courseCode,
                                         String name, String identity) {
         // 应考人数
         Long totalNum = 0L;
-        List<Map<String, Object>> total = examStudentMapper.getTotalCount(orgId,examId, examActivityId, roomCode, courseCode);
+        List<Map<String, Object>> total = examStudentMapper.getTotalCount(orgId, examId, examActivityId, roomCode, courseCode);
         Map<Long, Long> totalMap = new HashMap<Long, Long>();
         for (Map<String, Object> map : total) {
             Long acId = (Long) map.get("activityId");
@@ -109,7 +89,7 @@ public class TIeReportServiceImpl implements TIeReportService {
         }
         // 实考人数
         Long doneNum = 0L;
-        List<Map<String, Object>> doneCount = examRecordMapper.getDoneCount(orgId,examId, examActivityId, roomCode,
+        List<Map<String, Object>> doneCount = examRecordMapper.getDoneCount(orgId, examId, examActivityId, roomCode,
                 courseCode);
         Map<Long, Long> doneMap = new HashMap<Long, Long>();
         for (Map<String, Object> map : doneCount) {
@@ -134,15 +114,15 @@ public class TIeReportServiceImpl implements TIeReportService {
 //                }
 //                absentMap.put(acId, totalMap.get(acId) - done);
 //            }
-        	 ExamActivityCacheBean ac = examActivityService.getExamActivityCacheBean(acId);
-        	 ExamCacheBean exam=examService.getExamCacheBean(ac.getExamId());
-             if (InvigilateMonitorStatusEnum.FINISHED.equals(exam.getMonitorStatus())) {// 结束监考的,未考试的都是缺考
-                 Long done = doneMap.get(acId);
-                 if (done == null) {
-                     done = 0L;
-                 }
-                 absentMap.put(acId, totalMap.get(acId) - done);
-             }
+            ExamActivityCacheBean ac = examActivityService.getExamActivityCacheBean(acId);
+            ExamCacheBean exam = examService.getExamCacheBean(ac.getExamId());
+            if (InvigilateMonitorStatusEnum.FINISHED.equals(exam.getMonitorStatus())) {// 结束监考的,未考试的都是缺考
+                Long done = doneMap.get(acId);
+                if (done == null) {
+                    done = 0L;
+                }
+                absentMap.put(acId, totalMap.get(acId) - done);
+            }
         }
         Long absentNum = 0L;
         if (absentMap.size() > 0) {
@@ -151,7 +131,7 @@ public class TIeReportServiceImpl implements TIeReportService {
             }
         }
         // 每日已考人数
-        List<Map<String, Object>> doneCountByDay = examRecordMapper.getDoneCountByDay(orgId,examId, examActivityId, roomCode,
+        List<Map<String, Object>> doneCountByDay = examRecordMapper.getDoneCountByDay(orgId, examId, examActivityId, roomCode,
                 courseCode);
 
         Map<String, Object> ret = new HashMap<String, Object>();
@@ -165,11 +145,11 @@ public class TIeReportServiceImpl implements TIeReportService {
     }
 
     @Override
-    public IPage<ExamViewCountListBean> examViewCount(Long orgId,Long examId, Long examActivityId, String roomCode, String courseCode, String name,
-                               String identity, int pageNumber, int pageSize) {
+    public IPage<ExamViewCountListBean> examViewCount(Long orgId, Long examId, Long examActivityId, String roomCode, String courseCode, String name,
+                                                      String identity, int pageNumber, int pageSize) {
         // 应考人数
         IPage<ExamViewCountListBean> total = examStudentMapper.getTotalCountInfo(new Page<>(pageNumber, pageSize),
-        		orgId,examId, examActivityId, roomCode, courseCode);
+                orgId, examId, examActivityId, roomCode, courseCode);
         List<ExamViewCountListBean> data = total.getRecords();
         if (data == null || data.size() == 0) {
             return total;
@@ -190,7 +170,7 @@ public class TIeReportServiceImpl implements TIeReportService {
         List<Long> absentActivityIds = new ArrayList<>();
         for (Long acid : activityIds) {
             ExamActivityCacheBean ac = examActivityService.getExamActivityCacheBean(acid);
-       	 	ExamCacheBean exam=examService.getExamCacheBean(ac.getExamId());
+            ExamCacheBean exam = examService.getExamCacheBean(ac.getExamId());
             if (InvigilateMonitorStatusEnum.FINISHED.equals(exam.getMonitorStatus())) {// 结束监考的,未考试的都是缺考
                 absentActivityIds.add(acid);
             }
@@ -225,14 +205,14 @@ public class TIeReportServiceImpl implements TIeReportService {
     }
 
     @Override
-    public IPage<ExamDeficiencyListBean> examDeficiencyList(Long orgId,Long examId, Long examActivityId, String roomCode, String courseCode,
-                                    String name, String identity, int pageNumber, int pageSize) {
-        
-        List<TEExamActivity> acs = examActivityService.findByExamIdAndOrgId(examId,orgId);
-        
+    public IPage<ExamDeficiencyListBean> examDeficiencyList(Long orgId, Long examId, Long examActivityId, String roomCode, String courseCode,
+                                                            String name, String identity, int pageNumber, int pageSize) {
+
+        List<TEExamActivity> acs = examActivityService.findByExamIdAndOrgId(examId, orgId);
+
         List<Long> absentActivityIds = new ArrayList<>();
         for (TEExamActivity ac : acs) {
-        	ExamCacheBean exam=examService.getExamCacheBean(ac.getExamId());
+            ExamCacheBean exam = examService.getExamCacheBean(ac.getExamId());
             if (InvigilateMonitorStatusEnum.FINISHED.equals(exam.getMonitorStatus())) {// 结束监考的,未考试的都是缺考
                 absentActivityIds.add(ac.getId());
             }
@@ -240,11 +220,11 @@ public class TIeReportServiceImpl implements TIeReportService {
         if (absentActivityIds.size() == 0) {
             return new Page<>(pageNumber, pageSize);
         }
-        
+
         Page<ExamDeficiencyListBean> ipage = new Page<>(pageNumber, pageSize);
         ipage.addOrder(OrderItem.asc("t.exam_activity_id"));
         ipage.addOrder(OrderItem.asc("t.room_code"));
-        IPage<ExamDeficiencyListBean> total = examStudentMapper.getExamDeficiencyPage(ipage,examId, examActivityId,
+        IPage<ExamDeficiencyListBean> total = examStudentMapper.getExamDeficiencyPage(ipage, examId, examActivityId,
                 roomCode, courseCode, name, identity, absentActivityIds);
         List<ExamDeficiencyListBean> data = total.getRecords();
         if (data == null || data.size() == 0) {
@@ -259,12 +239,12 @@ public class TIeReportServiceImpl implements TIeReportService {
 
     @Override
     public IPage<ExamExceptionListBean> examExceptionList(Long examId, Long examActivityId, String roomCode, String courseCode, String name,
-                                   String identity, int pageNumber, int pageSize) {
-    	TBUser tbUser = (TBUser) ServletUtil.getRequestAccount();
-        Long orgId=tbUser.getOrgId();
+                                                          String identity, int pageNumber, int pageSize) {
+        TBUser tbUser = (TBUser) ServletUtil.getRequestAccount();
+        Long orgId = tbUser.getOrgId();
         Page<ExamExceptionListBean> ipage = new Page<>(pageNumber, pageSize);
         ipage.addOrder(OrderItem.asc("f.exam_student_id"));
-        IPage<ExamExceptionListBean> total = invigilateExceptionInfoMapper.getExamExceptionPage(ipage,orgId, examId,
+        IPage<ExamExceptionListBean> total = invigilateExceptionInfoMapper.getExamExceptionPage(ipage, orgId, examId,
                 examActivityId, roomCode, courseCode, name, identity);
         List<ExamExceptionListBean> data = total.getRecords();
         if (data == null || data.size() == 0) {
@@ -292,12 +272,12 @@ public class TIeReportServiceImpl implements TIeReportService {
 
     @Override
     public IPage<ExamReexamListBean> examReexamList(Long examId, Long examActivityId, String roomCode, String courseCode, String name,
-                                String identity, int pageNumber, int pageSize) {
-    	TBUser tbUser = (TBUser) ServletUtil.getRequestAccount();
-        Long orgId=tbUser.getOrgId();
+                                                    String identity, int pageNumber, int pageSize) {
+        TBUser tbUser = (TBUser) ServletUtil.getRequestAccount();
+        Long orgId = tbUser.getOrgId();
         Page<ExamReexamListBean> ipage = new Page<>(pageNumber, pageSize);
         ipage.addOrder(OrderItem.asc("f.exam_student_id"));
-        IPage<ExamReexamListBean> total = examReexamMapper.getExamReexamPage(ipage,orgId, examId, examActivityId, roomCode,
+        IPage<ExamReexamListBean> total = examReexamMapper.getExamReexamPage(ipage, orgId, examId, examActivityId, roomCode,
                 courseCode, name, identity);
         List<ExamReexamListBean> data = total.getRecords();
         if (data == null || data.size() == 0) {
@@ -312,12 +292,12 @@ public class TIeReportServiceImpl implements TIeReportService {
 
     @Override
     public IPage<ExamBreachListBean> examBreachList(Long examId, Long examActivityId, String roomCode, String courseCode, String name,
-                                String identity, int pageNumber, int pageSize) {
-    	TBUser tbUser = (TBUser) ServletUtil.getRequestAccount();
-        Long orgId=tbUser.getOrgId();
+                                                    String identity, int pageNumber, int pageSize) {
+        TBUser tbUser = (TBUser) ServletUtil.getRequestAccount();
+        Long orgId = tbUser.getOrgId();
         Page<ExamBreachListBean> ipage = new Page<>(pageNumber, pageSize);
         ipage.addOrder(OrderItem.asc("f.exam_student_id"));
-        IPage<ExamBreachListBean> total = examBreachLogMapper.getExamBreachPage(ipage, orgId,examId, examActivityId, roomCode,
+        IPage<ExamBreachListBean> total = examBreachLogMapper.getExamBreachPage(ipage, orgId, examId, examActivityId, roomCode,
                 courseCode, name, identity);
         List<ExamBreachListBean> data = total.getRecords();
         if (data == null || data.size() == 0) {
@@ -347,12 +327,12 @@ public class TIeReportServiceImpl implements TIeReportService {
 
     @Override
     public IPage<ExamBreachListBean> examRevokeBreachList(Long examId, Long examActivityId, String roomCode, String courseCode,
-                                      String name, String identity, int pageNumber, int pageSize) {
-    	TBUser tbUser = (TBUser) ServletUtil.getRequestAccount();
-        Long orgId=tbUser.getOrgId();
+                                                          String name, String identity, int pageNumber, int pageSize) {
+        TBUser tbUser = (TBUser) ServletUtil.getRequestAccount();
+        Long orgId = tbUser.getOrgId();
         Page<ExamBreachListBean> ipage = new Page<>(pageNumber, pageSize);
         ipage.addOrder(OrderItem.asc("f.exam_student_id"));
-        IPage<ExamBreachListBean> total = examBreachLogMapper.getExamRevokeBreachPage(ipage,orgId, examId, examActivityId,
+        IPage<ExamBreachListBean> total = examBreachLogMapper.getExamRevokeBreachPage(ipage, orgId, examId, examActivityId,
                 roomCode, courseCode, name, identity);
         List<ExamBreachListBean> data = total.getRecords();
         if (data == null || data.size() == 0) {
@@ -382,12 +362,12 @@ public class TIeReportServiceImpl implements TIeReportService {
 
     @Override
     public IPage<ExamStudentLogListBean> examStudentLogList(Long examId, Long examActivityId, String roomCode, String courseCode,
-                                    String name, String identity, int pageNumber, int pageSize) {
-    	TBUser tbUser = (TBUser) ServletUtil.getRequestAccount();
-        Long orgId=tbUser.getOrgId();
+                                                            String name, String identity, int pageNumber, int pageSize) {
+        TBUser tbUser = (TBUser) ServletUtil.getRequestAccount();
+        Long orgId = tbUser.getOrgId();
         Page<ExamStudentLogListBean> ipage = new Page<>(pageNumber, pageSize);
         ipage.addOrder(OrderItem.asc("t.id"));
-        IPage<ExamStudentLogListBean> total = examStudentMapper.getPageForStudentLog(ipage,orgId, examId, examActivityId,
+        IPage<ExamStudentLogListBean> total = examStudentMapper.getPageForStudentLog(ipage, orgId, examId, examActivityId,
                 roomCode, courseCode, name, identity);
         List<ExamStudentLogListBean> data = total.getRecords();
         if (data == null || data.size() == 0) {
@@ -414,9 +394,9 @@ public class TIeReportServiceImpl implements TIeReportService {
      */
     @Override
     public List<InvigilateListPatrolReportBean> patrolReport(Long examId, Long userId) {
-    	TBUser tbUser = (TBUser) ServletUtil.getRequestAccount();
-        Long orgId=tbUser.getOrgId();
-        return tOeExamRecordMapper.patrolReport(orgId,examId, userId);
+        TBUser tbUser = (TBUser) ServletUtil.getRequestAccount();
+        Long orgId = tbUser.getOrgId();
+        return tOeExamRecordMapper.patrolReport(orgId, examId, userId);
     }
 
     /**
@@ -425,23 +405,83 @@ public class TIeReportServiceImpl implements TIeReportService {
     @Override
     public ExaminationMonitorCountBean examinationMonitorCount() {
         TBUser tbUser = (TBUser) ServletUtil.getRequestAccount();
-        Long orgId=tbUser.getOrgId();
+        Long orgId = tbUser.getOrgId();
         ExaminationMonitorCountBean ret = new ExaminationMonitorCountBean();
-        Long onlineCount = tOeExamRecordMapper.getOnlineCount(orgId);
-        if (onlineCount == null) {
-            onlineCount = 0L;
-        }
-        // 在线人数
-        ret.setOnlineCount(onlineCount);
-        // 考试人数
-        Long examingCount = tOeExamRecordMapper.getExamingCount(orgId);
-        if (examingCount == null) {
-            examingCount = 0L;
-        }
-        ret.setExamingCount(examingCount);
+        //在线人数
+        QueryWrapper<TEExam> teExamQueryWrapper = new QueryWrapper<>();
+        teExamQueryWrapper.lambda().eq(TEExam::getOrgId, orgId);
+        List<TEExam> teExamList = examService.list(teExamQueryWrapper);
+        List<TEExamActivity> teExamActivityList = null;
+        if (Objects.isNull(teExamList)) {
+            return ret;
+        } else {
+            Set<Long> examIdSet = teExamList.stream().map(TEExam::getId).collect(Collectors.toSet());
+            QueryWrapper<TEExamActivity> teExamActivityQueryWrapper = new QueryWrapper<>();
+            teExamActivityQueryWrapper.lambda().in(TEExamActivity::getExamId, examIdSet);
+            teExamActivityList = examActivityService.list(teExamActivityQueryWrapper);
+        }
+        if (Objects.isNull(teExamActivityList)) {
+            return ret;
+        }
+        AtomicReference<Integer> onlineCount = new AtomicReference<>(0);
+        AtomicReference<Integer> examingCount = new AtomicReference<>(0);
+        AtomicReference<Integer> prepareCount = new AtomicReference<>(0);
+//        AtomicReference<Integer> orgExamingCount = new AtomicReference<>(0);
+        Set<Long> examActivityIdSet = teExamActivityList.stream().map(TEExamActivity::getId).collect(Collectors.toSet());
+        examActivityIdSet.forEach(s -> {
+            Map<String, Object> objectMap = redisUtil
+                    .getHashEntries(RedisKeyHelper.examActivityRecordCacheKey(s));
+            if (Objects.nonNull(objectMap) && objectMap.size() > 0) {
+                objectMap.forEach((k, v) -> {
+                    Long recordId = Long.parseLong(k);
+                    ExamActivityRecordCacheBean examActivityRecordCacheBean = (ExamActivityRecordCacheBean) v;
+                    ExamRecordStatusEnum examRecordStatusEnum = examActivityRecordCacheBean.getStatus();
+                    ExamStudentCacheBean examStudentCacheBean = teExamStudentService
+                            .getExamStudentCacheBean(examActivityRecordCacheBean.getExamStudentId());
+                    if (Objects.nonNull(examStudentCacheBean)
+                            && examStudentCacheBean.getEnable().intValue() == 1) {
+                        //客户端通讯状态
+                        WebsocketStatusEnum clientStatus = Objects
+                                .isNull(ExamRecordCacheUtil.getClientWebsocketStatus(recordId)) ?
+                                null :
+                                ExamRecordCacheUtil.getClientWebsocketStatus(recordId);
+                        // 在线人数
+                        if (Objects.nonNull(clientStatus) && Objects
+                                .equals(clientStatus, WebsocketStatusEnum.ON_LINE)) {
+                            onlineCount.getAndSet(onlineCount.get() + 1);
+                        }
+//                        // 机构在考人数
+//                        if (Objects
+//                                .nonNull(examRecordStatusEnum) && Objects
+//                                .equals(examRecordStatusEnum, ExamRecordStatusEnum.ANSWERING)) {
+//                            orgExamingCount.getAndSet(orgExamingCount.get() + 1);
+//                        }
+                        //已待考
+                        if (Objects.equals(examRecordStatusEnum, ExamRecordStatusEnum.FIRST_PREPARE)) {
+                            prepareCount.getAndSet(prepareCount.get() + 1);
+                        }
+                        // 考试人数
+                        else if (Objects.equals(examRecordStatusEnum, ExamRecordStatusEnum.ANSWERING)) {
+                            examingCount.getAndSet(examingCount.get() + 1);
+                        }
+                    }
+                });
+            }
+        });
+//        Long onlineCount = tOeExamRecordMapper.getOnlineCount(orgId);
+//        if (onlineCount == null) {
+//            onlineCount = 0L;
+//        }
+        ret.setOnlineCount(onlineCount.get().longValue());
+//        // 考试人数
+//        Long examingCount = tOeExamRecordMapper.getExamingCount(orgId);
+//        if (examingCount == null) {
+//            examingCount = 0L;
+//        }
+        ret.setExamingCount(examingCount.get().longValue());
 
         // 待考人数
-        ret.setWaitingCount(onlineCount - examingCount);
+        ret.setWaitingCount(prepareCount.get().longValue());
 
         // 通讯故障人数
         ret.setExceptionCount(tOeExamRecordMapper.getExceptionCount(orgId));
@@ -457,8 +497,8 @@ public class TIeReportServiceImpl implements TIeReportService {
      */
     @Override
     public ExaminationMonitorWarnDistributionBean warnDistribution() {
-    	TBUser tbUser = (TBUser) ServletUtil.getRequestAccount();
-        Long orgId=tbUser.getOrgId();
+        TBUser tbUser = (TBUser) ServletUtil.getRequestAccount();
+        Long orgId = tbUser.getOrgId();
         ExaminationMonitorWarnDistributionBean ret = new ExaminationMonitorWarnDistributionBean();
         ret.setOrgDistribution(tOeExamRecordMapper.getOrgDistribution(orgId));
         List<Map<String, Object>> typeList = tOeExamRecordMapper.getTypeDistribution(orgId);
@@ -471,8 +511,8 @@ public class TIeReportServiceImpl implements TIeReportService {
      */
     @Override
     public List<ExaminationMonitorHourWarnCountBean> warnTrend() {
-    	TBUser tbUser = (TBUser) ServletUtil.getRequestAccount();
-        Long orgId=tbUser.getOrgId();
+        TBUser tbUser = (TBUser) ServletUtil.getRequestAccount();
+        Long orgId = tbUser.getOrgId();
         List<ExaminationMonitorHourWarnCountBean> ret = new ArrayList<ExaminationMonitorHourWarnCountBean>();
         SimpleDateFormat sd = new SimpleDateFormat("HH");
         Date start = null;
@@ -490,7 +530,7 @@ public class TIeReportServiceImpl implements TIeReportService {
         start = DateUtils.setMinutes(start, 0);
         start = DateUtils.setSeconds(start, 0);
         start = DateUtils.setMilliseconds(start, 0);
-        List<ExaminationMonitorHourWarnCountBean> list = tOeExamRecordMapper.getWarnTrend(orgId,start.getTime());
+        List<ExaminationMonitorHourWarnCountBean> list = tOeExamRecordMapper.getWarnTrend(orgId, start.getTime());
         if (list != null && list.size() > 0) {
             Map<String, Long> map = list.stream().collect(Collectors.toMap(ExaminationMonitorHourWarnCountBean::getHour,
                     ExaminationMonitorHourWarnCountBean::getCount, (key1, key2) -> key2));
@@ -507,10 +547,10 @@ public class TIeReportServiceImpl implements TIeReportService {
 
     @Override
     public List<ExaminationMonitorWarnMsgBean> warnMsg() {
-    	TBUser tbUser = (TBUser) ServletUtil.getRequestAccount();
-        Long orgId=tbUser.getOrgId();
+        TBUser tbUser = (TBUser) ServletUtil.getRequestAccount();
+        Long orgId = tbUser.getOrgId();
         List<ExaminationMonitorWarnMsgBean> ret = new ArrayList<ExaminationMonitorWarnMsgBean>();
-        List<WarningNotifyBean> list = invigilateWarnInfoMapper.findLastMsg(6,orgId);
+        List<WarningNotifyBean> list = invigilateWarnInfoMapper.findLastMsg(6, orgId);
         if (list != null && list.size() > 0) {
             for (WarningNotifyBean b : list) {
                 ExaminationMonitorWarnMsgBean bean = new ExaminationMonitorWarnMsgBean();