xiatian 4 жил өмнө
parent
commit
fb4f556325

+ 9 - 0
themis-business/src/main/java/com/qmth/themis/business/service/CommonService.java

@@ -0,0 +1,9 @@
+package com.qmth.themis.business.service;
+
+public interface CommonService {
+
+	/**
+	 *考试记录数据持久化
+	 */
+	void persisted(Long recordId);
+}

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

@@ -138,4 +138,5 @@ public interface TEExamService extends IService<TEExam> {
 	 * @return
 	 */
 	public ExamResultBean result(Long studentId, Long recordId);
+
 }

+ 2 - 1
themis-business/src/main/java/com/qmth/themis/business/service/TOeExamRecordService.java

@@ -36,5 +36,6 @@ public interface TOeExamRecordService extends IService<TOeExamRecord> {
 	/**考试记录数据持久化
 	 * @param recordId
 	 */
-	public void persisted(Long recordId);
+	public void saveDataByCache(Long recordId);
+
 }

+ 47 - 0
themis-business/src/main/java/com/qmth/themis/business/service/impl/CommonServiceImpl.java

@@ -0,0 +1,47 @@
+package com.qmth.themis.business.service.impl;
+
+import javax.annotation.Resource;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Service;
+
+import com.qmth.themis.business.cache.RedisKeyHelper;
+import com.qmth.themis.business.constant.SystemConstant;
+import com.qmth.themis.business.service.CommonService;
+import com.qmth.themis.business.service.TOeExamRecordService;
+import com.qmth.themis.business.util.RedisUtil;
+
+/**
+ * @Description:
+ * @Author: xiatian
+ * @Date: 2020-08-04
+ */
+@Service
+public class CommonServiceImpl implements CommonService {
+	private final static Logger log = LoggerFactory.getLogger(CommonService.class);
+
+	@Resource
+	TOeExamRecordService examRecordService;
+	@Resource
+	RedisUtil redisUtil;
+
+	@Override
+	public void persisted(Long recordId) {
+		String lockKey = SystemConstant.REDIS_LOCK_EXAM_RECORD_PERSISTED_PREFIX + recordId;
+		Boolean lock = redisUtil.lock(lockKey, SystemConstant.REDIS_CACHE_TIME_OUT);
+		if (!lock) {
+			log.debug("persisted doing,request ignore");
+		}
+		try {
+			examRecordService.saveDataByCache(recordId);
+			// 清除缓存
+			redisUtil.delete(RedisKeyHelper.examRecordCacheKey(recordId));
+			redisUtil.delete(RedisKeyHelper.examAnswerKey(recordId));
+			redisUtil.delete(RedisKeyHelper.audioLeftPlayCountKey(recordId));
+		} finally {
+			redisUtil.releaseLock(lockKey);
+		}
+	}
+
+}

+ 74 - 17
themis-business/src/main/java/com/qmth/themis/business/service/impl/TEExamServiceImpl.java

@@ -1,11 +1,45 @@
 package com.qmth.themis.business.service.impl;
 
+import java.io.IOException;
+import java.io.InputStream;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+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.codec.digest.DigestUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.BeanUtils;
+import org.springframework.cache.annotation.Cacheable;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.multipart.MultipartFile;
+
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
-import com.qmth.themis.business.bean.exam.*;
+import com.qmth.themis.business.bean.exam.ExamFileUploadBean;
+import com.qmth.themis.business.bean.exam.ExamFinishBean;
+import com.qmth.themis.business.bean.exam.ExamPrepareBean;
+import com.qmth.themis.business.bean.exam.ExamResultBean;
+import com.qmth.themis.business.bean.exam.ExamResumeBean;
+import com.qmth.themis.business.bean.exam.ExamStartBean;
 import com.qmth.themis.business.cache.ExamRecordCacheUtil;
 import com.qmth.themis.business.cache.RedisKeyHelper;
-import com.qmth.themis.business.cache.bean.*;
+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.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.config.SystemConfig;
 import com.qmth.themis.business.dao.TEExamMapper;
 import com.qmth.themis.business.dto.response.TEExamActivityDto;
@@ -13,23 +47,15 @@ import com.qmth.themis.business.dto.response.TEExamDto;
 import com.qmth.themis.business.entity.TEExam;
 import com.qmth.themis.business.enums.ExamRecordStatusEnum;
 import com.qmth.themis.business.enums.FinishTypeEnum;
