Ver Fonte

待考接口修改

wangliang há 4 anos atrás
pai
commit
0ae11ebdc0

+ 170 - 115
themis-business/src/main/java/com/qmth/themis/business/bean/exam/ExamPrepareBean.java

@@ -1,124 +1,179 @@
 package com.qmth.themis.business.bean.exam;
 
 import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.fasterxml.jackson.databind.ser.Serializers;
 import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
+import com.qmth.themis.business.dto.response.TEExamActivityDto;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 
-@ApiModel("考试候考返回信息")
-public class ExamPrepareBean {
-
-	@JsonSerialize(using = ToStringSerializer.class)
-	@ApiModelProperty("考试记录id")
-	private Long recordId;
-	@ApiModelProperty("试卷数据包下载地址")
-	private String paperUrl;
-	@ApiModelProperty("试卷结构下载地址")
-	private String structUrl;
-	@ApiModelProperty("是否开启客观题乱序")
-	private Boolean objectiveShuffle;
-	@ApiModelProperty("是否开启选项乱序")
-	private Boolean optionShuffle;
-	@ApiModelProperty("是否有音频")
-	private Boolean hasAudio;
-	@ApiModelProperty("音频题播放次数")
-	private Integer audioPlayCount;
-	@ApiModelProperty("监控标识,默认使用recordId")
-	private String monitorKey;
-	@ApiModelProperty("加入房间用户ID")
-	private String monitorUserId;
-	@ApiModelProperty("用户认证签名")
-	private String monitorUserSig;
-
-	@ApiModelProperty("腾讯云SDK APP ID")
-	private String monitorAppId;
-
-	public String getMonitorAppId() {
-		return monitorAppId;
-	}
-
-	public void setMonitorAppId(String monitorAppId) {
-		this.monitorAppId = monitorAppId;
-	}
-
-	public String getMonitorKey() {
-		return monitorKey;
-	}
-
-	public void setMonitorKey(String monitorKey) {
-		this.monitorKey = monitorKey;
-	}
-
-	public String getMonitorUserId() {
-		return monitorUserId;
-	}
-
-	public void setMonitorUserId(String monitorUserId) {
-		this.monitorUserId = monitorUserId;
-	}
-
-	public String getMonitorUserSig() {
-		return monitorUserSig;
-	}
-
-	public void setMonitorUserSig(String monitorUserSig) {
-		this.monitorUserSig = monitorUserSig;
-	}
-
-	public Long getRecordId() {
-		return recordId;
-	}
-
-	public void setRecordId(Long recordId) {
-		this.recordId = recordId;
-	}
-
-	public String getPaperUrl() {
-		return paperUrl;
-	}
-
-	public void setPaperUrl(String paperUrl) {
-		this.paperUrl = paperUrl;
-	}
-
-	public String getStructUrl() {
-		return structUrl;
-	}
-
-	public void setStructUrl(String structUrl) {
-		this.structUrl = structUrl;
-	}
-
-	public Boolean getObjectiveShuffle() {
-		return objectiveShuffle;
-	}
-
-	public void setObjectiveShuffle(Boolean objectiveShuffle) {
-		this.objectiveShuffle = objectiveShuffle;
-	}
-
-	public Boolean getOptionShuffle() {
-		return optionShuffle;
-	}
-
-	public void setOptionShuffle(Boolean optionShuffle) {
-		this.optionShuffle = optionShuffle;
-	}
-
-	public Boolean getHasAudio() {
-		return hasAudio;
-	}
-
-	public void setHasAudio(Boolean hasAudio) {
-		this.hasAudio = hasAudio;
-	}
-
-	public Integer getAudioPlayCount() {
-		return audioPlayCount;
-	}
-
-	public void setAudioPlayCount(Integer audioPlayCount) {
-		this.audioPlayCount = audioPlayCount;
-	}
+import java.io.Serializable;
 
+@ApiModel("考试候考返回信息")
+public class ExamPrepareBean extends TEExamActivityDto implements Serializable {
+
+    @JsonSerialize(using = ToStringSerializer.class)
+    @ApiModelProperty("考试记录id")
+    private Long recordId;
+    //	@ApiModelProperty("试卷数据包下载地址")
+//	private String paperUrl;
+//	@ApiModelProperty("试卷结构下载地址")
+//	private String structUrl;
+    @ApiModelProperty("是否开启客观题乱序")
+    private Boolean objectiveShuffle;
+    @ApiModelProperty("是否开启选项乱序")
+    private Boolean optionShuffle;
+    @ApiModelProperty("是否有音频")
+    private Boolean hasAudio;
+    @ApiModelProperty("音频题播放次数")
+    private Integer audioPlayCount;
+    @ApiModelProperty("监控标识,默认使用recordId")
+    private String monitorKey;
+    @ApiModelProperty("加入房间用户ID")
+    private String monitorUserId;
+    @ApiModelProperty("用户认证签名")
+    private String monitorUserSig;
+    @ApiModelProperty("腾讯云SDK APP ID")
+    private String monitorAppId;
+
+    public ExamPrepareBean() {
+
+    }
+
+    public ExamPrepareBean(Long recordId, Boolean objectiveShuffle, Boolean optionShuffle, Boolean hasAudio, Integer audioPlayCount,
+                           String monitorKey, String monitorUserId, String monitorUserSig, String monitorAppId) {
+        this.recordId = recordId;
+        this.objectiveShuffle = objectiveShuffle;
+        this.optionShuffle = optionShuffle;
+        this.hasAudio = hasAudio;
+        this.audioPlayCount = audioPlayCount;
+        this.monitorKey = monitorKey;
+        this.monitorUserId = monitorUserId;
+        this.monitorUserSig = monitorUserSig;
+        this.monitorAppId = monitorAppId;
+    }
+
+    public void setTeExamActivityDto(TEExamActivityDto teExamActivityDto){
+        setId(teExamActivityDto.getId());
+        setPrepareTime(teExamActivityDto.getPrepareTime());
+        setMinStartTime(teExamActivityDto.getMinStartTime());
+        setMaxStartTime(teExamActivityDto.getMaxStartTime());
+        setMaxFinishTime(teExamActivityDto.getMaxFinishTime());
+        setMonitorVideoSourceStr(teExamActivityDto.getMonitorVideoSourceStr());
+        setMonitorVideoSource(teExamActivityDto.getMonitorVideoSource());
+        setOpeningSeconds(teExamActivityDto.getOpeningSeconds());
+        setActivityOpeningSeconds(teExamActivityDto.getActivityOpeningSeconds());
+        setPrepareSeconds(teExamActivityDto.getPrepareSeconds());
+        setActivityPrepareSeconds(teExamActivityDto.getActivityPrepareSeconds());
+        setMinDurationSeconds(teExamActivityDto.getMinDurationSeconds());
+        setMaxDurationSeconds(teExamActivityDto.getMaxDurationSeconds());
+        setActivityMaxDurationSeconds(teExamActivityDto.getActivityMaxDurationSeconds());
+        setExamCount(teExamActivityDto.getExamCount());
+        setForceFinish(teExamActivityDto.getForceFinish());
+        setEntryAuthenticationPolicy(teExamActivityDto.getEntryAuthenticationPolicy());
+        setInProcessFaceVerify(teExamActivityDto.getInProcessFaceVerify());
+        setInProcessFaceStrangerIgnore(teExamActivityDto.getInProcessFaceStrangerIgnore());
+        setInProcessLivenessVerify(teExamActivityDto.getInProcessLivenessVerify());
+        setInProcessLivenessFixedRangeStr(teExamActivityDto.getInProcessLivenessFixedRangeStr());
+        setInProcessLivenessFixedRange(teExamActivityDto.getInProcessLivenessFixedRange());
+        setInProcessLivenessJudgePolicy(teExamActivityDto.getInProcessLivenessJudgePolicy());
+        setCameraPhotoUpload(teExamActivityDto.getCameraPhotoUpload());
+        setStartTime(teExamActivityDto.getStartTime());
+        setFinishTime(teExamActivityDto.getFinishTime());
+        setLeftExamCount(teExamActivityDto.getLeftExamCount());
+        setMobilePhotoUpload(teExamActivityDto.getMobilePhotoUpload());
+        setMonitorAudioEnable(teExamActivityDto.getMonitorAudioEnable());
+        setExamId(teExamActivityDto.getExamId());
+        setHardwareTest(teExamActivityDto.getHardwareTest());
+        setPreNotice(teExamActivityDto.getPreNotice());
+        setPreNoticeStaySeconds(teExamActivityDto.getPreNoticeStaySeconds());
+    }
+
+    public String getMonitorAppId() {
+        return monitorAppId;
+    }
+
+    public void setMonitorAppId(String monitorAppId) {
+        this.monitorAppId = monitorAppId;
+    }
+
+    public String getMonitorKey() {
+        return monitorKey;
+    }
+
+    public void setMonitorKey(String monitorKey) {
+        this.monitorKey = monitorKey;
+    }
+
+    public String getMonitorUserId() {
+        return monitorUserId;
+    }
+
+    public void setMonitorUserId(String monitorUserId) {
+        this.monitorUserId = monitorUserId;
+    }
+
+    public String getMonitorUserSig() {
+        return monitorUserSig;
+    }
+
+    public void setMonitorUserSig(String monitorUserSig) {
+        this.monitorUserSig = monitorUserSig;
+    }
+
+    public Long getRecordId() {
+        return recordId;
+    }
+
+    public void setRecordId(Long recordId) {
+        this.recordId = recordId;
+    }
+
+//	public String getPaperUrl() {
+//		return paperUrl;
+//	}
+//
+//	public void setPaperUrl(String paperUrl) {
+//		this.paperUrl = paperUrl;
+//	}
+//
+//	public String getStructUrl() {
+//		return structUrl;
+//	}
+//
+//	public void setStructUrl(String structUrl) {
+//		this.structUrl = structUrl;
+//	}
+
+    public Boolean getObjectiveShuffle() {
+        return objectiveShuffle;
+    }
+
+    public void setObjectiveShuffle(Boolean objectiveShuffle) {
+        this.objectiveShuffle = objectiveShuffle;
+    }
+
+    public Boolean getOptionShuffle() {
+        return optionShuffle;
+    }
+
+    public void setOptionShuffle(Boolean optionShuffle) {
+        this.optionShuffle = optionShuffle;
+    }
+
+    public Boolean getHasAudio() {
+        return hasAudio;
+    }
+
+    public void setHasAudio(Boolean hasAudio) {
+        this.hasAudio = hasAudio;
+    }
+
+    public Integer getAudioPlayCount() {
+        return audioPlayCount;
+    }
+
+    public void setAudioPlayCount(Integer audioPlayCount) {
+        this.audioPlayCount = audioPlayCount;
+    }
 }

+ 9 - 0
themis-business/src/main/java/com/qmth/themis/business/dao/TEExamActivityMapper.java

@@ -2,6 +2,7 @@ package com.qmth.themis.business.dao;
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.qmth.themis.business.dto.response.TEExamActivityDto;
 import com.qmth.themis.business.dto.response.TEExamActivityQueryDto;
 import com.qmth.themis.business.dto.response.TEExamActivityWaitDto;
 import com.qmth.themis.business.entity.TEExamActivity;
@@ -85,5 +86,13 @@ public interface TEExamActivityMapper extends BaseMapper<TEExamActivity> {
      */
     public List<TEExamActivityWaitDto> getWaitingExam(@Param("studentId") Long studentId, @Param("examActivityIds") Set<Long> examActivityIds, @Param("mode") String mode);
 
+    /**
+     * 获取考试待考列表
+     *
+     * @param examActivityId
+     * @return
+     */
+    public TEExamActivityDto getWaitingExamByExamActivityId(@Param("examActivityId") Long examActivityId);
+
     public List<TEExamActivity> findByExamIdAndOrgId(@Param("examId") Long examId, @Param("orgId") Long orgId);
 }

+ 71 - 47
themis-business/src/main/java/com/qmth/themis/business/dto/response/TEExamActivityDto.java

@@ -31,18 +31,18 @@ public class TEExamActivityDto implements Serializable {
     @ApiModelProperty(name = "考试场次id")
     private Long id;//考试id
 
-    @ApiModelProperty(name = "考试场次代码")
-    private String code;//考试场次代码
-
-    @JsonSerialize(using = ToStringSerializer.class)
-    @ApiModelProperty(name = "考生id")
-    private Long examStudentId;//考生id
-
-    @ApiModelProperty(name = "科目代码")
-    private String courseCode;//科目代码
-
-    @ApiModelProperty(name = "科目名称")
-    private String courseName;//科目名称
+//    @ApiModelProperty(name = "考试场次代码")
+//    private String code;//考试场次代码
+//
+//    @JsonSerialize(using = ToStringSerializer.class)
+//    @ApiModelProperty(name = "考生id")
+//    private Long examStudentId;//考生id
+//
+//    @ApiModelProperty(name = "科目代码")
+//    private String courseCode;//科目代码
+//
+//    @ApiModelProperty(name = "科目名称")
+//    private String courseName;//科目名称
 
     @ApiModelProperty(name = "提前多长时间开始候考(时间戳)")
     private Long prepareTime;
@@ -138,6 +138,12 @@ public class TEExamActivityDto implements Serializable {
     @ApiModelProperty(name = "硬件检测集合")
     private List<String> hardwareTest;//硬件检测
 
+    @ApiModelProperty(name = "考前须知")
+    private String preNotice;//考前须知
+
+    @ApiModelProperty(name = "考试须知阅读时长")
+    private Integer preNoticeStaySeconds;//考试须知阅读时长(秒)
+
     public TEExamActivityDto() {
 
     }
@@ -145,10 +151,10 @@ public class TEExamActivityDto implements Serializable {
     public TEExamActivityDto(ExamCacheBean ec, ExamActivityCacheBean examActivityCacheBean, ExamStudentCacheBean examStudentCacheBean, Long examStudentId, ExamCourseCacheBean examCourseCacheBean,
                              Long startTime, Long endTime, Integer openingSeconds, Integer minDurationSeconds, Integer maxDurationSeconds, Integer forceFinish) {
         this.id = examActivityCacheBean.getId();
-        this.code = examActivityCacheBean.getCode();
-        this.examStudentId = examStudentId;
-        this.courseCode = examStudentCacheBean.getCourseCode();
-        this.courseName = examStudentCacheBean.getCourseName();
+//        this.code = examActivityCacheBean.getCode();
+//        this.examStudentId = examStudentId;
+//        this.courseCode = examStudentCacheBean.getCourseCode();
+//        this.courseName = examStudentCacheBean.getCourseName();
         if (Objects.nonNull(examActivityCacheBean.getPrepareSeconds())) {
             this.prepareTime = startTime - (examActivityCacheBean.getPrepareSeconds() * 1000);
         } else if (Objects.nonNull(ec.getPrepareSeconds())) {
@@ -223,6 +229,24 @@ public class TEExamActivityDto implements Serializable {
         this.leftExamCount = (ec.getExamCount().intValue() - examStudentCacheBean.getAlreadyExamCount().intValue()) < 0 ? 0 : ec.getExamCount().intValue() - examStudentCacheBean.getAlreadyExamCount().intValue();
         this.mobilePhotoUpload = ec.getMobilePhotoUpload();
         this.examId = ec.getId();
+        this.preNotice = ec.getPreNotice();
+        this.preNoticeStaySeconds = ec.getPreNoticeStaySeconds();
+    }
+
+    public String getPreNotice() {
+        return preNotice;
+    }
+
+    public void setPreNotice(String preNotice) {
+        this.preNotice = preNotice;
+    }
+
+    public Integer getPreNoticeStaySeconds() {
+        return preNoticeStaySeconds;
+    }
+
+    public void setPreNoticeStaySeconds(Integer preNoticeStaySeconds) {
+        this.preNoticeStaySeconds = preNoticeStaySeconds;
     }
 
     public Integer getInProcessRealnessVerify() {
@@ -337,37 +361,37 @@ public class TEExamActivityDto implements Serializable {
         this.id = id;
     }
 
-    public String getCode() {
-        return code;
-    }
-
-    public void setCode(String code) {
-        this.code = code;
-    }
-
-    public Long getExamStudentId() {
-        return examStudentId;
-    }
-
-    public void setExamStudentId(Long examStudentId) {
-        this.examStudentId = examStudentId;
-    }
-
-    public String getCourseCode() {
-        return courseCode;
-    }
-
-    public void setCourseCode(String courseCode) {
-        this.courseCode = courseCode;
-    }
-
-    public String getCourseName() {
-        return courseName;
-    }
-
-    public void setCourseName(String courseName) {
-        this.courseName = courseName;
-    }
+//    public String getCode() {
+//        return code;
+//    }
+//
+//    public void setCode(String code) {
+//        this.code = code;
+//    }
+//
+//    public Long getExamStudentId() {
+//        return examStudentId;
+//    }
+//
+//    public void setExamStudentId(Long examStudentId) {
+//        this.examStudentId = examStudentId;
+//    }
+//
+//    public String getCourseCode() {
+//        return courseCode;
+//    }
+//
+//    public void setCourseCode(String courseCode) {
+//        this.courseCode = courseCode;
+//    }
+//
+//    public String getCourseName() {
+//        return courseName;
+//    }
+//
+//    public void setCourseName(String courseName) {
+//        this.courseName = courseName;
+//    }
 
     public Integer getOpeningSeconds() {
         return openingSeconds;

+ 12 - 0
themis-business/src/main/java/com/qmth/themis/business/service/TEExamActivityService.java

@@ -2,7 +2,9 @@ package com.qmth.themis.business.service;
 
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.service.IService;
+import com.qmth.themis.business.bean.exam.ExamPrepareBean;
 import com.qmth.themis.business.cache.bean.ExamActivityCacheBean;
+import com.qmth.themis.business.dto.response.TEExamActivityDto;
 import com.qmth.themis.business.dto.response.TEExamActivityQueryDto;
 import com.qmth.themis.business.dto.response.TEExamActivityWaitDto;
 import com.qmth.themis.business.entity.TEExamActivity;
@@ -83,6 +85,16 @@ public interface TEExamActivityService extends IService<TEExamActivity> {
      */
     public List<TEExamActivityWaitDto> getWaitingExam(Long studentId, Set<Long> examActivityIds, String mode);
 
+    /**
+     * 获取考试待考列表
+     *
+     * @param examActivityId
+     * @param examStudentId
+     * @param courseCode
+     * @return
+     */
+    public TEExamActivityDto getWaitingExam(Long examActivityId, Long examStudentId, String courseCode);
+
     /**
      * 获取场次缓存
      *

+ 87 - 3
themis-business/src/main/java/com/qmth/themis/business/service/impl/TEExamActivityServiceImpl.java

@@ -2,21 +2,30 @@ package com.qmth.themis.business.service.impl;
 
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.qmth.themis.business.bean.exam.ExamPrepareBean;
 import com.qmth.themis.business.cache.bean.ExamActivityCacheBean;
+import com.qmth.themis.business.cache.bean.ExamCacheBean;
+import com.qmth.themis.business.cache.bean.ExamCourseCacheBean;
+import com.qmth.themis.business.cache.bean.ExamStudentCacheBean;
 import com.qmth.themis.business.dao.TEExamActivityMapper;
+import com.qmth.themis.business.dto.response.TEExamActivityDto;
 import com.qmth.themis.business.dto.response.TEExamActivityQueryDto;
 import com.qmth.themis.business.dto.response.TEExamActivityWaitDto;
 import com.qmth.themis.business.entity.TEExamActivity;
+import com.qmth.themis.business.enums.EntryAuthenticationPolicyEnum;
+import com.qmth.themis.business.enums.HardwareTestEnum;
+import com.qmth.themis.business.enums.MonitorVideoSourceEnum;
 import com.qmth.themis.business.service.TEExamActivityService;
+import com.qmth.themis.business.service.TEExamCourseService;
+import com.qmth.themis.business.service.TEExamService;
+import com.qmth.themis.business.service.TEExamStudentService;
 import org.springframework.cache.annotation.CacheEvict;
 import org.springframework.cache.annotation.CachePut;
 import org.springframework.cache.annotation.Cacheable;
 import org.springframework.stereotype.Service;
 
 import javax.annotation.Resource;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
+import java.util.*;
 
 /**
  * @Description: 考试场次 服务实现类
@@ -31,6 +40,15 @@ public class TEExamActivityServiceImpl extends ServiceImpl<TEExamActivityMapper,
     @Resource
     TEExamActivityMapper teExamActivityMapper;
 
+    @Resource
+    TEExamService teExamService;
+
+    @Resource
+    TEExamStudentService teExamStudentService;
+
+    @Resource
+    TEExamCourseService teExamCourseService;
+
     /**
      * 表是否存在
      *
@@ -114,6 +132,72 @@ public class TEExamActivityServiceImpl extends ServiceImpl<TEExamActivityMapper,
         return teExamActivityMapper.getWaitingExam(studentId, examActivityIds, mode);
     }
 
+    /**
+     * 获取考试待考列表
+     *
+     * @param examActivityId
+     * @param examStudentId
+     * @param courseCode
+     * @return
+     */
+    @Override
+    public TEExamActivityDto getWaitingExam(Long examActivityId, Long examStudentId, String courseCode) {
+        TEExamActivityDto teExamActivityDto = teExamActivityMapper.getWaitingExamByExamActivityId(examActivityId);
+        ExamCacheBean examCache = teExamService.getExamCacheBean(teExamActivityDto.getExamId());
+        ExamStudentCacheBean examStudentCacheBean = teExamStudentService
+                .getExamStudentCacheBean(examStudentId);
+        teExamActivityDto.setLeftExamCount(
+                (examCache.getExamCount().intValue() - (examStudentCacheBean.getAlreadyExamCount().intValue())
+                        < 0 ?
+                        0 :
+                        examCache.getExamCount().intValue() - (examStudentCacheBean.getAlreadyExamCount()
+                                .intValue())));
+        if (Objects.nonNull(teExamActivityDto.getInProcessLivenessFixedRangeStr())) {
+            String[] longs = teExamActivityDto.getInProcessLivenessFixedRangeStr().trim().replaceAll(" ", "").split(",");
+            List inProcessLivenessFixedRange = new ArrayList();
+            for (int i = 0; i < longs.length; i++) {
+                Integer integer = Integer.valueOf(longs[i].trim());
+                inProcessLivenessFixedRange.add(integer);
+            }
+            if (Objects.equals(inProcessLivenessFixedRange.toString().trim().replaceAll(" ", ""), "")) {
+                teExamActivityDto.setInProcessLivenessFixedRange(null);
+            } else {
+                teExamActivityDto.setInProcessLivenessFixedRange(inProcessLivenessFixedRange);
+            }
+        }
+        if (Objects.nonNull(teExamActivityDto.getMonitorVideoSourceStr()) && !Objects
+                .equals(teExamActivityDto.getMonitorVideoSourceStr().toString().trim().replaceAll(" ", ""), "")) {
+            teExamActivityDto.setMonitorVideoSource(Arrays.asList(
+                    teExamActivityDto.getMonitorVideoSourceStr().trim().toUpperCase().replaceAll(" ", "").split(",")));
+            teExamActivityDto.setMonitorAudioEnable(examCache.getMonitorAudioEnable());
+            //加入hardwareTest逻辑
+            if (teExamActivityDto.getMonitorVideoSourceStr().toUpperCase().contains(MonitorVideoSourceEnum.CLIENT_CAMERA.name())
+                    || (Objects.nonNull(teExamActivityDto.getEntryAuthenticationPolicy()) && (
+                    Objects.equals(teExamActivityDto.getEntryAuthenticationPolicy(),
+                            EntryAuthenticationPolicyEnum.LIVENESS_VERIFY.name()) || Objects
+                            .equals(teExamActivityDto.getEntryAuthenticationPolicy(),
+                                    EntryAuthenticationPolicyEnum.FACE_VERIFY_FORCE.name()))) || (
+                    Objects.nonNull(teExamActivityDto.getCameraPhotoUpload()) && teExamActivityDto.getCameraPhotoUpload() == 1)) {
+                List<String> hardwareTest = teExamActivityDto.getHardwareTest();
+                if (Objects.isNull(hardwareTest)) {
+                    hardwareTest = new ArrayList<>();
+                }
+                hardwareTest.add(HardwareTestEnum.CAMERA.name());
+                //取course缓存
+                ExamCourseCacheBean examCourseCacheBean = teExamCourseService
+                        .getExamCourseCacheBean(teExamActivityDto.getExamId(), courseCode);
+                if (Objects.nonNull(examCourseCacheBean) && Objects.nonNull(examCourseCacheBean.getHasAudio())
+                        && examCourseCacheBean.getHasAudio() == 1) {
+                    hardwareTest.add(HardwareTestEnum.AUDIOPLAY.name());
+                }
+                teExamActivityDto.setHardwareTest(hardwareTest);
+            }
+        } else {
+            teExamActivityDto.setMonitorVideoSource(null);
+        }
+        return teExamActivityDto;
+    }
+
     @Cacheable(value = "exam_activity", key = "#examActivityId", unless = "#result == null")
     @Override
     public ExamActivityCacheBean getExamActivityCacheBean(Long examActivityId) {

+ 29 - 78
themis-business/src/main/java/com/qmth/themis/business/service/impl/TEExamServiceImpl.java

@@ -5,6 +5,7 @@ import com.aliyun.oss.common.utils.BinaryUtil;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.google.gson.Gson;
 import com.qmth.themis.business.bean.admin.OpenExamBean;
 import com.qmth.themis.business.bean.exam.*;
 import com.qmth.themis.business.cache.*;
@@ -14,7 +15,10 @@ import com.qmth.themis.business.constant.SystemConstant;
 import com.qmth.themis.business.dao.TEExamMapper;
 import com.qmth.themis.business.dto.MqDto;
 import com.qmth.themis.business.dto.cache.TEStudentCacheDto;
-import com.qmth.themis.business.dto.response.*;
+import com.qmth.themis.business.dto.response.TEExamActivityDto;
+import com.qmth.themis.business.dto.response.TEExamActivityWaitDto;
+import com.qmth.themis.business.dto.response.TEExamQueryDto;
+import com.qmth.themis.business.dto.response.TEExamWaitDto;
 import com.qmth.themis.business.entity.TBSession;
 import com.qmth.themis.business.entity.TBTaskHistory;
 import com.qmth.themis.business.entity.TEExam;
@@ -153,49 +157,6 @@ public class TEExamServiceImpl extends ServiceImpl<TEExamMapper, TEExam> impleme
                                 0 :
                                 examCache.getExamCount().intValue() - (examStudentCacheBean.getAlreadyExamCount()
                                         .intValue())));
-//                if (Objects.nonNull(v.getInProcessLivenessFixedRangeStr())) {
-//                    String[] longs = v.getInProcessLivenessFixedRangeStr().trim().replaceAll(" ", "").split(",");
-//                    List inProcessLivenessFixedRange = new ArrayList();
-//                    for (int i = 0; i < longs.length; i++) {
-//                        Integer integer = Integer.valueOf(longs[i].trim());
-//                        inProcessLivenessFixedRange.add(integer);
-//                    }
-//                    if (Objects.equals(inProcessLivenessFixedRange.toString().trim().replaceAll(" ", ""), "")) {
-//                        v.setInProcessLivenessFixedRange(null);
-//                    } else {
-//                        v.setInProcessLivenessFixedRange(inProcessLivenessFixedRange);
-//                    }
-//                }
-//                if (Objects.nonNull(v.getMonitorVideoSourceStr()) && !Objects
-//                        .equals(v.getMonitorVideoSourceStr().toString().trim().replaceAll(" ", ""), "")) {
-//                    v.setMonitorVideoSource(Arrays.asList(
-//                            v.getMonitorVideoSourceStr().trim().toUpperCase().replaceAll(" ", "").split(",")));
-//                    v.setMonitorAudioEnable(examCache.getMonitorAudioEnable());
-//                    //加入hardwareTest逻辑
-//                    if (v.getMonitorVideoSourceStr().toUpperCase().contains(MonitorVideoSourceEnum.CLIENT_CAMERA.name())
-//                            || (Objects.nonNull(v.getEntryAuthenticationPolicy()) && (
-//                            Objects.equals(v.getEntryAuthenticationPolicy(),
-//                                    EntryAuthenticationPolicyEnum.LIVENESS_VERIFY.name()) || Objects
-//                                    .equals(v.getEntryAuthenticationPolicy(),
-//                                            EntryAuthenticationPolicyEnum.FACE_VERIFY_FORCE.name()))) || (
-//                            Objects.nonNull(v.getCameraPhotoUpload()) && v.getCameraPhotoUpload() == 1)) {
-//                        List<String> hardwareTest = v.getHardwareTest();
-//                        if (Objects.isNull(hardwareTest)) {
-//                            hardwareTest = new ArrayList<>();
-//                        }
-//                        hardwareTest.add(HardwareTestEnum.CAMERA.name());
-//                        //取course缓存
-//                        ExamCourseCacheBean examCourseCacheBean = teExamCourseService
-//                                .getExamCourseCacheBean(v.getExamId(), v.getCourseCode());
-//                        if (Objects.nonNull(examCourseCacheBean) && Objects.nonNull(examCourseCacheBean.getHasAudio())
-//                                && examCourseCacheBean.getHasAudio() == 1) {
-//                            hardwareTest.add(HardwareTestEnum.AUDIOPLAY.name());
-//                        }
-//                        v.setHardwareTest(hardwareTest);
-//                    }
-//                } else {
-//                    v.setMonitorVideoSource(null);
-//                }
             });
             list.forEach(s -> {
                 s.setActivities(new ArrayList<>(map.get(s.getId())));
@@ -231,8 +192,8 @@ public class TEExamServiceImpl extends ServiceImpl<TEExamMapper, TEExam> impleme
     @Transactional
     @Override
     public ExamPrepareBean prepare(Long studentId, Long examStudentId) {
-
         TBSession tbSession = (TBSession) ServletUtil.getRequestSession();
+        String monitorUserId = "s_" + tbSession.getId();
         ExamStudentCacheBean es = teExamStudentService.getExamStudentCacheBean(examStudentId);
         if (es == null) {
             throw new BusinessException(ExceptionResultEnum.NOT_FOUND_EXAM_STUDENT);
@@ -256,23 +217,22 @@ public class TEExamServiceImpl extends ServiceImpl<TEExamMapper, TEExam> impleme
                 ExamPaperCacheBean ep = teExamPaperService
                         .getExamPaperCacheBean(ExamRecordCacheUtil.getPaperId(recordId));
                 ExamCourseCacheBean ec = teExamCourseService.getExamCourseCacheBean(es.getExamId(), es.getCourseCode());
-                ExamPrepareBean prepare = new ExamPrepareBean();
-                prepare.setRecordId(recordId);
-                prepare.setAudioPlayCount(ep.getAudioPlayCount());
-                prepare.setHasAudio((ep.getHasAudio() == null || ep.getHasAudio().intValue() == 0 ? false : true));
-                prepare.setObjectiveShuffle(
-                        (ec.getObjectiveShuffle() == null || ec.getObjectiveShuffle().intValue() == 0 ? false : true));
-                prepare.setOptionShuffle(
-                        (ec.getOptionShuffle() == null || ec.getOptionShuffle().intValue() == 0 ? false : true));
-                prepare.setPaperUrl(ossUtil.getPrivateUrl(ep.getPaperPath()));
-                prepare.setStructUrl(ossUtil.getPrivateUrl(ep.getStructPath()));
-                prepare.setMonitorAppId(tencentYunUtil.getTencentYunDomain().getAppId());
-                prepare.setMonitorKey(ExamRecordCacheUtil.getMonitorKey(recordId));
-                prepare.setMonitorUserId("s_" + tbSession.getId());
-                prepare.setMonitorUserSig(
-                        tencentYunUtil.getSign(prepare.getMonitorUserId(), SystemConstant.TENCENT_EXPIRE_TIME));
-
+                ExamStudentCacheBean examStudentCacheBean = teExamStudentService.getExamStudentCacheBean(examStudentId);
                 ExamActivityCacheBean ac = teExamActivityService.getExamActivityCacheBean(es.getExamActivityId());
+                ExamPrepareBean prepare = new ExamPrepareBean(recordId, (ec.getObjectiveShuffle() == null || ec.getObjectiveShuffle().intValue() == 0 ? false : true),
+                        (ec.getOptionShuffle() == null || ec.getOptionShuffle().intValue() == 0 ? false : true),
+                        (ep.getHasAudio() == null || ep.getHasAudio().intValue() == 0 ? false : true)
+                        , ep.getAudioPlayCount(), ExamRecordCacheUtil.getMonitorKey(recordId), monitorUserId
+                        , tencentYunUtil.getSign(monitorUserId, SystemConstant.TENCENT_EXPIRE_TIME)
+                        , tencentYunUtil.getTencentYunDomain().getAppId());
+
+                TEExamActivityDto teExamActivityDto = new TEExamActivityDto(examCache, ac, examStudentCacheBean,
+                        examStudentId, ec, ExamRecordCacheUtil.getStartTime(recordId),
+                        ExamRecordCacheUtil.getEndTime(recordId), ExamRecordCacheUtil.getOpeningSeconds(recordId),
+                        ExamRecordCacheUtil.getMinDurationSeconds(recordId),
+                        ExamRecordCacheUtil.getMaxDurationSeconds(recordId), ExamRecordCacheUtil.getForceFinish(recordId));
+                prepare.setTeExamActivityDto(teExamActivityDto);
+
                 ExamRecordCacheUtil.setStartTime(recordId, ac.getStartTime(), false);
                 ExamRecordCacheUtil.setEndTime(recordId, ac.getFinishTime(), false);
                 ExamRecordCacheUtil.setOpeningSeconds(recordId, ac.getOpeningSeconds(), false);
@@ -343,23 +303,14 @@ public class TEExamServiceImpl extends ServiceImpl<TEExamMapper, TEExam> impleme
                         es.getAlreadyExamCount() + 1);
 
         es.setCurrentRecordId(recordId);
-
-        ExamPrepareBean prepare = new ExamPrepareBean();
-        prepare.setRecordId(recordId);
-        prepare.setAudioPlayCount(ep.getAudioPlayCount());
-        prepare.setHasAudio((ep.getHasAudio() == null || ep.getHasAudio().intValue() == 0 ? false : true));
-        prepare.setObjectiveShuffle(
-                (ec.getObjectiveShuffle() == null || ec.getObjectiveShuffle().intValue() == 0 ? false : true));
-        prepare.setOptionShuffle(
-                (ec.getOptionShuffle() == null || ec.getOptionShuffle().intValue() == 0 ? false : true));
-        prepare.setPaperUrl(ossUtil.getPrivateUrl(ep.getPaperPath()));
-        prepare.setStructUrl(ossUtil.getPrivateUrl(ep.getStructPath()));
-        prepare.setMonitorAppId(tencentYunUtil.getTencentYunDomain().getAppId());
-        prepare.setMonitorKey(ExamRecordCacheUtil.getMonitorKey(recordId));
-        prepare.setMonitorUserId("s_" + tbSession.getId());
-        prepare.setMonitorUserSig(
-                tencentYunUtil.getSign(prepare.getMonitorUserId(), SystemConstant.TENCENT_EXPIRE_TIME));
-
+        ExamPrepareBean prepare = new ExamPrepareBean(recordId, (ec.getObjectiveShuffle() == null || ec.getObjectiveShuffle().intValue() == 0 ? false : true),
+                (ec.getOptionShuffle() == null || ec.getOptionShuffle().intValue() == 0 ? false : true),
+                (ep.getHasAudio() == null || ep.getHasAudio().intValue() == 0 ? false : true)
+                , ep.getAudioPlayCount(), ExamRecordCacheUtil.getMonitorKey(recordId), monitorUserId
+                , tencentYunUtil.getSign(monitorUserId, SystemConstant.TENCENT_EXPIRE_TIME)
+                , tencentYunUtil.getTencentYunDomain().getAppId());
+        TEExamActivityDto teExamActivityDto = teExamActivityService.getWaitingExam(activityId, examStudentId, es.getCourseCode());
+        prepare.setTeExamActivityDto(teExamActivityDto);
         // 更新考生缓存
         redisUtil.set(RedisKeyHelper.examStudentCacheKey(examStudentId), es);
         //更新场次-考试记录缓存

+ 65 - 43
themis-business/src/main/resources/mapper/TEExamActivityMapper.xml

@@ -108,48 +108,34 @@
             <if test="finishDate != null and finishDate != ''">
                 and teea.finish_time = #{finishDate}
             </if>
-        </where> ) t order by t.code
+        </where>
+        ) t order by t.code
     </select>
 
+    <sql id="getWaitingHeadCommon">
+        select
+        teea.id,
+        teea.code,
+        (teea.start_time / 1000 - IFNULL(teea.prepare_seconds, tee.prepare_seconds)) * 1000 as prepareTime,
+        IFNULL(teea.start_time, tee.start_time) as minStartTime,
+        (teea.start_time / 1000 + IFNULL(teea.opening_seconds, tee.opening_seconds)) * 1000 as maxStartTime,
+        IF(tee.mode = 'TOGETHER' and tee.force_finish = 1, IFNULL(teea.finish_time , tee.end_time), null) as maxFinishTime,
+        tee.min_duration_seconds as minDurationSeconds,
+        IFNULL(teea.max_duration_seconds,tee.max_duration_seconds) as maxDurationSeconds,
+        tee.id as examId
+    </sql>
+
     <select id="getWaitingExam" resultType="com.qmth.themis.business.dto.response.TEExamActivityWaitDto">
-         select
-            teea.id,
-            teea.code,
-            tees.id as examStudentId,
-            tees.course_code as courseCode,
-            tees.course_name as courseName,
-            <!--IFNULL(teea.opening_seconds,tee.opening_seconds) as openingSeconds,
-             teea.opening_seconds as activityOpeningSeconds,-->
-            (teea.start_time / 1000 - IFNULL(teea.prepare_seconds, tee.prepare_seconds)) * 1000 as prepareTime,
-            IFNULL(teea.start_time, tee.start_time) as minStartTime,
-            (teea.start_time / 1000 + IFNULL(teea.opening_seconds, tee.opening_seconds)) * 1000 as maxStartTime,
-            IF(tee.mode = 'TOGETHER' and tee.force_finish = 1, IFNULL(teea.finish_time , tee.end_time), null) as maxFinishTime,
-            <!--tee.monitor_video_source as monitorVideoSourceStr,
-             IFNULL(teea.prepare_seconds,tee.prepare_seconds) as prepareSeconds,
-             teea.prepare_seconds as activityPrepareSeconds,-->
-            tee.min_duration_seconds as minDurationSeconds,
-            IFNULL(teea.max_duration_seconds,tee.max_duration_seconds) as maxDurationSeconds,
-            <!--teea.max_duration_seconds as activityMaxDurationSeconds,
-             tee.exam_count as examCount,
-             tee.force_finish as forceFinish,
-             tee.entry_authentication_policy as entryAuthenticationPolicy,
-             tee.in_process_face_verify as inProcessFaceVerify,
-             tee.in_process_face_stranger_ignore as inProcessFaceStrangerIgnore,
-             tee.in_process_liveness_verify as inProcessLivenessVerify,
-             tee.in_process_realness_verify as inProcessRealnessVerify,
-             tee.in_process_liveness_fixed_range as inProcessLivenessFixedRangeStr,
-             tee.in_process_liveness_judge_policy as inProcessLivenessJudgePolicy,
-             tee.camera_photo_upload as cameraPhotoUpload,
-             tee.mobile_photo_upload as mobilePhotoUpload,
-             teea.start_time as startTime,
-             teea.finish_time as finishTime,-->
-            tee.id as examId
+        <include refid="getWaitingHeadCommon"/>
+        ,tees.id as examStudentId,
+        tees.course_code as courseCode,
+        tees.course_name as courseName
         from
-            t_e_exam_student tees
+        t_e_exam_student tees
         left join t_e_exam tee on
-            tee.id = tees.exam_id
+        tee.id = tees.exam_id
         left join t_e_exam_activity teea on
-            teea.id = tees.exam_activity_id
+        teea.id = tees.exam_activity_id
         <where> 1 = 1
             and teea.id in
             <foreach collection="examActivityIds" item="examActivityId" index="index" open="(" close=")" separator=",">
@@ -166,13 +152,49 @@
             </if>-->
         </where>
     </select>
-    
+
+    <select id="getWaitingExamByExamActivityId" resultType="com.qmth.themis.business.bean.exam.ExamPrepareBean">
+        <include refid="getWaitingHeadCommon"/>
+        ,IFNULL(teea.opening_seconds,tee.opening_seconds) as openingSeconds,
+        teea.opening_seconds as activityOpeningSeconds,
+        tee.monitor_video_source as monitorVideoSourceStr,
+        IFNULL(teea.prepare_seconds,tee.prepare_seconds) as prepareSeconds,
+        teea.prepare_seconds as activityPrepareSeconds,
+        teea.max_duration_seconds as activityMaxDurationSeconds,
+        tee.exam_count as examCount,
+        tee.force_finish as forceFinish,
+        tee.entry_authentication_policy as entryAuthenticationPolicy,
+        tee.in_process_face_verify as inProcessFaceVerify,
+        tee.in_process_face_stranger_ignore as inProcessFaceStrangerIgnore,
+        tee.in_process_liveness_verify as inProcessLivenessVerify,
+        tee.in_process_realness_verify as inProcessRealnessVerify,
+        tee.in_process_liveness_fixed_range as inProcessLivenessFixedRangeStr,
+        tee.in_process_liveness_judge_policy as inProcessLivenessJudgePolicy,
+        tee.camera_photo_upload as cameraPhotoUpload,
+        tee.mobile_photo_upload as mobilePhotoUpload,
+        teea.start_time as startTime,
+        teea.finish_time as finishTime,
+        tee.pre_notice as preNotice,
+        tee.pre_notice_stay_seconds as preNoticeStaySeconds
+        from
+        t_e_exam_activity teea
+        left join t_e_exam tee on
+         tee.id = teea.exam_id
+        <where> 1 = 1
+            <if test="examActivityId != null and examActivityId != ''">
+                and teea.id = #{examActivityId}
+            </if>
+            and tee.enable = 1
+            and teea.enable = 1
+        </where>
+    </select>
+
     <select id="findByExamIdAndOrgId" resultType="com.qmth.themis.business.entity.TEExamActivity">
-    	select t.* from t_e_exam_activity t 
-    	left join t_e_exam f on t.exam_id=f.id
-    	where t.exam_id=#{examId}
-    	<if test="orgId != null">
-		 	and f.org_id=#{orgId}
-		</if>
+        select t.* from t_e_exam_activity t
+        left join t_e_exam f on t.exam_id=f.id
+        where t.exam_id=#{examId}
+        <if test="orgId != null">
+            and f.org_id=#{orgId}
+        </if>
     </select>
 </mapper>

+ 1 - 1
themis-exam/src/main/java/com/qmth/themis/exam/api/TEExamController.java

@@ -95,7 +95,7 @@ public class TEExamController {
 
     @ApiOperation(value = "开始候考")
     @RequestMapping(value = "/prepare", method = RequestMethod.POST)
-    @ApiResponses({@ApiResponse(code = 200, message = "试卷信息")})
+    @ApiResponses({@ApiResponse(code = 200, message = "候考信息", response = ExamPrepareBean.class)})
     public Result prepare(@RequestBody PrepareParamBean param) {
         TEStudentCacheDto teStudent = (TEStudentCacheDto) ServletUtil.getRequestStudentAccount();
         String lockKey = SystemConstant.REDIS_LOCK_STUDENT_PREFIX + teStudent.getId();