Forráskód Böngészése

合并dev_v1.1.2代码

wangliang 3 éve
szülő
commit
52fc4564bf
16 módosított fájl, 857 hozzáadás és 116 törlés
  1. 2 2
      themis-admin/src/main/java/com/qmth/themis/admin/api/TEExamController.java
  2. 29 0
      themis-admin/src/main/java/com/qmth/themis/admin/api/TIeInvigilateController.java
  3. 46 0
      themis-business/src/main/java/com/qmth/themis/business/bean/admin/InvigilateListHistoryBean.java
  4. 7 3
      themis-business/src/main/java/com/qmth/themis/business/bean/admin/InvigilateListVideoBean.java
  5. 0 2
      themis-business/src/main/java/com/qmth/themis/business/constant/SystemConstant.java
  6. 41 1
      themis-business/src/main/java/com/qmth/themis/business/dao/TOeExamRecordMapper.java
  7. 42 1
      themis-business/src/main/java/com/qmth/themis/business/service/TOeExamRecordService.java
  8. 7 4
      themis-business/src/main/java/com/qmth/themis/business/service/impl/TIeReportServiceImpl.java
  9. 50 9
      themis-business/src/main/java/com/qmth/themis/business/service/impl/TOeExamRecordServiceImpl.java
  10. 30 0
      themis-business/src/main/java/com/qmth/themis/business/util/HttpUtil.java
  11. 4 4
      themis-business/src/main/resources/mapper/TEExamBreachLogMapper.xml
  12. 2 2
      themis-business/src/main/resources/mapper/TEExamReexamMapper.xml
  13. 120 21
      themis-business/src/main/resources/mapper/TEExamStudentMapper.xml
  14. 2 2
      themis-business/src/main/resources/mapper/TIeInvigilateExceptionInfoMapper.xml
  15. 470 58
      themis-business/src/main/resources/mapper/TOeExamRecordMapper.xml
  16. 5 7
      themis-exam/src/main/java/com/qmth/themis/exam/listener/service/impl/MqOeLogicServiceImpl.java

+ 2 - 2
themis-admin/src/main/java/com/qmth/themis/admin/api/TEExamController.java

@@ -467,12 +467,12 @@ public class TEExamController {
                 examPropCountDto.get().setPrepareCount(list.get(0));
                 examPropCountDto.get().setExamCount(list.get(1));
                 examPropCountDto.get().setAlreadyComplete(list.get(2));
+//                examPropCountDto.get().setNotComplete(list.get(3) + list.get(4));
+                examPropCountDto.get().setNotComplete(list.get(3));
             }
-            Integer notComplete = examPropCountDto.get().getAllCount() - examPropCountDto.get().getAlreadyComplete();
             BigDecimal completionRate = new BigDecimal(examPropCountDto.get().getAlreadyComplete())
                     .divide(new BigDecimal(examPropCountDto.get().getAllCount()), 2, BigDecimal.ROUND_HALF_UP)
                     .setScale(2, BigDecimal.ROUND_HALF_UP);
-            examPropCountDto.get().setNotComplete(notComplete);
             examPropCountDto.get().setCompletionRate(completionRate);
         }
 //        long end = System.currentTimeMillis();

+ 29 - 0
themis-admin/src/main/java/com/qmth/themis/admin/api/TIeInvigilateController.java

@@ -249,6 +249,35 @@ public class TIeInvigilateController {
         return ResultUtil.ok(tOeExamRecordService.invigilatePageListHistory(new Page<>(pageNumber, pageSize), examId, examActivityId, roomCode, courseCode, status, breachStatus, finishType, name, identity, minMultipleFaceCount, maxMultipleFaceCount, minExceptionCount, maxExceptionCount, minWarningCount, maxWarningCount, userId, tbUser.getOrgId()));
     }
 
+    @ApiOperation(value = "监考明细管理列表导出接口")
+    @RequestMapping(value = "/history/list/export", method = RequestMethod.POST)
+    @ApiResponses({@ApiResponse(code = 200, message = "监考明细信息", response = InvigilateListHistoryBean.class)})
+    public void historyListExport(@ApiParam(value = "考试批次id", required = false) @RequestParam(required = false) Long examId,
+                                  @ApiParam(value = "考试场次id", required = false) @RequestParam(required = false) Long examActivityId,
+                                  @ApiParam(value = "虚拟考场代码", required = false) @RequestParam(required = false) String roomCode,
+                                  @ApiParam(value = "科目代码", required = false) @RequestParam(required = false) String courseCode,
+                                  @ApiParam(value = "考生状态", required = false) @RequestParam(required = false) String status,
+                                  @ApiParam(value = "违纪状态", required = false) @RequestParam(required = false) Integer breachStatus,
+                                  @ApiParam(value = "交卷方式", required = false) @RequestParam(required = false) String finishType,
+                                  @ApiParam(value = "姓名", required = false) @RequestParam(required = false) String name,
+                                  @ApiParam(value = "证件号", required = false) @RequestParam(required = false) String identity,
+                                  @ApiParam(value = "陌生人脸min", required = false) @RequestParam(required = false) Integer minMultipleFaceCount,
+                                  @ApiParam(value = "陌生人脸max", required = false) @RequestParam(required = false) Integer maxMultipleFaceCount,
+                                  @ApiParam(value = "异常处理min", required = false) @RequestParam(required = false) Integer minExceptionCount,
+                                  @ApiParam(value = "异常处理max", required = false) @RequestParam(required = false) Integer maxExceptionCount,
+                                  @ApiParam(value = "预警量min", required = false) @RequestParam(required = false) Integer minWarningCount,
+                                  @ApiParam(value = "预警量max", required = false) @RequestParam(required = false) Integer maxWarningCount) throws Exception {
+        TBUser tbUser = (TBUser) ServletUtil.getRequestAccount();
+        AuthDto authDto = cacheService.addAccountAuthCache(tbUser.getId());
+        //如果有监考员角色,只能查看自己所监考的考场,巡考员和管理员则可以查看全部考场
+        Long userId = null;
+        if (authDto.getRoleCodes().toString().contains(RoleEnum.INVIGILATE.name())) {
+            userId = tbUser.getId();
+        }
+        List<InvigilateListHistoryBean> invigilateListHistoryBeanList = tOeExamRecordService.invigilatePageListHistoryExport(examId, examActivityId, roomCode, courseCode, status, breachStatus, finishType, name, identity, minMultipleFaceCount, maxMultipleFaceCount, minExceptionCount, maxExceptionCount, minWarningCount, maxWarningCount, userId, tbUser.getOrgId());
+        ExportUtils.exportEXCEL("监考明细", InvigilateListHistoryBean.class, invigilateListHistoryBeanList, ServletUtil.getResponse());
+    }
+
     @ApiOperation(value = "实时监控台列表明细接口")
     @RequestMapping(value = "/list/detail", method = RequestMethod.POST)
     @ApiResponses({@ApiResponse(code = 200, message = "监考监控信息", response = InvigilateListDetailBean.class)})

