Преглед на файлове

前后台同时交卷处理

xiatian преди 4 години
родител
ревизия
9f6fbe9091

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

@@ -115,6 +115,9 @@ public class SystemConstant {
 
     //重新算分锁
     public static final String REDIS_LOCK_CALCULATE_SCORE_PREFIX = "lock:calculate_score:exam_id_";
+    
+    //交卷锁
+    public static final String REDIS_LOCK_FINISH_EXXAM_PREFIX = "lock:finish_exxam:record_id_";
     /**
      * redis过期时间
      */

+ 31 - 13
themis-business/src/main/java/com/qmth/themis/business/service/impl/TEExamServiceImpl.java

@@ -26,9 +26,7 @@ import java.util.stream.Collectors;
 
 import javax.annotation.Resource;
 
-import com.qmth.themis.common.enums.ExceptionResultEnum;
 import org.apache.commons.codec.digest.DigestUtils;
-import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.BeanUtils;
 import org.springframework.cache.annotation.CacheEvict;
 import org.springframework.cache.annotation.CachePut;
@@ -104,6 +102,7 @@ import com.qmth.themis.business.util.OssUtil;
 import com.qmth.themis.business.util.RedisUtil;
 import com.qmth.themis.business.util.ServletUtil;
 import com.qmth.themis.business.util.TencentYunUtil;
+import com.qmth.themis.common.enums.ExceptionResultEnum;
 import com.qmth.themis.common.exception.BusinessException;
 import com.qmth.themis.common.util.IpUtil;
 
@@ -921,18 +920,38 @@ public class TEExamServiceImpl extends ServiceImpl<TEExamMapper, TEExam> impleme
         });
         return ret;
     }
-
     /**
      * 结束考试
      */
     @Override
     public ExamFinishBean finish(Long studentId, Long recordId, String type, Integer durationSeconds) {
-
-        // 校验当前登录用户和参数一致性
-        if (ExamRecordCacheUtil.getId(recordId) == null) {
-            throw new BusinessException("未找到考试记录");
+        String lockKey = SystemConstant.REDIS_LOCK_FINISH_EXXAM_PREFIX + recordId;
+        Boolean lock = redisUtil.lock(lockKey, SystemConstant.REDIS_CACHE_TIME_OUT);
+        if (!lock) {
+        	Date now = new Date();
+            ExamFinishBean ret = new ExamFinishBean();
+            ret.setFinishTime(now.getTime());
+            ret.setStatus(FinishExamResultEnum.NORMAL);
+        	return ret;
         }
+        try {
+        	return diposeFinish(studentId, recordId, type, durationSeconds);
+        } finally {
+            redisUtil.releaseLock(lockKey);
+        }
+    }
+    
+    private ExamFinishBean diposeFinish(Long studentId, Long recordId, String type, Integer durationSeconds) {
+    	Date now = new Date();
+        ExamFinishBean ret = new ExamFinishBean();
+        ret.setFinishTime(now.getTime());
+        ret.setObjectiveScore(ExamRecordCacheUtil.getObjectiveScore(recordId));
         Long examStudentId = ExamRecordCacheUtil.getExamStudentId(recordId);
+        if (ExamRecordCacheUtil.getId(recordId) == null||examStudentId==null) {
+        	ret.setStatus(FinishExamResultEnum.NORMAL);
+        	return ret;
+        }
+        // 校验当前登录用户和参数一致性
         ExamStudentCacheBean es = (ExamStudentCacheBean) redisUtil
                 .get(RedisKeyHelper.examStudentCacheKey(examStudentId));
         if (es == null) {
@@ -941,16 +960,15 @@ public class TEExamServiceImpl extends ServiceImpl<TEExamMapper, TEExam> impleme
         if (!studentId.equals(es.getStudentId())) {
             throw new BusinessException("考试记录的学生Id和当前登录用户不一致");
         }
+        
+        ExamCacheBean exam = getExamCacheBeanNative(es.getExamId());
         ExamRecordStatusEnum sta = ExamRecordCacheUtil.getStatus(recordId);
         if (ExamRecordStatusEnum.FINISHED.equals(sta) || ExamRecordStatusEnum.PERSISTED.equals(sta)) {
-            throw new BusinessException("该考试已结束");
+        	ret.setStatus(FinishExamResultEnum.NORMAL);
+        	return ret;
         }
 
-        Date now = new Date();
-        ExamFinishBean ret = new ExamFinishBean();
-        ret.setFinishTime(now.getTime());
-        ret.setObjectiveScore(ExamRecordCacheUtil.getObjectiveScore(recordId));
-        ExamCacheBean exam = getExamCacheBeanNative(es.getExamId());
+        
         //页面结果
         if (exam.getShowObjectiveScore() != null && exam.getShowObjectiveScore().intValue() == 1) {//实时出分
             if (InvigilateVerifyEnum.NOW.equals(exam.getInvigilateVerify())) {//实时审核