Przeglądaj źródła

修复学生强登录提示BUG

wangliang 3 lat temu
rodzic
commit
100b9111da

+ 4 - 0
themis-admin/src/main/java/com/qmth/themis/admin/api/TEExamStudentController.java

@@ -210,6 +210,10 @@ public class TEExamStudentController {
                     .eq(TEExamStudent::getExamActivityId, s.getExamActivityId());
             TEExamStudent teExamStudent = teExamStudentService.getOne(teExamStudentQueryWrapper);
 
+            if (Objects.isNull(s.getId()) && Objects.nonNull(teExamStudent)) {
+                throw new BusinessException("此考生已存在");
+            }
+
             QueryWrapper<TEStudent> teStudentQueryWrapper = new QueryWrapper<>();
             teStudentQueryWrapper.lambda().eq(TEStudent::getIdentity, s.getIdentity()).eq(TEStudent::getOrgId, tbOrg.getId());
             TEStudent teStudent = teStudentService.getOne(teStudentQueryWrapper);

+ 9 - 1
themis-business/src/main/java/com/qmth/themis/business/cache/ExamingDataCacheUtil.java

@@ -1,6 +1,7 @@
 package com.qmth.themis.business.cache;
 
 import com.qmth.themis.business.constant.SpringContextHolder;
+import com.qmth.themis.business.dto.cache.TEStudentCacheDto;
 import com.qmth.themis.business.util.RedisUtil;
 
 /**
@@ -16,7 +17,7 @@ public class ExamingDataCacheUtil {
     public static void deleteUnFinishedRecordId(Long studentId) {
         redisUtil.delete(RedisKeyHelper.unFinishedRecordIdCacheKey(studentId));
     }
-    
+
     public static void setUnFinishedRecordId(Long studentId, Long examRecordId) {
         redisUtil.set(RedisKeyHelper.unFinishedRecordIdCacheKey(studentId), examRecordId);
     }
@@ -25,4 +26,11 @@ public class ExamingDataCacheUtil {
         return (Long) redisUtil.get(RedisKeyHelper.unFinishedRecordIdCacheKey(studentId));
     }
 
+    public static TEStudentCacheDto getStudentExaming(Long studentId) {
+        return (TEStudentCacheDto) redisUtil.get(RedisKeyHelper.studentCacheKey(studentId));
+    }
+
+    public static void setStudentExaming(Long studentId, TEStudentCacheDto teStudentCacheDto) {
+        redisUtil.set(RedisKeyHelper.studentCacheKey(studentId), teStudentCacheDto);
+    }
 }

+ 11 - 0
themis-business/src/main/java/com/qmth/themis/business/cache/RedisKeyHelper.java

@@ -1,5 +1,6 @@
 package com.qmth.themis.business.cache;
 
+import com.qmth.themis.business.constant.SystemConstant;
 import com.qmth.themis.business.enums.MobileModeEnum;
 
 public class RedisKeyHelper {
@@ -227,4 +228,14 @@ public class RedisKeyHelper {
     public static String objectiveAnswerCacheHashKey(Long paperId) {
         return objectiveAnswerHashKeyPrefix + paperId;
     }
+
+    /**
+     * 学生记录id key
+     *
+     * @param studentId
+     * @return
+     */
+    public static String studentCacheKey(Long studentId) {
+        return SystemConstant.studentAccount + ":" +studentId;
+    }
 }

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