-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.codec.digest.DigestUtils;
-import org.apache.commons.lang3.StringUtils;
-import org.springframework.beans.BeanUtils;
-import org.springframework.cache.annotation.Cacheable;
-import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
-import org.springframework.web.multipart.MultipartFile;
-
-import javax.annotation.Resource;
-import java.io.IOException;
-import java.io.InputStream;
-import java.text.SimpleDateFormat;
-import java.util.*;
 
 /**
  * @Description: 考试批次 服务实现类
@@ -113,6 +139,9 @@ public class TEExamServiceImpl extends ServiceImpl<TEExamMapper, TEExam> impleme
 //        return teExamMapper.getWaitingExamForJob();
 //    }
 
+    /**
+     *开始候考
+     */
     @Transactional
     @Override
     public ExamPrepareBean prepare(Long studentId, Long examStudentId) {
@@ -216,6 +245,9 @@ public class TEExamServiceImpl extends ServiceImpl<TEExamMapper, TEExam> impleme
         return -1;
     }
 
+    /**
+     *开始候考
+     */
     @Override
     public ExamStartBean start(Long studentId, Long recordId) {
         ExamStartBean ret = null;
@@ -266,6 +298,9 @@ public class TEExamServiceImpl extends ServiceImpl<TEExamMapper, TEExam> impleme
         return ret;
     }
 
+    /**
+     *上传个人试卷结构
+     */
     @Override
     public Long studentPaperStruct(Long studentId, Long recordId, String content) {
 
@@ -291,6 +326,9 @@ public class TEExamServiceImpl extends ServiceImpl<TEExamMapper, TEExam> impleme
         return struct.getTime();
     }
 
+    /**
+     *提交作答结果
+     */
     @Override
     public Long answerSubmit(Long studentId, Long recordId, Integer mainNumber, Integer subNumber, Integer subIndex,
                              String answer, Long version, Integer durationSeconds) {
@@ -338,6 +376,9 @@ public class TEExamServiceImpl extends ServiceImpl<TEExamMapper, TEExam> impleme
         return version;
     }
 
+    /**
+     *更新音频剩余播放次数
+     */
     @Override
     public Integer audioLeftPlayCountSubmit(Long studentId, Long recordId, String key, Integer count) {
 
@@ -361,6 +402,9 @@ public class TEExamServiceImpl extends ServiceImpl<TEExamMapper, TEExam> impleme
         return count;
     }
 
+    /**
+     *文件上传
+     */
     @Override
     public ExamFileUploadBean fileUpload(Long studentId, Long recordId, MultipartFile file, String suffix, String md5) {
 
@@ -408,6 +452,9 @@ public class TEExamServiceImpl extends ServiceImpl<TEExamMapper, TEExam> impleme
         return UUID.randomUUID().toString().replaceAll("-", "");
     }
 
+    /**
+     *断点恢复
+     */
     @SuppressWarnings("unchecked")
     @Override
     public ExamResumeBean resume(Long studentId, Long recordId) {
@@ -459,7 +506,10 @@ public class TEExamServiceImpl extends ServiceImpl<TEExamMapper, TEExam> impleme
         return ret;
     }
 
