xiatian 4 rokov pred
rodič
commit
104006bf5b

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

@@ -3,7 +3,7 @@ package com.qmth.themis.business.bean.exam;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 
-@ApiModel("考试候考试卷信息")
+@ApiModel("考试候考返回信息")
 public class ExamPrepareBean {
 	@ApiModelProperty("考试记录id")
 	private Long recordId;

+ 26 - 0
themis-business/src/main/java/com/qmth/themis/business/bean/exam/ExamStartBean.java

@@ -0,0 +1,26 @@
+package com.qmth.themis.business.bean.exam;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+@ApiModel("开始考试返回信息")
+public class ExamStartBean {
+	@ApiModelProperty("试卷解密密钥")
+	private String paperDecryptSecret;
+	@ApiModelProperty("试卷解密向量")
+	private String paperDecryptVector;
+	public String getPaperDecryptSecret() {
+		return paperDecryptSecret;
+	}
+	public void setPaperDecryptSecret(String paperDecryptSecret) {
+		this.paperDecryptSecret = paperDecryptSecret;
+	}
+	public String getPaperDecryptVector() {
+		return paperDecryptVector;
+	}
+	public void setPaperDecryptVector(String paperDecryptVector) {
+		this.paperDecryptVector = paperDecryptVector;
+	}
+
+	
+}

+ 8 - 0
themis-business/src/main/java/com/qmth/themis/business/service/TEExamService.java

@@ -6,6 +6,7 @@ import java.util.Map;
 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.bean.exam.ExamStartBean;
 import com.qmth.themis.business.entity.TEExam;
 
 /**
@@ -46,4 +47,11 @@ public interface TEExamService extends IService<TEExam> {
 	 * @return
 	 */
 	public ExamPrepareBean prepare(Long studentId, Long examStudentId);
+	
+	/**开始考试
+	 * @param id
+	 * @param recordId
+	 * @return
+	 */
+	public ExamStartBean start(Long studentId, Long recordId);
 }

+ 68 - 10
themis-business/src/main/java/com/qmth/themis/business/service/impl/TEExamServiceImpl.java

@@ -1,29 +1,38 @@
 package com.qmth.themis.business.service.impl;
 
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+
+import javax.annotation.Resource;
+
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
 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.bean.exam.ExamStartBean;
 import com.qmth.themis.business.cache.RedisKeyHelper;
 import com.qmth.themis.business.cache.bean.ExamActivityCacheBean;
 import com.qmth.themis.business.cache.bean.ExamCourseCacheBean;
 import com.qmth.themis.business.cache.bean.ExamPaperCacheBean;
+import com.qmth.themis.business.cache.bean.ExamRecordCacheBean;
 import com.qmth.themis.business.cache.bean.ExamStudentCacheBean;
 import com.qmth.themis.business.config.SystemConfig;
 import com.qmth.themis.business.dao.TEExamMapper;
 import com.qmth.themis.business.entity.TEExam;
-import com.qmth.themis.business.service.*;
+import com.qmth.themis.business.service.TEExamActivityService;
+import com.qmth.themis.business.service.TEExamCourseService;
+import com.qmth.themis.business.service.TEExamPaperService;
+import com.qmth.themis.business.service.TEExamService;
+import com.qmth.themis.business.service.TEExamStudentService;
+import com.qmth.themis.business.service.TOeExamRecordService;
 import com.qmth.themis.business.util.OssUtil;
 import com.qmth.themis.business.util.RedisUtil;
 import com.qmth.themis.common.exception.BusinessException;
