فهرست منبع

监考日志修改

wangliang 4 سال پیش
والد
کامیت
e6ba1a9b78

+ 6 - 3
themis-backend/src/main/java/com/qmth/themis/backend/api/TBUserController.java

@@ -15,7 +15,10 @@ import com.qmth.themis.business.entity.TBOrg;
 import com.qmth.themis.business.entity.TBSession;
 import com.qmth.themis.business.entity.TBUser;
 import com.qmth.themis.business.entity.TBUserRole;
-import com.qmth.themis.business.enums.*;
+import com.qmth.themis.business.enums.FieldUniqueEnum;
+import com.qmth.themis.business.enums.MqTagEnum;
+import com.qmth.themis.business.enums.MqTopicEnum;
+import com.qmth.themis.business.enums.SystemOperationEnum;
 import com.qmth.themis.business.service.*;
 import com.qmth.themis.business.util.*;
 import com.qmth.themis.common.contanst.Constants;
@@ -186,7 +189,7 @@ public class TBUserController {
         redisUtil.setUserSession(sessionId, tbSession, redisExpire);
         //mq发送消息start
         mqDtoService.assembleSendOneWayMsg(MqTopicEnum.themisTopic.getCode(), platform.name(), tbSession, platform.name(), tbSession.getId(), user.getLoginName());
-        mqDtoService.assembleSendOneWayMsg(MqTopicEnum.themisTopic.getCode(), authDto.getRoleCodes().toString().contains(RoleEnum.STUDENT.name()) ? MqTagEnum.STUDENT.name() : MqTagEnum.USER.name(), SystemOperationEnum.LOGIN, MqTagEnum.USER.name(), user.getId(), user.getLoginName());
+        mqDtoService.assembleSendOneWayMsg(MqTopicEnum.themisTopic.getCode(), MqTagEnum.USER.name(), SystemOperationEnum.LOGIN, MqTagEnum.USER.name(), user.getId(), user.getLoginName());
         //mq发送消息end
         //测试
         String test = SignatureInfo.build(SignatureType.TOKEN, sessionId, token);
@@ -525,7 +528,7 @@ public class TBUserController {
             cacheService.removeAccountCache(tbUser.getId());
         }
         //mq发送消息start
-        mqDtoService.assembleSendOneWayMsg(MqTopicEnum.themisTopic.getCode(), authDto.getRoleCodes().toString().contains(RoleEnum.STUDENT.name()) ? MqTagEnum.STUDENT.name() : MqTagEnum.USER.name(), SystemOperationEnum.LOGOUT, MqTagEnum.USER.name(), tbUser.getId(), tbUser.getLoginName());
+        mqDtoService.assembleSendOneWayMsg(MqTopicEnum.themisTopic.getCode(), MqTagEnum.USER.name(), SystemOperationEnum.LOGOUT, MqTagEnum.USER.name(), tbUser.getId(), tbUser.getLoginName());
         //mq发送消息end
         return ResultUtil.ok(JacksonUtil.parseJson(SystemConstant.SUCCESS));
     }

+ 71 - 72
themis-business/src/main/java/com/qmth/themis/business/cache/ExamBreakCacheUtil.java

@@ -1,86 +1,85 @@
 package com.qmth.themis.business.cache;
 
-import java.util.Date;
-
 import com.qmth.themis.business.constant.SpringContextHolder;
-import com.qmth.themis.business.enums.BreakReasonEnum;
+import com.qmth.themis.business.enums.ExceptionEnum;
 import com.qmth.themis.business.enums.VerifyExceptionEnum;
 import com.qmth.themis.business.util.RedisUtil;
 