+ 46 - 0
themis-business/src/main/java/com/qmth/themis/business/bean/admin/InvigilateListHistoryBean.java

@@ -4,10 +4,12 @@ import com.fasterxml.jackson.databind.annotation.JsonSerialize;
 import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
 import com.qmth.themis.business.enums.ExamRecordStatusEnum;
 import com.qmth.themis.business.enums.FinishTypeEnum;
+import com.qmth.themis.business.excel.ExcelProperty;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 
 import java.io.Serializable;
+import java.util.Objects;
 
 /**
  * @Description: 实时监控台视频返回对象
@@ -23,13 +25,16 @@ public class InvigilateListHistoryBean implements Serializable {
     private Integer seq;
 
     @ApiModelProperty(name = "考试批次名称")
+    @ExcelProperty(name = "批次", width = 30, index = 1)
     private String examName;
 
     @ApiModelProperty(name = "场次code")
+    @ExcelProperty(name = "场次", width = 30, index = 2)
     private String examActivityCode;
 
     @JsonSerialize(using = ToStringSerializer.class)
     @ApiModelProperty(name = "考试id")
+    @ExcelProperty(name = "考试ID", width = 30, index = 4)
     private Long examId;
 
     @JsonSerialize(using = ToStringSerializer.class)
@@ -45,18 +50,22 @@ public class InvigilateListHistoryBean implements Serializable {
     private Long examRecordId;
 
     @ApiModelProperty(name = "证件号")
+    @ExcelProperty(name = "证件号", width = 30, index = 5)
     private String identity;
 
     @ApiModelProperty(name = "虚拟考场代码")
     private String roomCode;
 
     @ApiModelProperty(name = "虚拟考场名称")
+    @ExcelProperty(name = "考场", width = 30, index = 3)
     private String roomName;
 
     @ApiModelProperty(name = "姓名")
+    @ExcelProperty(name = "姓名", width = 30, index = 6)
     private String name;
 
     @ApiModelProperty(name = "考生状态")
+    @ExcelProperty(name = "状态", width = 30, index = 9)
     private String status;
 
     @ApiModelProperty(name = "考生状态值")
@@ -65,27 +74,64 @@ public class InvigilateListHistoryBean implements Serializable {
     @ApiModelProperty(name = "交卷原因")
     private FinishTypeEnum finishType;
 
+    @ApiModelProperty(name = "交卷原因")
+    @ExcelProperty(name = "交卷方式", width = 30, index = 10)
+    private String finishTypeStr;
+
     @ApiModelProperty(name = "预警量")
+    @ExcelProperty(name = "预警数", width = 30, index = 13)
     private Integer warningCount;
 
     @ApiModelProperty(name = "陌生人脸")
+    @ExcelProperty(name = "陌生人脸", width = 30, index = 11)
     private Integer multipleFaceCount;
 
     @ApiModelProperty(name = "异常处理")
+    @ExcelProperty(name = "异常处理", width = 30, index = 12)
     private Integer exceptionCount;
 
     @ApiModelProperty(name = "是否违纪")
     private Integer breachStatus;
 
+    @ApiModelProperty(name = "是否违纪")
+    @ExcelProperty(name = "违纪", width = 30, index = 14)
+    private String breachStatusStr;
+
     @ApiModelProperty(name = "更新时间")
     private Long updateTime;
 
     @ApiModelProperty(name = "科目代码")
+    @ExcelProperty(name = "科目代码", width = 30, index = 8)
     private String courseCode;
 
     @ApiModelProperty(name = "联系电话")
+    @ExcelProperty(name = "联系电话", width = 30, index = 7)
     private String mobileNumber;
 
+    public String getBreachStatusStr() {
+        if (Objects.nonNull(breachStatus)) {
+            return breachStatus.intValue() == 1 ? "正常" : "违纪";
+        } else {
+            return breachStatusStr;
+        }
+    }
+
+    public void setBreachStatusStr(String breachStatusStr) {
+        this.breachStatusStr = breachStatusStr;
+    }
+
+    public String getFinishTypeStr() {
+        if (Objects.nonNull(finishType)) {
+            return finishType.getCode();
+        } else {
+            return finishTypeStr;
+        }
+    }
+
+    public void setFinishTypeStr(String finishTypeStr) {
+        this.finishTypeStr = finishTypeStr;
+    }
+
     public Integer getSeq() {
         return seq;
     }

+ 7 - 3
themis-business/src/main/java/com/qmth/themis/business/bean/admin/InvigilateListVideoBean.java

@@ -338,11 +338,15 @@ public class InvigilateListVideoBean implements Serializable {
         if (statusCode != null && Objects.equals(ExamRecordStatusEnum.FIRST_PREPARE, statusCode)) {
             return "已待考";
         } else if (statusCode != null && Objects.equals(ExamRecordStatusEnum.BREAK_OFF, statusCode)) {
-            return "通讯故障";
-        } else if (statusCode != null && Objects.equals(ExamRecordStatusEnum.ANSWERING, statusCode) || Objects.equals(ExamRecordStatusEnum.RESUME_PREPARE, statusCode)) {
+            return "已中断";
+        } else if (statusCode != null && (Objects.equals(ExamRecordStatusEnum.ANSWERING, statusCode) || Objects.equals(ExamRecordStatusEnum.RESUME_PREPARE, statusCode) || Objects.equals(ExamRecordStatusEnum.BREAK_OFF, statusCode))) {
             return "考试中";
         } else {
-            return statusCode.getCode();
+            if (Objects.nonNull(statusCode)) {
+                return statusCode.getCode();
+            } else {
+                return "未参加考试";
+            }
         }
     }
 

+ 0 - 2
themis-business/src/main/java/com/qmth/themis/business/constant/SystemConstant.java

@@ -698,6 +698,4 @@ public class SystemConstant {
             return null;
         }
     }
-
-
 }

+ 41 - 1
themis-business/src/main/java/com/qmth/themis/business/dao/TOeExamRecordMapper.java

@@ -316,6 +316,46 @@ public interface TOeExamRecordMapper extends BaseMapper<TOeExamRecord> {
                                                                       @Param("userId") Long userId,
                                                                       @Param("orgId") Long orgId);
 
+    /**
+     * 监考明细管理列表导出
+     *
+     * @param examId
+     * @param examActivityId
+     * @param roomCode
+     * @param courseCode
+     * @param status
+     * @param breachStatus
+     * @param finishType
+     * @param name
+     * @param identity
+     * @param minMultipleFaceCount
+     * @param maxMultipleFaceCount
+     * @param minExceptionCount
+     * @param maxExceptionCount
+     * @param minWarningCount
+     * @param maxWarningCount
+     * @param userId
+     * @param orgId
+     * @return
+     */
+    public List<InvigilateListHistoryBean> invigilatePageListHistoryExport(Long examId,
+                                                                           Long examActivityId,
+                                                                           String roomCode,
+                                                                           String courseCode,
+                                                                           String status,
+                                                                           Integer breachStatus,
+                                                                           String finishType,
+                                                                           String name,
+                                                                           String identity,
+                                                                           Integer minMultipleFaceCount,
+                                                                           Integer maxMultipleFaceCount,
+                                                                           Integer minExceptionCount,
+                                                                           Integer maxExceptionCount,
+                                                                           Integer minWarningCount,
+                                                                           Integer maxWarningCount,
+                                                                           Long userId,
+                                                                           Long orgId);
+
     public List<Map<String, Object>> getDoneCount(@Param("orgId") Long orgId, @Param("examId") Long examId, @Param("activityId") Long activityId,
                                                   @Param("roomCode") String roomCode, @Param("courseCode") String courseCode);
 
