|
@@ -1,49 +1,14 @@
|
|
|
package com.qmth.themis.business.service.impl;
|
|
|
|
|
|
-import java.io.File;
|
|
|
-import java.math.BigDecimal;
|
|
|
-import java.text.SimpleDateFormat;
|
|
|
-import java.time.LocalDateTime;
|
|
|
-import java.time.ZoneOffset;
|
|
|
-import java.util.Date;
|
|
|
-import java.util.HashMap;
|
|
|
-import java.util.List;
|
|
|
-import java.util.Map;
|
|
|
-import java.util.Objects;
|
|
|
-import java.util.UUID;
|
|
|
-
|
|
|
-import javax.annotation.Resource;
|
|
|
-
|
|
|
-import org.apache.commons.lang3.StringUtils;
|
|
|
-import org.slf4j.Logger;
|
|
|
-import org.slf4j.LoggerFactory;
|
|
|
-import org.springframework.beans.BeanUtils;
|
|
|
-import org.springframework.stereotype.Service;
|
|
|
-import org.springframework.transaction.annotation.Transactional;
|
|
|
-
|
|
|
import com.alibaba.fastjson.JSONArray;
|
|
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
|
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
|
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
|
-import com.qmth.themis.business.bean.backend.InvigilateListBean;
|
|
|
-import com.qmth.themis.business.bean.backend.InvigilateListHistoryBean;
|
|
|
-import com.qmth.themis.business.bean.backend.InvigilateListPatrolBean;
|
|
|
-import com.qmth.themis.business.bean.backend.InvigilateListProgressBean;
|
|
|
-import com.qmth.themis.business.bean.backend.InvigilateListProgressExcelBean;
|
|
|
-import com.qmth.themis.business.bean.backend.InvigilateListVideoBean;
|
|
|
-import com.qmth.themis.business.bean.backend.InvigilateListWarningBean;
|
|
|
-import com.qmth.themis.business.bean.backend.OpenRecordNeedMarkBean;
|
|
|
+import com.qmth.themis.business.bean.backend.*;
|
|
|
import com.qmth.themis.business.cache.ExamActivityRecordCacheUtil;
|
|
|
import com.qmth.themis.business.cache.ExamRecordCacheUtil;
|
|
|
import com.qmth.themis.business.cache.RedisKeyHelper;
|
|
|
-import com.qmth.themis.business.cache.bean.ExamActivityCacheBean;
|
|
|
-import com.qmth.themis.business.cache.bean.ExamActivityRecordCacheBean;
|
|
|
-import com.qmth.themis.business.cache.bean.ExamCacheBean;
|
|
|
-import com.qmth.themis.business.cache.bean.ExamPaperCacheBean;
|
|
|
-import com.qmth.themis.business.cache.bean.ExamStudentAnswerCacheBean;
|
|
|
-import com.qmth.themis.business.cache.bean.ExamStudentCacheBean;
|
|
|
-import com.qmth.themis.business.cache.bean.ExamStudentPaperStructCacheBean;
|
|
|
-import com.qmth.themis.business.cache.bean.ObjectiveAnswerCacheBean;
|
|
|
+import com.qmth.themis.business.cache.bean.*;
|
|
|
import com.qmth.themis.business.config.SystemConfig;
|
|
|
import com.qmth.themis.business.constant.SpringContextHolder;
|
|
|
import com.qmth.themis.business.constant.SystemConstant;
|
|
@@ -53,29 +18,28 @@ import com.qmth.themis.business.dto.response.MarkResultDto;
|
|
|
import com.qmth.themis.business.dto.response.TEExamUnFinishDto;
|
|
|
import com.qmth.themis.business.entity.TOeExamAnswer;
|
|
|
import com.qmth.themis.business.entity.TOeExamRecord;
|
|
|
-import com.qmth.themis.business.enums.ExamRecordFieldEnum;
|
|
|
-import com.qmth.themis.business.enums.ExamRecordStatusEnum;
|
|
|
-import com.qmth.themis.business.enums.ExamTypeEnum;
|
|
|
-import com.qmth.themis.business.enums.ExceptionEnum;
|
|
|
-import com.qmth.themis.business.enums.FinishTypeEnum;
|
|
|
-import com.qmth.themis.business.enums.LivenessTypeEnum;
|
|
|
-import com.qmth.themis.business.enums.MqTagEnum;
|
|
|
-import com.qmth.themis.business.enums.MqTopicEnum;
|
|
|
-import com.qmth.themis.business.enums.ObjectiveScorePolicyEnum;
|
|
|
-import com.qmth.themis.business.enums.RecordSelectStrategyEnum;
|
|
|
-import com.qmth.themis.business.enums.VerifyExceptionEnum;
|
|
|
-import com.qmth.themis.business.service.MqDtoService;
|
|
|
-import com.qmth.themis.business.service.TEExamActivityService;
|
|
|
-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.TOeExamAnswerService;
|
|
|
-import com.qmth.themis.business.service.TOeExamRecordService;
|
|
|
+import com.qmth.themis.business.enums.*;
|
|
|
+import com.qmth.themis.business.service.*;
|
|
|
import com.qmth.themis.business.util.OssUtil;
|
|
|
import com.qmth.themis.business.util.RedisUtil;
|
|
|
import com.qmth.themis.common.contanst.Constants;
|
|
|
+import com.qmth.themis.common.exception.BusinessException;
|
|
|
import com.qmth.themis.common.util.FileUtil;
|
|
|
import com.qmth.themis.common.util.SimpleBeanUtil;
|
|
|
+import org.apache.commons.lang3.StringUtils;
|
|
|
+import org.slf4j.Logger;
|
|
|
+import org.slf4j.LoggerFactory;
|
|
|
+import org.springframework.beans.BeanUtils;
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
+import org.springframework.transaction.annotation.Transactional;
|
|
|
+
|
|
|
+import javax.annotation.Resource;
|
|
|
+import java.io.File;
|
|
|
+import java.math.BigDecimal;
|
|
|
+import java.text.SimpleDateFormat;
|
|
|
+import java.time.LocalDateTime;
|
|
|
+import java.time.ZoneOffset;
|
|
|
+import java.util.*;
|
|
|
|
|
|
/**
|
|
|
* @Description: 考试记录 服务实现类
|
|
@@ -216,7 +180,7 @@ public class TOeExamRecordServiceImpl extends ServiceImpl<TOeExamRecordMapper, T
|
|
|
ExamStudentAnswerCacheBean answer = (ExamStudentAnswerCacheBean) redisUtil.get(
|
|
|
RedisKeyHelper.examAnswerKey(recordId), key);
|
|
|
if (answer == null) {
|
|
|
- log.error("no ExamStudentAnswerCacheBean for calculateObjectiveScore recordId:"+recordId+" key:" + key);
|
|
|
+ log.error("no ExamStudentAnswerCacheBean for calculateObjectiveScore recordId:" + recordId + " key:" + key);
|
|
|
|
|
|
// 计算客观分总分
|
|
|
calculateTotalObjectiveScore(param);
|
|
@@ -225,7 +189,7 @@ public class TOeExamRecordServiceImpl extends ServiceImpl<TOeExamRecordMapper, T
|
|
|
//整卷客观题标答缓存集合
|
|
|
Map<String, ObjectiveAnswerCacheBean> map = examPaperService.getObjectiveAnswerCacheBean(paperId);
|
|
|
if (map == null || map.size() == 0) {
|
|
|
- log.info("no ObjectiveAnswerCacheBean map for calculateObjectiveScore recordId:"+recordId+" paperId:" + paperId);
|
|
|
+ log.info("no ObjectiveAnswerCacheBean map for calculateObjectiveScore recordId:" + recordId + " paperId:" + paperId);
|
|
|
// 更新分数
|
|
|
answer.setScore(0.0);
|
|
|
redisUtil.set(RedisKeyHelper.examAnswerKey(recordId), key, answer);
|
|
@@ -237,7 +201,7 @@ public class TOeExamRecordServiceImpl extends ServiceImpl<TOeExamRecordMapper, T
|
|
|
//客观题标答缓存
|
|
|
ObjectiveAnswerCacheBean cb = map.get(key);
|
|
|
if (cb == null) {
|
|
|
- log.info("no ObjectiveAnswerCacheBean for calculateObjectiveScore recordId:"+recordId+" key:" + key);
|
|
|
+ log.info("no ObjectiveAnswerCacheBean for calculateObjectiveScore recordId:" + recordId + " key:" + key);
|
|
|
// 更新分数
|
|
|
answer.setScore(0.0);
|
|
|
redisUtil.set(RedisKeyHelper.examAnswerKey(recordId), key, answer);
|
|
@@ -302,16 +266,16 @@ public class TOeExamRecordServiceImpl extends ServiceImpl<TOeExamRecordMapper, T
|
|
|
|
|
|
@SuppressWarnings("unchecked")
|
|
|
private void calculateTotalObjectiveScore(Map<String, Object> param) {
|
|
|
- Long recordId = (Long) param.get("recordId");
|
|
|
+ Long recordId = (Long) param.get("recordId");
|
|
|
Integer mainNumber = (Integer) param.get("mainNumber");
|
|
|
Integer subNumber = (Integer) param.get("subNumber");
|
|
|
Integer subIndex = (Integer) param.get("subIndex");
|
|
|
String lockKey = SystemConstant.REDIS_LOCK_TOTAL_OBJECTIVE_SCORE_PREFIX + recordId;
|
|
|
try {
|
|
|
- String key = RedisKeyHelper.examAnswerHashKey(mainNumber, subNumber, subIndex);
|
|
|
+ String key = RedisKeyHelper.examAnswerHashKey(mainNumber, subNumber, subIndex);
|
|
|
Boolean lock = redisUtil.lock(lockKey, SystemConstant.REDIS_CACHE_TIME_OUT);
|
|
|
if (lock) {
|
|
|
- log.info("calculateTotalObjectiveScore get lock sucss recordId:"+recordId+" key:"+key);
|
|
|
+ log.info("calculateTotalObjectiveScore get lock sucss recordId:"+recordId+" key:"+key);
|
|
|
Map<String, ExamStudentAnswerCacheBean> as = redisUtil.getHashEntries(RedisKeyHelper.examAnswerKey(recordId));
|
|
|
if (as != null && as.size() > 0) {
|
|
|
Double total = 0.0;
|
|
@@ -320,7 +284,7 @@ public class TOeExamRecordServiceImpl extends ServiceImpl<TOeExamRecordMapper, T
|
|
|
if (sa.getScore() != null) {//有分值
|
|
|
total = total + sa.getScore();
|
|
|
} else {
|
|
|
- log.info("calculateTotalObjectiveScore ExamStudentAnswerCacheBean Score is null recordId:"+recordId+" key:"+RedisKeyHelper.examAnswerHashKey(sa.getMainNumber(), sa.getSubNumber(), sa.getSubIndex()));
|
|
|
+ log.info("calculateTotalObjectiveScore ExamStudentAnswerCacheBean Score is null recordId:"+recordId+" key:"+RedisKeyHelper.examAnswerHashKey(sa.getMainNumber(), sa.getSubNumber(), sa.getSubIndex()));
|
|
|
total = null;
|
|
|
break;
|
|
|
}
|
|
@@ -329,18 +293,18 @@ public class TOeExamRecordServiceImpl extends ServiceImpl<TOeExamRecordMapper, T
|
|
|
if (total != null) {
|
|
|
ExamRecordCacheUtil.setObjectiveScore(recordId, total, true);
|
|
|
}else {
|
|
|
- log.info("calculateTotalObjectiveScore total Score is null recordId:"+recordId+" key:"+key);
|
|
|
+ log.info("calculateTotalObjectiveScore total Score is null recordId:"+recordId+" key:"+key);
|
|
|
}
|
|
|
}
|
|
|
}else {
|
|
|
- log.info("calculateTotalObjectiveScore get lock faild recordId:"+recordId+" key:"+key);
|
|
|
- calculateObjectiveScoreMsg(recordId, mainNumber, subNumber, subIndex);
|
|
|
+ log.info("calculateTotalObjectiveScore get lock faild recordId:"+recordId+" key:"+key);
|
|
|
+ calculateObjectiveScoreMsg(recordId, mainNumber, subNumber, subIndex);
|
|
|
}
|
|
|
} finally {
|
|
|
redisUtil.releaseLock(lockKey);
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
//考试中计算客观分消息
|
|
|
private void calculateObjectiveScoreMsg(Long recordId, Integer mainNumber, Integer subNumber, Integer subIndex) {
|
|
|
Map<String, Object> transMap = new HashMap<String, Object>();
|
|
@@ -348,18 +312,18 @@ public class TOeExamRecordServiceImpl extends ServiceImpl<TOeExamRecordMapper, T
|
|
|
transMap.put("mainNumber", mainNumber);
|
|
|
transMap.put("subNumber", subNumber);
|
|
|
transMap.put("subIndex", subIndex);
|
|
|
-
|
|
|
- String level = "1s";
|
|
|
- Integer time = SystemConstant.mqDelayLevel.get(level);
|
|
|
- LocalDateTime dt = LocalDateTime.now();
|
|
|
- dt = dt.plusSeconds(Long.parseLong(level.replace("s", "")));
|
|
|
- Map<String, Object> propMap = new HashMap<String, Object>();
|
|
|
- propMap.put("timeOut", time);
|
|
|
- propMap.put("mqExecTime", dt.toInstant(ZoneOffset.of("+8")).toEpochMilli());
|
|
|
- MqDto mqDto = new MqDto(MqTopicEnum.THEMIS_TOPIC.getCode(), MqTagEnum.CALCULATE_OBJECTIVE_SCORE.name(),
|
|
|
- transMap, MqTagEnum.CALCULATE_OBJECTIVE_SCORE, recordId.toString(), propMap, recordId.toString());
|
|
|
-
|
|
|
- mqDtoService.assembleSendAsyncDelayMsg(mqDto);
|
|
|
+
|
|
|
+ String level = "1s";
|
|
|
+ Integer time = SystemConstant.mqDelayLevel.get(level);
|
|
|
+ LocalDateTime dt = LocalDateTime.now();
|
|
|
+ dt = dt.plusSeconds(Long.parseLong(level.replace("s", "")));
|
|
|
+ Map<String, Object> propMap = new HashMap<String, Object>();
|
|
|
+ propMap.put("timeOut", time);
|
|
|
+ propMap.put("mqExecTime", dt.toInstant(ZoneOffset.of("+8")).toEpochMilli());
|
|
|
+ MqDto mqDto = new MqDto(MqTopicEnum.THEMIS_TOPIC.getCode(), MqTagEnum.CALCULATE_OBJECTIVE_SCORE.name(),
|
|
|
+ transMap, MqTagEnum.CALCULATE_OBJECTIVE_SCORE, recordId.toString(), propMap, recordId.toString());
|
|
|
+
|
|
|
+ mqDtoService.assembleSendAsyncDelayMsg(mqDto);
|
|
|
}
|
|
|
|
|
|
private boolean checkSingleChoice(String answerArray, JSONArray ar) {
|
|
@@ -992,26 +956,41 @@ public class TOeExamRecordServiceImpl extends ServiceImpl<TOeExamRecordMapper, T
|
|
|
@Override
|
|
|
@Transactional
|
|
|
public void setExamBreak(Integer alreadyBreakCount, Long recordId, Long examActivityId) {
|
|
|
- alreadyBreakCount++;
|
|
|
- Long breakId = Constants.idGen.next();
|
|
|
- ExamRecordCacheUtil.setLastBreakId(recordId, breakId, false);
|
|
|
- ExamRecordCacheUtil.setStatus(recordId, ExamRecordStatusEnum.BREAK_OFF, false);
|
|
|
- Long lastBreakTimeNow = System.currentTimeMillis();
|
|
|
- ExamRecordCacheUtil.setLastBreakTime(recordId, lastBreakTimeNow, false);
|
|
|
- ExamRecordCacheUtil.setAlreadyBreakCount(recordId, alreadyBreakCount, false);
|
|
|
- Long lastStartTime = System.currentTimeMillis();
|
|
|
- ExamRecordCacheUtil.setLastStartTime(recordId, lastStartTime, false);
|
|
|
- String[] columns = new String[]{ExamRecordFieldEnum.last_break_id.name(), ExamRecordFieldEnum.status.name(), ExamRecordFieldEnum.last_break_time.name(), ExamRecordFieldEnum.already_break_count.name(), ExamRecordFieldEnum.last_start_time.name()};
|
|
|
- Object[] values = new Object[]{breakId, ExamRecordStatusEnum.BREAK_OFF, lastBreakTimeNow, alreadyBreakCount, lastStartTime};
|
|
|
- TOeExamRecordService tOeExamRecordService = SpringContextHolder.getBean(TOeExamRecordService.class);
|
|
|
- tOeExamRecordService.dataUpdatesMq(recordId, columns, values);
|
|
|
- //考试断点异常原因 发送mq start
|
|
|
- MqDto mqDtoBreak = new MqDto(MqTopicEnum.THEMIS_TOPIC.getCode(), MqTagEnum.EXAM_BREAK.name(), ExceptionEnum.NET_TIME_OUT, MqTagEnum.EXAM_BREAK, String.valueOf(recordId), String.valueOf(recordId));
|
|
|
- MqDtoService mqDtoService = SpringContextHolder.getBean(MqDtoService.class);
|
|
|
- mqDtoService.assembleSendOneWayMsg(mqDtoBreak);
|
|
|
- //考试断点异常原因 发送mq end
|
|
|
- //更新场次-考试记录缓存
|
|
|
- ExamActivityRecordCacheUtil.setExamRecordStatus(examActivityId, recordId, new ExamActivityRecordCacheBean(ExamRecordCacheUtil.getExamStudentId(recordId), ExamRecordCacheUtil.getStatus(recordId)));
|
|
|
+ try {
|
|
|
+ if (redisUtil.lock(SystemConstant.REDIS_LOCK_EXAM_BREAK_PREFIX + recordId, SystemConstant.REDIS_LOCK_EXAM_BREAK_TIME_OUT)) {
|
|
|
+ alreadyBreakCount++;
|
|
|
+ Long breakId = Constants.idGen.next();
|
|
|
+ ExamRecordCacheUtil.setLastBreakId(recordId, breakId, false);
|
|
|
+ ExamRecordCacheUtil.setStatus(recordId, ExamRecordStatusEnum.BREAK_OFF, false);
|
|
|
+ Long lastBreakTimeNow = System.currentTimeMillis();
|
|
|
+ ExamRecordCacheUtil.setLastBreakTime(recordId, lastBreakTimeNow, false);
|
|
|
+ ExamRecordCacheUtil.setAlreadyBreakCount(recordId, alreadyBreakCount, false);
|
|
|
+ Long lastStartTime = System.currentTimeMillis();
|
|
|
+ ExamRecordCacheUtil.setLastStartTime(recordId, lastStartTime, false);
|
|
|
+ String[] columns = new String[]{ExamRecordFieldEnum.last_break_id.name(), ExamRecordFieldEnum.status.name(), ExamRecordFieldEnum.last_break_time.name(), ExamRecordFieldEnum.already_break_count.name(), ExamRecordFieldEnum.last_start_time.name()};
|
|
|
+ Object[] values = new Object[]{breakId, ExamRecordStatusEnum.BREAK_OFF, lastBreakTimeNow, alreadyBreakCount, lastStartTime};
|
|
|
+ TOeExamRecordService tOeExamRecordService = SpringContextHolder.getBean(TOeExamRecordService.class);
|
|
|
+ tOeExamRecordService.dataUpdatesMq(recordId, columns, values);
|
|
|
+ //考试断点异常原因 发送mq start
|
|
|
+ MqDto mqDtoBreak = new MqDto(MqTopicEnum.THEMIS_TOPIC.getCode(), MqTagEnum.EXAM_BREAK.name(), ExceptionEnum.NET_TIME_OUT, MqTagEnum.EXAM_BREAK, String.valueOf(recordId), String.valueOf(recordId));
|
|
|
+ MqDtoService mqDtoService = SpringContextHolder.getBean(MqDtoService.class);
|
|
|
+ mqDtoService.assembleSendOneWayMsg(mqDtoBreak);
|
|
|
+ //考试断点异常原因 发送mq end
|
|
|
+ //更新场次-考试记录缓存
|
|
|
+ ExamActivityRecordCacheUtil.setExamRecordStatus(examActivityId, recordId, new ExamActivityRecordCacheBean(ExamRecordCacheUtil.getExamStudentId(recordId), ExamRecordCacheUtil.getStatus(recordId)));
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("请求出错", e);
|
|
|
+ if (e instanceof BusinessException) {
|
|
|
+ throw new BusinessException(e.getMessage());
|
|
|
+ } else {
|
|
|
+ throw new RuntimeException(e);
|
|
|
+ }
|
|
|
+ } finally {
|
|
|
+ if (Objects.nonNull(recordId)) {
|
|
|
+ redisUtil.releaseLock(SystemConstant.REDIS_LOCK_EXAM_BREAK_PREFIX + recordId);
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -1024,28 +1003,42 @@ public class TOeExamRecordServiceImpl extends ServiceImpl<TOeExamRecordMapper, T
|
|
|
@Override
|
|
|
public Boolean sendExamBreakMsg(Long recordId, boolean setBreak) {
|
|
|
Boolean finished = false;
|
|
|
- Long examId = ExamRecordCacheUtil.getExamId(recordId);
|
|
|
- Long examStudentId = ExamRecordCacheUtil.getExamStudentId(recordId);
|
|
|
- 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 durationSeconds = Objects.isNull(ExamRecordCacheUtil.getDurationSeconds(recordId)) ? 0 : ExamRecordCacheUtil.getDurationSeconds(recordId);
|
|
|
- Integer alreadyBreakCount = Objects.isNull(ExamRecordCacheUtil.getAlreadyBreakCount(recordId)) ? 0 : ExamRecordCacheUtil.getAlreadyBreakCount(recordId);
|
|
|
- Integer leftBreakResumeCount = ec.getBreakResumeCount() - alreadyBreakCount;
|
|
|
- if (Objects.nonNull(lastBreakTime) && (System.currentTimeMillis() - lastBreakTime) / 1000 >= breakExpireSeconds) {
|
|
|
- finished = true;
|
|
|
- examService.finish(examStudentCacheBean.getStudentId(), recordId, FinishTypeEnum.AUTO.name(), durationSeconds);
|
|
|
- } else {
|
|
|
- if (leftBreakResumeCount < 0) {
|
|
|
- finished = true;
|
|
|
- examService.finish(examStudentCacheBean.getStudentId(), recordId, FinishTypeEnum.AUTO.name(), durationSeconds);
|
|
|
- } else {
|
|
|
- if (setBreak) {
|
|
|
- this.setExamBreak(alreadyBreakCount, recordId, examStudentCacheBean.getExamActivityId());
|
|
|
+ try {
|
|
|
+ if (redisUtil.lock(SystemConstant.REDIS_LOCK_EXAM_BREAK_LOGIC_PREFIX + recordId, SystemConstant.REDIS_LOCK_EXAM_BREAK_LOGIC_TIME_OUT)) {
|
|
|
+ Long examId = ExamRecordCacheUtil.getExamId(recordId);
|
|
|
+ Long examStudentId = ExamRecordCacheUtil.getExamStudentId(recordId);
|
|
|
+ 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 durationSeconds = Objects.isNull(ExamRecordCacheUtil.getDurationSeconds(recordId)) ? 0 : ExamRecordCacheUtil.getDurationSeconds(recordId);
|
|
|
+ Integer alreadyBreakCount = Objects.isNull(ExamRecordCacheUtil.getAlreadyBreakCount(recordId)) ? 0 : ExamRecordCacheUtil.getAlreadyBreakCount(recordId);
|
|
|
+ Integer leftBreakResumeCount = ec.getBreakResumeCount() - alreadyBreakCount;
|
|
|
+ if (Objects.nonNull(lastBreakTime) && (System.currentTimeMillis() - lastBreakTime) / 1000 >= breakExpireSeconds) {
|
|
|
+ finished = true;
|
|
|
+ examService.finish(examStudentCacheBean.getStudentId(), recordId, FinishTypeEnum.AUTO.name(), durationSeconds);
|
|
|
+ } else {
|
|
|
+ if (leftBreakResumeCount < 0) {
|
|
|
+ finished = true;
|
|
|
+ examService.finish(examStudentCacheBean.getStudentId(), recordId, FinishTypeEnum.AUTO.name(), durationSeconds);
|
|
|
+ } else {
|
|
|
+ if (setBreak) {
|
|
|
+ this.setExamBreak(alreadyBreakCount, recordId, examStudentCacheBean.getExamActivityId());
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("请求出错", e);
|
|
|
+ if (e instanceof BusinessException) {
|
|
|
+ throw new BusinessException(e.getMessage());
|
|
|
+ } else {
|
|
|
+ throw new RuntimeException(e);
|
|
|
+ }
|
|
|
+ } finally {
|
|
|
+ if (Objects.nonNull(recordId)) {
|
|
|
+ redisUtil.releaseLock(SystemConstant.REDIS_LOCK_EXAM_BREAK_LOGIC_PREFIX + recordId);
|
|
|
+ }
|
|
|
}
|
|
|
return finished;
|
|
|
}
|