+import java.util.Date;
+
 /**
  * 断点缓存hash值操作
- * 
+ *
  * @Description:
  * @Author: xiatian
  * @Date: 2020-07-29
  */
 public class ExamBreakCacheUtil {
-	private static RedisUtil redisUtil = SpringContextHolder.getBean(RedisUtil.class);
-
-	public static void setExamRecordId(Long examBreakId,Long examRecordId) {
-		redisUtil.set(RedisKeyHelper.examBreakCacheKey(examBreakId), "examRecordId", examRecordId);
-	}
-	
-	public static Long getExamRecordId(Long examBreakId) {
-		return (Long) redisUtil.get(RedisKeyHelper.examBreakCacheKey(examBreakId), "examRecordId");
-	}
-	
-	public static void setBreakTime(Long examBreakId,Date breakTime) {
-		redisUtil.set(RedisKeyHelper.examBreakCacheKey(examBreakId), "breakTime", breakTime);
-	}
-	
-	public static Date getBreakTime(Long examBreakId) {
-		return (Date) redisUtil.get(RedisKeyHelper.examBreakCacheKey(examBreakId), "breakTime");
-	}
-	
-	
-	public static void setBreakReason(Long examBreakId,BreakReasonEnum breakReason) {
-		redisUtil.set(RedisKeyHelper.examBreakCacheKey(examBreakId), "breakReason", breakReason);
-	}
-	
-	public static BreakReasonEnum getBreakReason(Long examBreakId) {
-		return (BreakReasonEnum) redisUtil.get(RedisKeyHelper.examBreakCacheKey(examBreakId), "breakReason");
-	}
-	
-	public static void setResumeReason(Long examBreakId,String resumeReason) {
-		redisUtil.set(RedisKeyHelper.examBreakCacheKey(examBreakId), "resumeReason", resumeReason);
-	}
-	
-	public static Long getResumeReason(Long examBreakId) {
-		return (Long) redisUtil.get(RedisKeyHelper.examBreakCacheKey(examBreakId), "resumeReason");
-	}
-	
-	
-	public static void setPrepareTime(Long examBreakId,Date prepareTime) {
-		redisUtil.set(RedisKeyHelper.examBreakCacheKey(examBreakId), "prepareTime", prepareTime);
-	}
-	
-	public static Date getPrepareTime(Long examBreakId) {
-		return (Date) redisUtil.get(RedisKeyHelper.examBreakCacheKey(examBreakId), "prepareTime");
-	}
-	
-	
-	public static void setStartTime(Long examBreakId,Date startTime) {
-		redisUtil.set(RedisKeyHelper.examBreakCacheKey(examBreakId), "startTime", startTime);
-	}
-	
-	public static Date getStartTime(Long examBreakId) {
-		return (Date) redisUtil.get(RedisKeyHelper.examBreakCacheKey(examBreakId), "startTime");
-	}
-	
-	public static void setEntryAuthenticationResult(Long examBreakId,VerifyExceptionEnum entryAuthenticationResult) {
-		redisUtil.set(RedisKeyHelper.examBreakCacheKey(examBreakId), "entryAuthenticationResult", entryAuthenticationResult);
-	}
-	
-	public static VerifyExceptionEnum getEntryAuthenticationResult(Long examBreakId) {
-		return (VerifyExceptionEnum) redisUtil.get(RedisKeyHelper.examBreakCacheKey(examBreakId), "entryAuthenticationResult");
-	}
-	
-	public static void setEntryAuthenticationId(Long examBreakId,Long entryAuthenticationId) {
-		redisUtil.set(RedisKeyHelper.examBreakCacheKey(examBreakId), "entryAuthenticationId", entryAuthenticationId);
-	}
-	
-	public static Long getEntryAuthenticationId(Long examBreakId) {
-		return (Long) redisUtil.get(RedisKeyHelper.examBreakCacheKey(examBreakId), "entryAuthenticationId");
-	}
+    private static RedisUtil redisUtil = SpringContextHolder.getBean(RedisUtil.class);
+
+    public static void setExamRecordId(Long examBreakId, Long examRecordId) {
+        redisUtil.set(RedisKeyHelper.examBreakCacheKey(examBreakId), "examRecordId", examRecordId);
+    }
+
+    public static Long getExamRecordId(Long examBreakId) {
+        return (Long) redisUtil.get(RedisKeyHelper.examBreakCacheKey(examBreakId), "examRecordId");
+    }
+
+    public static void setBreakTime(Long examBreakId, Date breakTime) {
+        redisUtil.set(RedisKeyHelper.examBreakCacheKey(examBreakId), "breakTime", breakTime);
+    }
+
+    public static Date getBreakTime(Long examBreakId) {
+        return (Date) redisUtil.get(RedisKeyHelper.examBreakCacheKey(examBreakId), "breakTime");
+    }
+
+    public static void setBreakReason(Long examBreakId, ExceptionEnum breakReason) {
+        redisUtil.set(RedisKeyHelper.examBreakCacheKey(examBreakId), "breakReason", breakReason);
+    }
+
+    public static ExceptionEnum getBreakReason(Long examBreakId) {
+        return (ExceptionEnum) redisUtil.get(RedisKeyHelper.examBreakCacheKey(examBreakId), "breakReason");
+    }
+
+    public static void setResumeReason(Long examBreakId, String resumeReason) {
+        redisUtil.set(RedisKeyHelper.examBreakCacheKey(examBreakId), "resumeReason", resumeReason);
+    }
+
+    public static Long getResumeReason(Long examBreakId) {
+        return (Long) redisUtil.get(RedisKeyHelper.examBreakCacheKey(examBreakId), "resumeReason");
+    }
+
+
+    public static void setPrepareTime(Long examBreakId, Date prepareTime) {
+        redisUtil.set(RedisKeyHelper.examBreakCacheKey(examBreakId), "prepareTime", prepareTime);
+    }
+
+    public static Date getPrepareTime(Long examBreakId) {
+        return (Date) redisUtil.get(RedisKeyHelper.examBreakCacheKey(examBreakId), "prepareTime");
+    }
+
+
+    public static void setStartTime(Long examBreakId, Date startTime) {
+        redisUtil.set(RedisKeyHelper.examBreakCacheKey(examBreakId), "startTime", startTime);
+    }
+
+    public static Date getStartTime(Long examBreakId) {
+        return (Date) redisUtil.get(RedisKeyHelper.examBreakCacheKey(examBreakId), "startTime");
+    }
+
+    public static void setEntryAuthenticationResult(Long examBreakId, VerifyExceptionEnum entryAuthenticationResult) {
+        redisUtil.set(RedisKeyHelper.examBreakCacheKey(examBreakId), "entryAuthenticationResult", entryAuthenticationResult);
+    }
+
+    public static VerifyExceptionEnum getEntryAuthenticationResult(Long examBreakId) {
+        return (VerifyExceptionEnum) redisUtil.get(RedisKeyHelper.examBreakCacheKey(examBreakId), "entryAuthenticationResult");
+    }
+
+    public static void setEntryAuthenticationId(Long examBreakId, Long entryAuthenticationId) {
+        redisUtil.set(RedisKeyHelper.examBreakCacheKey(examBreakId), "entryAuthenticationId", entryAuthenticationId);
+    }
+
+    public static Long getEntryAuthenticationId(Long examBreakId) {
+        return (Long) redisUtil.get(RedisKeyHelper.examBreakCacheKey(examBreakId), "entryAuthenticationId");
+    }
 }