@@ -424,7 +464,7 @@ public interface TOeExamRecordMapper extends BaseMapper<TOeExamRecord> {
      * @param courseCode
      * @return
      */
-    List<Integer> findByViewAdmin(@Param("orgId") Long orgId, @Param("examId") Long examId, @Param("examActivityId") Long examActivityId, @Param("roomCode") String roomCode, @Param("courseCode") String courseCode);
+    List<Integer> findByViewAdmin(@Param("orgId") Long orgId, @Param("examId") Long examId, @Param("examActivityId") Long examActivityId, @Param("roomCode") String roomCode, @Param("courseCode") String courseCode, @Param("monitorStatus") String monitorStatus);
 
     /**
      * 考试明细查询接口

+ 42 - 1
themis-business/src/main/java/com/qmth/themis/business/service/TOeExamRecordService.java

@@ -343,6 +343,46 @@ public interface TOeExamRecordService extends IService<TOeExamRecord> {
                                                                       Long userId,
                                                                       Long orgId);
 
+    /**
+     * 监考明细管理列表导出
+     *
+     * @param examId
+     * @param examActivityId
+     * @param roomCode
+     * @param courseCode
+     * @param status
+     * @param breachStatus
+     * @param finishType
+     * @param name
+     * @param identity
+     * @param minMultipleFaceCount
+     * @param maxMultipleFaceCount
+     * @param minExceptionCount
+     * @param maxExceptionCount
+     * @param minWarningCount
+     * @param maxWarningCount
+     * @param userId
+     * @param orgId
+     * @return
+     */
+    public List<InvigilateListHistoryBean> invigilatePageListHistoryExport(Long examId,
+                                                                           Long examActivityId,
+                                                                           String roomCode,
+                                                                           String courseCode,
+                                                                           String status,
+                                                                           Integer breachStatus,
+                                                                           String finishType,
+                                                                           String name,
+                                                                           String identity,
+                                                                           Integer minMultipleFaceCount,
+                                                                           Integer maxMultipleFaceCount,
+                                                                           Integer minExceptionCount,
+                                                                           Integer maxExceptionCount,
+                                                                           Integer minWarningCount,
+                                                                           Integer maxWarningCount,
+                                                                           Long userId,
+                                                                           Long orgId);
+
 
     /**
      * 重新算分
@@ -458,9 +498,10 @@ public interface TOeExamRecordService extends IService<TOeExamRecord> {
      * @param examActivityId
      * @param roomCode
      * @param courseCode
+     * @param monitorStatus
      * @return
      */
-    List<Integer> findByViewAdmin(Long orgId, Long examId, Long examActivityId, String roomCode, String courseCode);
+    List<Integer> findByViewAdmin(Long orgId, Long examId, Long examActivityId, String roomCode, String courseCode, InvigilateMonitorStatusEnum monitorStatus);
 
     /**
      * 考试明细查询接口

+ 7 - 4
themis-business/src/main/java/com/qmth/themis/business/service/impl/TIeReportServiceImpl.java

@@ -66,14 +66,15 @@ public class TIeReportServiceImpl implements TIeReportService {
     public Map<String, Object> examView(Long orgId, Long examId, Long examActivityId, String roomCode, String courseCode,
                                         String name, String identity) {
         // 缺考人数
-        Integer examTotal = 0, actualExamTotal = 0, absentNum = 0;
+        Integer examTotal = 0, actualExamTotal = 0, absentNum = 0, completeOffExamTotal = 0;
+        ExamCacheBean exam = examService.getExamCacheBean(examId);
         // 应考人数&实考人数
-        List<Integer> list = tOeExamRecordService.findByViewAdmin(orgId, examId, examActivityId, roomCode, courseCode);
+        List<Integer> list = tOeExamRecordService.findByViewAdmin(orgId, examId, examActivityId, roomCode, courseCode, exam.getMonitorStatus());
         if (Objects.nonNull(list) && list.size() > 0) {
             examTotal = list.get(0);
             actualExamTotal = list.get(1);
+            completeOffExamTotal = list.get(2);
         }
-        ExamCacheBean exam = examService.getExamCacheBean(examId);
         if (exam.getMonitorStatus() == InvigilateMonitorStatusEnum.FINISHED) {// 结束监考的,未考试的都是缺考
             absentNum = examTotal.intValue() - actualExamTotal.intValue();
         }
@@ -81,10 +82,12 @@ public class TIeReportServiceImpl implements TIeReportService {
         List<Map<String, Object>> doneCountByDay = tOeExamRecordMapper.getDoneCountByDay(orgId, examId, examActivityId, roomCode, courseCode);
 
         Map<String, Object> ret = new HashMap<String, Object>();
+        ret.put("monitorStatus", exam.getMonitorStatus());
         ret.put("examTotal", examTotal.intValue());
         ret.put("actualExamTotal", actualExamTotal.intValue());
         ret.put("deficiencyExamTotal", absentNum.intValue());
-        ret.put("completeOffExamTotal", examTotal.intValue() - actualExamTotal.intValue() - absentNum.intValue());
+//        ret.put("completeOffExamTotal", examTotal.intValue() - actualExamTotal.intValue() - absentNum.intValue());
+        ret.put("completeOffExamTotal", completeOffExamTotal);
         ret.put("examTotalList", doneCountByDay);
         return ret;
     }

+ 50 - 9
themis-business/src/main/java/com/qmth/themis/business/service/impl/TOeExamRecordServiceImpl.java

@@ -922,6 +922,51 @@ public class TOeExamRecordServiceImpl extends ServiceImpl<TOeExamRecordMapper, T
                         maxExceptionCount, minWarningCount, maxWarningCount, userId, orgId);
     }
 
+    /**
+     * 监考明细管理列表导出
+     *
+     * @param examId
+     * @param examActivityId
+     * @param roomCode
+     * @param courseCode
+     * @param status
+     * @param breachStatus
+     * @param finishType
+     * @param name
+     * @param identity
+     * @param minMultipleFaceCount
+     * @param maxMultipleFaceCount
+     * @param minExceptionCount
+     * @param maxExceptionCount
+     * @param minWarningCount
+     * @param maxWarningCount
+     * @param userId
+     * @param orgId
+     * @return
+     */
+    public List<InvigilateListHistoryBean> invigilatePageListHistoryExport(Long examId,
+                                                                           Long examActivityId,
+                                                                           String roomCode,
+                                                                           String courseCode,
+                                                                           String status,
+                                                                           Integer breachStatus,
+                                                                           String finishType,
+                                                                           String name,
+                                                                           String identity,
+                                                                           Integer minMultipleFaceCount,
+                                                                           Integer maxMultipleFaceCount,
+                                                                           Integer minExceptionCount,
+                                                                           Integer maxExceptionCount,
+                                                                           Integer minWarningCount,
+                                                                           Integer maxWarningCount,
+                                                                           Long userId,
+                                                                           Long orgId) {
+        return tOeExamRecordMapper
+                .invigilatePageListHistoryExport(examId, examActivityId, roomCode, courseCode, status, breachStatus,
+                        finishType, name, identity, minMultipleFaceCount, maxMultipleFaceCount, minExceptionCount,
+                        maxExceptionCount, minWarningCount, maxWarningCount, userId, orgId);
+    }
+
     /**
      * 重新算分
      */
@@ -1152,11 +1197,6 @@ public class TOeExamRecordServiceImpl extends ServiceImpl<TOeExamRecordMapper, T
                     SystemConstant.REDIS_LOCK_EXAM_STATUS_TIME_OUT);
             if (lock) {
                 try {
-                    ExamRecordStatusEnum examRecordStatusEnum = ExamRecordCacheUtil.getStatus(recordId);
-                    if (Objects.nonNull(examRecordStatusEnum) && examRecordStatusEnum == ExamRecordStatusEnum.BREAK_OFF) {
-                        log.info("examRecordId{}已经设置了断点", recordId);
-                        return false;
-                    }
                     Integer alreadyBreakCount = Objects.isNull(ExamRecordCacheUtil.getAlreadyBreakCount(recordId)) ?
                             0 :
                             ExamRecordCacheUtil.getAlreadyBreakCount(recordId);
@@ -1179,7 +1219,7 @@ public class TOeExamRecordServiceImpl extends ServiceImpl<TOeExamRecordMapper, T
                     }
                     ExamStudentCacheBean es = teExamStudentService.getExamStudentCacheBean(examStudentId);
                     ExamingDataCacheUtil.setUnFinishedRecordId(es.getStudentId(), recordId);
-                    examRecordStatusEnum = ExamRecordCacheUtil.getStatus(recordId);
+                    ExamRecordStatusEnum examRecordStatusEnum = ExamRecordCacheUtil.getStatus(recordId);
                     if (Objects.nonNull(examRecordStatusEnum) && examRecordStatusEnum == ExamRecordStatusEnum.BREAK_OFF) {
                         this.sendExamRecordDataSaveMq(recordId, lastBreakTimeNow);
 //                        //考试断点异常原因 发送mq start
@@ -1242,7 +1282,8 @@ public class TOeExamRecordServiceImpl extends ServiceImpl<TOeExamRecordMapper, T
             Long examId = ExamRecordCacheUtil.getExamId(recordId);
             Long examStudentId = ExamRecordCacheUtil.getExamStudentId(recordId);
             if (Objects.isNull(examStudentId)) {
-                TOeExamRecord tOeExamRecord = SystemConstant.getExamRecord(recordId);
+                TOeExamRecord tOeExamRecord = this.getById(recordId);
+                Optional.ofNullable(tOeExamRecord).orElseThrow(() -> new BusinessException(ExceptionResultEnum.NOT_FOUND_EXAM_RECORD));
                 examStudentId = tOeExamRecord.getExamStudentId();
                 examId = tOeExamRecord.getExamId();
             }
@@ -1352,8 +1393,8 @@ public class TOeExamRecordServiceImpl extends ServiceImpl<TOeExamRecordMapper, T
      * @return
      */
     @Override
-    public List<Integer> findByViewAdmin(Long orgId, Long examId, Long examActivityId, String roomCode, String courseCode) {
-        return tOeExamRecordMapper.findByViewAdmin(orgId, examId, examActivityId, roomCode, courseCode);
+    public List<Integer> findByViewAdmin(Long orgId, Long examId, Long examActivityId, String roomCode, String courseCode, InvigilateMonitorStatusEnum monitorStatus) {
+        return tOeExamRecordMapper.findByViewAdmin(orgId, examId, examActivityId, roomCode, courseCode, Objects.nonNull(monitorStatus) ? monitorStatus.name() : null);
     }
 
     /**

+ 30 - 0
themis-business/src/main/java/com/qmth/themis/business/util/HttpUtil.java

@@ -3,6 +3,7 @@ package com.qmth.themis.business.util;
 import com.qmth.themis.business.constant.SystemConstant;
 import com.qmth.themis.common.exception.BusinessException;
 import org.apache.commons.io.FileUtils;
+import org.apache.http.Consts;
 import org.apache.http.HttpEntity;
 import org.apache.http.HttpResponse;
 import org.apache.http.client.HttpClient;
@@ -130,6 +131,35 @@ public class HttpUtil {
         return getRespString(post);
     }
 
+    /**
+     * get 请求
+     *
+     * @param url
+     * @param params
+     * @param secret
+     * @param timestamp
+     * @return
+     */
+    public static String get(String url, Map<String, Object> params, String secret, Long timestamp) throws IOException {
+        // 构建请求参数
+        List<BasicNameValuePair> pairs = new ArrayList<BasicNameValuePair>();
+        if (params != null) {
+            for (String key : params.keySet()) {
+                pairs.add(new BasicNameValuePair(key, String.valueOf(params.get(key))));
+            }
+        }
+        String str = EntityUtils.toString(new UrlEncodedFormEntity(pairs, Consts.UTF_8));//转换为键值对
+        HttpGet get = new HttpGet(url + "?" + str);
+        if (Objects.nonNull(secret)) {
+            get.setHeader(SystemConstant.HEADER_AUTHORIZATION, secret);
+        }
+        if (Objects.nonNull(timestamp)) {
+            get.setHeader(SystemConstant.HEADER_TIME, String.valueOf(timestamp));
+        }
+        // 执行请求,获取响应
+        return getRespString(get);
+    }
+
     /**
      * 获取响应信息
      *

+ 4 - 4
themis-business/src/main/resources/mapper/TEExamBreachLogMapper.xml

@@ -39,10 +39,10 @@
 			and t.course_code = #{courseCode}
 		</if>
 		<if test="identity != null and identity != ''">
-			and t.identity like concat(#{identity},'%')
+			and t.identity like concat('%',#{identity},'%')
 		</if>
 		<if test="name != null and name != ''">
-			and t.name like concat(#{name},'%')
+			and t.name like concat('%',#{name},'%')
 		</if>
         order by f.exam_student_id
 	</select>
@@ -84,10 +84,10 @@
 			and t.course_code = #{courseCode}
 		</if>
 		<if test="identity != null and identity != ''">
-			and t.identity like concat(#{identity},'%')
+			and t.identity like concat('%',#{identity},'%')
 		</if>
 		<if test="name != null and name != ''">
-			and t.name like concat(#{name},'%')
+			and t.name like concat('%',#{name},'%')
 		</if>
         order by f.exam_student_id
 	</select>

+ 2 - 2
themis-business/src/main/resources/mapper/TEExamReexamMapper.xml

@@ -263,10 +263,10 @@
             and t.course_code = #{courseCode}
         </if>
         <if test="identity != null and identity != ''">
-            and t.identity like concat(#{identity},'%')
+            and t.identity like concat('%',#{identity},'%')
         </if>
         <if test="name != null and name != ''">
-            and t.name like concat(#{name},'%')
+            and t.name like concat('%',#{name},'%')
         </if>
         GROUP BY f.exam_student_id
         order by f.exam_student_id

+ 120 - 21
themis-business/src/main/resources/mapper/TEExamStudentMapper.xml

@@ -14,7 +14,6 @@
         teea.code,
         tees.course_code as courseCode,
         tees.course_name as courseName,
-        if(tees.enable = 1,'启用','停用') as enableText,
         tees.enable,
         tees.room_code as roomCode,
         tees.room_name as roomName,
@@ -183,7 +182,7 @@
         where
         toer.exam_id = t.exam_id
         and toer.exam_activity_id = t.exam_activity_id
-        and tees.room_code = t.room_code and tees.room_name = t.room_name) as actualExamTotal
+        and tees.room_code = t.room_code and tees.room_name = t.room_name and toer.first_start_time is not null) as actualExamTotal
         from
         t_e_exam_student t
         left join t_e_student h on
@@ -267,17 +266,35 @@
 
     <select id="getExamDeficiencyPage"
             resultType="com.qmth.themis.business.bean.admin.ExamDeficiencyListBean">
-        select tee.name as examName,t.exam_id examId,t.exam_activity_id
-        examActivityId,t.room_code
-        roomCode,t.course_code courseCode,t.course_name
-        courseName,t.name,t.identity
-        ,t.room_name roomName,f.code as examActivityCode from
+        select
+        *
+        from
+        (
+        select
+        distinct tee.name as examName,
+        t.exam_id examId,
+        t.exam_activity_id examActivityId,
+        t.room_code roomCode,
+        t.course_code courseCode,
+        t.course_name courseName,
+        t.name,
+        t.identity ,
+        t.room_name roomName,
+        f.code as examActivityCode,
+        t.id
+        from
         t_e_exam_student t
-        left join t_e_exam_activity f on
-        t.exam_activity_id=f.id
-        join t_e_exam tee on tee.id = t.exam_id
-        where t.exam_id = #{examId} and
-        t.current_record_id is null
+        join t_e_exam_activity f on
+        t.exam_activity_id = f.id
+        join t_e_exam tee on
+        tee.id = t.exam_id
+        where
+        NOT EXISTS(
+        select distinct toer.exam_student_id
+        from
+        t_oe_exam_record toer
+        where t.id = toer.exam_student_id)
+        and t.exam_id = #{examId}
         and t.exam_activity_id in
         <foreach collection="activityIds" item="acid" index="index"
                  open="(" close=")" separator=",">
@@ -293,12 +310,98 @@
             and t.course_code = #{courseCode}
         </if>
         <if test="identity != null and identity != ''">
-            and t.identity like concat(#{identity},'%')
+            and t.identity like concat('%',#{identity},'%')
+        </if>
+        <if test="name != null and name != ''">
+            and t.name like concat('%',#{name},'%')
+        </if>
+        union all
+        select
+        distinct tee.name as examName,
+        t.exam_id examId,
+        t.exam_activity_id examActivityId,
+        t.room_code roomCode,
+        t.course_code courseCode,
+        t.course_name courseName,
+        t.name,
+        t.identity ,
+        t.room_name roomName,
+        f.code as examActivityCode,
+        t.id
+        from
+        t_oe_exam_record toer
+        join t_e_exam_student t on
+        t.id = toer.exam_student_id
+        and t.exam_id = toer.exam_id
+        and t.exam_activity_id = toer.exam_activity_id
+        join t_e_exam_activity f on
+        t.exam_activity_id = f.id
+        join t_e_exam tee on
+        tee.id = t.exam_id
+        where
+        toer.exam_id = #{examId}
+        and toer.exam_activity_id in
+        <foreach collection="activityIds" item="acid" index="index"
+                 open="(" close=")" separator=",">
+            #{acid}
+        </foreach>
+        <if test="activityId != null and activityId != ''">
+            and t.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>
+        <if test="identity != null and identity != ''">
+            and t.identity like concat('%',#{identity},'%')
         </if>
         <if test="name != null and name != ''">
-            and t.name like concat(#{name},'%')
+            and t.name like concat('%',#{name},'%')
         </if>
-        order by t.exam_activity_id,t.room_code
+        and toer.first_start_time is null
+        and not exists(
+        select
+        *
+        from
+        (
+        select
+        distinct t.exam_student_id as id
+        from
+        t_oe_exam_record t
+        join t_e_exam_student s on
+        t.exam_student_id = s.id
+        where
+        t.exam_id = #{examId}
+        and t.first_start_time is not null
+        and t.exam_activity_id in
+        <foreach collection="activityIds" item="acid" index="index"
+                 open="(" close=")" separator=",">
+            #{acid}
+        </foreach>
+        <if test="activityId != null and activityId != ''">
+            and s.exam_activity_id = #{activityId}
+        </if>
+        <if test="roomCode != null and roomCode != ''">
+            and s.room_code =#{roomCode}
+        </if>
+        <if test="courseCode != null and courseCode != ''">
+            and s.course_code = #{courseCode}
+        </if>
+        <if test="identity != null and identity != ''">
+            and s.identity like concat('%',#{identity},'%')
+        </if>
+        <if test="name != null and name != ''">
+            and s.name like concat('%',#{name},'%')
+        </if>
+        ) temp
+        where
+        temp.id = toer.exam_student_id)
+            ) t
+        order by
+        t.examActivityId,
+        t.roomCode
     </select>
 
     <select id="getPageForStudentLog"
@@ -326,10 +429,10 @@
             and t.course_code = #{courseCode}
         </if>
         <if test="identity != null and identity != ''">
-            and t.identity like concat(#{identity},'%')
+            and t.identity like concat('%',#{identity},'%')
         </if>
         <if test="name != null and name != ''">
-            and t.name like concat(#{name},'%')
+            and t.name like concat('%',#{name},'%')
         </if>
         order by t.id
     </select>
@@ -413,10 +516,6 @@
         <include refid="markResultCommon" />
     </select>
 
-    <select id="markResultQueryExportIpage" resultType="com.qmth.themis.business.dto.MarkResultSimpleExportDto">
-        <include refid="markResultCommon" />
-    </select>
-
     <select id="findExamStudentNeedMark" resultType="com.qmth.themis.business.dto.response.TEExamStudentDto">
         select
         tees.id,

+ 2 - 2
themis-business/src/main/resources/mapper/TIeInvigilateExceptionInfoMapper.xml

@@ -38,10 +38,10 @@
 			and t.course_code = #{courseCode}
 		</if>
 		<if test="identity != null and identity != ''">
-			and t.identity like concat(#{identity},'%')
+			and t.identity like concat('%',#{identity},'%')
 		</if>
 		<if test="name != null and name != ''">
-			and t.name like concat(#{name},'%')
+			and t.name like concat('%',#{name},'%')
 		</if>
 		GROUP BY f.exam_student_id
 	</select>

+ 470 - 58
themis-business/src/main/resources/mapper/TOeExamRecordMapper.xml

@@ -136,7 +136,7 @@
             <if test="status != null and status != ''">
                 <choose>
                     <when test="status == 'EXAMING'">
-                        and (t.status = 'ANSWERING' or t.status = 'RESUME_PREPARE')
+                        and (t.status = 'ANSWERING' or t.status = 'RESUME_PREPARE' or t.status = 'BREAK_OFF')
                     </when>
                     <otherwise>
                         and t.status = #{status}
@@ -230,37 +230,135 @@
     </select>
 
     <select id="invigilatePageListVideo" resultType="com.qmth.themis.business.bean.admin.InvigilateListVideoBean">
+        select (@i := @i + 1) as seq,t.* from(
         select
-        (@i := @i + 1) as seq,
-        t.*
+        temp.*,
+        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
+        ,(select count(1) from t_ie_invigilate_warn_info tiiwi where tiiwi.exam_record_id = toer.id and
+        tiiwi.approve_status = 0) as warningNew
         from
         (
-        <include refid="invigilatePageHead"/>
-        <!--,t.monitor_live_url as monitorLiveUrl-->
-        ,(select count(1) from t_ie_invigilate_warn_info tiiwi where tiiwi.exam_record_id = t.id and
-        tiiwi.approve_status = 0) as warningNew
-        <include refid="invigilatePageMiddle"/>
-        <include refid="invigilatePageFoot"/>
-        <if test="paperDownload != null and paperDownload != '' or paperDownload == 0">
-            and t.paper_download = #{paperDownload}
+        select
+        distinct 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
+        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
+        WHERE
+        <choose>
+            <when test="status != null and status != '' and status == 'UN_FINISH'">
+                NOT EXISTS(
+            </when>
+            <otherwise>
+                EXISTS(
+            </otherwise>
+        </choose>
+        select
+        toer.exam_student_id
+        from
+        t_oe_exam_record toer
+        where
+        s.id = toer.exam_student_id
+        <!--<if test="status != null and status != '' and status == 'UN_FINISH'">
+            and (toer.STATUS = 'FINISHED' or toer.STATUS = 'PERSISTED')
+            and toer.first_start_time is not null
+        </if>-->
+                    )
+        <if test="examId != null and examId != ''">
+            and s.exam_id = #{examId}
         </if>
-        <if test="status == null or status == ''">
-            and (t.status = 'FIRST_PREPARE' or t.status = 'ANSWERING' or t.status = 'BREAK_OFF' or t.status =
-            'RESUME_PREPARE')
+        <if test="userId != null and userId != ''">
+            and exists (select tbeiu.exam_id from t_b_exam_invigilate_user tbeiu
+            where tbeiu.user_id = #{userId}
+            and tbeiu.exam_id = s.exam_id and tbeiu.room_code = s.room_code)
         </if>
-        <if test="cameraMonitorStatus != null and cameraMonitorStatus != ''">
-            and t.camera_monitor_status = upper(#{cameraMonitorStatus})
+        <if test="orgId != null and orgId != ''">
+            and tee.org_id = #{orgId}
         </if>
-        <if test="screenMonitorStatus != null and screenMonitorStatus != ''">
-            and t.screen_monitor_status = upper(#{screenMonitorStatus})
+        <if test="examActivityId != null and examActivityId != ''">
+            and s.exam_activity_id = #{examActivityId}
         </if>
-        <if test="mobileFirstMonitorStatus != null and mobileFirstMonitorStatus != ''">
-            and t.mobile_first_monitor_status = upper(#{mobileFirstMonitorStatus})
+        <if test="roomCode != null and roomCode != ''">
+            and s.room_code = #{roomCode}
         </if>
-        <if test="mobileSecondMonitorStatus != null and mobileSecondMonitorStatus != ''">
-            and t.mobile_second_monitor_status = upper(#{mobileSecondMonitorStatus})
+        <if test="name != null and name !=''">
+            and s.name like CONCAT('%', #{name},'%')
         </if>
-        ) t,
+        <if test="identity != null and identity !=''">
+            and s.identity like CONCAT('%', #{identity},'%')
+        </if>
+        and teea.finish_time > unix_timestamp(current_timestamp()) * 1000
+        ) temp
+        left join t_oe_exam_record toer on
+        toer.exam_student_id = temp.examStudentId
+        <where> 1 = 1
+            <if test="status != null and status != '' and status != 'UN_FINISH'">
+                <choose>
+                    <when test="status == 'EXAMING'">
+                        and (toer.status = 'ANSWERING' or toer.status = 'RESUME_PREPARE' or toer.status = 'BREAK_OFF')
+                    </when>
+                    <otherwise>
+                        and toer.status = #{status}
+                    </otherwise>
+                </choose>
+            </if>
+            <!--<if test="status != null and status != '' and status == 'UN_FINISH'">
+                and (toer.first_start_time is null or toer.first_prepare_time is null)
+            </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' or toer.status = 'ANSWERING' or toer.status = 'BREAK_OFF' or toer.status = '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>
+        </where>) t,
         (SELECT @i := 0) as i
         order by t.warningNew desc
     </select>
@@ -286,18 +384,122 @@
 
     <select id="invigilatePagePatrolList" resultType="com.qmth.themis.business.bean.admin.InvigilateListPatrolBean">
         select (@i := @i + 1) as seq,t.* from(
-        <include refid="invigilatePageHead"/>
-        ,(select count(1) from t_ie_invigilate_exception_info tiiei where tiiei.exam_record_id = t.id) as exceptionCount
-        ,(select count(1) from t_ie_invigilate_warn_info tiiwi where tiiwi.exam_record_id = t.id and tiiwi.`type` =
+        select
+        temp.*,
+        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
+        ,(select count(1) from t_ie_invigilate_exception_info tiiei where tiiei.exam_record_id = toer.id) as exceptionCount
+        ,(select count(1) from t_ie_invigilate_warn_info tiiwi where tiiwi.exam_record_id = toer.id and tiiwi.`type` =
         'FACE_COUNT_ERROR' and tiiwi.`level` = 'D8') as multipleFaceCount
-        <include refid="invigilatePageMiddle"/>
-        <include refid="invigilatePageFoot"/>
-        <if test="status == null or status == ''">
-            and (t.status = 'FIRST_PREPARE' or t.status = 'ANSWERING' or t.status = 'BREAK_OFF' or t.status =
-            'RESUME_PREPARE')
+        from
+        (
+        select
+        distinct 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
+        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
+        WHERE
+        <choose>
+            <when test="status != null and status != '' and status == 'UN_FINISH'">
+                NOT EXISTS(
+            </when>
+            <otherwise>
+                EXISTS(
+            </otherwise>
+        </choose>
+        select
+        toer.exam_student_id
+        from
+        t_oe_exam_record toer
+        where
+        s.id = toer.exam_student_id
+        <!--<if test="status != null and status != '' and status == 'UN_FINISH'">
+            and (toer.STATUS = 'FINISHED' or toer.STATUS = 'PERSISTED')
+            and toer.first_start_time is not null
+        </if>-->
+                    )
+        <if test="examId != null and examId != ''">
+            and s.exam_id = #{examId}
         </if>
-        ) t,(SELECT @i := 0) as i
-        <where>
+        <if test="userId != null and userId != ''">
+            and exists (select tbeiu.exam_id from t_b_exam_invigilate_user tbeiu
+            where tbeiu.user_id = #{userId}
+            and tbeiu.exam_id = s.exam_id and tbeiu.room_code = s.room_code)
+        </if>
+        <if test="orgId != null and orgId != ''">
+            and tee.org_id = #{orgId}
+        </if>
+        <if test="examActivityId != null and examActivityId != ''">
+            and s.exam_activity_id = #{examActivityId}
+        </if>
+        <if test="roomCode != null and roomCode != ''">
+            and s.room_code = #{roomCode}
+        </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
+        ) temp
+        left join t_oe_exam_record toer on
+        toer.exam_student_id = temp.examStudentId
+        <where> 1 = 1
+            <if test="status != null and status != '' and status != 'UN_FINISH'">
+                <choose>
+                    <when test="status == 'EXAMING'">
+                        and (toer.status = 'ANSWERING' or toer.status = 'RESUME_PREPARE' or toer.status = 'BREAK_OFF')
+                    </when>
+                    <otherwise>
+                        and toer.status = #{status}
+                    </otherwise>
+                </choose>
+            </if>
+            <!--<if test="status != null and status != '' and status == 'UN_FINISH'">
+                and (toer.first_start_time is null or toer.first_prepare_time is null)
+            </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 = 'FIRST_PREPARE' or toer.status = 'ANSWERING' or toer.status = 'BREAK_OFF' or toer.status = 'RESUME_PREPARE')
+            </if>
+        </where>) t,
+        (SELECT @i := 0) as i
+        <where> 1 = 1
             <if test="minMultipleFaceCount != null and minMultipleFaceCount != '' or minMultipleFaceCount == 0">
                 and t.multipleFaceCount &gt;= #{minMultipleFaceCount}
             </if>
@@ -311,7 +513,7 @@
                 and t.exceptionCount &lt;= #{maxExceptionCount}
             </if>
         </where>
-        order by t.roomCode
+        order by t.roomCode desc
     </select>
 
     <select id="invigilatePageWarningList" resultType="com.qmth.themis.business.bean.admin.InvigilateListWarningBean">
@@ -379,7 +581,7 @@
             </if>
         </where>
         ) t,(SELECT @i := 0) as i
-        <where>
+        <where> 1 = 1
             <if test="minMultipleFaceCount != null and minMultipleFaceCount != '' or minMultipleFaceCount == 0">
                 and t.multipleFaceCount &gt;= #{minMultipleFaceCount}
             </if>
@@ -575,33 +777,141 @@
     </select>
 
     <select id="invigilatePageListHistory" resultType="com.qmth.themis.business.bean.admin.InvigilateListHistoryBean">
+        <include refid="invigilatePageListHistorySql" />
+    </select>
+
+    <sql id="invigilatePageListHistorySql">
         select (@i := @i + 1) as seq,t.* from(
-        <include refid="invigilatePageHead"/>
-        ,tes.mobile_number as mobileNumber
-        ,t.finish_type as finishType
-        ,(select count(1) from t_ie_invigilate_warn_info tiiwi where tiiwi.exam_record_id = t.id and tiiwi.`type` =
+        select
+        temp.*,
+        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
+        ,(select count(1) from t_ie_invigilate_warn_info tiiwi where tiiwi.exam_record_id = toer.id and tiiwi.`type` =
         'FACE_COUNT_ERROR' and tiiwi.`level` = 'D8') as multipleFaceCount
-        ,(select count(1) from t_ie_invigilate_exception_info tiiei where tiiei.exam_record_id = t.id) as exceptionCount
-        <include refid="invigilatePageMiddle"/>
-        left join t_e_student tes on s.student_id = tes.id
-        <include refid="invigilatePageHistoryFoot"/>
-        <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>
+        ,(select count(1) from t_ie_invigilate_exception_info tiiei where tiiei.exam_record_id = toer.id) as exceptionCount
+        from
+        (
+        select
+        distinct 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
+        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
+        WHERE
+        <choose>
+            <when test="status != null and status != '' and status == 'UN_FINISH'">
+                NOT EXISTS(
+            </when>
+            <otherwise>
+                EXISTS(
+            </otherwise>
+        </choose>
+        select
+        toer.exam_student_id
+        from
+        t_oe_exam_record toer
+        where
+        s.id = toer.exam_student_id
+        <!--<if test="status != null and status != '' and status == 'UN_FINISH'">
+            and (toer.STATUS = 'FINISHED' or toer.STATUS = 'PERSISTED')
+            and toer.first_start_time is not null
+        </if>-->
+                    )
+        <if test="examId != null and examId != ''">
+            and s.exam_id = #{examId}
+        </if>
+        <if test="userId != null and userId != ''">
+            and exists (select tbeiu.exam_id from t_b_exam_invigilate_user tbeiu
+            where tbeiu.user_id = #{userId}
+            and tbeiu.exam_id = s.exam_id and tbeiu.room_code = s.room_code)
+        </if>
+        <if test="orgId != null and orgId != ''">
+            and tee.org_id = #{orgId}
+        </if>
+        <if test="examActivityId != null and examActivityId != ''">
+            and s.exam_activity_id = #{examActivityId}
+        </if>
+        <if test="roomCode != null and roomCode != ''">
+            and s.room_code = #{roomCode}
+        </if>
+        <if test="name != null and name !=''">
+            and s.name like CONCAT('%', #{name},'%')
         </if>
-        <if test="finishType != null and finishType != ''">
-            and t.finish_type = #{finishType}
+        <if test="identity != null and identity !=''">
+            and s.identity like CONCAT('%', #{identity},'%')
         </if>
         <if test="courseCode != null and courseCode != ''">
             and s.course_code like CONCAT('%', #{courseCode},'%')
         </if>
-        ) t,
+        ) temp
+        left join t_oe_exam_record toer on
+        toer.exam_student_id = temp.examStudentId
+        <where> 1 = 1
+            <if test="status != null and status != '' and status != 'UN_FINISH'">
+                <choose>
+                    <when test="status == 'EXAMING'">
+                        and (toer.status = 'ANSWERING' or toer.status = 'RESUME_PREPARE' or toer.status = 'BREAK_OFF')
+                    </when>
+                    <otherwise>
+                        and toer.status = #{status}
+                    </otherwise>
+                </choose>
+            </if>
+            <!--<if test="status != null and status != '' and status == 'UN_FINISH'">
+                and (toer.first_start_time is null or toer.first_prepare_time is null)
+            </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="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 = 'MANUAL' or toer.finish_type = 'AUTO' or toer.finish_type = 'BREACH' or toer.finish_type = 'INTERRUPT')
+                    </when>
+                    <otherwise>
+                        and toer.finish_type = #{finishType}
+                    </otherwise>
+                </choose>
+            </if>
+        </where>) t,
         (SELECT @i := 0) as i
-        <where>
+        <where> 1 = 1
             <if test="minMultipleFaceCount != null and minMultipleFaceCount != '' or minMultipleFaceCount == 0">
                 and t.multipleFaceCount &gt;= #{minMultipleFaceCount}
             </if>
@@ -616,6 +926,10 @@
             </if>
         </where>
         order by t.roomCode
+    </sql>
+
+    <select id="invigilatePageListHistoryExport" resultType="com.qmth.themis.business.bean.admin.InvigilateListHistoryBean">
+        <include refid="invigilatePageListHistorySql" />
     </select>
 
     <select id="getDoneCount" resultType="java.util.Map">
@@ -1021,7 +1335,6 @@
             #{roomCode}
         </foreach>
         and t.STATUS = 'FIRST_PREPARE'
-        and t.client_websocket_status = 'ON_LINE'
         union all
         select
         count(1) as c
@@ -1035,8 +1348,9 @@
         <foreach collection="roomCodeSet" item="roomCode" index="index" open="(" close=")" separator=",">
             #{roomCode}
         </foreach>
-        and t.STATUS = 'ANSWERING'
-        and t.client_websocket_status = 'ON_LINE'
+        and ((t.STATUS = 'ANSWERING' and t.client_websocket_status = 'ON_LINE')
+           or t.STATUS = 'RESUME_PREPARE'
+           or t.STATUS = 'BREAK_OFF')
         union all
         select
         count(distinct t.exam_student_id) as c
@@ -1052,6 +1366,71 @@
         </foreach>
         and (t.STATUS = 'FINISHED'
         or t.STATUS = 'PERSISTED')
+        union all
+        select
+        count(distinct t.id) as c
+        from
+        t_e_exam_student t
+        left join t_e_exam_activity f on
+        t.exam_activity_id = f.id
+        left join t_e_exam tee on
+        tee.id = t.exam_id
+        where
+        NOT EXISTS(
+        select
+        toer.exam_student_id
+        from
+        t_oe_exam_record toer
+        where
+        t.id = toer.exam_student_id)
+        and t.exam_id = #{examId}
+        and t.room_code in
+        <foreach collection="roomCodeSet" item="roomCode" index="index" open="(" close=")" separator=",">
+            #{roomCode}
+        </foreach>
+        <!--
+        union all
+        select
+        count(distinct toer.exam_student_id) as c
+        from
+        t_oe_exam_record toer
+        left join t_e_exam_student t on
+        t.id = toer.exam_student_id
+        and t.exam_id = toer.exam_id
+        and t.exam_activity_id = toer.exam_activity_id
+        left join t_e_exam_activity f on
+        t.exam_activity_id = f.id
+        left join t_e_exam tee on
+        tee.id = t.exam_id
+        where
+        toer.exam_id = #{examId} and t.room_code in
+        <foreach collection="roomCodeSet" item="roomCode" index="index" open="(" close=")" separator=",">
+            #{roomCode}
+        </foreach>
+        and (toer.first_start_time is null or toer.first_prepare_time is null)
+        and not exists(
+        select
+        *
+        from
+        (
+        select
+        distinct t.exam_student_id as id
+        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 (t.STATUS = 'FINISHED' or t.STATUS = 'PERSISTED')
+        and t.first_start_time is not null
+        and s.room_code in
+        <foreach collection="roomCodeSet" item="roomCode" index="index" open="(" close=")" separator=",">
+            #{roomCode}
+        </foreach>
+        ) temp
+        where
+        temp.id = toer.exam_student_id)
+        -->
     </select>
 
     <select id="findByOnlineInfoRecord" resultType="com.qmth.themis.business.entity.TOeExamRecord">
@@ -1184,7 +1563,40 @@
         </where>
         )) t
         where
-        t.id = toer.exam_student_id)
+        t.id = toer.exam_student_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">

+ 5 - 7
themis-exam/src/main/java/com/qmth/themis/exam/listener/service/impl/MqOeLogicServiceImpl.java

@@ -53,9 +53,6 @@ public class MqOeLogicServiceImpl implements MqOeLogicService {
     @Resource
     TIeExamInvigilateNoticeService tIeExamInvigilateNoticeService;
 
-    @Resource
-    TOeExamRecordService tOeExamRecordService;
-
     /**
      * 强制离线交卷持久化逻辑
      *
@@ -66,7 +63,7 @@ public class MqOeLogicServiceImpl implements MqOeLogicService {
      * @return
      */
     @Transactional
-    protected Map<String, Object> oeMonitorFinishLogicPersisted(Object s,
+    public Map<String, Object> oeMonitorFinishLogicPersisted(Object s,
                                                                 ConcurrentHashMap<String, WebSocketOeServer> webSocketMap,
                                                                 MqDto mqDto,
                                                                 String key) {
@@ -108,7 +105,7 @@ public class MqOeLogicServiceImpl implements MqOeLogicService {
      * @return
      */
     @Transactional
-    protected Map<String, Object> oeWarningFinishLogicPersisted(Object s,
+    public Map<String, Object> oeWarningFinishLogicPersisted(Object s,
                                                                 ConcurrentHashMap<String, WebSocketOeServer> webSocketMap,
                                                                 MqDto mqDto,
                                                                 String key) {
@@ -147,7 +144,7 @@ public class MqOeLogicServiceImpl implements MqOeLogicService {
      * @return
      */
     @Transactional
-    protected Map<String, Object> oeImClusteringLogicPersisted(ConcurrentHashMap<String, WebSocketOeServer> webSocketMap,
+    public Map<String, Object> oeImClusteringLogicPersisted(ConcurrentHashMap<String, WebSocketOeServer> webSocketMap,
                                                                MqDto mqDto,
                                                                String key) {
         Map<String, Object> map = null;
@@ -188,7 +185,8 @@ public class MqOeLogicServiceImpl implements MqOeLogicService {
      * @param key
      * @return
      */
-    protected Map<String, Object> oeLivenessVerifyLogicPersisted(ConcurrentHashMap<String, WebSocketOeServer> webSocketMap,
+    @Transactional
+    public Map<String, Object> oeLivenessVerifyLogicPersisted(ConcurrentHashMap<String, WebSocketOeServer> webSocketMap,
                                                                  MqDto mqDto,
                                                                  String key) {
         Map<String, Object> map = null;