|
@@ -39,6 +39,7 @@ import cn.com.qmth.examcloud.support.cache.bean.ExtractConfigDetailCacheBean;
|
|
|
import cn.com.qmth.examcloud.support.cache.bean.ExtractConfigPaperCacheBean;
|
|
|
import cn.com.qmth.examcloud.support.cache.bean.SysPropertyCacheBean;
|
|
|
import cn.com.qmth.examcloud.web.bootstrap.PropertyHolder;
|
|
|
+import cn.com.qmth.examcloud.web.exception.SequenceLockException;
|
|
|
import cn.com.qmth.examcloud.web.helpers.GlobalHelper;
|
|
|
import cn.com.qmth.examcloud.web.helpers.SequenceLockHelper;
|
|
|
import cn.com.qmth.examcloud.web.redis.RedisClient;
|
|
@@ -64,7 +65,6 @@ import java.net.URLEncoder;
|
|
|
import java.text.SimpleDateFormat;
|
|
|
import java.util.*;
|
|
|
import java.util.concurrent.TimeUnit;
|
|
|
-import java.util.concurrent.locks.LockSupport;
|
|
|
import java.util.stream.Collectors;
|
|
|
|
|
|
/**
|
|
@@ -258,7 +258,7 @@ public class ExamControlServiceImpl implements ExamControlService {
|
|
|
|
|
|
// 更新考生信息
|
|
|
startTime = System.currentTimeMillis();
|
|
|
- examStudentEntity=examStudentService.updateExamStudentByStartExam(examStudentEntity, examBean);
|
|
|
+ examStudentEntity = examStudentService.updateExamStudentByStartExam(examStudentEntity, examBean);
|
|
|
if (log.isDebugEnabled()) {
|
|
|
log.debug("7 更新考生信息耗时:" + (System.currentTimeMillis() - startTime) + " ms");
|
|
|
}
|
|
@@ -734,7 +734,7 @@ public class ExamControlServiceImpl implements ExamControlService {
|
|
|
|
|
|
startTime = System.currentTimeMillis();
|
|
|
// 计算保存考试分数
|
|
|
- examScoreService.saveExamScore(examRecord,examRecordData);
|
|
|
+ examScoreService.saveExamScore(examRecord, examRecordData);
|
|
|
if (log.isDebugEnabled()) {
|
|
|
log.debug("3 [HAND_IN_EXAM]计算保存考试分数耗时:" + (System.currentTimeMillis() - startTime) + " ms");
|
|
|
}
|
|
@@ -854,7 +854,7 @@ public class ExamControlServiceImpl implements ExamControlService {
|
|
|
// 更新心跳次数
|
|
|
examSessionInfo.setHeartbeat(examSessionInfo.getHeartbeat() + 1);
|
|
|
// 会话过期时间:秒
|
|
|
- int expireTime = (examSessionInfo.getExamReconnectTime() + 1) * 60;
|
|
|
+ int expireTime = (examSessionInfo.getExamReconnectTime() + 1) * 60;
|
|
|
// 更新考试会话过期时间
|
|
|
examSessionInfoService.saveExamSessionInfo(studentId, examSessionInfo, expireTime);
|
|
|
// 返回考试剩余时间 :考试时长-心跳次数*60000
|
|
@@ -915,7 +915,7 @@ public class ExamControlServiceImpl implements ExamControlService {
|
|
|
// 查询考试记录
|
|
|
ExamRecordDataEntity examRecordData = GlobalHelper.getEntity(examRecordDataRepo, examingRecord.getExamRecordDataId(),
|
|
|
ExamRecordDataEntity.class);
|
|
|
- handInExam(examRecordData, HandInExamType.AUTO);
|
|
|
+ delayHandInExamIfLocked(examRecordData);
|
|
|
return null;
|
|
|
}
|
|
|
// 如果已经过了断点续考时间,清除考试记录,清除会话
|
|
@@ -929,11 +929,38 @@ public class ExamControlServiceImpl implements ExamControlService {
|
|
|
ExamRecordDataEntity examRecordDataEntity = GlobalHelper.getEntity(examRecordDataRepo,
|
|
|
examingRecord.getExamRecordDataId(), ExamRecordDataEntity.class);
|
|
|
handInExam(examRecordDataEntity, HandInExamType.AUTO);
|
|
|
+ delayHandInExamIfLocked(examRecordDataEntity);
|
|
|
return null;
|
|
|
}
|
|
|
return examingRecord;
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * 如果有序列化锁,则延迟交卷
|
|
|
+ * @param examRecordData
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ private void delayHandInExamIfLocked(ExamRecordDataEntity examRecordData) {
|
|
|
+ try {
|
|
|
+ handInExam(examRecordData, HandInExamType.AUTO);
|
|
|
+ } catch (SequenceLockException e) {
|
|
|
+ //如果发现自动服务正在交卷,则重试1500毫秒获取考试记录状态,判断是否已交卷
|
|
|
+ int loopTimes = 0;
|
|
|
+ while (loopTimes <= 15) {
|
|
|
+ loopTimes++;
|
|
|
+ examRecordData = GlobalHelper.getEntity(examRecordDataRepo, examRecordData.getId(),
|
|
|
+ ExamRecordDataEntity.class);
|
|
|
+
|
|
|
+ //1500毫秒内如果交卷成功,则退出循环
|
|
|
+ if (examRecordData.getExamRecordStatus() != ExamRecordStatus.EXAM_ING) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ Util.sleep(TimeUnit.MILLISECONDS, 100);
|
|
|
+ }
|
|
|
+ throw e;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
@Override
|
|
|
public void cleanExamingRecord(ExamingRecordEntity examingRecord) {
|
|
|
|
|
@@ -1358,7 +1385,7 @@ public class ExamControlServiceImpl implements ExamControlService {
|
|
|
|
|
|
res.setQuestionOrder(eqe.getOrder());
|
|
|
res.setQuestionMainNumber(eqe.getMainNumber());
|
|
|
- res.setSubNumber(getSubNumber(examRecordQuestionsEntity,Integer.valueOf(order)));
|
|
|
+ res.setSubNumber(getSubNumber(examRecordQuestionsEntity, Integer.valueOf(order)));
|
|
|
try {
|
|
|
this.sendScanQrCodeToWebSocket(clientId, Long.valueOf(examRecordDataId), Integer.valueOf(order));
|
|
|
} catch (Exception e) {
|
|
@@ -1367,7 +1394,7 @@ public class ExamControlServiceImpl implements ExamControlService {
|
|
|
return res;
|
|
|
}
|
|
|
|
|
|
- private Integer getSubNumber(ExamRecordQuestionsEntity examRecordQuestionsEntity,Integer order) {
|
|
|
+ private Integer getSubNumber(ExamRecordQuestionsEntity examRecordQuestionsEntity, Integer order) {
|
|
|
List<UploadedFileAnswerInfo> list = getReSortedQuestionList(examRecordQuestionsEntity);
|
|
|
for (UploadedFileAnswerInfo info : list) {
|
|
|
if (order.intValue() == info.getOrder().intValue()) {
|
|
@@ -1504,6 +1531,7 @@ public class ExamControlServiceImpl implements ExamControlService {
|
|
|
|
|
|
/**
|
|
|
* 根据考试记录id获取所有已经重排序号的考试列表
|
|
|
+ *
|
|
|
* @param examRecordQuestionsEntity
|
|
|
* @return
|
|
|
*/
|