浏览代码

merge from release_v4.0.2

deason 4 年之前
父节点
当前提交
9246c97029

+ 7 - 2
examcloud-core-oe-student-api-provider/src/main/java/cn/com/qmth/examcloud/core/oe/student/api/controller/ExamQuestionController.java

@@ -28,6 +28,8 @@ import cn.com.qmth.examcloud.web.support.ControllerSupport;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import io.swagger.annotations.ApiOperation;
 
 
+import javax.servlet.http.HttpServletRequest;
+
 /**
 /**
  * @author  	chenken
  * @author  	chenken
  * @date    	2018年9月5日 下午4:57:05
  * @date    	2018年9月5日 下午4:57:05
@@ -99,7 +101,8 @@ public class ExamQuestionController extends ControllerSupport {
 	 */
 	 */
 	@ApiOperation(value = "考试过程中-考生作答:更新试题作答信息(包括提交试题答案,更新是否标记)")
 	@ApiOperation(value = "考试过程中-考生作答:更新试题作答信息(包括提交试题答案,更新是否标记)")
 	@PostMapping("/submitQuestionAnswer")
 	@PostMapping("/submitQuestionAnswer")
-	public void submitQuestionAnswer(@RequestBody List<ExamStudentQuestionInfo> examQuestionInfos){
+	public void submitQuestionAnswer(@RequestBody List<ExamStudentQuestionInfo> examQuestionInfos,
+									 HttpServletRequest request){
 		if(log.isDebugEnabled()) {
 		if(log.isDebugEnabled()) {
 			String strJosn=JsonUtil.toJson(examQuestionInfos);
 			String strJosn=JsonUtil.toJson(examQuestionInfos);
 			log.debug("ExamQuestionController--submitQuestionAnswer参数信息:"+strJosn);
 			log.debug("ExamQuestionController--submitQuestionAnswer参数信息:"+strJosn);
@@ -111,7 +114,9 @@ public class ExamQuestionController extends ControllerSupport {
 					throw new StatusException("2001", "illegal params");
 					throw new StatusException("2001", "illegal params");
 				}
 				}
 			}
 			}
-			examRecordQuestionsService.submitQuestionAnswer(user.getUserId(),examQuestionInfos);
+			String referer = request.getHeader("REFERER");
+			String agent = request.getHeader("USER-AGENT");
+			examRecordQuestionsService.submitQuestionAnswer(user.getUserId(),examQuestionInfos,referer,agent);
 		}
 		}
 	}
 	}
 }
 }

+ 3 - 1
examcloud-core-oe-student-dao/src/main/java/cn/com/qmth/examcloud/core/oe/student/dao/enums/FaceVerifyResult.java