-    // 作答排序
+    /**作答排序
+     * @param answers
+     * @return
+     */
     private List<ExamStudentAnswerCacheBean> sortAnswers(Map<String, ExamStudentAnswerCacheBean> answers) {
         List<ExamStudentAnswerCacheBean> ret = new ArrayList<ExamStudentAnswerCacheBean>(answers.values());
         Collections.sort(ret, new Comparator<ExamStudentAnswerCacheBean>() {
@@ -495,6 +545,9 @@ public class TEExamServiceImpl extends ServiceImpl<TEExamMapper, TEExam> impleme
         return ret;
     }
 
+    /**
+     *结束考试
+     */
     @Override
     public ExamFinishBean finish(Long studentId, Long recordId, String type, Integer durationSeconds) {
 
@@ -538,6 +591,9 @@ public class TEExamServiceImpl extends ServiceImpl<TEExamMapper, TEExam> impleme
         return ret;
     }
 
+    /**
+     *查询交卷结果
+     */
     @Override
     public ExamResultBean result(Long studentId, Long recordId) {
         // 校验当前登录用户和参数一致性
@@ -563,4 +619,5 @@ public class TEExamServiceImpl extends ServiceImpl<TEExamMapper, TEExam> impleme
         ret.setReviewResult("");
         return ret;
     }
+    
 }

+ 4 - 13
themis-business/src/main/java/com/qmth/themis/business/service/impl/TOeExamRecordServiceImpl.java

@@ -289,14 +289,10 @@ public class TOeExamRecordServiceImpl extends ServiceImpl<TOeExamRecordMapper, T
 	/**
 	 *考试记录数据持久化
 	 */
-	@SuppressWarnings("unchecked")
+    @SuppressWarnings("unchecked")
+    @Transactional
 	@Override
-	public void persisted(Long recordId) {
-		String lockKey = SystemConstant.REDIS_LOCK_EXAM_RECORD_PERSISTED_PREFIX + recordId;
-        Boolean lock = redisUtil.lock(lockKey, SystemConstant.REDIS_CACHE_TIME_OUT);
-        if (!lock) {
-        	log.debug("persisted doing,request ignore");
-        }
+	public void saveDataByCache(Long recordId) {
         String tempDir = systemConfig.getProperty("sys.config.tempDataDir");
         String dir = tempDir + "/" + uuid() + "/";
         File dfile = new File(dir);
@@ -326,17 +322,12 @@ public class TOeExamRecordServiceImpl extends ServiceImpl<TOeExamRecordMapper, T
             FileUtil.saveAsFile(structFile.getAbsolutePath(), struct.getContent());
             SystemConfig systemConfig = SpringContextHolder.getBean(SystemConfig.class);
             OssUtil.ossUpload(systemConfig.getOssEnv(3), structFilePath, structFile);
-            
-            //清除缓存
-            redisUtil.delete(RedisKeyHelper.examRecordCacheKey(recordId));
-            redisUtil.delete(RedisKeyHelper.examAnswerKey(recordId));
-            redisUtil.delete(RedisKeyHelper.audioLeftPlayCountKey(recordId));
         } finally {
-            redisUtil.releaseLock(lockKey);
             FileUtil.deleteFolder(dir);
         }
 	}
 	private String uuid() {
         return UUID.randomUUID().toString().replaceAll("-", "");
     }
+	
 }

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

@@ -14,11 +14,13 @@ import org.springframework.web.bind.annotation.RestController;
 import org.springframework.web.multipart.MultipartFile;
 
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.qmth.themis.business.cache.ExamRecordCacheUtil;
 import com.qmth.themis.business.constant.SystemConstant;
 import com.qmth.themis.business.dto.response.TEExamDto;
 import com.qmth.themis.business.dto.response.TEExamResultDto;
 import com.qmth.themis.business.entity.TEExam;
 import com.qmth.themis.business.entity.TEStudent;
+import com.qmth.themis.business.enums.ExamRecordStatusEnum;
 import com.qmth.themis.business.enums.MqEnum;
 import com.qmth.themis.business.service.TEExamService;
 import com.qmth.themis.business.util.RedisUtil;
@@ -230,7 +232,9 @@ public class TEExamController {
             throw new BusinessException(ExceptionResultEnum.REQUEST_AWAIT);
         }
         try {
-            return ResultUtil.ok(teExamService.finish(teStudent.getId(), recordId, type, durationSeconds));
+        	Result re=ResultUtil.ok(teExamService.finish(teStudent.getId(), recordId, type, durationSeconds));
+        	checkToPersisted(recordId);
+            return re;
         } finally {
             redisUtil.releaseLock(lockKey);
         }
@@ -263,4 +267,24 @@ public class TEExamController {
             redisUtil.releaseLock(lockKey);
         }
     }
+    
+    /**检查条件并发送持久化消息
+     * @param recordId
+     */
+    private void checkToPersisted(Long recordId) {
+    	ExamRecordStatusEnum status=ExamRecordCacheUtil.getStatus(recordId);
+    	if(!ExamRecordStatusEnum.FINISHED.equals(status)) {
+    		return;
+    	}
+    	Double score=ExamRecordCacheUtil.getObjectiveScore(recordId);
+    	if(score==null) {
+    		return;
+    	}
+    	
+    	Map<String, Object> transMap = new HashMap<String, Object>();
+        transMap.put("recordId", recordId);
+        //mq发送消息start
+        MqDto mqDto = new MqDto(MqTopicEnum.themisTopic.getCode(), MqTagEnum.examRecordPersisted.name(), transMap, MqEnum.EXAM, null, null);
+        mqDtoService.assembleSendOneWayMsg(mqDto);
+    }
 }