-import org.apache.commons.lang3.StringUtils;
-import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
-
-import javax.annotation.Resource;
-import java.util.Date;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
 
 /**
  * @Description: 考试批次 服务实现类
@@ -200,4 +209,53 @@ public class TEExamServiceImpl extends ServiceImpl<TEExamMapper, TEExam> impleme
 
         return -1;
     }
+    
+    @Transactional
+	@Override
+	public ExamStartBean start(Long studentId, Long recordId) {
+		ExamStartBean ret = null;
+		ExamRecordCacheBean er = (ExamRecordCacheBean) redisUtil.get(RedisKeyHelper.examRecordCacheKey(recordId));
+		if (er == null) {
+			throw new BusinessException("未找到考试记录");
+		}
+		ExamStudentCacheBean es = (ExamStudentCacheBean) redisUtil.get(RedisKeyHelper.examStudentCacheKey(er.getExamStudentId()));
+		if (es == null) {
+			throw new BusinessException("未找到考生");
+		}
+		if (studentId.equals(es.getStudentId())) {
+			throw new BusinessException("考试记录的学生Id和当前登录用户不一致");
+		}
+		Long activityId = es.getExamActivityId();
+		ExamActivityCacheBean ac = teExamActivityService.getExamActivityCacheBean(activityId);
+		if (ac == null) {
+			throw new BusinessException("未找到场次");
+		}
+		Date now = new Date();
+		Long start = ac.getStartTime().getTime();
+		Long end = ac.getStartTime().getTime() + (ac.getOpeningSeconds() * 1000);
+		if (now.getTime() < start) {
+			throw new BusinessException("没有到允许开考的时间");
+		}
+		if (now.getTime() > end) {
+			throw new BusinessException("允许开考的时间已结束");
+		}
+
+		//修改考试记录数据
+		er.setFirstStartTime(new Date());
+		er.setStatus(2);
+		
+		ExamPaperCacheBean ep = teExamPaperService.getExamPaperCacheBean(er.getPaperId());
+		if (ep == null) {
+			throw new BusinessException("未找到试卷");
+		}
+
+		ret = new ExamStartBean();
+		ret.setPaperDecryptSecret(ep.getDecryptSecret());
+		ret.setPaperDecryptVector(ep.getDecryptVector());
+
+		// 更新考试记录缓存
+		redisUtil.set(RedisKeyHelper.examRecordCacheKey(recordId), er);
+
+		return ret;
+	}
 }

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

@@ -1,5 +1,15 @@
 package com.qmth.themis.business.service.impl;
 
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+
+import javax.annotation.Resource;
+
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.qmth.themis.business.cache.RedisKeyHelper;
 import com.qmth.themis.business.cache.bean.ExamRecordCacheBean;
@@ -7,14 +17,6 @@ import com.qmth.themis.business.dao.TOeExamRecordMapper;
 import com.qmth.themis.business.entity.TOeExamRecord;
 import com.qmth.themis.business.service.TOeExamRecordService;
 import com.qmth.themis.business.util.RedisUtil;
-import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
-
-import javax.annotation.Resource;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Objects;
 
 /**
  * @Description: 考试记录 服务实现类
@@ -86,28 +88,67 @@ public class TOeExamRecordServiceImpl extends ServiceImpl<TOeExamRecordMapper, T
         }
     }
 
-    @Transactional
+    @Transactional 
     @Override
-    public Long saveByPrepare(Long examId, Long examActivityId, Long examStudentId, Long paperId, Integer serialNumber) {
-        TOeExamRecord er = new TOeExamRecord();
-        er.setExamId(examId);
-        er.setExamActivityId(examActivityId);
-        er.setExamStudentId(examStudentId);
-        er.setPaperId(paperId);
-        er.setSerialNumber(serialNumber);
-        er.setFirstPrepareTime(new Date());
-        er.setStatus(0);
-        saveOrUpdate(er);
-        ExamRecordCacheBean erCache = new ExamRecordCacheBean();
-        erCache.setId(er.getId());
-        erCache.setExamId(examId);
-        erCache.setExamActivityId(examActivityId);
-        erCache.setExamStudentId(examStudentId);
-        erCache.setPaperId(paperId);
-        erCache.setSerialNumber(serialNumber);
-        erCache.setFirstPrepareTime(new Date());
-        erCache.setStatus(0);
-        redisUtil.set(RedisKeyHelper.examRecordCacheKey(er.getId()), erCache);
-        return er.getId();
+    public Long saveByPrepare(Long examId,Long examActivityId,Long examStudentId,Long paperId,Integer serialNumber) {
+    	TOeExamRecord er=new TOeExamRecord();
+    	er.setExamId(examId);
+    	er.setExamActivityId(examActivityId);
+    	er.setExamStudentId(examStudentId);
+    	er.setPaperId(paperId);
+    	er.setSerialNumber(serialNumber);
+    	er.setFirstPrepareTime(new Date());
+    	er.setStatus(0);
+    	saveOrUpdate(er);
+    	ExamRecordCacheBean erCache=new ExamRecordCacheBean();
+    	copy(erCache, er);
+    	redisUtil.set(RedisKeyHelper.examRecordCacheKey(er.getId()), erCache);
+    	return er.getId();
+    }
+    
+    
+    private void copy(ExamRecordCacheBean tb,TOeExamRecord sb) {
+    	tb.setId(sb.getId());
+    	tb.setExamId(sb.getExamId());
+    	tb.setExamActivityId(tb.getExamActivityId());
+    	tb.setPaperId(sb.getPaperId());
+    	tb.setAnswerPath(sb.getAnswerPath());
+    	tb.setStatus(sb.getStatus());
+    	tb.setFirstPrepareTime(sb.getFirstPrepareTime());
+    	tb.setFirstStartTime(sb.getFirstStartTime());
+    	tb.setLastPrepareTime(sb.getLastPrepareTime());
+    	tb.setLastBreakTime(sb.getLastBreakTime());
+    	tb.setLastStartTime(sb.getLastStartTime());
+    	tb.setLeftBreakResumeCount(sb.getLeftBreakResumeCount());
+    	tb.setClientCurrentIp(sb.getClientCurrentIp());
+    	tb.setClientLastSyncTime(sb.getClientLastSyncTime());
+    	tb.setClientVideoPushKey(sb.getClientVideoPushKey());
+    	tb.setClientVideoPushStatus(sb.getClientVideoPushStatus());
+    	tb.setClientWebsocketId(sb.getClientWebsocketId());
+    	tb.setClientWebsocketStatus(sb.getClientWebsocketStatus());
+    	tb.setWxappLastSyncTime(sb.getWxappLastSyncTime());
+    	tb.setWarningCount(sb.getWarningCount());
+    	tb.setWxappVideoPushKey(sb.getWxappVideoPushKey());
+    	tb.setWxappVideoPushStatus(sb.getWxappVideoPushStatus());
+    	tb.setWxappWebsocketId(sb.getWxappWebsocketId());
+    	tb.setWxappWebsocketStatus(sb.getWxappWebsocketStatus());
+    	tb.setAnswerProgress(sb.getAnswerProgress());
+    	tb.setDurationSeconds(sb.getDurationSeconds());
+    	tb.setFinishTime(sb.getFinishTime());
+    	tb.setFinishType(sb.getFinishType());
+    	tb.setWarningCount(sb.getWarningCount());
+    	tb.setReviewResult(sb.getReviewResult());
+    	tb.setObjectiveScore(sb.getObjectiveScore());
+    	tb.setPaperDownload(sb.getPaperDownload());
+    	tb.setBreachStatus(sb.getBreachStatus());
+    	tb.setPaperStruct(sb.getPaperStruct());
+    	tb.setPaperStructUpload(sb.getPaperStructUpload());
+    	tb.setSerialNumber(sb.getSerialNumber());
+    	tb.setLastBreakId(sb.getLastBreakId());
+    	tb.setEntryAuthenticationId(sb.getEntryAuthenticationId());
+    	tb.setEntryAuthenticationResult(sb.getEntryAuthenticationResult());
+    	tb.setInProcessFaceVerifyStatus(sb.getInProcessFaceVerifyStatus());
+    	tb.setInProcessLivenessVerifyCount(sb.getInProcessLivenessVerifyCount());
+    	tb.setInProcessLivenessVerifyStatus(sb.getInProcessLivenessVerifyStatus());
     }
 }

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

@@ -13,6 +13,7 @@ import org.springframework.web.bind.annotation.RestController;
 
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.qmth.themis.business.bean.exam.ExamPrepareBean;
+import com.qmth.themis.business.bean.exam.ExamStartBean;
 import com.qmth.themis.business.constant.SystemConstant;
 import com.qmth.themis.business.entity.TEExam;
 import com.qmth.themis.business.entity.TEStudent;
@@ -75,4 +76,22 @@ public class TEExamController {
 			redisUtil.releaseLock(lockKey);
 		}
 	}
+	
+	@ApiOperation(value = "开始考试")
+	@RequestMapping(value = "/start", method = RequestMethod.POST)
+	@ApiResponses({ @ApiResponse(code = 200, message = "试卷信息") })
+	public ExamStartBean start(@ApiParam(value = "考生ID", required = true) @RequestParam Long recordId,
+			@ApiParam(value = "断点续考原因", required = false) @RequestParam String reason) {
+		TEStudent teStudent = (TEStudent) ServletUtil.getRequestStudentAccount();
+		String lockKey = SystemConstant.REDIS_LOCK_STUDENT_PREFIX + teStudent.getId();
+		Boolean lock = redisUtil.lock(lockKey, SystemConstant.REDIS_CACHE_TIME_OUT);
+		if (!lock) {
+			throw new BusinessException(ExceptionResultEnum.REQUEST_AWAIT);
+		}
+		try {
+			return teExamService.start(teStudent.getId(), recordId);
+		} finally {
+			redisUtil.releaseLock(lockKey);
+		}
+	}
 }