@@ -133,6 +133,8 @@ public class SystemConstant {
 
     public static final String RECORD_ID = "recordId";
 
+    public static final String STUDENT_ID = "studentId";
+
     public static final String MESSAGE = "message";
 
     public static final String ADMIN = "ADMIN";

+ 11 - 0
themis-business/src/main/java/com/qmth/themis/business/dto/cache/TEStudentCacheDto.java

@@ -32,6 +32,17 @@ public class TEStudentCacheDto implements Serializable {
     @ApiModelProperty(name = "学生底照")
     private String basePhotoPath;
 
+    @ApiModelProperty(name = "正在考试的id")
+    private Long examingRecordId;
+
+    public Long getExamingRecordId() {
+        return examingRecordId;
+    }
+
+    public void setExamingRecordId(Long examingRecordId) {
+        this.examingRecordId = examingRecordId;
+    }
+
     public Long getId() {
         return id;
     }

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

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

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

@@ -29,7 +29,7 @@ public interface TOeExamRecordService extends IService<TOeExamRecord> {
      */
     public Map getUnFinishExam(Long studentId, Long examId, Long orgId);
 
-    Long saveByPrepare(Long examId, Long examActivityId, Long examStudentId, Long paperId, Integer serialNumber);
+    Long saveByPrepare(Long examId, Long examActivityId, Long examStudentId, Long paperId, Integer serialNumber, Long studentId);
 
     /**
      * 计算客观分

+ 13 - 2
themis-business/src/main/java/com/qmth/themis/business/service/impl/CacheServiceImpl.java

@@ -2,6 +2,7 @@ package com.qmth.themis.business.service.impl;
 
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.google.gson.Gson;
+import com.qmth.themis.business.cache.ExamingDataCacheUtil;
 import com.qmth.themis.business.constant.SpringContextHolder;
 import com.qmth.themis.business.constant.SystemConstant;
 import com.qmth.themis.business.dto.AuthDto;
@@ -273,7 +274,12 @@ public class CacheServiceImpl implements CacheService {
     public TEStudentCacheDto addStudentAccountCache(Long studentId) {
         TEStudent teStudent = teStudentService.getById(studentId);
         Gson gson = new Gson();
-        return gson.fromJson(gson.toJson(teStudent), TEStudentCacheDto.class);
+        TEStudentCacheDto teStudentCacheDto = gson.fromJson(gson.toJson(teStudent), TEStudentCacheDto.class);
+        TEStudentCacheDto teStudentCacheDtoCache = ExamingDataCacheUtil.getStudentExaming(teStudentCacheDto.getId());
+        if (Objects.nonNull(teStudentCacheDtoCache) && Objects.nonNull(teStudentCacheDtoCache.getExamingRecordId())) {
+            teStudentCacheDto.setExamingRecordId(teStudentCacheDtoCache.getExamingRecordId());
+        }
+        return teStudentCacheDto;
     }
 
     /**
@@ -287,7 +293,12 @@ public class CacheServiceImpl implements CacheService {
     public TEStudentCacheDto updateStudentAccountCache(Long studentId) {
         TEStudent teStudent = teStudentService.getById(studentId);
         Gson gson = new Gson();
-        return gson.fromJson(gson.toJson(teStudent), TEStudentCacheDto.class);
+        TEStudentCacheDto teStudentCacheDto = gson.fromJson(gson.toJson(teStudent), TEStudentCacheDto.class);
+        TEStudentCacheDto teStudentCacheDtoCache = ExamingDataCacheUtil.getStudentExaming(teStudentCacheDto.getId());
+        if (Objects.nonNull(teStudentCacheDtoCache) && Objects.nonNull(teStudentCacheDtoCache.getExamingRecordId())) {
+            teStudentCacheDto.setExamingRecordId(teStudentCacheDtoCache.getExamingRecordId());
+        }
+        return teStudentCacheDto;
     }
 
     /**

+ 15 - 4
themis-business/src/main/java/com/qmth/themis/business/service/impl/CommonServiceImpl.java

@@ -2,13 +2,18 @@ package com.qmth.themis.business.service.impl;
 
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.qmth.themis.business.cache.ExamRecordCacheUtil;
+import com.qmth.themis.business.cache.ExamingDataCacheUtil;
 import com.qmth.themis.business.cache.RedisKeyHelper;
 import com.qmth.themis.business.constant.SystemConstant;
 import com.qmth.themis.business.dto.MqDto;
+import com.qmth.themis.business.dto.cache.TEStudentCacheDto;
 import com.qmth.themis.business.entity.TOeExamBreakHistory;
 import com.qmth.themis.business.enums.ExamRecordStatusEnum;
 import com.qmth.themis.business.enums.MqTagEnum;
-import com.qmth.themis.business.service.*;
+import com.qmth.themis.business.service.CommonService;
+import com.qmth.themis.business.service.MqDtoService;
+import com.qmth.themis.business.service.TOeExamBreakHistoryService;
+import com.qmth.themis.business.service.TOeExamRecordService;
 import com.qmth.themis.business.util.MqUtil;
 import com.qmth.themis.business.util.RedisUtil;
 import org.slf4j.Logger;
@@ -16,7 +21,6 @@ import org.slf4j.LoggerFactory;
 import org.springframework.stereotype.Service;
 
 import javax.annotation.Resource;
-import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
@@ -46,7 +50,7 @@ public class CommonServiceImpl implements CommonService {
     TOeExamBreakHistoryService tOeExamBreakHistoryService;
 
     @Override
-    public void persisted(Long recordId) {
+    public void persisted(Long recordId, Long studentId) {
         String lockKey = SystemConstant.REDIS_LOCK_EXAM_RECORD_PERSISTED_PREFIX + recordId;
         Boolean lock = redisUtil.lock(lockKey, SystemConstant.REDIS_CACHE_TIME_OUT);
         if (!lock) {
@@ -66,8 +70,9 @@ public class CommonServiceImpl implements CommonService {
                 //算分未完成的 发送10秒延迟消息
                 Map<String, Object> propMap = mqDtoService.buildMqDelayMsg("10s");
                 propMap.put(SystemConstant.RECORD_ID, recordId);
+                propMap.put(SystemConstant.STUDENT_ID, studentId);
                 MqDto mqDto = new MqDto(mqUtil.getMqGroupDomain().getTopic(), MqTagEnum.EXAM_RECORD_PERSISTED.name(),
-                        Collections.singletonMap(SystemConstant.RECORD_ID, recordId), MqTagEnum.EXAM_RECORD_PERSISTED, recordId.toString(), propMap, recordId.toString());
+                        propMap, MqTagEnum.EXAM_RECORD_PERSISTED, recordId.toString(), propMap, recordId.toString());
                 mqDtoService.assembleSendAsyncDelayMsg(mqDto);
                 return;
             }
@@ -86,6 +91,12 @@ public class CommonServiceImpl implements CommonService {
             redisUtil.delete(RedisKeyHelper.faceVerifyCacheKey(recordId));
             //2021-03-01新增
             redisUtil.delete(RedisKeyHelper.studentPaperStructKey(recordId));
+            TEStudentCacheDto teStudentCacheDto = ExamingDataCacheUtil.getStudentExaming(studentId);
+            if (Objects.nonNull(teStudentCacheDto)) {
+                teStudentCacheDto.setExamingRecordId(null);
+                ExamingDataCacheUtil.setStudentExaming(studentId, teStudentCacheDto);
+            }
+
 //            redisUtil.delete(RedisKeyHelper.examStudentCacheKey(examStudentId));
             //先查询之前的断点记录
             QueryWrapper<TOeExamBreakHistory> tOeExamBreakHistoryQueryWrapper = new QueryWrapper<>();

+ 6 - 4
themis-business/src/main/java/com/qmth/themis/business/service/impl/TEExamServiceImpl.java

@@ -321,7 +321,8 @@ public class TEExamServiceImpl extends ServiceImpl<TEExamMapper, TEExam> impleme
 
         Long recordId = toeExamRecordService
                 .saveByPrepare(es.getExamId(), es.getExamActivityId(), examStudentId, paperId,
-                        es.getAlreadyExamCount() + 1);
+                        es.getAlreadyExamCount() + 1, studentId);
+
 
         es.setCurrentRecordId(recordId);
         ExamPrepareBean prepare = new ExamPrepareBean(recordId, (ec.getObjectiveShuffle() == null || ec.getObjectiveShuffle().intValue() == 0 ? false : true),
@@ -1191,7 +1192,7 @@ public class TEExamServiceImpl extends ServiceImpl<TEExamMapper, TEExam> impleme
         mqDtoService.assembleSendOneOrderMsg(mobileMqDto);
 
         //异步持久化
-        checkToPersisted(recordId);
+        checkToPersisted(recordId, studentId);
         //mq发送消息start
         MqDto mqDto = new MqDto(mqUtil.getMqGroupDomain().getTopic(), MqTagEnum.STUDENT.name(),
                 SystemOperationEnum.FINISHED, MqTagEnum.STUDENT, String.valueOf(teStudentCacheDto.getId()),
@@ -1215,14 +1216,15 @@ public class TEExamServiceImpl extends ServiceImpl<TEExamMapper, TEExam> impleme
      *
      * @param recordId
      */
-    private void checkToPersisted(Long recordId) {
+    private void checkToPersisted(Long recordId,Long studentId) {
         ExamRecordStatusEnum status = ExamRecordCacheUtil.getStatus(recordId);
         if (!ExamRecordStatusEnum.FINISHED.equals(status)) {
             return;
         }
         Map<String, Object> propMap = mqDtoService.buildMqDelayMsg("10s");
         propMap.put(SystemConstant.RECORD_ID, recordId);
-        MqDto mqDto = new MqDto(mqUtil.getMqGroupDomain().getTopic(), MqTagEnum.EXAM_RECORD_PERSISTED.name(), Collections.singletonMap(SystemConstant.RECORD_ID, recordId),
+        propMap.put(SystemConstant.STUDENT_ID, studentId);
+        MqDto mqDto = new MqDto(mqUtil.getMqGroupDomain().getTopic(), MqTagEnum.EXAM_RECORD_PERSISTED.name(), propMap,
                 MqTagEnum.EXAM_RECORD_PERSISTED, recordId.toString(), propMap, recordId.toString());
         mqDtoService.assembleSendAsyncDelayMsg(mqDto);
     }

+ 8 - 1
themis-business/src/main/java/com/qmth/themis/business/service/impl/TOeExamRecordServiceImpl.java

@@ -17,6 +17,7 @@ import com.qmth.themis.business.cache.bean.*;
 import com.qmth.themis.business.constant.SystemConstant;
 import com.qmth.themis.business.dao.TOeExamRecordMapper;
 import com.qmth.themis.business.dto.MqDto;
+import com.qmth.themis.business.dto.cache.TEStudentCacheDto;
 import com.qmth.themis.business.dto.response.MarkResultDto;
 import com.qmth.themis.business.dto.response.TEExamUnFinishDto;
 import com.qmth.themis.business.entity.TOeExamAnswer;
@@ -149,7 +150,7 @@ public class TOeExamRecordServiceImpl extends ServiceImpl<TOeExamRecordMapper, T
     @Transactional
     @Override
     public Long saveByPrepare(Long examId, Long examActivityId, Long examStudentId, Long paperId,
-                              Integer serialNumber) {
+                              Integer serialNumber, Long studentId) {
         ExamActivityCacheBean ac = examActivityService.getExamActivityCacheBean(examActivityId);
         ExamCacheBean exam = examService.getExamCacheBean(examId);
         TOeExamRecord er = new TOeExamRecord();
@@ -193,6 +194,12 @@ public class TOeExamRecordServiceImpl extends ServiceImpl<TOeExamRecordMapper, T
         map.put(SystemConstant.STATUS, examStatusBean);
         redisUtil.setForHash(RedisKeyHelper.examRecordCacheKey(er.getId()), map);
         sendExamRecordDataSaveMq(er.getId(), System.currentTimeMillis());
+
+        TEStudentCacheDto teStudentCacheDto = ExamingDataCacheUtil.getStudentExaming(studentId);
+        if (Objects.nonNull(teStudentCacheDto)) {
+            teStudentCacheDto.setExamingRecordId(er.getId());
+            ExamingDataCacheUtil.setStudentExaming(studentId, teStudentCacheDto);
+        }
         return er.getId();
     }
 

+ 11 - 1
themis-exam/src/main/java/com/qmth/themis/exam/api/TEStudentController.java

@@ -47,7 +47,10 @@ import org.springframework.web.bind.annotation.RestController;
 import javax.annotation.Resource;
 import java.io.File;
 import java.security.NoSuchAlgorithmException;
-import java.util.*;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
 
 /**
  * @Description: 考生 前端控制器
@@ -163,6 +166,13 @@ public class TEStudentController {
         }
         //判断是否有正在考试的
         Long unFinishedRecordId = Objects.nonNull(ExamingDataCacheUtil.getUnFinishedRecordId(user.getId())) ? ExamingDataCacheUtil.getUnFinishedRecordId(user.getId()) : null;
+        if (Objects.isNull(unFinishedRecordId)) {
+            TEStudentCacheDto teStudentCacheDto = ExamingDataCacheUtil.getStudentExaming(user.getId());
+            if (Objects.nonNull(teStudentCacheDto) && Objects.nonNull(teStudentCacheDto.getExamingRecordId())) {
+                unFinishedRecordId = teStudentCacheDto.getExamingRecordId();
+            }
+        }
+
         if (Objects.nonNull(unFinishedRecordId)) {
             WebsocketStatusEnum sta = ExamRecordCacheUtil.getClientWebsocketStatus(unFinishedRecordId);
             ExamRecordStatusEnum status = ExamRecordCacheUtil.getStatus(unFinishedRecordId);

+ 2 - 1
themis-mq/src/main/java/com/qmth/themis/mq/service/impl/MqLogicServiceImpl.java

@@ -669,7 +669,8 @@ public class MqLogicServiceImpl implements MqLogicService {
     public void execMqRecordPersistedLogic(MqDto mqDto, String key) {
         Map<String, Object> param = (Map<String, Object>) mqDto.getBody();
         Long recordId = (Long) param.get(SystemConstant.RECORD_ID);
-        commonService.persisted(recordId);
+        Long studentId = (Long) param.get(SystemConstant.STUDENT_ID);
+        commonService.persisted(recordId, studentId);
         tmRocketMessageService.saveMqMessageSuccess(mqDto, key);
     }