@@ -16,7 +16,9 @@ public enum FaceVerifyResult {
 
 
     TIME_OUT("超时未完成"),
     TIME_OUT("超时未完成"),
 
 
-    UNKNOWN("未知");;
+    SCREEN_REPLAY("屏幕翻拍"),
+
+    UNKNOWN("未知");
 
 
     public static String getDescByName(Object name) {
     public static String getDescByName(Object name) {
         if (name == null) {
         if (name == null) {

+ 1 - 1
examcloud-core-oe-student-service/src/main/java/cn/com/qmth/examcloud/core/oe/student/service/ExamRecordQuestionsService.java

@@ -41,7 +41,7 @@ public interface ExamRecordQuestionsService {
 
 
     String getQuestionContent(Long studentId, String questionId);
     String getQuestionContent(Long studentId, String questionId);
 
 
-    void submitQuestionAnswer(Long studentId, List<ExamStudentQuestionInfo> examQuestionInfos);
+    void submitQuestionAnswer(Long studentId, List<ExamStudentQuestionInfo> examQuestionInfos, String referer, String agent);
 
 
     GetExamRecordQuestionsResp getExamRecordQuestions(GetExamRecordQuestionsReq req);
     GetExamRecordQuestionsResp getExamRecordQuestions(GetExamRecordQuestionsReq req);
 
 

+ 24 - 1
examcloud-core-oe-student-service/src/main/java/cn/com/qmth/examcloud/core/oe/student/service/impl/ExamFaceLivenessVerifyServiceImpl.java

@@ -121,7 +121,20 @@ public class ExamFaceLivenessVerifyServiceImpl implements ExamFaceLivenessVerify
                 if (confidence > 50D) {
                 if (confidence > 50D) {
                     JSONObject livenessResultJson = faceIdResultJsonObject.getJSONObject("liveness_result");
                     JSONObject livenessResultJson = faceIdResultJsonObject.getJSONObject("liveness_result");
                     if (livenessResultJson.has("result") && "success".equals(livenessResultJson.getString("result"))) {
                     if (livenessResultJson.has("result") && "success".equals(livenessResultJson.getString("result"))) {
-                        faceVerify.setVerifyResult(FaceVerifyResult.VERIFY_SUCCESS);
+                        JSONObject faceGenuineness = verifyResultJson.getJSONObject("face_genuineness");
+                        //如果开启了翻拍检测
+                        if(faceGenuineness.has("screen_replay_threshold") && faceGenuineness.has("screen_replay_confidence")){
+                            double replayThreshold = faceGenuineness.getDouble("screen_replay_threshold");
+                            double replayConfidence = faceGenuineness.getDouble("screen_replay_confidence");
+                            //如果大于阈值,表明为翻拍
+                            if (replayConfidence >= replayThreshold) {
+                                faceVerify.setVerifyResult(FaceVerifyResult.SCREEN_REPLAY);
+                            } else {
+                                faceVerify.setVerifyResult(FaceVerifyResult.VERIFY_SUCCESS);
+                            }
+                        } else {
+                            faceVerify.setVerifyResult(FaceVerifyResult.VERIFY_SUCCESS);
+                        }
                     }
                     }
                 } else {
                 } else {
                     faceVerify.setVerifyResult(FaceVerifyResult.NOT_ONESELF);
                     faceVerify.setVerifyResult(FaceVerifyResult.NOT_ONESELF);
@@ -261,6 +274,16 @@ public class ExamFaceLivenessVerifyServiceImpl implements ExamFaceLivenessVerify
         multipartEntityBuilder.addTextBody("biz_no", bizNo);
         multipartEntityBuilder.addTextBody("biz_no", bizNo);
         multipartEntityBuilder.addTextBody("uuid", bizNo);
         multipartEntityBuilder.addTextBody("uuid", bizNo);
 
 
+        /**
+         *
+         * screen_replay表示是否开启屏幕翻拍检测。
+         *
+         * 0:默认值,不开启屏幕翻拍的检测;
+         * 1:开启屏幕翻拍检测(若检测屏幕翻拍,返回值将增加屏幕翻拍的结果返回)
+         * 注:由于PC端的某些摄像头的驱动,自带增加摄像头视频特效等功能。开启屏幕翻拍检测之后,有可能导致误检增加。
+         */
+        multipartEntityBuilder.addTextBody("screen_replay","1");
+
         multipartEntityBuilder.addBinaryBody("image_ref1", basePhotoFile);
         multipartEntityBuilder.addBinaryBody("image_ref1", basePhotoFile);
         return multipartEntityBuilder;
         return multipartEntityBuilder;
     }
     }

+ 5 - 2
examcloud-core-oe-student-service/src/main/java/cn/com/qmth/examcloud/core/oe/student/service/impl/ExamRecordQuestionsServiceImpl.java

@@ -29,7 +29,6 @@ import com.google.common.cache.CacheBuilder;
 import org.apache.commons.lang.StringUtils;
 import org.apache.commons.lang.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.stereotype.Service;
-
 import java.util.ArrayList;
 import java.util.ArrayList;
 import java.util.Date;
 import java.util.Date;
 import java.util.List;
 import java.util.List;
@@ -180,7 +179,7 @@ public class ExamRecordQuestionsServiceImpl implements ExamRecordQuestionsServic
     }
     }
 
 
     @Override
     @Override
-    public void submitQuestionAnswer(Long studentId, List<ExamStudentQuestionInfo> examQuestionInfos) {
+    public void submitQuestionAnswer(Long studentId, List<ExamStudentQuestionInfo> examQuestionInfos, String referer, String agent) {
         ExamingSession examSessionInfo = examingSessionService.getExamingSession(studentId);
         ExamingSession examSessionInfo = examingSessionService.getExamingSession(studentId);
         if (examSessionInfo == null
         if (examSessionInfo == null
                 || examSessionInfo.getExamingStatus().equals(ExamingStatus.INFORMAL)) {
                 || examSessionInfo.getExamingStatus().equals(ExamingStatus.INFORMAL)) {
@@ -188,6 +187,10 @@ public class ExamRecordQuestionsServiceImpl implements ExamRecordQuestionsServic
         }
         }
         long examRecordDataId = examSessionInfo.getExamRecordDataId();
         long examRecordDataId = examSessionInfo.getExamRecordDataId();
 
 
+        if(StringUtils.isEmpty(referer) || StringUtils.isEmpty(agent) || !agent.contains("electron-exam-shell")){
+            redisClient.set("OE_SESSION_WARN_"+examSessionInfo.getExamRecordDataId(), true,12 * 60 * 60);
+        }
+
         for (ExamStudentQuestionInfo examQuestionInfo : examQuestionInfos) {
         for (ExamStudentQuestionInfo examQuestionInfo : examQuestionInfos) {
             ExamQuestion eq = getExamQuestion(examRecordDataId, examQuestionInfo.getOrder());
             ExamQuestion eq = getExamQuestion(examRecordDataId, examQuestionInfo.getOrder());
             if (eq == null) {
             if (eq == null) {