+ 5 - 6
themis-business/src/main/java/com/qmth/themis/business/entity/TOeExamBreakHistory.java

@@ -2,8 +2,7 @@ package com.qmth.themis.business.entity;
 
 import com.baomidou.mybatisplus.annotation.TableField;
 import com.baomidou.mybatisplus.annotation.TableId;
-import com.qmth.themis.business.enums.BreakReasonEnum;
-import com.qmth.themis.business.enums.EntryAuthenticationPolicyEnum;
+import com.qmth.themis.business.enums.ExceptionEnum;
 import com.qmth.themis.business.enums.VerifyExceptionEnum;
 import com.qmth.themis.common.contanst.Constants;
 import io.swagger.annotations.ApiModel;
@@ -37,7 +36,7 @@ public class TOeExamBreakHistory implements Serializable {
 
     @ApiModelProperty(value = "断点判定原因")
     @TableField(value = "break_reason")
-    private BreakReasonEnum breakReason;
+    private ExceptionEnum breakReason;
 
     @ApiModelProperty(value = "提交异常原因")
     @TableField(value = "resume_reason")
@@ -63,7 +62,7 @@ public class TOeExamBreakHistory implements Serializable {
 
     }
 
-    public TOeExamBreakHistory(Long examRecordId, Date breakTime, BreakReasonEnum breakReason, String resumeReason) {
+    public TOeExamBreakHistory(Long examRecordId, Date breakTime, ExceptionEnum breakReason, String resumeReason) {
         this.id = Constants.idGen.next();
         this.examRecordId = examRecordId;
         this.breakTime = breakTime;
@@ -99,11 +98,11 @@ public class TOeExamBreakHistory implements Serializable {
         this.breakTime = breakTime;
     }
 
-    public BreakReasonEnum getBreakReason() {
+    public ExceptionEnum getBreakReason() {
         return breakReason;
     }
 
-    public void setBreakReason(BreakReasonEnum breakReason) {
+    public void setBreakReason(ExceptionEnum breakReason) {
         this.breakReason = breakReason;
     }
 

+ 0 - 25
themis-business/src/main/java/com/qmth/themis/business/enums/BreakReasonEnum.java

@@ -1,25 +0,0 @@
-package com.qmth.themis.business.enums;
-
-/**
-* @Description: 断点原因 enum
-* @Param:
-* @return:
-* @Author: wangliang
-* @Date: 2020/7/29
-*/
-public enum BreakReasonEnum {
-
-    NET_TIME_OUT("网络超时"),
-
-    MACHINE_FAULT("机器故障");
-
-    private String code;
-
-    private BreakReasonEnum(String code){
-        this.code = code;
-    }
-
-    public String getCode() {
-        return code;
-    }
-}

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

@@ -4,10 +4,11 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.qmth.themis.business.bean.exam.*;
 import com.qmth.themis.business.cache.bean.ExamCacheBean;
+import com.qmth.themis.business.dto.MqDto;
 import com.qmth.themis.business.dto.response.TEExamDto;
 import com.qmth.themis.business.dto.response.TEExamQueryDto;
 import com.qmth.themis.business.entity.TEExam;
-import org.apache.ibatis.annotations.Param;
+import com.qmth.themis.business.enums.SystemOperationEnum;
 import org.springframework.web.multipart.MultipartFile;
 
 import java.util.List;
@@ -173,4 +174,14 @@ public interface TEExamService extends IService<TEExam> {
      * @return
      */
     public IPage<TEExamQueryDto> examList(IPage<Map> iPage, Long orgId);
+
+    /**
+     * 发送考试轨迹消息
+     *
+     * @param systemOperationEnum
+     * @param examStudentId
+     * @param recordId
+     * @param mqDto
+     */
+    public void sendOeLogMessage(SystemOperationEnum systemOperationEnum, Long examStudentId, Long recordId, MqDto mqDto);
 }

+ 49 - 59
themis-business/src/main/java/com/qmth/themis/business/service/impl/TEExamServiceImpl.java

@@ -1,52 +1,12 @@
 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.Arrays;
-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.CacheEvict;
-import org.springframework.cache.annotation.CachePut;
-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.AnswerSubmitBean;
-import com.qmth.themis.business.bean.exam.AudioLeftPlayCountSubmitBean;
-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.bean.exam.StudentPaperStructBean;
+import com.qmth.themis.business.bean.exam.*;
 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.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.cache.bean.*;
 import com.qmth.themis.business.config.SystemConfig;
 import com.qmth.themis.business.dao.TEExamMapper;
 import com.qmth.themis.business.dto.MqDto;
@@ -56,26 +16,27 @@ import com.qmth.themis.business.dto.response.TEExamDto;
 import com.qmth.themis.business.dto.response.TEExamQueryDto;
 import com.qmth.themis.business.entity.TEExam;
 import com.qmth.themis.business.entity.TOeExamRecord;
-import com.qmth.themis.business.enums.EntryAuthenticationPolicyEnum;
-import com.qmth.themis.business.enums.ExamRecordStatusEnum;
-import com.qmth.themis.business.enums.FinishExamResultEnum;
-import com.qmth.themis.business.enums.FinishTypeEnum;
-import com.qmth.themis.business.enums.HardwareTestEnum;
-import com.qmth.themis.business.enums.InvigilateVerifyEnum;
-import com.qmth.themis.business.enums.MonitorVideoSourceEnum;
-import com.qmth.themis.business.enums.MqTagEnum;
-import com.qmth.themis.business.enums.MqTopicEnum;
-import com.qmth.themis.business.enums.ReviewResultEnum;
-import com.qmth.themis.business.service.MqDtoService;
-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.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.business.util.ServletUtil;
 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.CacheEvict;
+import org.springframework.cache.annotation.CachePut;
+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: 考试批次 服务实现类
@@ -311,6 +272,10 @@ public class TEExamServiceImpl extends ServiceImpl<TEExamMapper, TEExam> impleme
         teStudentCacheDto.setUnFinishedRecordId(recordId);
         redisUtil.setStudent(studentId, teStudentCacheDto);
         ExamRecordCacheUtil.setLeftBreakResumeCount(recordId, breakResumeCount);
+        //mq发送消息start
+        MqDto mqDto = new MqDto(MqTopicEnum.themisTopic.getCode(), MqTagEnum.STUDENT.name(), SystemOperationEnum.PREPARE, MqTagEnum.STUDENT, String.valueOf(teStudentCacheDto.getId()), teStudentCacheDto.getIdentity());
+        this.sendOeLogMessage(SystemOperationEnum.PREPARE, examStudentId, recordId, mqDto);
+        //mq发送消息end
         return prepare;
     }
 
@@ -741,6 +706,11 @@ public class TEExamServiceImpl extends ServiceImpl<TEExamMapper, TEExam> impleme
         teStudentCacheDto.setUnFinishedRecordId(null);
         redisUtil.setStudent(teStudentCacheDto.getId(), teStudentCacheDto);
         checkToPersisted(recordId);
+        TEStudentCacheDto teStudent = (TEStudentCacheDto) ServletUtil.getRequestStudentAccount();
+        //mq发送消息start
+        MqDto mqDto = new MqDto(MqTopicEnum.themisTopic.getCode(), MqTagEnum.STUDENT.name(), SystemOperationEnum.FINISHED, MqTagEnum.STUDENT, String.valueOf(teStudentCacheDto.getId()), teStudentCacheDto.getIdentity());
+        this.sendOeLogMessage(SystemOperationEnum.FINISHED, examStudentId, recordId, mqDto);
+        //mq发送消息end
         return ret;
     }
 
@@ -867,6 +837,26 @@ public class TEExamServiceImpl extends ServiceImpl<TEExamMapper, TEExam> impleme
         return teExamMapper.examList(iPage, orgId);
     }
 
+    /**
+     * 发送考试轨迹消息
+     *
+     * @param systemOperationEnum
+     * @param examStudentId
+     * @param recordId
+     * @param mqDto
+     */
+    @Override
+    public void sendOeLogMessage(SystemOperationEnum systemOperationEnum, Long examStudentId, Long recordId, MqDto mqDto) {
+        //mq发送消息start
+        Map<String, Object> properties = new HashMap<>();
+        properties.put("remark", systemOperationEnum.getCode());
+        properties.put("examStudentId", examStudentId);
+        properties.put("examRecordId", recordId);
+        mqDto.setProperties(properties);
+        mqDtoService.assembleSendOneWayMsg(mqDto);
+        //mq发送消息end
+    }
+
     /**
      * 缓存操作
      *

+ 26 - 31
themis-exam/src/main/java/com/qmth/themis/exam/api/TEExamController.java

@@ -1,52 +1,41 @@
 package com.qmth.themis.exam.api;
 
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.concurrent.ConcurrentHashMap;
-
-import javax.annotation.Resource;
-
-import com.qmth.themis.business.bean.exam.*;
-import com.qmth.themis.business.dto.MqDto;
-import com.qmth.themis.business.dto.WebsocketDto;
-import com.qmth.themis.business.enums.FinishTypeEnum;
-import com.qmth.themis.business.enums.MqTagEnum;
-import com.qmth.themis.business.enums.MqTopicEnum;
-import com.qmth.themis.business.enums.WebsocketTypeEnum;
-import com.qmth.themis.business.service.MqDtoService;
-import com.qmth.themis.business.util.JacksonUtil;
-import com.qmth.themis.exam.websocket.WebSocketMobileServer;
-import com.qmth.themis.exam.websocket.WebSocketOeServer;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestMethod;
-import org.springframework.web.bind.annotation.RequestParam;
-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.annotation.ApiJsonObject;
 import com.qmth.themis.business.annotation.ApiJsonProperty;
+import com.qmth.themis.business.bean.exam.*;
+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.WebsocketDto;
 import com.qmth.themis.business.dto.cache.TEStudentCacheDto;
 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.enums.MqTagEnum;
+import com.qmth.themis.business.enums.MqTopicEnum;
+import com.qmth.themis.business.enums.SystemOperationEnum;
+import com.qmth.themis.business.enums.WebsocketTypeEnum;
+import com.qmth.themis.business.service.MqDtoService;
 import com.qmth.themis.business.service.TEExamService;
+import com.qmth.themis.business.util.JacksonUtil;
 import com.qmth.themis.business.util.RedisUtil;
 import com.qmth.themis.business.util.ServletUtil;
 import com.qmth.themis.common.enums.ExceptionResultEnum;
 import com.qmth.themis.common.exception.BusinessException;
 import com.qmth.themis.common.util.Result;
 import com.qmth.themis.common.util.ResultUtil;
+import com.qmth.themis.exam.websocket.WebSocketMobileServer;
+import io.swagger.annotations.*;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
 
-import io.swagger.annotations.Api;
-import io.swagger.annotations.ApiOperation;
-import io.swagger.annotations.ApiParam;
-import io.swagger.annotations.ApiResponse;
-import io.swagger.annotations.ApiResponses;
+import javax.annotation.Resource;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.concurrent.ConcurrentHashMap;
 
 @Api(tags = "考试Controller")
 @RestController
@@ -136,6 +125,12 @@ public class TEExamController {
                 MqDto mqDto = new MqDto(MqTopicEnum.themisTopic.getCode(), MqTagEnum.EXCEPTION_LOG.name(), JacksonUtil.parseJson(param), MqTagEnum.EXCEPTION_LOG, String.valueOf(param.getRecordId()), param.getReason());
                 mqDtoService.assembleSendOneWayMsg(mqDto);
                 //考试断点异常原因 发送mq end
+            } else {
+                //mq发送消息start
+                MqDto mqDto = new MqDto(MqTopicEnum.themisTopic.getCode(), MqTagEnum.STUDENT.name(), SystemOperationEnum.ANSWERING, MqTagEnum.STUDENT, String.valueOf(teStudent.getId()), teStudent.getIdentity());
+                Map<String, Object> objectMap = redisUtil.getHashEntries(RedisKeyHelper.examRecordCacheKey(param.getRecordId()));
+                teExamService.sendOeLogMessage(SystemOperationEnum.ANSWERING, Long.parseLong(String.valueOf(objectMap.get("examStudentId"))), param.getRecordId(), mqDto);
+                //mq发送消息end
             }
             ConcurrentHashMap<Long, WebSocketMobileServer> webSocketMap = WebSocketMobileServer.getWebSocketMap();
             if (Objects.nonNull(webSocketMap.get(param.getRecordId()))) {

+ 2 - 3
themis-exam/src/main/java/com/qmth/themis/exam/api/TEStudentController.java

@@ -14,7 +14,6 @@ import com.qmth.themis.business.cache.bean.ExamCourseCacheBean;
 import com.qmth.themis.business.cache.bean.ExamStudentCacheBean;
 import com.qmth.themis.business.constant.SystemConstant;
 import com.qmth.themis.business.dto.AuthDto;
-import com.qmth.themis.business.dto.MqDto;
 import com.qmth.themis.business.dto.cache.TEStudentCacheDto;
 import com.qmth.themis.business.dto.response.TEExamActivityDto;
 import com.qmth.themis.business.dto.response.TEExamDto;
@@ -180,7 +179,7 @@ public class TEStudentController {
         redisUtil.setUserSession(sessionId, tbSession, redisExpire);
         //mq发送消息start
         mqDtoService.assembleSendOneWayMsg(MqTopicEnum.themisTopic.getCode(), platform.name(), tbSession, platform.name(), tbSession.getId(), teStudent.getIdentity());
-        mqDtoService.assembleSendOneWayMsg(MqTopicEnum.themisTopic.getCode(), authDto.getRoleCodes().toString().contains(RoleEnum.STUDENT.name()) ? MqTagEnum.STUDENT.name() : MqTagEnum.USER.name(), SystemOperationEnum.LOGIN, MqTagEnum.STUDENT.name(), teStudent.getId(), teStudent.getIdentity());
+        mqDtoService.assembleSendOneWayMsg(MqTopicEnum.themisTopic.getCode(), MqTagEnum.STUDENT.name(), SystemOperationEnum.LOGIN, MqTagEnum.STUDENT.name(), teStudent.getId(), teStudent.getIdentity());
         //mq发送消息end
         //测试
         String test = SignatureInfo.build(SignatureType.TOKEN, sessionId, token);
@@ -282,7 +281,7 @@ public class TEStudentController {
             cacheService.removeStudentCache(teStudent.getId());
         }
         //mq发送消息start
-        mqDtoService.assembleSendOneWayMsg(MqTopicEnum.themisTopic.getCode(), authDto.getRoleCodes().toString().contains(RoleEnum.STUDENT.name()) ? MqTagEnum.STUDENT.name() : MqTagEnum.USER.name(), SystemOperationEnum.LOGOUT, MqTagEnum.STUDENT.name(), teStudent.getId(), teStudent.getIdentity());
+        mqDtoService.assembleSendOneWayMsg(MqTopicEnum.themisTopic.getCode(), MqTagEnum.STUDENT.name(), SystemOperationEnum.LOGOUT, MqTagEnum.STUDENT.name(), teStudent.getId(), teStudent.getIdentity());
         //mq发送消息end
         return ResultUtil.ok(JacksonUtil.parseJson(SystemConstant.SUCCESS));
     }

+ 19 - 17
themis-mq/src/main/java/com/qmth/themis/mq/service/impl/MqLogicServiceImpl.java

@@ -431,7 +431,7 @@ public class MqLogicServiceImpl implements MqLogicService {
             tIeExamInvigilateCallLogService.saveOrUpdate(tIeExamInvigilateCallLog);
         } else if (tag.contains(MqTagEnum.EXCEPTION_LOG.name())) {//考试断点异常日志
             JSONObject jsonObject = JSONObject.parseObject(String.valueOf(mqDto.getBody()));
-            //更新考试记录
+            ExceptionEnum exceptionEnum = ExceptionEnum.valueOf(ExceptionEnum.convertToName(String.valueOf(jsonObject.getJSONObject("reason").get("type"))));
             Long recordId = Long.parseLong(mqDto.getObjId());
             Map<String, Object> objectMap = redisUtil.getHashEntries(RedisKeyHelper.examRecordCacheKey(recordId));
             //获取最近同步时间
@@ -441,22 +441,9 @@ public class MqLogicServiceImpl implements MqLogicService {
                 Long l = ((System.currentTimeMillis() - clientLastSyncTime.getTime()) / 1000 / 60);
                 diff = l.intValue();
             }
-            //先查询之前的断点记录
-            QueryWrapper<TOeExamBreakHistory> tOeExamBreakHistoryQueryWrapper = new QueryWrapper<>();
-            tOeExamBreakHistoryQueryWrapper.lambda().eq(TOeExamBreakHistory::getExamRecordId, recordId);
-            List<TOeExamBreakHistory> tOeExamBreakHistoryList = tOeExamBreakHistoryService.list(tOeExamBreakHistoryQueryWrapper);
-            //删除历史断点缓存
-            if (Objects.nonNull(tOeExamBreakHistoryList) && tOeExamBreakHistoryList.size() > 0) {
-                tOeExamBreakHistoryList.forEach(s -> {
-                    redisUtil.delete(RedisKeyHelper.examBreakCacheKey(s.getId()));
-                });
-            }
-            //增加断点记录
-            TOeExamBreakHistory tOeExamBreakHistory = new TOeExamBreakHistory(recordId, new Date(), BreakReasonEnum.NET_TIME_OUT, BreakReasonEnum.NET_TIME_OUT.name());
-            tOeExamBreakHistoryService.save(tOeExamBreakHistory);
-            redisUtil.setForHash(RedisKeyHelper.examBreakCacheKey(tOeExamBreakHistory.getId()), SimpleBeanUtil.objectToMap(tOeExamBreakHistory));
 
             Long examStudentId = Long.parseLong(String.valueOf(objectMap.get("examStudentId")));
+            ExamStudentCacheBean examStudentCacheBean = teExamStudentService.getExamStudentCacheBean(examStudentId);
             Integer leftBreakResumeCount = Objects.isNull(ExamRecordCacheUtil.getLeftBreakResumeCount(recordId)) ? 0 : ExamRecordCacheUtil.getLeftBreakResumeCount(recordId);
             leftBreakResumeCount--;
             leftBreakResumeCount = leftBreakResumeCount <= 0 ? 0 : leftBreakResumeCount;
@@ -467,21 +454,36 @@ public class MqLogicServiceImpl implements MqLogicService {
                 } else {
                     durationSeconds = Integer.parseInt(String.valueOf(objectMap.get("durationSeconds")));
                 }
-                ExamStudentCacheBean examStudentCacheBean = teExamStudentService.getExamStudentCacheBean(examStudentId);
                 teExamService.finish(examStudentCacheBean.getStudentId(), recordId, FinishTypeEnum.AUTO.name(), durationSeconds);
             } else {
+                //先查询之前的断点记录
+                QueryWrapper<TOeExamBreakHistory> tOeExamBreakHistoryQueryWrapper = new QueryWrapper<>();
+                tOeExamBreakHistoryQueryWrapper.lambda().eq(TOeExamBreakHistory::getExamRecordId, recordId);
+                List<TOeExamBreakHistory> tOeExamBreakHistoryList = tOeExamBreakHistoryService.list(tOeExamBreakHistoryQueryWrapper);
+                //删除历史断点缓存
+                if (Objects.nonNull(tOeExamBreakHistoryList) && tOeExamBreakHistoryList.size() > 0) {
+                    tOeExamBreakHistoryList.forEach(s -> {
+                        redisUtil.delete(RedisKeyHelper.examBreakCacheKey(s.getId()));
+                    });
+                }
+                //增加断点记录
+                TOeExamBreakHistory tOeExamBreakHistory = new TOeExamBreakHistory(recordId, new Date(), exceptionEnum, exceptionEnum.name());
+                tOeExamBreakHistoryService.save(tOeExamBreakHistory);
+                redisUtil.setForHash(RedisKeyHelper.examBreakCacheKey(tOeExamBreakHistory.getId()), SimpleBeanUtil.objectToMap(tOeExamBreakHistory));
+
                 objectMap.put("lastBreakId", tOeExamBreakHistory.getId());
                 objectMap.put("status", ExamRecordStatusEnum.RESUME_PREPARE);
                 objectMap.put("lastBreakTime", new Date());
                 objectMap.put("leftBreakResumeCount", leftBreakResumeCount);
                 objectMap.put("lastStartTime", new Date());
                 redisUtil.setForHash(RedisKeyHelper.examRecordCacheKey(recordId), objectMap);
+                teExamStudentLogService.saveStudentLogInfo(SystemOperationEnum.RESUME_PREPARE.name(), SystemOperationEnum.RESUME_PREPARE.getCode(), SystemOperationEnum.RESUME_PREPARE.getCode(), examStudentCacheBean.getStudentId(), examStudentId, recordId);
             }
 
             //增加异常日志
             Long examId = Long.parseLong(String.valueOf(objectMap.get("examId")));
             Long examActivityId = Long.parseLong(String.valueOf(objectMap.get("examActivityId")));
-            TIeInvigilateExceptionInfo tIeInvigilateExceptionInfo = new TIeInvigilateExceptionInfo(examId, examActivityId, recordId, examStudentId, String.valueOf(jsonObject.getJSONObject("reason").get("reason")), ExceptionEnum.valueOf(ExceptionEnum.convertToName(String.valueOf(jsonObject.getJSONObject("reason").get("type")))), String.valueOf(diff));
+            TIeInvigilateExceptionInfo tIeInvigilateExceptionInfo = new TIeInvigilateExceptionInfo(examId, examActivityId, recordId, examStudentId, String.valueOf(jsonObject.getJSONObject("reason").get("reason")), exceptionEnum, String.valueOf(diff));
             tIeInvigilateExceptionInfoService.saveOrUpdate(tIeInvigilateExceptionInfo);
         } else if (tag.contains(MqTagEnum.WARNING_LOG.name())) {//考试预警日志