فهرست منبع

修改开放接口逻辑错误;优化获取试卷详情代码;修改获取待评卷考试记录的数据结构

luoshi 4 سال پیش
والد
کامیت
e0f58d5b3e
16فایلهای تغییر یافته به همراه964 افزوده شده و 1222 حذف شده
  1. 26 40
      themis-backend/src/main/java/com/qmth/themis/backend/api/TEOpenController.java
  2. 32 55
      themis-business/src/main/java/com/qmth/themis/business/bean/backend/OpenRecordAnswerBean.java
  3. 37 96
      themis-business/src/main/java/com/qmth/themis/business/bean/backend/OpenRecordNeedMarkBean.java
  4. 37 26
      themis-business/src/main/java/com/qmth/themis/business/dao/TEExamStudentMapper.java
  5. 3 4
      themis-business/src/main/java/com/qmth/themis/business/dao/TOeExamAnswerMapper.java
  6. 75 106
      themis-business/src/main/java/com/qmth/themis/business/dao/TOeExamRecordMapper.java
  7. 10 5
      themis-business/src/main/java/com/qmth/themis/business/service/TEExamStudentService.java
  8. 3 3
      themis-business/src/main/java/com/qmth/themis/business/service/TOeExamAnswerService.java
  9. 31 102
      themis-business/src/main/java/com/qmth/themis/business/service/TOeExamRecordService.java
  10. 20 11
      themis-business/src/main/java/com/qmth/themis/business/service/impl/TEExamStudentServiceImpl.java
  11. 182 275
      themis-business/src/main/java/com/qmth/themis/business/service/impl/TEOpenServiceImpl.java
  12. 11 12
      themis-business/src/main/java/com/qmth/themis/business/service/impl/TOeExamAnswerServiceImpl.java
  13. 44 44
      themis-business/src/main/java/com/qmth/themis/business/service/impl/TOeExamRecordServiceImpl.java
  14. 384 359
      themis-business/src/main/resources/mapper/TEExamStudentMapper.xml
  15. 11 21
      themis-business/src/main/resources/mapper/TOeExamAnswerMapper.xml
  16. 58 63
      themis-business/src/main/resources/mapper/TOeExamRecordMapper.xml

+ 26 - 40
themis-backend/src/main/java/com/qmth/themis/backend/api/TEOpenController.java

@@ -1,11 +1,11 @@
 package com.qmth.themis.backend.api;
 
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
 import com.qmth.themis.business.service.TEOpenService;
-import com.qmth.themis.business.util.RedisUtil;
 import com.qmth.themis.common.exception.BusinessException;
-import com.qmth.themis.common.util.Result;
-import com.qmth.themis.common.util.ResultUtil;
 import io.swagger.annotations.*;
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RequestMethod;
 import org.springframework.web.bind.annotation.RequestParam;