+ 28 - 11
themis-mq/src/main/java/com/qmth/themis/mq/service/impl/MqLogicServiceImpl.java

@@ -1,5 +1,17 @@
 package com.qmth.themis.mq.service.impl;
 
+import java.io.IOException;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+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.core.conditions.query.QueryWrapper;
 import com.google.gson.Gson;
 import com.qmth.themis.business.cache.ExamRecordCacheUtil;
@@ -13,7 +25,16 @@ import com.qmth.themis.business.enums.BreakReasonEnum;
 import com.qmth.themis.business.enums.ExamRecordStatusEnum;
 import com.qmth.themis.business.enums.MqEnum;
 import com.qmth.themis.business.enums.SystemOperationEnum;
-import com.qmth.themis.business.service.*;
+import com.qmth.themis.business.service.CommonService;
+import com.qmth.themis.business.service.TBSessionService;
+import com.qmth.themis.business.service.TEExamService;
+import com.qmth.themis.business.service.TEExamStudentLogService;
+import com.qmth.themis.business.service.TEUserLogService;
+import com.qmth.themis.business.service.TMRocketMessageService;
+import com.qmth.themis.business.service.TOeExamBreakHistoryService;
+import com.qmth.themis.business.service.TOeExamRecordService;
+import com.qmth.themis.business.service.TOeFaceVerifyHistoryService;
+import com.qmth.themis.business.service.TOeLivenessVerifyHistoryService;
 import com.qmth.themis.business.templete.TaskExportTemplete;
 import com.qmth.themis.business.templete.TaskImportTemplete;
 import com.qmth.themis.business.templete.impl.TaskExamPaperImportTemplete;
@@ -24,14 +45,7 @@ import com.qmth.themis.business.threadPool.MyThreadPool;
 import com.qmth.themis.business.util.JacksonUtil;
 import com.qmth.themis.business.util.RedisUtil;
 import com.qmth.themis.mq.dto.MqDto;
-import com.qmth.themis.mq.service.MqDtoService;
 import com.qmth.themis.mq.service.MqLogicService;
-import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
-
-import javax.annotation.Resource;
-import java.io.IOException;
-import java.util.*;
 
 /**
  * @Description: mq执行逻辑 impl
@@ -79,6 +93,9 @@ public class MqLogicServiceImpl implements MqLogicService {
     @Resource
     TEExamService teExamService;
 
+    @Resource
+    CommonService commonService;
+    
     /*** mq最大重试次数逻辑
      *
      * @param mqDto
@@ -221,11 +238,12 @@ public class MqLogicServiceImpl implements MqLogicService {
      * @param key
      */
     @Override
-    @Transactional
     public void execMqCalculateObjectiveScoreLogic(MqDto mqDto, String key) {
         Gson gson = new Gson();
         Map<String, Object> param = (Map<String, Object>) mqDto.getBody();
         examRecordService.calculateObjectiveScore(param);
+        Long recordId = (Long) param.get("recordId");
+        commonService.persisted(recordId);
         mqDto.setAck(SystemConstant.STANDARD_ACK_TYPE);
         TMRocketMessage tmRocketMessage = gson.fromJson(gson.toJson(mqDto), TMRocketMessage.class);
         tmRocketMessage.setBody(JacksonUtil.parseJson(tmRocketMessage.getBody()));
@@ -295,12 +313,11 @@ public class MqLogicServiceImpl implements MqLogicService {
      * @param key
      */
     @Override
-    @Transactional
     public void execMqExamRecordPersistedLogic(MqDto mqDto, String key) {
         Gson gson = new Gson();
         Map<String, Object> param = (Map<String, Object>) mqDto.getBody();
         Long recordId = (Long) param.get("recordId");
-        examRecordService.persisted(recordId);
+        commonService.persisted(recordId);
         mqDto.setAck(SystemConstant.STANDARD_ACK_TYPE);
         TMRocketMessage tmRocketMessage = gson.fromJson(gson.toJson(mqDto), TMRocketMessage.class);
         tmRocketMessage.setBody(JacksonUtil.parseJson(tmRocketMessage.getBody()));