@@ -29,84 +29,70 @@ public class TEOpenController {
     @Resource
     private TEOpenService openService;
 
-    @Resource
-    RedisUtil redisUtil;
-
     @ApiOperation(value = "获取考试详情")
     @RequestMapping(value = "/exam/query", method = RequestMethod.POST)
     @ApiResponses({ @ApiResponse(code = 200, message = "结果信息") })
-    public Result examQueryPage(@ApiParam(value = "考试id", required = false) @RequestParam(required = false) Long examId,
+    public Object examQueryPage(@ApiParam(value = "考试id", required = false) @RequestParam(required = false) Long id,
             @ApiParam(value = "考试code", required = false) @RequestParam(required = false) String code,
             @ApiParam(value = "分页页码", required = false) @RequestParam(required = false) Integer pageNumber,
             @ApiParam(value = "分页数", required = false) @RequestParam(required = false) Integer pageSize) {
-
-        if (pageSize != null && pageSize > 20) {
-            throw new BusinessException("每页最大条数为20");
-        }
-        if (pageNumber == null) {
+        if (pageNumber == null || pageNumber < 1) {
             pageNumber = 1;
         }
-        if (pageSize == null) {
+        if (pageSize == null || pageSize < 1 || pageSize > 20) {
             pageSize = 20;
         }
-        return ResultUtil.ok(openService.examQueryPage(examId, code, pageNumber, pageSize));
+        return openService.examQueryPage(id, StringUtils.trimToNull(code), pageNumber, pageSize);
     }
 
     @ApiOperation(value = "获取考试课程详情")
     @RequestMapping(value = "/exam/course/query", method = RequestMethod.POST)
     @ApiResponses({ @ApiResponse(code = 200, message = "结果信息") })
-    public Result examCourseQueryPage(@ApiParam(value = "考试id", required = true) @RequestParam Long examId,
+    public Object examCourseQueryPage(@ApiParam(value = "考试id", required = true) @RequestParam Long examId,
             @ApiParam(value = "课程code", required = false) @RequestParam(required = false) String courseCode,
             @ApiParam(value = "是否有试卷", required = false) @RequestParam(required = false) Boolean hasPaper,
             @ApiParam(value = "分页页码", required = false) @RequestParam(required = false) Integer pageNumber,
             @ApiParam(value = "分页数", required = false) @RequestParam(required = false) Integer pageSize) {
-        if (pageSize != null && pageSize > 100) {
-            throw new BusinessException("每页最大条数为100");
-        }
-        if (pageNumber == null) {
+        if (pageNumber == null || pageNumber < 1) {
             pageNumber = 1;
         }
-        if (pageSize == null) {
-            pageSize = 100;
+        if (pageSize == null || pageSize < 1) {
+            pageSize = 20;
         }
-        if (examId == null) {
-            throw new BusinessException("考试id不能为空");
+        if (pageSize > 100) {
+            pageSize = 100;
         }
-        return ResultUtil.ok(openService.examCourseQueryPage(examId, courseCode, hasPaper, pageNumber, pageSize));
+        return openService
+                .examCourseQueryPage(examId, StringUtils.trimToNull(courseCode), hasPaper, pageNumber, pageSize);
     }
 
     @ApiOperation(value = "获取考试试卷详情")
     @RequestMapping(value = "/exam/paper/detail", method = RequestMethod.POST)
     @ApiResponses({ @ApiResponse(code = 200, message = "结果信息") })
-    public Result examPaperDetail(@ApiParam(value = "试卷id", required = true) @RequestParam Long paperId,
-            @ApiParam(value = "内容过滤", required = false) @RequestParam(required = false) String filter)
+    public JSONObject examPaperDetail(@ApiParam(value = "试卷id", required = true) @RequestParam Long id,
+            @ApiParam(value = "内容过滤", required = false) @RequestParam(required = false) String filter)
             throws IOException {
-        if (paperId == null) {
-            throw new BusinessException("试卷id不能为空");
+        filter = StringUtils.trimToNull(filter);
+        if (filter != null && !"objective".equals(filter) && !"subjective".equals(filter)) {
+            throw new BusinessException("filter参数无效");
         }
-        return ResultUtil.ok(openService.examPaperDetail(paperId, filter));
+        return openService.examPaperDetail(id, filter);
     }
 
     @ApiOperation(value = "待评卷考试记录查询")
     @RequestMapping(value = "/exam/record/need_mark", method = RequestMethod.POST)
     @ApiResponses({ @ApiResponse(code = 200, message = "结果信息") })
-    public Result examRecordNeedMark(@ApiParam(value = "考试id", required = true) @RequestParam Long examId,
-            @ApiParam(value = "内容过滤卷", required = false) @RequestParam(required = false) String courseCode,
+    public JSONArray examRecordNeedMark(@ApiParam(value = "考试id", required = true) @RequestParam Long examId,
+            @ApiParam(value = "课程代码", required = false) @RequestParam(required = false) String courseCode,
             @ApiParam(value = "考生ID大于此参数", required = false) @RequestParam(required = false) Long examStudentIdGt,
             @ApiParam(value = "数量(最大20)", required = false) @RequestParam(required = false) Integer count) {
-        if (examId == null) {
-            throw new BusinessException("考试id不能为空");
-        }
-        if (examStudentIdGt == null) {
+        if (examStudentIdGt == null || examStudentIdGt < 0) {
             examStudentIdGt = 0L;
         }
-        if (count != null && count > 20) {
-            throw new BusinessException("count最大为20");
-        }
-        if (count == null) {
+        if (count == null || count < 0 || count > 20) {
             count = 20;
         }
-        return ResultUtil.ok(openService.examRecordNeedMark(examId, courseCode, examStudentIdGt, count));
+        return openService.examRecordNeedMark(examId, StringUtils.trimToNull(courseCode), examStudentIdGt, count);
     }
 
 }

+ 32 - 55
themis-business/src/main/java/com/qmth/themis/business/bean/backend/OpenRecordAnswerBean.java

@@ -6,71 +6,48 @@ import io.swagger.annotations.ApiModelProperty;
 @ApiModel("开放接口-待评卷考试记录答案")
 public class OpenRecordAnswerBean {
 
-	@ApiModelProperty("考试记录id")
-	private Long recordId;
-	
-	@ApiModelProperty("试卷id")
-	private Long paperId;
-	
-	@ApiModelProperty("大题号")
-	private Integer mainNumber;
+    @ApiModelProperty("大题号")
+    private Integer mainNumber;
 
-	@ApiModelProperty("小题号")
-	private Integer subNumber;
-	
-	@ApiModelProperty("套题子题序号")
-	private Integer subIndex;
-	
-	@ApiModelProperty("作答")
-	private String answer;
+    @ApiModelProperty("小题号")
+    private Integer subNumber;
 
-	public Long getRecordId() {
-		return recordId;
-	}
+    @ApiModelProperty("套题子题序号")
+    private Integer subIndex;
 
-	public void setRecordId(Long recordId) {
-		this.recordId = recordId;
-	}
+    @ApiModelProperty("作答")
+    private String answer;
 
-	public Integer getMainNumber() {
-		return mainNumber;
-	}
+    public Integer getMainNumber() {
+        return mainNumber;
+    }
 
-	public void setMainNumber(Integer mainNumber) {
-		this.mainNumber = mainNumber;
-	}
+    public void setMainNumber(Integer mainNumber) {
+        this.mainNumber = mainNumber;
+    }
 
-	public Integer getSubNumber() {
-		return subNumber;
-	}
+    public Integer getSubNumber() {
+        return subNumber;
+    }
 
-	public void setSubNumber(Integer subNumber) {
-		this.subNumber = subNumber;
-	}
+    public void setSubNumber(Integer subNumber) {
+        this.subNumber = subNumber;
+    }
 
-	public Integer getSubIndex() {
-		return subIndex;
-	}
+    public Integer getSubIndex() {
+        return subIndex;
+    }
 
-	public void setSubIndex(Integer subIndex) {
-		this.subIndex = subIndex;
-	}
+    public void setSubIndex(Integer subIndex) {
+        this.subIndex = subIndex;
+    }
 
-	public String getAnswer() {
-		return answer;
-	}
+    public String getAnswer() {
+        return answer;
+    }
 
-	public void setAnswer(String answer) {
-		this.answer = answer;
-	}
+    public void setAnswer(String answer) {
+        this.answer = answer;
+    }
 
-	public Long getPaperId() {
-		return paperId;
-	}
-
-	public void setPaperId(Long paperId) {
-		this.paperId = paperId;
-	}
-	
-	
 }

+ 37 - 96
themis-business/src/main/java/com/qmth/themis/business/bean/backend/OpenRecordNeedMarkBean.java

@@ -1,125 +1,66 @@
 package com.qmth.themis.business.bean.backend;
 
-import java.util.List;
-
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 
+import java.util.List;
+
 @ApiModel("开放接口-待评卷考试记录")
 public class OpenRecordNeedMarkBean {
 
-	
-	@ApiModelProperty(name = "考生id")
-    private Long examStudentId;
-	
-	@ApiModelProperty(name = "考试记录id")
-    private Long examRecordId;
-
-	@ApiModelProperty(value = "证件号")
-    private String identity;
-
-    @ApiModelProperty(value = "姓名")
-    private String name;
-
-    @ApiModelProperty(value = "场次代码")
-    private String activityCode;
-
-    @ApiModelProperty(value = "课程名称")
-    private String courseName;
+    @ApiModelProperty(name = "考试记录id")
+    private Long id;
 
     @ApiModelProperty(value = "试卷ID")
     private Long paperId;
-    
+
     @ApiModelProperty(value = "客观得分")
     private Double objectiveScore;
-    
+
     @ApiModelProperty(value = "交卷时间")
     private Long finishTime;
-    
-    
+
     @ApiModelProperty(value = "作答结果")
     private List<OpenRecordAnswerBean> answers;
 
+    public Long getId() {
+        return id;
+    }
 
-	public String getIdentity() {
-		return identity;
-	}
-
-	public void setIdentity(String identity) {
-		this.identity = identity;
-	}
-
-	public String getName() {
-		return name;
-	}
-
-	public void setName(String name) {
-		this.name = name;
-	}
-
-	public String getActivityCode() {
-		return activityCode;
-	}
-
-	public void setActivityCode(String activityCode) {
-		this.activityCode = activityCode;
-	}
-
-	public String getCourseName() {
-		return courseName;
-	}
-
-	public void setCourseName(String courseName) {
-		this.courseName = courseName;
-	}
-
-	public Long getPaperId() {
-		return paperId;
-	}
-
-	public void setPaperId(Long paperId) {
-		this.paperId = paperId;
-	}
-
-	public Double getObjectiveScore() {
-		return objectiveScore;
-	}
+    public void setId(Long id) {
+        this.id = id;
+    }
 
-	public void setObjectiveScore(Double objectiveScore) {
-		this.objectiveScore = objectiveScore;
-	}
+    public Long getPaperId() {
+        return paperId;
+    }
 
-	public List<OpenRecordAnswerBean> getAnswers() {
-		return answers;
-	}
+    public void setPaperId(Long paperId) {
+        this.paperId = paperId;
+    }
 
-	public void setAnswers(List<OpenRecordAnswerBean> answers) {
-		this.answers = answers;
-	}
+    public Double getObjectiveScore() {
+        return objectiveScore;
+    }
 
-	public Long getExamStudentId() {
-		return examStudentId;
-	}
+    public void setObjectiveScore(Double objectiveScore) {
+        this.objectiveScore = objectiveScore;
+    }
 
-	public void setExamStudentId(Long examStudentId) {
-		this.examStudentId = examStudentId;
-	}
+    public List<OpenRecordAnswerBean> getAnswers() {
+        return answers;
+    }
 
-	public Long getExamRecordId() {
-		return examRecordId;
-	}
+    public void setAnswers(List<OpenRecordAnswerBean> answers) {
+        this.answers = answers;
+    }
 
-	public void setExamRecordId(Long examRecordId) {
-		this.examRecordId = examRecordId;
-	}
+    public Long getFinishTime() {
+        return finishTime;
+    }
 
-	public Long getFinishTime() {
-		return finishTime;
-	}
+    public void setFinishTime(Long finishTime) {
+        this.finishTime = finishTime;
+    }
 
-	public void setFinishTime(Long finishTime) {
-		this.finishTime = finishTime;
-	}
-    
-	
 }

+ 37 - 26
themis-business/src/main/java/com/qmth/themis/business/dao/TEExamStudentMapper.java

@@ -42,19 +42,23 @@ public interface TEExamStudentMapper extends BaseMapper<TEExamStudent> {
      * @return
      */
     public IPage<TEExamStudentDto> examStudentQuery(IPage<Map> iPage, @Param("examId") Long examId,
-                                                    @Param("activityId") Long activityId, @Param("identity") String identity, @Param("name") String name,
-                                                    @Param("roomCode") String roomCode, @Param("courseCode") String courseCode, @Param("grade") String grade,
-                                                    @Param("enable") Integer enable, @Param("classNo") String classNo, @Param("hasPhoto") Integer hasPhoto);
+            @Param("activityId") Long activityId, @Param("identity") String identity, @Param("name") String name,
+            @Param("roomCode") String roomCode, @Param("courseCode") String courseCode, @Param("grade") String grade,
+            @Param("enable") Integer enable, @Param("classNo") String classNo, @Param("hasPhoto") Integer hasPhoto);
 
-    public List<Map<String, Object>> getTotalCount(@Param("orgId")Long orgId,@Param("examId") Long examId, @Param("activityId") Long activityId,
-                                                   @Param("roomCode") String roomCode, @Param("courseCode") String courseCode);
+    public List<Map<String, Object>> getTotalCount(@Param("orgId") Long orgId, @Param("examId") Long examId,
+            @Param("activityId") Long activityId, @Param("roomCode") String roomCode,
+            @Param("courseCode") String courseCode);
 
-    public IPage<ExamViewCountListBean> getTotalCountInfo(IPage<Map> iPage,@Param("orgId")Long orgId, @Param("examId") Long examId, @Param("activityId") Long activityId,
-                                                          @Param("roomCode") String roomCode, @Param("courseCode") String courseCode);
+    public IPage<ExamViewCountListBean> getTotalCountInfo(IPage<Map> iPage, @Param("orgId") Long orgId,
+            @Param("examId") Long examId, @Param("activityId") Long activityId, @Param("roomCode") String roomCode,
+            @Param("courseCode") String courseCode);
 
-    public List<Map<String, Object>> getDoneCountByActivityIds(@Param("examId") Long examId, @Param("activityIds") List<Long> activityIds);
+    public List<Map<String, Object>> getDoneCountByActivityIds(@Param("examId") Long examId,
+            @Param("activityIds") List<Long> activityIds);
 
-    public List<Map<String, Object>> getAbsentCountByActivityIds(@Param("examId") Long examId, @Param("activityIds") List<Long> activityIds);
+    public List<Map<String, Object>> getAbsentCountByActivityIds(@Param("examId") Long examId,
+            @Param("activityIds") List<Long> activityIds);
 
     /**
      * 考场查询
@@ -64,23 +68,26 @@ public interface TEExamStudentMapper extends BaseMapper<TEExamStudent> {
      */
     public List<RoomCodeQueryDto> examRoomQuery(@Param("roomName") String roomName);
 
-    public IPage<ExamDeficiencyListBean> getExamDeficiencyPage(IPage<ExamDeficiencyListBean> iPage, @Param("examId") Long examId,
-                                                               @Param("activityId") Long activityId, @Param("roomCode") String roomCode,
-                                                               @Param("courseCode") String courseCode, @Param("name") String name, @Param("identity") String identity, @Param("activityIds") List<Long> activityIds);
+    public IPage<ExamDeficiencyListBean> getExamDeficiencyPage(IPage<ExamDeficiencyListBean> iPage,
+            @Param("examId") Long examId, @Param("activityId") Long activityId, @Param("roomCode") String roomCode,
+            @Param("courseCode") String courseCode, @Param("name") String name, @Param("identity") String identity,
+            @Param("activityIds") List<Long> activityIds);
 
-    public IPage<ExamStudentLogListBean> getPageForStudentLog(IPage<ExamStudentLogListBean> iPage,@Param("orgId") Long orgId,@Param("examId") Long examId,
-                                                              @Param("activityId") Long activityId, @Param("roomCode") String roomCode,
-                                                              @Param("courseCode") String courseCode, @Param("name") String name, @Param("identity") String identity);
+    public IPage<ExamStudentLogListBean> getPageForStudentLog(IPage<ExamStudentLogListBean> iPage,
+            @Param("orgId") Long orgId, @Param("examId") Long examId, @Param("activityId") Long activityId,
+            @Param("roomCode") String roomCode, @Param("courseCode") String courseCode, @Param("name") String name,
+            @Param("identity") String identity);
 
+    public List<TEExamStudentDto> examStudentList(@Param("examId") Long examId, @Param("activityId") Long activityId,
+            @Param("identity") String identity, @Param("name") String name, @Param("roomCode") String roomCode,
+            @Param("courseCode") String courseCode, @Param("grade") String grade, @Param("enable") Integer enable,
+            @Param("classNo") String classNo, @Param("hasPhoto") Integer hasPhoto);
 
-    public List<TEExamStudentDto> examStudentList(@Param("examId") Long examId,
-                                                  @Param("activityId") Long activityId, @Param("identity") String identity, @Param("name") String name,
-                                                  @Param("roomCode") String roomCode, @Param("courseCode") String courseCode, @Param("grade") String grade,
-                                                  @Param("enable") Integer enable, @Param("classNo") String classNo, @Param("hasPhoto") Integer hasPhoto);
+    public void updateAlreadyExamCount(@Param("examStudentId") Long examStudentId,
+            @Param("alreadyExamCount") Integer alreadyExamCount);
 
-    public void updateAlreadyExamCount(@Param("examStudentId") Long examStudentId, @Param("alreadyExamCount") Integer alreadyExamCount);
-
-    public void updateCurrentRecordId(@Param("examStudentId") Long examStudentId, @Param("currentRecordId") Long currentRecordId);
+    public void updateCurrentRecordId(@Param("examStudentId") Long examStudentId,
+            @Param("currentRecordId") Long currentRecordId);
 
     /**
      * 查询学生成绩信息
@@ -93,7 +100,9 @@ public interface TEExamStudentMapper extends BaseMapper<TEExamStudent> {
      * @param courseCode
      * @return
      */
-    public IPage<MarkResultDto> markResultQuery(IPage<Map> iPage, @Param("examId") Long examId, @Param("activityId") Long activityId, @Param("identity") String identity, @Param("name") String name, @Param("courseCode") String courseCode);
+    public IPage<MarkResultDto> markResultQuery(IPage<Map> iPage, @Param("examId") Long examId,
+            @Param("activityId") Long activityId, @Param("identity") String identity, @Param("name") String name,
+            @Param("courseCode") String courseCode);
 
     /**
      * 查询学生成绩信息(导出用)
@@ -105,8 +114,10 @@ public interface TEExamStudentMapper extends BaseMapper<TEExamStudent> {
      * @param courseCode
      * @return
      */
-    public List<MarkResultSimpleExportDto> markResultQueryExport(@Param("examId") Long examId, @Param("activityId") Long activityId, @Param("identity") String identity, @Param("name") String name, @Param("courseCode") String courseCode);
+    public List<MarkResultSimpleExportDto> markResultQueryExport(@Param("examId") Long examId,
+            @Param("activityId") Long activityId, @Param("identity") String identity, @Param("name") String name,
+            @Param("courseCode") String courseCode);
 
-	public List<Long> findExamStudentIdsNeedMark(@Param("examId") Long examId, @Param("courseCode") String courseCode,
-            @Param("idGt") Long idGt, @Param("count") Integer count);
+    public List<TEExamStudentDto> findExamStudentIdsNeedMark(@Param("examId") Long examId,
+            @Param("courseCode") String courseCode, @Param("idGt") Long idGt, @Param("count") Integer count);
 }

+ 3 - 4
themis-business/src/main/java/com/qmth/themis/business/dao/TOeExamAnswerMapper.java

@@ -3,12 +3,11 @@ package com.qmth.themis.business.dao;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.qmth.themis.business.bean.backend.OpenRecordAnswerBean;
 import com.qmth.themis.business.entity.TOeExamAnswer;
-
-import java.util.List;
-
 import org.apache.ibatis.annotations.Mapper;
 import org.apache.ibatis.annotations.Param;
 
+import java.util.List;
+
 /**
  * @Description: 作答结果 Mapper 接口
  * @Param:
@@ -19,6 +18,6 @@ import org.apache.ibatis.annotations.Param;
 @Mapper
 public interface TOeExamAnswerMapper extends BaseMapper<TOeExamAnswer> {
 
-	List<OpenRecordAnswerBean> findByRecordIds(@Param("ids") List<Long> ids);
+    List<OpenRecordAnswerBean> findByExamRecordId(@Param("examRecordId") Long examRecordId);
 
 }

+ 75 - 106
themis-business/src/main/java/com/qmth/themis/business/dao/TOeExamRecordMapper.java

@@ -29,7 +29,8 @@ public interface TOeExamRecordMapper extends BaseMapper<TOeExamRecord> {
      * @param orgId
      * @return
      */
-    public TEExamUnFinishDto getUnFinishExam(@Param("studentId") Long studentId, @Param("examId") Long examId, @Param("orgId") Long orgId);
+    public TEExamUnFinishDto getUnFinishExam(@Param("studentId") Long studentId, @Param("examId") Long examId,
+            @Param("orgId") Long orgId);
 
     /**
      * 数据更新
@@ -38,7 +39,8 @@ public interface TOeExamRecordMapper extends BaseMapper<TOeExamRecord> {
      * @param colName
      * @param colValue
      */
-    public void dataUpdate(@Param("recordId") Long recordId, @Param("colName") String colName, @Param("colValue") Object colValue);
+    public void dataUpdate(@Param("recordId") Long recordId, @Param("colName") String colName,
+            @Param("colValue") Object colValue);
 
     /**
      * 查询实时监控台列表
@@ -59,17 +61,12 @@ public interface TOeExamRecordMapper extends BaseMapper<TOeExamRecord> {
      * @return
      */
     public IPage<InvigilateListBean> invigilatePageList(IPage<Map> iPage, @Param("examId") Long examId,
-                                                        @Param("examActivityId") Long examActivityId,
-                                                        @Param("roomCode") String roomCode,
-                                                        @Param("paperDownload") Integer paperDownload,
-                                                        @Param("status") String status,
-                                                        @Param("name") String name,
-                                                        @Param("identity") String identity,
-                                                        @Param("minWarningCount") Integer minWarningCount,
-                                                        @Param("maxWarningCount") Integer maxWarningCount,
-                                                        @Param("clientWebsocketStatus") String clientWebsocketStatus,
-                                                        @Param("monitorStatusSource") String monitorStatusSource,
-                                                        @Param("userId") Long userId);
+            @Param("examActivityId") Long examActivityId, @Param("roomCode") String roomCode,
+            @Param("paperDownload") Integer paperDownload, @Param("status") String status, @Param("name") String name,
+            @Param("identity") String identity, @Param("minWarningCount") Integer minWarningCount,
+            @Param("maxWarningCount") Integer maxWarningCount,
+            @Param("clientWebsocketStatus") String clientWebsocketStatus,
+            @Param("monitorStatusSource") String monitorStatusSource, @Param("userId") Long userId);
 
     /**
      * 查询实时监控台视频列表
@@ -90,17 +87,12 @@ public interface TOeExamRecordMapper extends BaseMapper<TOeExamRecord> {
      * @return
      */
     public IPage<InvigilateListVideoBean> invigilatePageListVideo(IPage<Map> iPage, @Param("examId") Long examId,
-                                                                  @Param("examActivityId") Long examActivityId,
-                                                                  @Param("roomCode") String roomCode,
-                                                                  @Param("paperDownload") Integer paperDownload,
-                                                                  @Param("status") String status,
-                                                                  @Param("name") String name,
-                                                                  @Param("identity") String identity,
-                                                                  @Param("minWarningCount") Integer minWarningCount,
-                                                                  @Param("maxWarningCount") Integer maxWarningCount,
-                                                                  @Param("clientWebsocketStatus") String clientWebsocketStatus,
-                                                                  @Param("userId") Long userId,
-                                                                  @Param("orgId") Long orgId);
+            @Param("examActivityId") Long examActivityId, @Param("roomCode") String roomCode,
+            @Param("paperDownload") Integer paperDownload, @Param("status") String status, @Param("name") String name,
+            @Param("identity") String identity, @Param("minWarningCount") Integer minWarningCount,
+            @Param("maxWarningCount") Integer maxWarningCount,
+            @Param("clientWebsocketStatus") String clientWebsocketStatus, @Param("userId") Long userId,
+            @Param("orgId") Long orgId);
 
     /**
      * 实时监控台视频随机列表
@@ -111,7 +103,8 @@ public interface TOeExamRecordMapper extends BaseMapper<TOeExamRecord> {
      * @param orgId
      * @return
      */
-    public List<InvigilateListVideoBean> invigilatePageListVideoRandom(@Param("examId") Long examId, @Param("userId") Long userId, @Param("randomNum") Integer randomNum, @Param("orgId") Long orgId);
+    public List<InvigilateListVideoBean> invigilatePageListVideoRandom(@Param("examId") Long examId,
+            @Param("userId") Long userId, @Param("randomNum") Integer randomNum, @Param("orgId") Long orgId);
 
     /**
      * 查询在线巡考列表
@@ -135,20 +128,15 @@ public interface TOeExamRecordMapper extends BaseMapper<TOeExamRecord> {
      * @return
      */
     public IPage<InvigilateListPatrolBean> invigilatePagePatrolList(IPage<Map> iPage, @Param("examId") Long examId,
-                                                                    @Param("examActivityId") Long examActivityId,
-                                                                    @Param("roomCode") String roomCode,
-                                                                    @Param("status") String status,
-                                                                    @Param("name") String name,
-                                                                    @Param("identity") String identity,
-                                                                    @Param("minMultipleFaceCount") Integer minMultipleFaceCount,
-                                                                    @Param("maxMultipleFaceCount") Integer maxMultipleFaceCount,
-                                                                    @Param("minExceptionCount") Integer minExceptionCount,
-                                                                    @Param("maxExceptionCount") Integer maxExceptionCount,
-                                                                    @Param("minWarningCount") Integer minWarningCount,
-                                                                    @Param("maxWarningCount") Integer maxWarningCount,
-                                                                    @Param("clientWebsocketStatus") String clientWebsocketStatus,
-                                                                    @Param("userId") Long userId,
-                                                                    @Param("orgId") Long orgId);
+            @Param("examActivityId") Long examActivityId, @Param("roomCode") String roomCode,
+            @Param("status") String status, @Param("name") String name, @Param("identity") String identity,
+            @Param("minMultipleFaceCount") Integer minMultipleFaceCount,
+            @Param("maxMultipleFaceCount") Integer maxMultipleFaceCount,
+            @Param("minExceptionCount") Integer minExceptionCount,
+            @Param("maxExceptionCount") Integer maxExceptionCount, @Param("minWarningCount") Integer minWarningCount,
+            @Param("maxWarningCount") Integer maxWarningCount,
+            @Param("clientWebsocketStatus") String clientWebsocketStatus, @Param("userId") Long userId,
+            @Param("orgId") Long orgId);
 
     /**
      * 预警提醒列表
@@ -171,19 +159,14 @@ public interface TOeExamRecordMapper extends BaseMapper<TOeExamRecord> {
      * @return
      */
     public IPage<InvigilateListWarningBean> invigilatePageWarningList(IPage<Map> iPage, @Param("examId") Long examId,
-                                                                      @Param("examActivityId") Long examActivityId,
-                                                                      @Param("roomCode") String roomCode,
-                                                                      @Param("approveStatus") Integer approveStatus,
-                                                                      @Param("name") String name,
-                                                                      @Param("identity") String identity,
-                                                                      @Param("minMultipleFaceCount") Integer minMultipleFaceCount,
-                                                                      @Param("maxMultipleFaceCount") Integer maxMultipleFaceCount,
-                                                                      @Param("minExceptionCount") Integer minExceptionCount,
-                                                                      @Param("maxExceptionCount") Integer maxExceptionCount,
-                                                                      @Param("minWarningCount") Integer minWarningCount,
-                                                                      @Param("maxWarningCount") Integer maxWarningCount,
-                                                                      @Param("userId") Long userId,
-                                                                      @Param("orgId") Long orgId);
+            @Param("examActivityId") Long examActivityId, @Param("roomCode") String roomCode,
+            @Param("approveStatus") Integer approveStatus, @Param("name") String name,
+            @Param("identity") String identity, @Param("minMultipleFaceCount") Integer minMultipleFaceCount,
+            @Param("maxMultipleFaceCount") Integer maxMultipleFaceCount,
+            @Param("minExceptionCount") Integer minExceptionCount,
+            @Param("maxExceptionCount") Integer maxExceptionCount, @Param("minWarningCount") Integer minWarningCount,
+            @Param("maxWarningCount") Integer maxWarningCount, @Param("userId") Long userId,
+            @Param("orgId") Long orgId);
 
     /**
      * 预警提醒清除未阅列表
@@ -204,20 +187,15 @@ public interface TOeExamRecordMapper extends BaseMapper<TOeExamRecord> {
      * @param orgId
      * @return
      */
-    public Integer approveStatusListUpdate(@Param("examId") Long examId,
-                                           @Param("examActivityId") Long examActivityId,
-                                           @Param("roomCode") String roomCode,
-                                           @Param("approveStatus") Integer approveStatus,
-                                           @Param("name") String name,
-                                           @Param("identity") String identity,
-                                           @Param("minMultipleFaceCount") Integer minMultipleFaceCount,
-                                           @Param("maxMultipleFaceCount") Integer maxMultipleFaceCount,
-                                           @Param("minExceptionCount") Integer minExceptionCount,
-                                           @Param("maxExceptionCount") Integer maxExceptionCount,
-                                           @Param("minWarningCount") Integer minWarningCount,
-                                           @Param("maxWarningCount") Integer maxWarningCount,
-                                           @Param("userId") Long userId,
-                                           @Param("orgId") Long orgId);
+    public Integer approveStatusListUpdate(@Param("examId") Long examId, @Param("examActivityId") Long examActivityId,
+            @Param("roomCode") String roomCode, @Param("approveStatus") Integer approveStatus,
+            @Param("name") String name, @Param("identity") String identity,
+            @Param("minMultipleFaceCount") Integer minMultipleFaceCount,
+            @Param("maxMultipleFaceCount") Integer maxMultipleFaceCount,
+            @Param("minExceptionCount") Integer minExceptionCount,
+            @Param("maxExceptionCount") Integer maxExceptionCount, @Param("minWarningCount") Integer minWarningCount,
+            @Param("maxWarningCount") Integer maxWarningCount, @Param("userId") Long userId,
+            @Param("orgId") Long orgId);
 
     /**
      * 进度查询列表
@@ -234,13 +212,9 @@ public interface TOeExamRecordMapper extends BaseMapper<TOeExamRecord> {
      * @return
      */
     public IPage<InvigilateListProgressBean> invigilatePageProgressList(IPage<Map> iPage, @Param("examId") Long examId,
-                                                                        @Param("examActivityId") Long examActivityId,
-                                                                        @Param("roomCode") String roomCode,
-                                                                        @Param("courseCode") String courseCode,
-                                                                        @Param("name") String name,
-                                                                        @Param("identity") String identity,
-                                                                        @Param("userId") Long userId,
-                                                                        @Param("orgId") Long orgId);
+            @Param("examActivityId") Long examActivityId, @Param("roomCode") String roomCode,
+            @Param("courseCode") String courseCode, @Param("name") String name, @Param("identity") String identity,
+            @Param("userId") Long userId, @Param("orgId") Long orgId);
 
     /**
      * 进度查询列表导出
@@ -256,13 +230,9 @@ public interface TOeExamRecordMapper extends BaseMapper<TOeExamRecord> {
      * @return
      */
     public List<InvigilateListProgressExcelBean> invigilatePageProgressListExport(@Param("examId") Long examId,
-                                                                                  @Param("examActivityId") Long examActivityId,
-                                                                                  @Param("roomCode") String roomCode,
-                                                                                  @Param("courseCode") String courseCode,
-                                                                                  @Param("name") String name,
-                                                                                  @Param("identity") String identity,
-                                                                                  @Param("userId") Long userId,
-                                                                                  @Param("orgId") Long orgId);
+            @Param("examActivityId") Long examActivityId, @Param("roomCode") String roomCode,
+            @Param("courseCode") String courseCode, @Param("name") String name, @Param("identity") String identity,
+            @Param("userId") Long userId, @Param("orgId") Long orgId);
 
     /**
      * 监考明细管理列表
@@ -288,28 +258,24 @@ public interface TOeExamRecordMapper extends BaseMapper<TOeExamRecord> {
      * @return
      */
     public IPage<InvigilateListHistoryBean> invigilatePageListHistory(IPage<Map> iPage, @Param("examId") Long examId,
-                                                                      @Param("examActivityId") Long examActivityId,
-                                                                      @Param("roomCode") String roomCode,
-                                                                      @Param("courseCode") String courseCode,
-                                                                      @Param("status") String status,
-                                                                      @Param("breachStatus") Integer breachStatus,
-                                                                      @Param("finishType") String finishType,
-                                                                      @Param("name") String name,
-                                                                      @Param("identity") String identity,
-                                                                      @Param("minMultipleFaceCount") Integer minMultipleFaceCount,
-                                                                      @Param("maxMultipleFaceCount") Integer maxMultipleFaceCount,
-                                                                      @Param("minExceptionCount") Integer minExceptionCount,
-                                                                      @Param("maxExceptionCount") Integer maxExceptionCount,
-                                                                      @Param("minWarningCount") Integer minWarningCount,
-                                                                      @Param("maxWarningCount") Integer maxWarningCount,
-                                                                      @Param("userId") Long userId,
-                                                                      @Param("orgId") 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);
-
-    public List<Map<String, Object>> getDoneCountByDay(@Param("orgId") Long orgId, @Param("examId") Long examId, @Param("activityId") Long activityId,
-                                                       @Param("roomCode") String roomCode, @Param("courseCode") String courseCode);
+            @Param("examActivityId") Long examActivityId, @Param("roomCode") String roomCode,
+            @Param("courseCode") String courseCode, @Param("status") String status,
+            @Param("breachStatus") Integer breachStatus, @Param("finishType") String finishType,
+            @Param("name") String name, @Param("identity") String identity,
+            @Param("minMultipleFaceCount") Integer minMultipleFaceCount,
+            @Param("maxMultipleFaceCount") Integer maxMultipleFaceCount,
+            @Param("minExceptionCount") Integer minExceptionCount,
+            @Param("maxExceptionCount") Integer maxExceptionCount, @Param("minWarningCount") Integer minWarningCount,
+            @Param("maxWarningCount") Integer maxWarningCount, @Param("userId") Long userId,
+            @Param("orgId") 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);
+
+    public List<Map<String, Object>> getDoneCountByDay(@Param("orgId") Long orgId, @Param("examId") Long examId,
+            @Param("activityId") Long activityId, @Param("roomCode") String roomCode,
+            @Param("courseCode") String courseCode);
 
     public Long getCountByExamId(@Param("examId") Long examId);
 
@@ -326,7 +292,8 @@ public interface TOeExamRecordMapper extends BaseMapper<TOeExamRecord> {
      * @param userId
      * @return
      */
-    public List<InvigilateListPatrolReportBean> patrolReport(@Param("orgId") Long orgId, @Param("examId") Long examId, @Param("userId") Long userId);
+    public List<InvigilateListPatrolReportBean> patrolReport(@Param("orgId") Long orgId, @Param("examId") Long examId,
+            @Param("userId") Long userId);
 
     public TOeExamRecord findOneByExamId(@Param("examId") Long examId, @Param("status") String status);
 
@@ -344,11 +311,12 @@ public interface TOeExamRecordMapper extends BaseMapper<TOeExamRecord> {
 
     public List<Map<String, Object>> getTypeDistribution(@Param("orgId") Long orgId);
 
-    public List<ExaminationMonitorHourWarnCountBean> getWarnTrend(@Param("orgId") Long orgId, @Param("startTime") Long startTime);
+    public List<ExaminationMonitorHourWarnCountBean> getWarnTrend(@Param("orgId") Long orgId,
+            @Param("startTime") Long startTime);
 
     public void updateHasAnswerFile(@Param("recordId") Long recordId, @Param("hasAnswerFile") Integer hasAnswerFile);
 
-    public List<OpenRecordNeedMarkBean> findExamRecordNeedMark(@Param("examId") Long examId, @Param("examStudentIds") List<Long> examStudentIds);
+    public List<OpenRecordNeedMarkBean> findExamRecordNeedMark(@Param("examStudentId") Long examStudentId);
 
     /**
      * 寻找客观分最高
@@ -357,5 +325,6 @@ public interface TOeExamRecordMapper extends BaseMapper<TOeExamRecord> {
      * @param examStudentId
      * @return
      */
-    public List<TOeExamRecord> findMaxObjectiveScore(@Param("examId") Long examId, @Param("examStudentId") Long examStudentId);
+    public List<TOeExamRecord> findMaxObjectiveScore(@Param("examId") Long examId,
+            @Param("examStudentId") Long examStudentId);
 }

+ 10 - 5
themis-business/src/main/java/com/qmth/themis/business/service/TEExamStudentService.java

@@ -36,9 +36,12 @@ public interface TEExamStudentService extends IService<TEExamStudent> {
      * @param classNo
      * @return
      */
-    public IPage<TEExamStudentDto> examStudentQuery(IPage<Map> iPage, Long examId, Long activityId, String identity, String name, String roomCode, String courseCode, String grade, Integer enable, String classNo, Integer hasPhoto);
+    public IPage<TEExamStudentDto> examStudentQuery(IPage<Map> iPage, Long examId, Long activityId, String identity,
+            String name, String roomCode, String courseCode, String grade, Integer enable, String classNo,
+            Integer hasPhoto);
 
-    public List<TEExamStudentDto> examStudentList(Long examId, Long activityId, String identity, String name, String roomCode, String courseCode, String grade, Integer enable, String classNo, Integer hasPhoto);
+    public List<TEExamStudentDto> examStudentList(Long examId, Long activityId, String identity, String name,
+            String roomCode, String courseCode, String grade, Integer enable, String classNo, Integer hasPhoto);
 
     ExamStudentCacheBean getExamStudentCacheBean(Long examStudentId);
 
@@ -78,7 +81,8 @@ public interface TEExamStudentService extends IService<TEExamStudent> {
      * @param courseCode
      * @return
      */
-    public IPage<MarkResultDto> markResultQuery(IPage<Map> iPage, Long examId, Long activityId, String identity, String name, String courseCode);
+    public IPage<MarkResultDto> markResultQuery(IPage<Map> iPage, Long examId, Long activityId, String identity,
+            String name, String courseCode);
 
     /**
      * 查询学生成绩信息(导出用)
@@ -90,7 +94,8 @@ public interface TEExamStudentService extends IService<TEExamStudent> {
      * @param courseCode
      * @return
      */
-    public List<MarkResultSimpleExportDto> markResultQueryExport(Long examId, Long activityId, String identity, String name, String courseCode);
+    public List<MarkResultSimpleExportDto> markResultQueryExport(Long examId, Long activityId, String identity,
+            String name, String courseCode);
 
-	public List<Long> findExamStudentIdsNeedMark(Long examId, String courseCode, Long idGt, Integer count);
+    public List<TEExamStudentDto> findExamStudentIdsNeedMark(Long examId, String courseCode, Long idGt, Integer count);
 }

+ 3 - 3
themis-business/src/main/java/com/qmth/themis/business/service/TOeExamAnswerService.java

@@ -1,11 +1,11 @@
 package com.qmth.themis.business.service;
 
-import java.util.List;
-
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.qmth.themis.business.bean.backend.OpenRecordAnswerBean;
 import com.qmth.themis.business.entity.TOeExamAnswer;
 
+import java.util.List;
+
 /**
  * @Description: 作答结果 服务类
  * @Param:
@@ -15,6 +15,6 @@ import com.qmth.themis.business.entity.TOeExamAnswer;
  */
 public interface TOeExamAnswerService extends IService<TOeExamAnswer> {
 
-	List<OpenRecordAnswerBean> findByRecordIds(List<Long> ids);
+    List<OpenRecordAnswerBean> findByExamRecordId(Long examRecordId);
 
 }

+ 31 - 102
themis-business/src/main/java/com/qmth/themis/business/service/TOeExamRecordService.java

@@ -46,10 +46,10 @@ public interface TOeExamRecordService extends IService<TOeExamRecord> {
     public void saveDataByCache(Long recordId);
 
     void saveFaceVerify(ExamTypeEnum type, Long recordId, Long entryAuthenticationId,
-                        VerifyExceptionEnum entryAuthenticationResult);
+            VerifyExceptionEnum entryAuthenticationResult);
 
     void saveLivenessVerify(LivenessTypeEnum type, Long recordId, Long entryAuthenticationId,
-                            VerifyExceptionEnum entryAuthenticationResult);
+            VerifyExceptionEnum entryAuthenticationResult);
 
     /**
      * 考试记录字段同步消息发送
@@ -110,18 +110,10 @@ public interface TOeExamRecordService extends IService<TOeExamRecord> {
      * @param userId
      * @return
      */
-    public IPage<InvigilateListBean> invigilatePageList(IPage<Map> iPage, Long examId,
-                                                        Long examActivityId,
-                                                        String roomCode,
-                                                        Integer paperDownload,
-                                                        String status,
-                                                        String name,
-                                                        String identity,
-                                                        Integer minWarningCount,
-                                                        Integer maxWarningCount,
-                                                        String clientWebsocketStatus,
-                                                        String monitorStatusSource,
-                                                        Long userId);
+    public IPage<InvigilateListBean> invigilatePageList(IPage<Map> iPage, Long examId, Long examActivityId,
+            String roomCode, Integer paperDownload, String status, String name, String identity,
+            Integer minWarningCount, Integer maxWarningCount, String clientWebsocketStatus, String monitorStatusSource,
+            Long userId);
 
     /**
      * 查询实时监控台视频列表
@@ -141,18 +133,9 @@ public interface TOeExamRecordService extends IService<TOeExamRecord> {
      * @param orgId
      * @return
      */
-    public IPage<InvigilateListVideoBean> invigilatePageListVideo(IPage<Map> iPage, Long examId,
-                                                                  Long examActivityId,
-                                                                  String roomCode,
-                                                                  Integer paperDownload,
-                                                                  String status,
-                                                                  String name,
-                                                                  String identity,
-                                                                  Integer minWarningCount,
-                                                                  Integer maxWarningCount,
-                                                                  String clientWebsocketStatus,
-                                                                  Long userId,
-                                                                  Long orgId);
+    public IPage<InvigilateListVideoBean> invigilatePageListVideo(IPage<Map> iPage, Long examId, Long examActivityId,
+            String roomCode, Integer paperDownload, String status, String name, String identity,
+            Integer minWarningCount, Integer maxWarningCount, String clientWebsocketStatus, Long userId, Long orgId);
 
     /**
      * 实时监控台视频随机列表
@@ -163,7 +146,8 @@ public interface TOeExamRecordService extends IService<TOeExamRecord> {
      * @param orgId
      * @return
      */
-    public List<InvigilateListVideoBean> invigilatePageListVideoRandom(Long examId, Long userId, Integer randomNum, Long orgId);
+    public List<InvigilateListVideoBean> invigilatePageListVideoRandom(Long examId, Long userId, Integer randomNum,
+            Long orgId);
 
     /**
      * 查询在线巡考列表
@@ -186,21 +170,10 @@ public interface TOeExamRecordService extends IService<TOeExamRecord> {
      * @param orgId
      * @return
      */
-    public IPage<InvigilateListPatrolBean> invigilatePagePatrolList(IPage<Map> iPage, Long examId,
-                                                                    Long examActivityId,
-                                                                    String roomCode,
-                                                                    String status,
-                                                                    String name,
-                                                                    String identity,
-                                                                    Integer minMultipleFaceCount,
-                                                                    Integer maxMultipleFaceCount,
-                                                                    Integer minExceptionCount,
-                                                                    Integer maxExceptionCount,
-                                                                    Integer minWarningCount,
-                                                                    Integer maxWarningCount,
-                                                                    String clientWebsocketStatus,
-                                                                    Long userId,
-                                                                    Long orgId);
+    public IPage<InvigilateListPatrolBean> invigilatePagePatrolList(IPage<Map> iPage, Long examId, Long examActivityId,
+            String roomCode, String status, String name, String identity, Integer minMultipleFaceCount,
+            Integer maxMultipleFaceCount, Integer minExceptionCount, Integer maxExceptionCount, Integer minWarningCount,
+            Integer maxWarningCount, String clientWebsocketStatus, Long userId, Long orgId);
 
     /**
      * 预警提醒列表
@@ -223,19 +196,9 @@ public interface TOeExamRecordService extends IService<TOeExamRecord> {
      * @return
      */
     public IPage<InvigilateListWarningBean> invigilatePageWarningList(IPage<Map> iPage, Long examId,
-                                                                      Long examActivityId,
-                                                                      String roomCode,
-                                                                      Integer approveStatus,
-                                                                      String name,
-                                                                      String identity,
-                                                                      Integer minMultipleFaceCount,
-                                                                      Integer maxMultipleFaceCount,
-                                                                      Integer minExceptionCount,
-                                                                      Integer maxExceptionCount,
-                                                                      Integer minWarningCount,
-                                                                      Integer maxWarningCount,
-                                                                      Long userId,
-                                                                      Long orgId);
+            Long examActivityId, String roomCode, Integer approveStatus, String name, String identity,
+            Integer minMultipleFaceCount, Integer maxMultipleFaceCount, Integer minExceptionCount,
+            Integer maxExceptionCount, Integer minWarningCount, Integer maxWarningCount, Long userId, Long orgId);
 
     /**
      * 预警提醒清除未阅列表
@@ -256,20 +219,10 @@ public interface TOeExamRecordService extends IService<TOeExamRecord> {
      * @param orgId
      * @return
      */
-    public Integer approveStatusListUpdate(Long examId,
-                                           Long examActivityId,
-                                           String roomCode,
-                                           Integer approveStatus,
-                                           String name,
-                                           String identity,
-                                           Integer minMultipleFaceCount,
-                                           Integer maxMultipleFaceCount,
-                                           Integer minExceptionCount,
-                                           Integer maxExceptionCount,
-                                           Integer minWarningCount,
-                                           Integer maxWarningCount,
-                                           Long userId,
-                                           Long orgId);
+    public Integer approveStatusListUpdate(Long examId, Long examActivityId, String roomCode, Integer approveStatus,
+            String name, String identity, Integer minMultipleFaceCount, Integer maxMultipleFaceCount,
+            Integer minExceptionCount, Integer maxExceptionCount, Integer minWarningCount, Integer maxWarningCount,
+            Long userId, Long orgId);
 
     /**
      * 进度查询列表
@@ -286,13 +239,8 @@ public interface TOeExamRecordService extends IService<TOeExamRecord> {
      * @return
      */
     public IPage<InvigilateListProgressBean> invigilatePageProgressList(IPage<Map> iPage, Long examId,
-                                                                        Long examActivityId,
-                                                                        String roomCode,
-                                                                        String courseCode,
-                                                                        String name,
-                                                                        String identity,
-                                                                        Long userId,
-                                                                        Long orgId);
+            Long examActivityId, String roomCode, String courseCode, String name, String identity, Long userId,
+            Long orgId);
 
     /**
      * 进度查询列表导出
@@ -307,14 +255,8 @@ public interface TOeExamRecordService extends IService<TOeExamRecord> {
      * @param orgId
      * @return
      */
-    public List<InvigilateListProgressExcelBean> invigilatePageProgressListExport(Long examId,
-                                                                                  Long examActivityId,
-                                                                                  String roomCode,
-                                                                                  String courseCode,
-                                                                                  String name,
-                                                                                  String identity,
-                                                                                  Long userId,
-                                                                                  Long orgId);
+    public List<InvigilateListProgressExcelBean> invigilatePageProgressListExport(Long examId, Long examActivityId,
+            String roomCode, String courseCode, String name, String identity, Long userId, Long orgId);
 
     /**
      * 监考明细管理列表
@@ -340,23 +282,10 @@ public interface TOeExamRecordService extends IService<TOeExamRecord> {
      * @return
      */
     public IPage<InvigilateListHistoryBean> invigilatePageListHistory(IPage<Map> iPage, 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);
-
+            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);
 
     /**
      * 重新算分
@@ -384,7 +313,7 @@ public interface TOeExamRecordService extends IService<TOeExamRecord> {
 
     TOeExamRecord findOneByExamId(Long examId, ExamRecordStatusEnum status);
 
-    public List<OpenRecordNeedMarkBean> findExamRecordNeedMark(Long examId, List<Long> examStudentIds);
+    public List<OpenRecordNeedMarkBean> findExamRecordNeedMark(Long examStudentId);
 
     /**
      * 寻找客观分最高

+ 20 - 11
themis-business/src/main/java/com/qmth/themis/business/service/impl/TEExamStudentServiceImpl.java

@@ -28,7 +28,8 @@ import java.util.Map;
  * @Date: 2020/6/25
  */
 @Service
-public class TEExamStudentServiceImpl extends ServiceImpl<TEExamStudentMapper, TEExamStudent> implements TEExamStudentService {
+public class TEExamStudentServiceImpl extends ServiceImpl<TEExamStudentMapper, TEExamStudent>
+        implements TEExamStudentService {
 
     @Resource
     TEExamStudentMapper teExamStudentMapper;
@@ -49,8 +50,12 @@ public class TEExamStudentServiceImpl extends ServiceImpl<TEExamStudentMapper, T
      * @return
      */
     @Override
-    public IPage<TEExamStudentDto> examStudentQuery(IPage<Map> iPage, Long examId, Long activityId, String identity, String name, String roomCode, String courseCode, String grade, Integer enable, String classNo, Integer hasPhoto) {
-        return teExamStudentMapper.examStudentQuery(iPage, examId, activityId, identity, name, roomCode, courseCode, grade, enable, classNo, hasPhoto);
+    public IPage<TEExamStudentDto> examStudentQuery(IPage<Map> iPage, Long examId, Long activityId, String identity,
+            String name, String roomCode, String courseCode, String grade, Integer enable, String classNo,
+            Integer hasPhoto) {
+        return teExamStudentMapper
+                .examStudentQuery(iPage, examId, activityId, identity, name, roomCode, courseCode, grade, enable,
+                        classNo, hasPhoto);
     }
 
     @Cacheable(value = "exam_student", key = "#examStudentId", unless = "#result == null")
@@ -127,8 +132,10 @@ public class TEExamStudentServiceImpl extends ServiceImpl<TEExamStudentMapper, T
 
     @Override
     public List<TEExamStudentDto> examStudentList(Long examId, Long activityId, String identity, String name,
-                                                  String roomCode, String courseCode, String grade, Integer enable, String classNo, Integer hasPhoto) {
-        return teExamStudentMapper.examStudentList(examId, activityId, identity, name, roomCode, courseCode, grade, enable, classNo, hasPhoto);
+            String roomCode, String courseCode, String grade, Integer enable, String classNo, Integer hasPhoto) {
+        return teExamStudentMapper
+                .examStudentList(examId, activityId, identity, name, roomCode, courseCode, grade, enable, classNo,
+                        hasPhoto);
     }
 
     @Transactional
@@ -157,7 +164,8 @@ public class TEExamStudentServiceImpl extends ServiceImpl<TEExamStudentMapper, T
      * @return
      */
     @Override
-    public IPage<MarkResultDto> markResultQuery(IPage<Map> iPage, Long examId, Long activityId, String identity, String name, String courseCode) {
+    public IPage<MarkResultDto> markResultQuery(IPage<Map> iPage, Long examId, Long activityId, String identity,
+            String name, String courseCode) {
         return teExamStudentMapper.markResultQuery(iPage, examId, activityId, identity, name, courseCode);
     }
 
@@ -172,12 +180,13 @@ public class TEExamStudentServiceImpl extends ServiceImpl<TEExamStudentMapper, T
      * @return
      */
     @Override
-    public List<MarkResultSimpleExportDto> markResultQueryExport(Long examId, Long activityId, String identity, String name, String courseCode) {
+    public List<MarkResultSimpleExportDto> markResultQueryExport(Long examId, Long activityId, String identity,
+            String name, String courseCode) {
         return teExamStudentMapper.markResultQueryExport(examId, activityId, identity, name, courseCode);
     }
 
-	@Override
-	public List<Long> findExamStudentIdsNeedMark(Long examId, String courseCode, Long idGt, Integer count) {
-		return teExamStudentMapper.findExamStudentIdsNeedMark( examId, courseCode,  idGt, count);
-	}
+    @Override
+    public List<TEExamStudentDto> findExamStudentIdsNeedMark(Long examId, String courseCode, Long idGt, Integer count) {
+        return teExamStudentMapper.findExamStudentIdsNeedMark(examId, courseCode, idGt, count);
+    }
 }

+ 182 - 275
themis-business/src/main/java/com/qmth/themis/business/service/impl/TEOpenServiceImpl.java

@@ -11,25 +11,25 @@ import com.qmth.themis.business.bean.backend.OpenRecordAnswerBean;
 import com.qmth.themis.business.bean.backend.OpenRecordNeedMarkBean;
 import com.qmth.themis.business.cache.RedisKeyHelper;
 import com.qmth.themis.business.cache.bean.ExamPaperCacheBean;
-import com.qmth.themis.business.constant.SystemConstant;
+import com.qmth.themis.business.dto.response.TEExamStudentDto;
 import com.qmth.themis.business.entity.TEExam;
-import com.qmth.themis.business.entity.TEExamCourse;
 import com.qmth.themis.business.enums.InvigilateMonitorStatusEnum;
 import com.qmth.themis.business.enums.RecordSelectStrategyEnum;
 import com.qmth.themis.business.service.*;
 import com.qmth.themis.business.util.OssUtil;
 import com.qmth.themis.common.exception.BusinessException;
-import com.qmth.themis.common.util.FileUtil;
 import org.apache.commons.lang3.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.stereotype.Service;
 
 import javax.annotation.Resource;
-import java.io.File;
 import java.io.IOException;
 import java.nio.charset.StandardCharsets;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
 import java.util.stream.Collectors;
 
 @Service
@@ -69,6 +69,7 @@ public class TEOpenServiceImpl implements TEOpenService {
     @Override
     public List<OpenExamCourseBean> examCourseQueryPage(Long examId, String courseCode, Boolean hasPaper,
             int pageNumber, int pageSize) {
+        checkExam(examId);
         Page<OpenExamCourseBean> ipage = new Page<>(pageNumber, pageSize);
         ipage.addOrder(OrderItem.desc("t.id"));
         IPage<OpenExamCourseBean> ret = examCourseService.examCourseQueryForOpen(ipage, examId, courseCode, hasPaper);
@@ -76,309 +77,215 @@ public class TEOpenServiceImpl implements TEOpenService {
     }
 
     @Override
-    public JSONObject examPaperDetail(Long paperId, String filter) {
-        String tempDir = SystemConstant.TEMP_FILES_DIR;
-        String dir = tempDir + "/" + uuid() + "/";
-        File dfile = new File(dir);
+    public JSONObject examPaperDetail(Long paperId, String filter) throws IOException {
+        ExamPaperCacheBean paper = examPaperService.getExamPaperCacheBean(paperId);
+        if (paper == null) {
+            throw new BusinessException("未找到试卷信息");
+        }
+        checkExam(paper.getExamId());
+        if (StringUtils.isBlank(paper.getAnswerPath())) {
+            throw new BusinessException("该试卷未上传答案");
+        }
+        boolean acceptObjective = filter == null || "objective".equals(filter);
+        boolean acceptSubjective = filter == null || "subjective".equals(filter);
+        //解析答案JSON文件
+        JSONObject answerJson = JSONObject
+                .parseObject(new String(ossUtil.download(false, paper.getAnswerPath()), StandardCharsets.UTF_8));
+        JSONArray answerDetails = answerJson.getJSONArray("details");
+        //解析试卷JSON文件
+        JSONObject paperResult = JSONObject
+                .parseObject(new String(ossUtil.download(false, paper.getPaperViewPath()), StandardCharsets.UTF_8));
+        paperResult.put("id", paper.getId());
+        paperResult.put("code", paper.getCode());
+        paperResult.put("name", paper.getName());
+        JSONArray paperDetails = paperResult.getJSONArray("details");
+        for (int i = 0; i < paperDetails.size(); i++) {
+            //遍历所有大题
+            JSONObject paperDetail = paperDetails.getJSONObject(i);
+            JSONObject answerDetail = answerDetails.getJSONObject(i);
+            JSONArray answers = answerDetail != null ? answerDetail.getJSONArray("questions") : null;
+            //按条件过滤需要的小题同时合并答案
+            paperDetail.put("questions",
+                    filterQuestions(paperDetail.getJSONArray("questions"), answers, acceptObjective, acceptSubjective));
+        }
+        return paperResult;
+    }
 
-        try {
-            ExamPaperCacheBean paper = examPaperService.getExamPaperCacheBean(paperId);
-            if (paper == null) {
-                throw new BusinessException("未找到试卷信息");
+    private JSONArray filterQuestions(JSONArray questions, JSONArray answers, boolean acceptObjective,
+            boolean acceptSubjective) {
+        JSONArray collection = new JSONArray();
+        for (int i = 0; i < questions.size(); i++) {
+            JSONObject question = questions.getJSONObject(i);
+            //根据题号查找答案
+            JSONObject answer = findJsonObject(answers, question.getIntValue("number"));
+            boolean accept = true;
+            //判断结构类型
+            switch (question.getIntValue("structType")) {
+            case 1:
+                //单选
+            case 2:
+                //多选
+            case 3:
+                //判断
+                accept = acceptObjective;
+                break;
+            case 4:
+                //填空
+            case 5:
+                //问答
+                accept = acceptSubjective;
+                break;
+            case 6:
+                //套题
+                //按条件过滤套题下所有子题
+                JSONArray subAnswers = answer != null ? answer.getJSONArray("subQuestions") : null;
+                question.put("subQuestions",
+                        filterQuestions(question.getJSONArray("subQuestions"), subAnswers, acceptObjective,
+                                acceptSubjective));
+                break;
+            default:
+                accept = false;
             }
-            checkExam(paper.getExamId());
-            dfile.mkdirs();
-            String paperPath = paper.getPaperViewPath();
-            String anwserPath = paper.getAnswerPath();
-            File paperFile = new File(dir + uuid() + ".json");
-            File anwserFile = new File(dir + uuid() + ".json");
-            FileUtil.saveUrlAsFile(ossUtil.getAliYunOssPrivateDomain().getPrivateUrl() + "/" + paperPath, paperFile);
-            FileUtil.saveUrlAsFile(ossUtil.getAliYunOssPrivateDomain().getPrivateUrl() + "/" + anwserPath, anwserFile);
-            JSONObject answerJson = JSONObject.parseObject(FileUtil.readFileContent(anwserFile));
-            JSONArray answerdetails = answerJson.getJSONArray("details");
-            JSONObject structJson = JSONObject.parseObject(FileUtil.readFileContent(paperFile));
-            structJson.put("id", paperId);
-            structJson.put("code", paper.getCode());
-            JSONArray structdetails = structJson.getJSONArray("details");
-            for (int i = 0; i < answerdetails.size(); i++) {
-                JSONArray answerdetailquestions = answerdetails.getJSONObject(i).getJSONArray("questions");
-                JSONArray structdetailquestions = structdetails.getJSONObject(i).getJSONArray("questions");
-                for (int j = 0; j < structdetailquestions.size(); j++) {
-                    JSONObject answerquestion = answerdetailquestions.getJSONObject(j);
-                    JSONObject structquestion = structdetailquestions.getJSONObject(j);
-                    if ("objective".equals(filter)) {
-                        if (structquestion.getInteger("structType").intValue() == 1
-                                || structquestion.getInteger("structType").intValue() == 2
-                                || structquestion.getInteger("structType").intValue() == 3) {
-                            if (structquestion.getInteger("structType").intValue() == 3) {
-                                structquestion.put("answer", answerquestion.getBoolean("answer"));
-                            } else {
-                                structquestion.put("answer", answerquestion.getJSONArray("answer"));
-                            }
-                        } else {
-                            if (structquestion.getInteger("structType").intValue() == 6) {
-                                JSONArray answersubQuestions = answerquestion.getJSONArray("subQuestions");
-                                JSONArray structsubQuestions = structquestion.getJSONArray("subQuestions");
-                                for (int k = 0; k < structsubQuestions.size(); k++) {
-                                    JSONObject answersubquestion = answersubQuestions.getJSONObject(k);
-                                    JSONObject structsubquestion = structsubQuestions.getJSONObject(k);
-                                    if (structsubquestion.getInteger("structType").intValue() == 1
-                                            || structsubquestion.getInteger("structType").intValue() == 2
-                                            || structsubquestion.getInteger("structType").intValue() == 3) {
-                                        if (structsubquestion.getInteger("structType").intValue() == 3) {
-                                            structsubquestion.put("answer", answersubquestion.getBoolean("answer"));
-                                        } else {
-                                            structsubquestion.put("answer", answersubquestion.getJSONArray("answer"));
-                                        }
-                                    } else {
-                                        structsubQuestions.remove(k);
-                                        k--;
-                                    }
-                                }
-                            } else {
-                                structdetailquestions.remove(j);
-                                j--;
-                            }
-                        }
-
-                    } else if ("subjective".equals(filter)) {
-                        if (structquestion.getInteger("structType").intValue() != 1
-                                && structquestion.getInteger("structType").intValue() != 2
-                                && structquestion.getInteger("structType").intValue() != 3) {
-                            structquestion.put("answer", answerquestion.getJSONArray("answer"));
-                        } else {
-                            if (structquestion.getInteger("structType").intValue() == 6) {
-                                JSONArray answersubQuestions = answerquestion.getJSONArray("subQuestions");
-                                JSONArray structsubQuestions = structquestion.getJSONArray("subQuestions");
-                                for (int k = 0; k < structsubQuestions.size(); k++) {
-                                    JSONObject answersubquestion = answersubQuestions.getJSONObject(k);
-                                    JSONObject structsubquestion = structsubQuestions.getJSONObject(k);
-                                    if (structsubquestion.getInteger("structType").intValue() != 1
-                                            && structsubquestion.getInteger("structType").intValue() != 2
-                                            && structsubquestion.getInteger("structType").intValue() != 3) {
-                                        structsubquestion.put("answer", answersubquestion.getJSONArray("answer"));
-                                    } else {
-                                        structsubQuestions.remove(k);
-                                        k--;
-                                    }
-                                }
-                            } else {
-                                structdetailquestions.remove(j);
-                                j--;
-                            }
-                        }
-                    } else {
-                        if (structquestion.getInteger("structType").intValue() != 6) {
-                            if (structquestion.getInteger("structType").intValue() == 3) {
-                                structquestion.put("answer", answerquestion.getBoolean("answer"));
-                            } else {
-                                structquestion.put("answer", answerquestion.getJSONArray("answer"));
-                            }
-                        } else {
-                            JSONArray answersubQuestions = answerquestion.getJSONArray("subQuestions");
-                            JSONArray structsubQuestions = structquestion.getJSONArray("subQuestions");
-                            for (int k = 0; k < structsubQuestions.size(); k++) {
-                                JSONObject answersubquestion = answersubQuestions.getJSONObject(k);
-                                JSONObject structsubquestion = structsubQuestions.getJSONObject(k);
-                                if (structsubquestion.getInteger("structType").intValue() == 3) {
-                                    structsubquestion.put("answer", answersubquestion.getBoolean("answer"));
-                                } else {
-                                    structsubquestion.put("answer", answersubquestion.getJSONArray("answer"));
-                                }
-                            }
-                        }
-                    }
-
+            if (accept) {
+                if (answer != null) {
+                    question.put("answer", answer.get("answer"));
                 }
+                collection.add(question);
             }
-            return structJson;
-        } finally {
-            FileUtil.deleteFolder(dir);
         }
+        return collection;
     }
 
-    private String uuid() {
-        return UUID.randomUUID().toString().replaceAll("-", "");
+    private JSONObject findJsonObject(JSONArray array, int number) {
+        if (array != null) {
+            for (int i = 0; i < array.size(); i++) {
+                JSONObject item = array.getJSONObject(i);
+                if (item.getIntValue("number") == number) {
+                    return item;
+                }
+            }
+        }
+        return null;
     }
 
-    private void checkExam(Long examId) {
+    private TEExam checkExam(Long examId) {
         TEExam exam = examService.getById(examId);
         if (exam == null) {
             throw new BusinessException("未找到考试信息");
         }
-        if (exam.getEnable() == null || exam.getEnable().intValue() == 0) {
+        if (exam.getEnable() == null || exam.getEnable() == 0) {
             throw new BusinessException("考试批次已禁用");
         }
         if (!InvigilateMonitorStatusEnum.FINISHED.equals(exam.getMonitorStatus())) {
             throw new BusinessException("考试批次监考未结束");
         }
-        List<TEExamCourse> courses = examCourseService.findByExamId(examId);
-        if (courses == null || courses.size() == 0) {
-            throw new BusinessException("考试批次下没有课程");
-        }
-        for (TEExamCourse course : courses) {
-            if (course.getHasAnswer() == null || course.getHasAnswer().intValue() == 0) {
-                throw new BusinessException("考试批次下标答未齐全");
-            }
-        }
+        return exam;
+        //        List<TEExamCourse> courses = examCourseService.findByExamId(examId);
+        //        if (courses == null || courses.size() == 0) {
+        //            throw new BusinessException("考试批次下没有课程");
+        //        }
+        //        for (TEExamCourse course : courses) {
+        //            if (course.getHasAnswer() == null || course.getHasAnswer().intValue() == 0) {
+        //                throw new BusinessException("考试批次下标答未齐全");
+        //            }
+        //        }
     }
 
     @Override
     public JSONArray examRecordNeedMark(Long examId, String courseCode, Long idGt, Integer count) {
-        checkExam(examId);
-        List<OpenRecordNeedMarkBean> list;
-        for (; ; ) {
-            List<Long> examStudentIds = examStudentService.findExamStudentIdsNeedMark(examId, courseCode, idGt, count);
-            if (examStudentIds == null || examStudentIds.size() == 0) {
-                return null;
-            }
-            list = findExamRecordNeedMark(examId, examStudentIds);
-            if (list == null || list.size() == 0) {
-                idGt = examStudentIds.get(examStudentIds.size() - 1);
-            } else {
-                break;
-            }
-        }
-        List<Long> ids = list.stream().map(dto -> dto.getExamRecordId()).collect(Collectors.toList());
-        List<OpenRecordAnswerBean> answers = examAnswerService.findByRecordIds(ids);
-        if (answers != null && answers.size() > 0) {
-            for (int i = 0; i < answers.size(); i++) {//剔除客观题答案
-                OpenRecordAnswerBean answer = answers.get(i);
-                Map<String, Integer> struct = examPaperService.getPaperStructCacheBean(answer.getPaperId());
-                Integer type = struct.get(RedisKeyHelper
-                        .examAnswerHashKey(answer.getMainNumber(), answer.getSubNumber(), answer.getSubIndex()));
-                if (type == 1 || type == 2 || type == 3) {
-                    answers.remove(i);
-                    i--;
-                }
-            }
-        }
-        if (answers != null && answers.size() > 0) {
-            Map<Long, Integer> map = new HashMap<>();
-            for (int i = 0; i < list.size(); i++) {
-                map.put(list.get(i).getExamRecordId(), i);
-            }
-            for (OpenRecordAnswerBean anwser : answers) {
-                OpenRecordNeedMarkBean mark = list.get(map.get(anwser.getRecordId()));
-                List<OpenRecordAnswerBean> ans = mark.getAnswers();
-                if (ans == null) {
-                    ans = new ArrayList<OpenRecordAnswerBean>();
-                    mark.setAnswers(ans);
-                }
-                ans.add(anwser);
-            }
-        }
-        JSONArray ja = JSONArray.parseArray(JSONArray.toJSONString(list));
-        for (int i = 0; i < ja.size(); i++) {
-            JSONObject job = ja.getJSONObject(i);
-            JSONArray answersJa = job.getJSONArray("answers");
-            if (answersJa != null) {
-                for (int j = 0; j < answersJa.size(); j++) {
-                    JSONObject answersJob = answersJa.getJSONObject(j);
-                    answersJob.remove("recordId");
-                    answersJob.remove("paperId");
-                    String answerStr = answersJob.getString("answer");
-                    if (StringUtils.isNotBlank(answerStr)) {
-                        if (answerStr.toLowerCase().startsWith("true") || answerStr.toLowerCase().startsWith("false")) {
-                            answersJob.put("answer", Boolean.getBoolean(answerStr.replaceAll("\n", "")));
-                        } else {
-                            answersJob.put("answer", answersJob.getJSONArray("answer"));
+        JSONArray result = new JSONArray();
+        TEExam exam = checkExam(examId);
+        Map<Long, ExamPaperCacheBean> paperMap = new HashMap<>();
+        final Map<Long, Map<String, Integer>> paperStructMap = new HashMap<>();
+        //查询需要参与评卷的考生
+        List<TEExamStudentDto> examStudents = examStudentService
+                .findExamStudentIdsNeedMark(examId, courseCode, idGt, count);
+        if (examStudents != null) {
+            for (TEExamStudentDto examStudent : examStudents) {
+                JSONObject obj = new JSONObject();
+                obj.put("id", examStudent.getId());
+                obj.put("identity", examStudent.getIdentity());
+                obj.put("name", examStudent.getName());
+                obj.put("activityCode", examStudent.getActivityCode());
+                obj.put("courseCode", examStudent.getCourseCode());
+                obj.put("courseName", examStudent.getCourseName());
+                //查询需要主观题评卷的考试记录
+                List<OpenRecordNeedMarkBean> recordList = findExamRecordNeedMark(examStudent.getId(), paperMap,
+                        exam.getRecordSelectStrategy());
+                for (OpenRecordNeedMarkBean record : recordList) {
+                    //查询所有单题作答结果
+                    List<OpenRecordAnswerBean> answers = examAnswerService.findByExamRecordId(record.getId());
+                    record.setAnswers(answers.stream().filter(answer -> {
+                        Map<String, Integer> struct = paperStructMap.get(record.getPaperId());
+                        if (struct == null) {
+                            struct = examPaperService.getPaperStructCacheBean(record.getPaperId());
+                            if (struct != null) {
+                                paperStructMap.put(record.getPaperId(), struct);
+                            } else {
+                                log.error("找不到对应的试卷结构,paperId=" + record.getPaperId());
+                                return false;
+                            }
                         }
-                    }
+                        Integer type = struct.get(RedisKeyHelper
+                                .examAnswerHashKey(answer.getMainNumber(), answer.getSubNumber(),
+                                        answer.getSubIndex()));
+                        //过滤单选、多选、判断题
+                        return type != null && type != 1 && type != 2 && type != 3;
+                    }).collect(Collectors.toList()));
                 }
+                obj.put("records", recordList);
+                result.add(obj);
             }
         }
-        return ja;
+        paperMap.clear();
+        paperStructMap.clear();
+        return result;
     }
 
-    private List<OpenRecordNeedMarkBean> findExamRecordNeedMark(Long examId, List<Long> examStudentIds) {
-        List<OpenRecordNeedMarkBean> list = examRecordService.findExamRecordNeedMark(examId, examStudentIds);
-        if (list == null || list.size() == 0) {
-            return null;
-        }
-        for (int i = 0; i < list.size(); i++) {//剔除没有主观题的试卷考试记录
-            ExamPaperCacheBean paper = examPaperService.getExamPaperCacheBean(list.get(i).getPaperId());
-            if (paper.getTotalSubjectiveScore() == 0) {
-                list.remove(i);
-                i--;
-            }
+    private List<OpenRecordNeedMarkBean> findExamRecordNeedMark(Long examStudentId,
+            Map<Long, ExamPaperCacheBean> paperMap, RecordSelectStrategyEnum strategy) {
+        List<OpenRecordNeedMarkBean> list = examRecordService.findExamRecordNeedMark(examStudentId);
+        List<OpenRecordNeedMarkBean> result = new ArrayList<>();
+        if (list == null) {
+            return result;
         }
-        if (list == null || list.size() == 0) {
-            return null;
-        }
-        TEExam exam = examService.getById(examId);
-        if (RecordSelectStrategyEnum.HIGHEST_TOTAL_SCORE.equals(exam.getRecordSelectStrategy())) {//全阅
-            return list;
-        } else if (RecordSelectStrategyEnum.HIGHEST_OBJECTIVE_SCORE
-                .equals(exam.getRecordSelectStrategy())) {//客观分最高,相同则都阅
-            Map<Long, List<OpenRecordNeedMarkBean>> map = new HashMap<>();
-            for (OpenRecordNeedMarkBean bean : list) {
-                List<OpenRecordNeedMarkBean> temList = map.get(bean.getExamStudentId());
-                if (temList == null) {
-                    temList = new ArrayList<OpenRecordNeedMarkBean>();
-                    temList.add(bean);
-                    map.put(bean.getExamStudentId(), temList);
+        double highestObjectiveScore = 0.0;
+        long maxFinishTime = 0L;
+        for (OpenRecordNeedMarkBean bean : list) {
+            //获取对应的试卷信息
+            ExamPaperCacheBean paper = paperMap.get(bean.getPaperId());
+            if (paper == null) {
+                paper = examPaperService.getExamPaperCacheBean(bean.getPaperId());
+                if (paper == null) {
+                    log.error("找不到对应的试卷信息, paperId=" + bean.getPaperId());
+                    continue;
                 } else {
-                    if (temList.get(0).getObjectiveScore() == bean.getObjectiveScore()) {
-                        temList.add(bean);
-                    } else if (temList.get(0).getObjectiveScore() < bean.getObjectiveScore()) {
-                        temList = new ArrayList<OpenRecordNeedMarkBean>();
-                        temList.add(bean);
-                        map.put(bean.getExamStudentId(), temList);
-                    }
-                }
-            }
-            List<OpenRecordNeedMarkBean> ret = new ArrayList<OpenRecordNeedMarkBean>();
-            for (List<OpenRecordNeedMarkBean> tem : map.values()) {
-                for (OpenRecordNeedMarkBean bean : tem) {
-                    ret.add(bean);
+                    paperMap.put(bean.getPaperId(), paper);
                 }
             }
-            Collections.sort(ret, new Comparator<OpenRecordNeedMarkBean>() {
-
-                @Override
-                public int compare(OpenRecordNeedMarkBean o1, OpenRecordNeedMarkBean o2) {
-                    Long c1 = o1.getExamStudentId();
-                    Long c2 = o2.getExamStudentId();
-                    if (c1 > c2) {
-                        return 1;
-                    } else if (c1 < c2) {
-                        return -1;
-                    } else {
-                        return 0;
-                    }
-                }
-
-            });
-            return ret;
-        } else if (RecordSelectStrategyEnum.LATEST.equals(exam.getRecordSelectStrategy())) {//最后一次提交
-            Map<Long, OpenRecordNeedMarkBean> map = new HashMap<>();
-            for (OpenRecordNeedMarkBean bean : list) {
-                OpenRecordNeedMarkBean old = map.get(bean.getExamStudentId());
-                if (old == null || old.getFinishTime() < bean.getFinishTime()) {
-                    map.put(bean.getExamStudentId(), bean);
-                }
+            //根据试卷结构过滤没有主观题的情况
+            if (paper.getTotalSubjectiveScore() == 0) {
+                continue;
             }
-            List<OpenRecordNeedMarkBean> ret = map.values().stream().collect(Collectors.toList());
-            Collections.sort(ret, new Comparator<OpenRecordNeedMarkBean>() {
-
-                @Override
-                public int compare(OpenRecordNeedMarkBean o1, OpenRecordNeedMarkBean o2) {
-                    Long c1 = o1.getExamStudentId();
-                    Long c2 = o2.getExamStudentId();
-                    if (c1 > c2) {
-                        return 1;
-                    } else if (c1 < c2) {
-                        return -1;
-                    } else {
-                        return 0;
-                    }
-                }
-
-            });
-            return ret;
-        } else {
-            throw new BusinessException("考试批次阅卷类型未定义");
+            highestObjectiveScore = Math.max(highestObjectiveScore, bean.getObjectiveScore());
+            maxFinishTime = Math.max(maxFinishTime, bean.getFinishTime());
+            result.add(bean);
+        }
+        if (result.isEmpty()) {
+            return result;
+        }
+        switch (strategy) {
+        case HIGHEST_OBJECTIVE_SCORE:
+            //客观分最高,客观分相同则全部提交阅卷
+            final double score = highestObjectiveScore;
+            return result.stream().filter(bean -> bean.getObjectiveScore() == score).collect(Collectors.toList());
+        case LATEST:
+            //最后一次提交
+            final long time = maxFinishTime;
+            return result.stream().filter(bean -> bean.getFinishTime() == time).collect(Collectors.toList());
+        default:
+            //总分最高,全部提交阅卷
+            return result;
         }
     }
 }

+ 11 - 12
themis-business/src/main/java/com/qmth/themis/business/service/impl/TOeExamAnswerServiceImpl.java

@@ -5,12 +5,10 @@ import com.qmth.themis.business.bean.backend.OpenRecordAnswerBean;
 import com.qmth.themis.business.dao.TOeExamAnswerMapper;
 import com.qmth.themis.business.entity.TOeExamAnswer;
 import com.qmth.themis.business.service.TOeExamAnswerService;
-
-import java.util.List;
+import org.springframework.stereotype.Service;
 
 import javax.annotation.Resource;
-
-import org.springframework.stereotype.Service;
+import java.util.List;
 
 /**
  * @Description: 作答结果 服务实现类
@@ -20,14 +18,15 @@ import org.springframework.stereotype.Service;
  * @Date: 2020/6/25
  */
 @Service
-public class TOeExamAnswerServiceImpl extends ServiceImpl<TOeExamAnswerMapper, TOeExamAnswer> implements TOeExamAnswerService {
+public class TOeExamAnswerServiceImpl extends ServiceImpl<TOeExamAnswerMapper, TOeExamAnswer>
+        implements TOeExamAnswerService {
+
+    @Resource
+    TOeExamAnswerMapper examAnswerMapper;
 
-	@Resource
-	TOeExamAnswerMapper examAnswerMapper;
-	
-	@Override
-	public List<OpenRecordAnswerBean> findByRecordIds(List<Long> ids) {
-		return examAnswerMapper.findByRecordIds(ids);
-	}
+    @Override
+    public List<OpenRecordAnswerBean> findByExamRecordId(Long examRecordId) {
+        return examAnswerMapper.findByExamRecordId(examRecordId);
+    }
 
 }

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

@@ -142,7 +142,7 @@ public class TOeExamRecordServiceImpl extends ServiceImpl<TOeExamRecordMapper, T
     @Transactional
     @Override
     public Long saveByPrepare(Long examId, Long examActivityId, Long examStudentId, Long paperId,
-                              Integer serialNumber) {
+            Integer serialNumber) {
         ExamActivityCacheBean ac = examActivityService.getExamActivityCacheBean(examActivityId);
         ExamCacheBean exam = examService.getExamCacheBean(examId);
         TOeExamRecord er = new TOeExamRecord();
@@ -442,13 +442,13 @@ public class TOeExamRecordServiceImpl extends ServiceImpl<TOeExamRecordMapper, T
 
     @Override
     public void saveFaceVerify(ExamTypeEnum type, Long recordId, Long entryAuthenticationId,
-                               VerifyExceptionEnum entryAuthenticationResult) {
+            VerifyExceptionEnum entryAuthenticationResult) {
         if (ExamTypeEnum.FIRST_START.equals(type)) {
             ExamRecordCacheUtil.setEntryAuthenticationId(recordId, entryAuthenticationId, false);
             ExamRecordCacheUtil.setEntryAuthenticationResult(recordId, entryAuthenticationResult, false);
-            String[] columns = new String[]{ExamRecordFieldEnum.entry_authentication_id.name(),
-                    ExamRecordFieldEnum.entry_authentication_result.name()};
-            Object[] values = new Object[]{entryAuthenticationId, entryAuthenticationResult};
+            String[] columns = new String[] { ExamRecordFieldEnum.entry_authentication_id.name(),
+                    ExamRecordFieldEnum.entry_authentication_result.name() };
+            Object[] values = new Object[] { entryAuthenticationId, entryAuthenticationResult };
             this.dataUpdatesMq(recordId, columns, values);
         } else if (ExamTypeEnum.IN_PROCESS.equals(type)) {
 
@@ -457,13 +457,13 @@ public class TOeExamRecordServiceImpl extends ServiceImpl<TOeExamRecordMapper, T
 
     @Override
     public void saveLivenessVerify(LivenessTypeEnum type, Long recordId, Long entryAuthenticationId,
-                                   VerifyExceptionEnum entryAuthenticationResult) {
+            VerifyExceptionEnum entryAuthenticationResult) {
         if (LivenessTypeEnum.FIRST_START.equals(type)) {
             ExamRecordCacheUtil.setEntryAuthenticationId(recordId, entryAuthenticationId, false);
             ExamRecordCacheUtil.setEntryAuthenticationResult(recordId, entryAuthenticationResult, false);
-            String[] columns = new String[]{ExamRecordFieldEnum.entry_authentication_id.name(),
-                    ExamRecordFieldEnum.entry_authentication_result.name()};
-            Object[] values = new Object[]{entryAuthenticationId, entryAuthenticationResult};
+            String[] columns = new String[] { ExamRecordFieldEnum.entry_authentication_id.name(),
+                    ExamRecordFieldEnum.entry_authentication_result.name() };
+            Object[] values = new Object[] { entryAuthenticationId, entryAuthenticationResult };
             this.dataUpdatesMq(recordId, columns, values);
         } else if (LivenessTypeEnum.IN_PROCESS.equals(type)) {
             Integer count = ExamRecordCacheUtil.getInProcessLivenessVerifyCount(recordId);
@@ -570,9 +570,9 @@ public class TOeExamRecordServiceImpl extends ServiceImpl<TOeExamRecordMapper, T
      */
     @Override
     public IPage<InvigilateListBean> invigilatePageList(IPage<Map> iPage, Long examId, Long examActivityId,
-                                                        String roomCode, Integer paperDownload, String status, String name, String identity,
-                                                        Integer minWarningCount, Integer maxWarningCount, String clientWebsocketStatus, String monitorStatusSource,
-                                                        Long userId) {
+            String roomCode, Integer paperDownload, String status, String name, String identity,
+            Integer minWarningCount, Integer maxWarningCount, String clientWebsocketStatus, String monitorStatusSource,
+            Long userId) {
         return tOeExamRecordMapper
                 .invigilatePageList(iPage, examId, examActivityId, roomCode, paperDownload, status, name, identity,
                         minWarningCount, maxWarningCount, clientWebsocketStatus, monitorStatusSource, userId);
@@ -598,8 +598,8 @@ public class TOeExamRecordServiceImpl extends ServiceImpl<TOeExamRecordMapper, T
      */
     @Override
     public IPage<InvigilateListVideoBean> invigilatePageListVideo(IPage<Map> iPage, Long examId, Long examActivityId,
-                                                                  String roomCode, Integer paperDownload, String status, String name, String identity,
-                                                                  Integer minWarningCount, Integer maxWarningCount, String clientWebsocketStatus, Long userId, Long orgId) {
+            String roomCode, Integer paperDownload, String status, String name, String identity,
+            Integer minWarningCount, Integer maxWarningCount, String clientWebsocketStatus, Long userId, Long orgId) {
         return tOeExamRecordMapper
                 .invigilatePageListVideo(iPage, examId, examActivityId, roomCode, paperDownload, status, name, identity,
                         minWarningCount, maxWarningCount, clientWebsocketStatus, userId, orgId);
@@ -616,7 +616,7 @@ public class TOeExamRecordServiceImpl extends ServiceImpl<TOeExamRecordMapper, T
      */
     @Override
     public List<InvigilateListVideoBean> invigilatePageListVideoRandom(Long examId, Long userId, Integer randomNum,
-                                                                       Long orgId) {
+            Long orgId) {
         return tOeExamRecordMapper.invigilatePageListVideoRandom(examId, userId, randomNum, orgId);
     }
 
@@ -643,9 +643,9 @@ public class TOeExamRecordServiceImpl extends ServiceImpl<TOeExamRecordMapper, T
      */
     @Override
     public IPage<InvigilateListPatrolBean> invigilatePagePatrolList(IPage<Map> iPage, Long examId, Long examActivityId,
-                                                                    String roomCode, String status, String name, String identity, Integer minMultipleFaceCount,
-                                                                    Integer maxMultipleFaceCount, Integer minExceptionCount, Integer maxExceptionCount, Integer minWarningCount,
-                                                                    Integer maxWarningCount, String clientWebsocketStatus, Long userId, Long orgId) {
+            String roomCode, String status, String name, String identity, Integer minMultipleFaceCount,
+            Integer maxMultipleFaceCount, Integer minExceptionCount, Integer maxExceptionCount, Integer minWarningCount,
+            Integer maxWarningCount, String clientWebsocketStatus, Long userId, Long orgId) {
         return tOeExamRecordMapper
                 .invigilatePagePatrolList(iPage, examId, examActivityId, roomCode, status, name, identity,
                         minMultipleFaceCount, maxMultipleFaceCount, minExceptionCount, maxExceptionCount,
@@ -674,9 +674,9 @@ public class TOeExamRecordServiceImpl extends ServiceImpl<TOeExamRecordMapper, T
      */
     @Override
     public IPage<InvigilateListWarningBean> invigilatePageWarningList(IPage<Map> iPage, Long examId,
-                                                                      Long examActivityId, String roomCode, Integer approveStatus, String name, String identity,
-                                                                      Integer minMultipleFaceCount, Integer maxMultipleFaceCount, Integer minExceptionCount,
-                                                                      Integer maxExceptionCount, Integer minWarningCount, Integer maxWarningCount, Long userId, Long orgId) {
+            Long examActivityId, String roomCode, Integer approveStatus, String name, String identity,
+            Integer minMultipleFaceCount, Integer maxMultipleFaceCount, Integer minExceptionCount,
+            Integer maxExceptionCount, Integer minWarningCount, Integer maxWarningCount, Long userId, Long orgId) {
         return tOeExamRecordMapper
                 .invigilatePageWarningList(iPage, examId, examActivityId, roomCode, approveStatus, name, identity,
                         minMultipleFaceCount, maxMultipleFaceCount, minExceptionCount, maxExceptionCount,
@@ -704,9 +704,9 @@ public class TOeExamRecordServiceImpl extends ServiceImpl<TOeExamRecordMapper, T
      */
     @Override
     public Integer approveStatusListUpdate(Long examId, Long examActivityId, String roomCode, Integer approveStatus,
-                                           String name, String identity, Integer minMultipleFaceCount, Integer maxMultipleFaceCount,
-                                           Integer minExceptionCount, Integer maxExceptionCount, Integer minWarningCount, Integer maxWarningCount,
-                                           Long userId, Long orgId) {
+            String name, String identity, Integer minMultipleFaceCount, Integer maxMultipleFaceCount,
+            Integer minExceptionCount, Integer maxExceptionCount, Integer minWarningCount, Integer maxWarningCount,
+            Long userId, Long orgId) {
         return tOeExamRecordMapper
                 .approveStatusListUpdate(examId, examActivityId, roomCode, approveStatus, name, identity,
                         minMultipleFaceCount, maxMultipleFaceCount, minExceptionCount, maxExceptionCount,
@@ -728,8 +728,8 @@ public class TOeExamRecordServiceImpl extends ServiceImpl<TOeExamRecordMapper, T
      */
     @Override
     public IPage<InvigilateListProgressBean> invigilatePageProgressList(IPage<Map> iPage, Long examId,
-                                                                        Long examActivityId, String roomCode, String courseCode, String name, String identity, Long userId,
-                                                                        Long orgId) {
+            Long examActivityId, String roomCode, String courseCode, String name, String identity, Long userId,
+            Long orgId) {
         return tOeExamRecordMapper
                 .invigilatePageProgressList(iPage, examId, examActivityId, roomCode, courseCode, name, identity, userId,
                         orgId);
@@ -750,7 +750,7 @@ public class TOeExamRecordServiceImpl extends ServiceImpl<TOeExamRecordMapper, T
      */
     @Override
     public List<InvigilateListProgressExcelBean> invigilatePageProgressListExport(Long examId, Long examActivityId,
-                                                                                  String roomCode, String courseCode, String name, String identity, Long userId, Long orgId) {
+            String roomCode, String courseCode, String name, String identity, Long userId, Long orgId) {
         return tOeExamRecordMapper
                 .invigilatePageProgressListExport(examId, examActivityId, roomCode, courseCode, name, identity, userId,
                         orgId);
@@ -781,10 +781,10 @@ public class TOeExamRecordServiceImpl extends ServiceImpl<TOeExamRecordMapper, T
      */
     @Override
     public IPage<InvigilateListHistoryBean> invigilatePageListHistory(IPage<Map> iPage, 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) {
+            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
                 .invigilatePageListHistory(iPage, examId, examActivityId, roomCode, courseCode, status, breachStatus,
                         finishType, name, identity, minMultipleFaceCount, maxMultipleFaceCount, minExceptionCount,
@@ -921,8 +921,8 @@ public class TOeExamRecordServiceImpl extends ServiceImpl<TOeExamRecordMapper, T
     }
 
     @Override
-    public List<OpenRecordNeedMarkBean> findExamRecordNeedMark(Long examId, List<Long> examStudentIds) {
-        return tOeExamRecordMapper.findExamRecordNeedMark(examId, examStudentIds);
+    public List<OpenRecordNeedMarkBean> findExamRecordNeedMark(Long examStudentId) {
+        return tOeExamRecordMapper.findExamRecordNeedMark(examStudentId);
     }
 
     /**
@@ -946,7 +946,7 @@ public class TOeExamRecordServiceImpl extends ServiceImpl<TOeExamRecordMapper, T
      */
     @Override
     public TOeExamRecord findMarkResult(MarkResultDto markResultDto,
-                                        RecordSelectStrategyEnum recordSelectStrategyEnum) {
+            RecordSelectStrategyEnum recordSelectStrategyEnum) {
         TOeExamRecord tOeExamRecord = null;
         Double sumScore = null;
         //客观分最高
@@ -1032,13 +1032,14 @@ public class TOeExamRecordServiceImpl extends ServiceImpl<TOeExamRecordMapper, T
                     Long lastBreakTimeNow = System.currentTimeMillis();
                     ExamRecordCacheUtil.setLastBreakTime(recordId, lastBreakTimeNow, false);
                     ExamRecordCacheUtil.setAlreadyBreakCount(recordId, alreadyBreakCount, false);
-                    String[] columns = new String[]{ExamRecordFieldEnum.last_break_id.name(),
+                    String[] columns = new String[] { ExamRecordFieldEnum.last_break_id.name(),
                             ExamRecordFieldEnum.status.name(), ExamRecordFieldEnum.last_break_time.name(),
-                            ExamRecordFieldEnum.already_break_count.name()};
-                    Object[] values = new Object[]{breakId, ExamRecordStatusEnum.BREAK_OFF, lastBreakTimeNow,
-                            alreadyBreakCount};
+                            ExamRecordFieldEnum.already_break_count.name() };
+                    Object[] values = new Object[] { breakId, ExamRecordStatusEnum.BREAK_OFF, lastBreakTimeNow,
+                            alreadyBreakCount };
                     ExamRecordStatusEnum examRecordStatusEnum = ExamRecordCacheUtil.getStatus(recordId);
-                    if (Objects.nonNull(examRecordStatusEnum) && examRecordStatusEnum == ExamRecordStatusEnum.BREAK_OFF) {
+                    if (Objects.nonNull(examRecordStatusEnum)
+                            && examRecordStatusEnum == ExamRecordStatusEnum.BREAK_OFF) {
                         this.dataUpdatesMq(recordId, columns, values);
                         //考试断点异常原因 发送mq start
                         MqDto mqDtoBreak = new MqDto(MqTopicEnum.THEMIS_TOPIC.getCode(), MqTagEnum.EXAM_BREAK.name(),
@@ -1084,8 +1085,9 @@ public class TOeExamRecordServiceImpl extends ServiceImpl<TOeExamRecordMapper, T
                             tranMap.put("mqExecTime", dt.toInstant(ZoneOffset.of("+8")).toEpochMilli());
                             //考试断点延时消息 发送mq start
                             MqDto mqDtoBreakDelay = new MqDto(MqTopicEnum.THEMIS_TOPIC.getCode(),
-                                    MqTagEnum.EXAM_BREAK_DELAY.name(), MqTagEnum.EXAM_BREAK_DELAY, MqTagEnum.EXAM_BREAK_DELAY,
-                                    String.valueOf(recordId), tranMap, String.valueOf(recordId));
+                                    MqTagEnum.EXAM_BREAK_DELAY.name(), MqTagEnum.EXAM_BREAK_DELAY,
+                                    MqTagEnum.EXAM_BREAK_DELAY, String.valueOf(recordId), tranMap,
+                                    String.valueOf(recordId));
                             mqDtoService.assembleSendAsyncDelayMsg(mqDtoBreakDelay);
                             //考试断点延时消息 发送mq end
                         }
@@ -1144,9 +1146,7 @@ public class TOeExamRecordServiceImpl extends ServiceImpl<TOeExamRecordMapper, T
             ExamStudentCacheBean examStudentCacheBean = teExamStudentService.getExamStudentCacheBean(examStudentId);
             ExamCacheBean ec = examService.getExamCacheBean(examId);//考试缓存
             Long lastBreakTime = ExamRecordCacheUtil.getLastBreakTime(recordId);
-            Integer breakExpireSeconds = Objects.isNull(ec.getBreakExpireSeconds()) ?
-                    0 :
-                    ec.getBreakExpireSeconds();
+            Integer breakExpireSeconds = Objects.isNull(ec.getBreakExpireSeconds()) ? 0 : ec.getBreakExpireSeconds();
             Integer durationSeconds = Objects.isNull(ExamRecordCacheUtil.getDurationSeconds(recordId)) ?
                     0 :
                     ExamRecordCacheUtil.getDurationSeconds(recordId);

+ 384 - 359
themis-business/src/main/resources/mapper/TEExamStudentMapper.xml

@@ -1,373 +1,398 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 <mapper
-	namespace="com.qmth.themis.business.dao.TEExamStudentMapper">
+        namespace="com.qmth.themis.business.dao.TEExamStudentMapper">
 
-	<select id="examStudentQuery"
-		resultType="com.qmth.themis.business.dto.response.TEExamStudentDto">
-		select
-		tees.id,
-		tee.id as examId,
-		tee.name as examName,
-		tees.name,
-		tees.`identity`,
-		teea.code,
-		tees.course_code as courseCode,
-		tees.course_name as courseName,
-		tees.enable,
-		tees.room_code as roomCode,
-		tees.room_name as roomName,
-		tees.grade,
-		tees.class_no as classNo,
-		teea.id as examActivityId,
-		teea.code as activityCode,
-		stu.base_photo_path basePhotoUrl
-		from
-		t_e_exam_student tees
-		left join t_e_student stu on tees.student_id=stu.id
-		left join t_e_exam tee on
-		tees.exam_id = tee.id
-		left join t_e_exam_activity teea on
-		tees.exam_activity_id = teea.id
-		<where>
-			<if test="examId != null and examId != ''">
-				and tees.exam_id = #{examId}
-			</if>
-			<if test="activityId != null and activityId != ''">
-				and tees.exam_activity_id = #{activityId}
-			</if>
-			<if test="identity != null and identity != ''">
-				and tees.identity like concat('%', #{identity}, '%')
-			</if>
-			<if test="name != null and name != ''">
-				and tees.name like concat('%', #{name}, '%')
-			</if>
-			<if test="roomCode != null and roomCode != ''">
-				and tees.room_code like concat('%', #{roomCode}, '%')
-			</if>
-			<if test="courseCode != null and courseCode != ''">
-				and tees.course_code = #{courseCode}
-			</if>
-			<if test="enable != null and enable != '' or enable == 0">
-				and tees.enable = #{enable}
-			</if>
-			<if test="grade != null and grade != ''">
-				and tees.grade like concat('%', #{grade}, '%')
-			</if>
-			<if test="classNo != null and classNo != ''">
-				and tees.class_no like concat('%', #{classNo}, '%')
-			</if>
-			<if test="hasPhoto != null">
-				<if test="hasPhoto == 0">
-					and stu.base_photo_path is null
-				</if>
-				<if test="hasPhoto == 1">
-					and stu.base_photo_path is not null
-				</if>
-			</if>
-		</where>
-	</select>
+    <select id="examStudentQuery"
+            resultType="com.qmth.themis.business.dto.response.TEExamStudentDto">
+        select
+        tees.id,
+        tee.id as examId,
+        tee.name as examName,
+        tees.name,
+        tees.`identity`,
+        teea.code,
+        tees.course_code as courseCode,
+        tees.course_name as courseName,
+        tees.enable,
+        tees.room_code as roomCode,
+        tees.room_name as roomName,
+        tees.grade,
+        tees.class_no as classNo,
+        teea.id as examActivityId,
+        teea.code as activityCode,
+        stu.base_photo_path basePhotoUrl
+        from
+        t_e_exam_student tees
+        left join t_e_student stu on tees.student_id=stu.id
+        left join t_e_exam tee on
+        tees.exam_id = tee.id
+        left join t_e_exam_activity teea on
+        tees.exam_activity_id = teea.id
+        <where>
+            <if test="examId != null and examId != ''">
+                and tees.exam_id = #{examId}
+            </if>
+            <if test="activityId != null and activityId != ''">
+                and tees.exam_activity_id = #{activityId}
+            </if>
+            <if test="identity != null and identity != ''">
+                and tees.identity like concat('%', #{identity}, '%')
+            </if>
+            <if test="name != null and name != ''">
+                and tees.name like concat('%', #{name}, '%')
+            </if>
+            <if test="roomCode != null and roomCode != ''">
+                and tees.room_code like concat('%', #{roomCode}, '%')
+            </if>
+            <if test="courseCode != null and courseCode != ''">
+                and tees.course_code = #{courseCode}
+            </if>
+            <if test="enable != null and enable != '' or enable == 0">
+                and tees.enable = #{enable}
+            </if>
+            <if test="grade != null and grade != ''">
+                and tees.grade like concat('%', #{grade}, '%')
+            </if>
+            <if test="classNo != null and classNo != ''">
+                and tees.class_no like concat('%', #{classNo}, '%')
+            </if>
+            <if test="hasPhoto != null">
+                <if test="hasPhoto == 0">
+                    and stu.base_photo_path is null
+                </if>
+                <if test="hasPhoto == 1">
+                    and stu.base_photo_path is not null
+                </if>
+            </if>
+        </where>
+    </select>
 
-	<select id="examStudentList"
-		resultType="com.qmth.themis.business.dto.response.TEExamStudentDto">
-		select
-		tees.id,
-		tee.id as examId,
-		tee.name as examName,
-		tees.name,
-		tees.`identity`,
-		teea.code,
-		tees.course_code as courseCode,
-		tees.course_name as courseName,
-		tees.enable,
-		tees.room_code as roomCode,
-		tees.room_name as roomName,
-		tees.grade,
-		tees.class_no as classNo,
-		teea.id as examActivityId,
-		teea.code as activityCode,
-		stu.base_photo_path basePhotoUrl
-		from
-		t_e_exam_student tees
-		left join t_e_student stu on tees.student_id=stu.id
-		left join t_e_exam tee on
-		tees.exam_id = tee.id
-		left join t_e_exam_activity teea on
-		tees.exam_activity_id = teea.id
-		<where>
-			<if test="examId != null and examId != ''">
-				and tees.exam_id = #{examId}
-			</if>
-			<if test="activityId != null and activityId != ''">
-				and tees.exam_activity_id = #{activityId}
-			</if>
-			<if test="identity != null and identity != ''">
-				and tees.identity like concat('%', #{identity}, '%')
-			</if>
-			<if test="name != null and name != ''">
-				and tees.name like concat('%', #{name}, '%')
-			</if>
-			<if test="roomCode != null and roomCode != ''">
-				and tees.room_code like concat('%', #{roomCode}, '%')
-			</if>
-			<if test="courseCode != null and courseCode != ''">
-				and tees.course_code = #{courseCode}
-			</if>
-			<if test="enable != null and enable != '' or enable == 0">
-				and tees.enable = #{enable}
-			</if>
-			<if test="grade != null and grade != ''">
-				and tees.grade like concat('%', #{grade}, '%')
-			</if>
-			<if test="classNo != null and classNo != ''">
-				and tees.class_no like concat('%', #{classNo}, '%')
-			</if>
-			<if test="hasPhoto != null and hasPhoto != ''">
-				<if test="hasPhoto == 0">
-					and stu.base_photo_path is null
-				</if>
-				<if test="hasPhoto == 1">
-					and stu.base_photo_path is not null
-				</if>
-			</if>
-		</where>
-	</select>
-	
-	<select id="getTotalCount" resultType="java.util.Map">
-		select t.exam_activity_id activityId,count(1) cc from t_e_exam_student
-		t left join t_e_student f on t.student_id=f.id
-		where t.exam_id = #{examId}
-		<if test="orgId != null">
-		 	and f.org_id=#{orgId}
-		</if>
-		<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>
-		group by t.exam_activity_id
-	</select>
+    <select id="examStudentList"
+            resultType="com.qmth.themis.business.dto.response.TEExamStudentDto">
+        select
+        tees.id,
+        tee.id as examId,
+        tee.name as examName,
+        tees.name,
+        tees.`identity`,
+        teea.code,
+        tees.course_code as courseCode,
+        tees.course_name as courseName,
+        tees.enable,
+        tees.room_code as roomCode,
+        tees.room_name as roomName,
+        tees.grade,
+        tees.class_no as classNo,
+        teea.id as examActivityId,
+        teea.code as activityCode,
+        stu.base_photo_path basePhotoUrl
+        from
+        t_e_exam_student tees
+        left join t_e_student stu on tees.student_id=stu.id
+        left join t_e_exam tee on
+        tees.exam_id = tee.id
+        left join t_e_exam_activity teea on
+        tees.exam_activity_id = teea.id
+        <where>
+            <if test="examId != null and examId != ''">
+                and tees.exam_id = #{examId}
+            </if>
+            <if test="activityId != null and activityId != ''">
+                and tees.exam_activity_id = #{activityId}
+            </if>
+            <if test="identity != null and identity != ''">
+                and tees.identity like concat('%', #{identity}, '%')
+            </if>
+            <if test="name != null and name != ''">
+                and tees.name like concat('%', #{name}, '%')
+            </if>
+            <if test="roomCode != null and roomCode != ''">
+                and tees.room_code like concat('%', #{roomCode}, '%')
+            </if>
+            <if test="courseCode != null and courseCode != ''">
+                and tees.course_code = #{courseCode}
+            </if>
+            <if test="enable != null and enable != '' or enable == 0">
+                and tees.enable = #{enable}
+            </if>
+            <if test="grade != null and grade != ''">
+                and tees.grade like concat('%', #{grade}, '%')
+            </if>
+            <if test="classNo != null and classNo != ''">
+                and tees.class_no like concat('%', #{classNo}, '%')
+            </if>
+            <if test="hasPhoto != null and hasPhoto != ''">
+                <if test="hasPhoto == 0">
+                    and stu.base_photo_path is null
+                </if>
+                <if test="hasPhoto == 1">
+                    and stu.base_photo_path is not null
+                </if>
+            </if>
+        </where>
+    </select>
 
-	<select id="getTotalCountInfo"
-		resultType="com.qmth.themis.business.bean.backend.ExamViewCountListBean">
-		select t.exam_id examId,t.exam_activity_id examActivityId,t.room_code
-		roomCode,t.room_name roomName, count(1) examTotal from
-		t_e_exam_student t left join t_e_student h on t.student_id=h.id
-		where t.exam_id = #{examId}
-		<if test="orgId != null">
-		 	and h.org_id=#{orgId}
-		</if>
-		<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>
-		group by t.exam_id,t.exam_activity_id, t.room_code,t.room_name
-	</select>
+    <select id="getTotalCount" resultType="java.util.Map">
+        select t.exam_activity_id activityId,count(1) cc from t_e_exam_student
+        t left join t_e_student f on t.student_id=f.id
+        where t.exam_id = #{examId}
+        <if test="orgId != null">
+            and f.org_id=#{orgId}
+        </if>
+        <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>
+        group by t.exam_activity_id
+    </select>
 
-	<select id="getDoneCountByActivityIds"
-		resultType="java.util.Map">
-		select t.exam_activity_id activityId,t.room_code roomCode,count(1) cc
-		from t_e_exam_student t
-		where t.exam_id = #{examId} and t.current_record_id is not null
-		<if test="activityIds != null">
-			and t.exam_activity_id in
-			<foreach collection="activityIds" item="acid" index="index"
-				open="(" close=")" separator=",">
-				#{acid}
-			</foreach>
-		</if>
-		group by t.exam_activity_id, t.room_code
-	</select>
+    <select id="getTotalCountInfo"
+            resultType="com.qmth.themis.business.bean.backend.ExamViewCountListBean">
+        select t.exam_id examId,t.exam_activity_id examActivityId,t.room_code
+        roomCode,t.room_name roomName, count(1) examTotal from
+        t_e_exam_student t left join t_e_student h on t.student_id=h.id
+        where t.exam_id = #{examId}
+        <if test="orgId != null">
+            and h.org_id=#{orgId}
+        </if>
+        <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>
+        group by t.exam_id,t.exam_activity_id, t.room_code,t.room_name
+    </select>
 
-	<select id="getAbsentCountByActivityIds"
-		resultType="java.util.Map">
-		select t.exam_activity_id activityId,t.room_code roomCode,count(1) cc
-		from t_e_exam_student t
-		where t.exam_id = #{examId} and t.current_record_id is null
-		<if test="activityIds != null">
-			and t.exam_activity_id in
-			<foreach collection="activityIds" item="acid" index="index"
-				open="(" close=")" separator=",">
-				#{acid}
-			</foreach>
-		</if>
-		group by t.exam_activity_id, t.room_code
-	</select>
+    <select id="getDoneCountByActivityIds"
+            resultType="java.util.Map">
+        select t.exam_activity_id activityId,t.room_code roomCode,count(1) cc
+        from t_e_exam_student t
+        where t.exam_id = #{examId} and t.current_record_id is not null
+        <if test="activityIds != null">
+            and t.exam_activity_id in
+            <foreach collection="activityIds" item="acid" index="index"
+                     open="(" close=")" separator=",">
+                #{acid}
+            </foreach>
+        </if>
+        group by t.exam_activity_id, t.room_code
+    </select>
 
-	<select id="examRoomQuery"
-		resultType="com.qmth.themis.business.dto.response.RoomCodeQueryDto">
-		select
-		DISTINCT
-		tees.room_code as roomCode,
-		tees.room_name as roomName
-		from
-		t_e_exam_student tees
-		<where>
-			<if test="roomName != null and roomName != ''">
-				and tees.room_name like concat('%', #{roomName}, '%')
-			</if>
-		</where>
-	</select>
+    <select id="getAbsentCountByActivityIds"
+            resultType="java.util.Map">
+        select t.exam_activity_id activityId,t.room_code roomCode,count(1) cc
+        from t_e_exam_student t
+        where t.exam_id = #{examId} and t.current_record_id is null
+        <if test="activityIds != null">
+            and t.exam_activity_id in
+            <foreach collection="activityIds" item="acid" index="index"
+                     open="(" close=")" separator=",">
+                #{acid}
+            </foreach>
+        </if>
+        group by t.exam_activity_id, t.room_code
+    </select>
 
-	<select id="getExamDeficiencyPage"
-		resultType="com.qmth.themis.business.bean.backend.ExamDeficiencyListBean">
-		select 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 from
-		t_e_exam_student t
-		left join t_e_exam_activity f on
-		t.exam_activity_id=f.id
-		where t.exam_id = #{examId} and
-		t.current_record_id is 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 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},'%')
-		</if>
-	</select>
-	
-	<select id="getPageForStudentLog"
-		resultType="com.qmth.themis.business.bean.backend.ExamStudentLogListBean">
-		select t.id examStudentId,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 from
-		t_e_exam_student t
-		left join t_e_student h on t.student_id=h.id
-		where t.exam_id = #{examId} 
-		<if test="orgId != null">
-		 	and h.org_id=#{orgId}
-		</if>
-		<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},'%')
-		</if>
-	</select>
-	
-	<update id="updateAlreadyExamCount">
-	update t_e_exam_student set already_exam_count=#{alreadyExamCount} where id=#{examStudentId} and (already_exam_count is null or already_exam_count &lt; #{alreadyExamCount})
-	</update>
-	
-	<update id="updateCurrentRecordId">
-	update t_e_exam_student set current_record_id=#{currentRecordId} where id=#{examStudentId} and (current_record_id is null or current_record_id &lt; #{currentRecordId})
-	</update>
+    <select id="examRoomQuery"
+            resultType="com.qmth.themis.business.dto.response.RoomCodeQueryDto">
+        select
+        DISTINCT
+        tees.room_code as roomCode,
+        tees.room_name as roomName
+        from
+        t_e_exam_student tees
+        <where>
+            <if test="roomName != null and roomName != ''">
+                and tees.room_name like concat('%', #{roomName}, '%')
+            </if>
+        </where>
+    </select>
 
-	<sql id="markResultCommon">
-		select
-		t.examActivityCode,
-		t.name,
-		t.identity,
-		t.courseCode,
-		t.courseName,
-		t.roomCode,
-		t.roomName,
-		t.grade,
-		t.classNo,
-		if(t.examCount <![CDATA[ <= ]]> 0,'是','否') as examAbsent,
-		t.examCount,
-		t.examName,
-		if(t.breachCount is null,0,t.breachCount) as breachCount,
-		ifnull(t.objectiveScore,0) as objectiveScore,
-		ifnull(t.objectiveScore,0) as sumScore,
-		t.examId,
-		t.examActivityId,
-		t.objectiveScore,
-		t.subjectiveScore,
-		(t.objectiveScore + t.subjectiveScore) as sumScore,
-		t.examStudentId
-		from
-		(
-		select tees.id as examStudentId,tee.id as examId,tee.name as examName,teea.id as examActivityId, teea.code as examActivityCode, tes.name, tes.`identity`, tees.course_code as courseCode, tees.course_name as courseName, tees.room_code as roomCode, tees.room_name as roomName, tees.grade, tees.class_no as classNo, (
-		select
-		count(1)
-		from
-		t_oe_exam_record toer
-		where
-		toer.exam_student_id = tees.id) as examCount,
-		(select count(toer.id) from t_oe_exam_record toer
-		where toer.exam_student_id = tees.id and toer.breach_status = 0) as breachCount,
-		0 as objectiveScore,
-		0 as subjectiveScore
-		from
-		t_e_student tes
-		left join t_e_exam_student tees on
-		tees.student_id = tes.id
-		left join t_e_exam tee on
-		tee.id = tees.exam_id
-		left join t_e_exam_activity teea on
-		teea.id = tees.exam_activity_id
-		<where>
-			<if test="examId != null and examId != ''">
-				and tee.id = #{examId}
-			</if>
-			<if test="activityId != null and activityId != ''">
-				and teea.id = #{activityId}
-			</if>
-			<if test="identity != null and identity != ''">
-				and tes.identity like concat('%', #{identity}, '%')
-			</if>
-			<if test="name != null and name != ''">
-				and tes.name like concat('%', #{name}, '%')
-			</if>
-			<if test="courseCode != null and courseCode != ''">
-				and tees.course_code = #{courseCode}
-			</if>
-		</where> ) t
-	</sql>
+    <select id="getExamDeficiencyPage"
+            resultType="com.qmth.themis.business.bean.backend.ExamDeficiencyListBean">
+        select 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 from
+        t_e_exam_student t
+        left join t_e_exam_activity f on
+        t.exam_activity_id=f.id
+        where t.exam_id = #{examId} and
+        t.current_record_id is 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 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},'%')
+        </if>
+    </select>
 
-	<select id="markResultQuery" resultType="com.qmth.themis.business.dto.response.MarkResultDto">
-		<include refid="markResultCommon" />
-	</select>
+    <select id="getPageForStudentLog"
+            resultType="com.qmth.themis.business.bean.backend.ExamStudentLogListBean">
+        select t.id examStudentId,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 from
+        t_e_exam_student t
+        left join t_e_student h on t.student_id=h.id
+        where t.exam_id = #{examId}
+        <if test="orgId != null">
+            and h.org_id=#{orgId}
+        </if>
+        <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},'%')
+        </if>
+    </select>
 
-	<select id="markResultQueryExport" resultType="com.qmth.themis.business.dto.MarkResultSimpleExportDto">
-		<include refid="markResultCommon" />
-	</select>
-	
-	<select id="findExamStudentIdsNeedMark" resultType="java.lang.Long">
-		select t.id from t_e_exam_student t
-		where t.exam_id=#{examId} and t.id&gt;#{idGt}
-		<if test="courseCode != null and courseCode != ''">
-			and t.course_code=#{courseCode}
-		</if>
-		order by t.id
-		limit #{count}
-	</select>
+    <update id="updateAlreadyExamCount">
+        update t_e_exam_student
+        set already_exam_count=#{alreadyExamCount}
+        where id = #{examStudentId}
+          and (already_exam_count is null or already_exam_count &lt; #{alreadyExamCount})
+    </update>
+
+    <update id="updateCurrentRecordId">
+        update t_e_exam_student
+        set current_record_id=#{currentRecordId}
+        where id = #{examStudentId}
+          and (current_record_id is null or current_record_id &lt; #{currentRecordId})
+    </update>
+
+    <sql id="markResultCommon">
+        select
+        t.examActivityCode,
+        t.name,
+        t.identity,
+        t.courseCode,
+        t.courseName,
+        t.roomCode,
+        t.roomName,
+        t.grade,
+        t.classNo,
+        if(t.examCount <![CDATA[ <= ]]> 0,'是','否') as examAbsent,
+        t.examCount,
+        t.examName,
+        if(t.breachCount is null,0,t.breachCount) as breachCount,
+        ifnull(t.objectiveScore,0) as objectiveScore,
+        ifnull(t.objectiveScore,0) as sumScore,
+        t.examId,
+        t.examActivityId,
+        t.objectiveScore,
+        t.subjectiveScore,
+        (t.objectiveScore + t.subjectiveScore) as sumScore,
+        t.examStudentId
+        from
+        (
+        select tees.id as examStudentId,tee.id as examId,tee.name as examName,teea.id as examActivityId, teea.code as
+        examActivityCode, tes.name, tes.`identity`, tees.course_code as courseCode, tees.course_name as courseName,
+        tees.room_code as roomCode, tees.room_name as roomName, tees.grade, tees.class_no as classNo, (
+        select
+        count(1)
+        from
+        t_oe_exam_record toer
+        where
+        toer.exam_student_id = tees.id) as examCount,
+        (select count(toer.id) from t_oe_exam_record toer
+        where toer.exam_student_id = tees.id and toer.breach_status = 0) as breachCount,
+        0 as objectiveScore,
+        0 as subjectiveScore
+        from
+        t_e_student tes
+        left join t_e_exam_student tees on
+        tees.student_id = tes.id
+        left join t_e_exam tee on
+        tee.id = tees.exam_id
+        left join t_e_exam_activity teea on
+        teea.id = tees.exam_activity_id
+        <where>
+            <if test="examId != null and examId != ''">
+                and tee.id = #{examId}
+            </if>
+            <if test="activityId != null and activityId != ''">
+                and teea.id = #{activityId}
+            </if>
+            <if test="identity != null and identity != ''">
+                and tes.identity like concat('%', #{identity}, '%')
+            </if>
+            <if test="name != null and name != ''">
+                and tes.name like concat('%', #{name}, '%')
+            </if>
+            <if test="courseCode != null and courseCode != ''">
+                and tees.course_code = #{courseCode}
+            </if>
+        </where>
+        ) t
+    </sql>
+
+    <select id="markResultQuery" resultType="com.qmth.themis.business.dto.response.MarkResultDto">
+        <include refid="markResultCommon"/>
+    </select>
+
+    <select id="markResultQueryExport" resultType="com.qmth.themis.business.dto.MarkResultSimpleExportDto">
+        <include refid="markResultCommon"/>
+    </select>
+
+    <select id="findExamStudentIdsNeedMark" resultType="com.qmth.themis.business.dto.response.TEExamStudentDto">
+        select
+        tees.id,
+        tees.name,
+        tees.`identity`,
+        tees.course_code as courseCode,
+        tees.course_name as courseName,
+        teea.code as activityCode
+        from t_e_exam_student tees
+        inner join t_e_exam_activity teea
+        on tees.exam_activity_id = teea.id
+        and teea.enable = 1
+        <where>
+            tees.exam_id = #{examId}
+            and tess.enable = 1
+            and tess.id <![CDATA[ > ]]> #{idGt}
+            and tess.already_exam_count is not null
+            and tess.already_exam_count <![CDATA[ > ]]> 0
+            <if test="courseCode != null and courseCode != ''">
+                and tees.course_code = #{courseCode}
+            </if>
+        </where>
+        order by tees.id
+        limit #{count}
+    </select>
 </mapper>

+ 11 - 21
themis-business/src/main/resources/mapper/TOeExamAnswerMapper.xml

@@ -1,25 +1,15 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
-<mapper
-	namespace="com.qmth.themis.business.dao.TOeExamAnswerMapper">
+<mapper namespace="com.qmth.themis.business.dao.TOeExamAnswerMapper">
 
-	<select id="findByRecordIds"
-		resultType="com.qmth.themis.business.bean.backend.OpenRecordAnswerBean">
-		SELECT
-		t.exam_record_id recordId,
-		t.main_number mainNumber,
-		t.sub_number
-		subNumber,
-		t.sub_index subIndex,
-		t.answer,
-		f.paper_id paperId
-		FROM
-		t_oe_exam_answer t left join t_oe_exam_record f on t.exam_record_id=f.id
-		WHERE t.exam_record_id in
-		<foreach collection="ids" item="rid"
-			index="index" open="(" close=")" separator=",">
-			#{rid}
-		</foreach>
-		order by t.id
-	</select>
+    <select id="findByExamRecordId"
+            resultType="com.qmth.themis.business.bean.backend.OpenRecordAnswerBean">
+        SELECT t.main_number as mainNumber,
+               t.sub_number  as subNumber,
+               t.sub_index   as subIndex,
+               t.answer      as answer
+        FROM t_oe_exam_answer t
+        WHERE t.exam_record_id = #{examRecordId}
+        order by t.main_number, t.sub_number, t.sub_index
+    </select>
 </mapper>

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

@@ -77,40 +77,40 @@
     </select>
 
     <update id="dataUpdate">
-		update t_oe_exam_record t set
-		t.${colName}=#{colValue} where t.id=#{recordId}
-	</update>
+        update t_oe_exam_record t
+        set t.${colName}=#{colValue}
+        where t.id = #{recordId}
+    </update>
 
     <sql id="invigilatePageHead">
-		select
-		distinct t.exam_id examId,
-		tee.name as examName,
-		t.exam_activity_id examActivityId,
-		teea.code as examActivityCode,
-		t.exam_student_id examStudentId,
-		t.id examRecordId,
-		s.identity identity,
-		s.room_code roomCode,
-		s.room_name roomName,
-		s.name name,
-		s.course_name courseName,
-		s.course_code courseCode,
-		IFNULL(t.paper_download,1) paperDownload,
-		t.status statusCode,
-	    TRUNCATE(t.answer_progress,2) progress,
-		IFNULL(t.client_current_ip,'无') clientCurrentIp,
-		IFNULL(t.warning_count,0) as warningCount,
-		IFNULL(t.breach_status,1) as breachStatus,
-		IFNULL(t.client_websocket_status,'OFF_LINE') as clientWebsocketStatus,
-		t.client_last_sync_time as updateTime
-	</sql>
+        select distinct t.exam_id                                        examId,
+                        tee.name                                      as examName,
+                        t.exam_activity_id                               examActivityId,
+                        teea.code                                     as examActivityCode,
+                        t.exam_student_id                                examStudentId,
+                        t.id                                             examRecordId,
+                        s.identity                                       identity,
+                        s.room_code                                      roomCode,
+                        s.room_name                                      roomName,
+                        s.name                                           name,
+                        s.course_name                                    courseName,
+                        s.course_code                                    courseCode,
+                        IFNULL(t.paper_download, 1)                      paperDownload,
+                        t.status                                         statusCode,
+                        TRUNCATE(t.answer_progress, 2)                   progress,
+                        IFNULL(t.client_current_ip, '无')                 clientCurrentIp,
+                        IFNULL(t.warning_count, 0)                    as warningCount,
+                        IFNULL(t.breach_status, 1)                    as breachStatus,
+                        IFNULL(t.client_websocket_status, 'OFF_LINE') as clientWebsocketStatus,
+                        t.client_last_sync_time                       as updateTime
+    </sql>
 
     <sql id="invigilatePageMiddle">
-		from t_oe_exam_record t
+        from t_oe_exam_record t
 		left join t_e_exam_student s on t.exam_student_id = s.id
 		left join t_e_exam tee on tee.id = t.exam_id
 		left join t_e_exam_activity teea on teea.id = t.exam_activity_id
-	</sql>
+    </sql>
 
     <sql id="invigilatePageFoot">
         <where>
@@ -638,9 +638,10 @@
     </select>
 
     <select id="getCountByExamId" resultType="java.lang.Long">
-		select count(1) from t_oe_exam_record f
-		where f.exam_id = #{examId}
-	</select>
+        select count(1)
+        from t_oe_exam_record f
+        where f.exam_id = #{examId}
+    </select>
 
     <select id="findOneByExamId" resultType="com.qmth.themis.business.entity.TOeExamRecord">
         select f.* from t_oe_exam_record f
@@ -656,21 +657,26 @@
     </select>
 
     <select id="getListByExamIdAndStartId" resultType="com.qmth.themis.business.entity.TOeExamRecord">
-		select f.* from t_oe_exam_record f
-		where f.exam_id = #{examId} and f.id>#{startId}
-		order by f.id
-		limit 500
-	</select>
+        select f.*
+        from t_oe_exam_record f
+        where f.exam_id = #{examId}
+          and f.id > #{startId}
+        order by f.id
+        limit 500
+    </select>
 
     <update id="updateObjectiveScore">
-		update t_oe_exam_record t set t.objective_score=#{score} where t.id=#{recordId}
-	</update>
+        update t_oe_exam_record t
+        set t.objective_score=#{score}
+        where t.id = #{recordId}
+    </update>
 
     <select id="findOneByPaperId" resultType="com.qmth.themis.business.entity.TOeExamRecord">
-		select f.* from t_oe_exam_record f
-		where f.paper_id = #{paperId}
-		limit 1
-	</select>
+        select f.*
+        from t_oe_exam_record f
+        where f.paper_id = #{paperId}
+        limit 1
+    </select>
 
     <select id="patrolReport" resultType="com.qmth.themis.business.bean.backend.InvigilateListPatrolReportBean">
         select
@@ -843,30 +849,19 @@
     </select>
 
     <update id="updateHasAnswerFile">
-		update t_oe_exam_record t set t.has_answer_file=#{hasAnswerFile} where t.id=#{recordId}
-	</update>
+        update t_oe_exam_record t
+        set t.has_answer_file=#{hasAnswerFile}
+        where t.id = #{recordId}
+    </update>
 
     <select id="findExamRecordNeedMark" resultType="com.qmth.themis.business.bean.backend.OpenRecordNeedMarkBean">
-        SELECT
-        t.id examRecordId,
-        t.exam_student_id examStudentId,
-        f.identity,
-        f.NAME,
-        g.CODE activityCode,
-        f.course_code courseCode,
-        f.course_name courseName,
-        t.paper_id paperId,
-        t.objective_score objectiveScore,
-        t.finish_time finishTime
-        FROM
-        t_oe_exam_record t
-        LEFT JOIN t_e_exam_student f ON t.exam_student_id = f.id
-        LEFT JOIN t_e_exam_activity g ON t.exam_activity_id = g.id
-        where t.exam_id=#{examId} and t.breach_status!=1 and t.exam_student_id in
-        <foreach collection="examStudentIds" item="examStudentId"
-                 index="index" open="(" close=")" separator=",">
-            #{examStudentId}
-        </foreach>
+        SELECT t.id              as id,
+               t.paper_id        as paperId,
+               t.objective_score as objectiveScore,
+               t.finish_time     as finishTime
+        FROM t_oe_exam_record t
+        where t.exam_student_id = #{examStudentId}
+          and t.breach_status != 1
     </select>
 
     <select id="findMaxObjectiveScore" resultType="com.qmth.themis.business.entity.TOeExamRecord">