deason преди 3 години
родител
ревизия
1e748b2095

+ 1 - 1
src/main/java/cn/com/qmth/examcloud/app/controller/ExamController.java

@@ -31,7 +31,7 @@ public class ExamController extends ControllerSupport {
     @Autowired
     private CoreOeService oeService;
 
-	@ApiOperation(value = "查询考生的考试批次属性集")
+    @ApiOperation(value = "查询考试配置属性接口")
 	@GetMapping("getExamProperty/{examId}/{keys}")
 	public Result getExamPropertyFromCacheByStudentSession(@RequestHeader(name = PARAM_APP_KEY) String key, @RequestHeader(name = PARAM_APP_TOKEN) String token,@PathVariable Long examId,
 			@PathVariable String keys) throws Exception{

+ 67 - 0
src/main/java/cn/com/qmth/examcloud/app/controller/FaceVerifyController.java

@@ -0,0 +1,67 @@
+package cn.com.qmth.examcloud.app.controller;
+
+import cn.com.qmth.examcloud.app.model.CaptureInfo;
+import cn.com.qmth.examcloud.app.model.Result;
+import cn.com.qmth.examcloud.app.service.FaceVerifyService;
+import cn.com.qmth.examcloud.web.support.ControllerSupport;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import static cn.com.qmth.examcloud.app.model.Constants.PARAM_APP_KEY;
+import static cn.com.qmth.examcloud.app.model.Constants.PARAM_APP_TOKEN;
+
+@RestController
+@RequestMapping("${$rmp}/v2/face/verify")
+@Api(tags = "人脸识别、比对验证相关接口")
+public class FaceVerifyController extends ControllerSupport {
+
+    @Autowired
+    private FaceVerifyService faceVerifyService;
+
+    @ApiOperation(value = "是否开启人脸验证接口")
+    @PostMapping("/faceCheckEnabled/{examId}")
+    public Result faceCheckEnabled(@RequestHeader(name = PARAM_APP_KEY) String key,
+                                   @RequestHeader(name = PARAM_APP_TOKEN) String token,
+                                   @PathVariable Long examId) throws Exception {
+        return faceVerifyService.faceCheckEnabled(key, token, examId);
+    }
+
+    @ApiOperation(value = "获取照片的云存储签名接口", notes = "拿到签名后,将抓拍照片上传至云存储")
+    @PostMapping("/getPhotoSign")
+    public Result getPhotoSign(@RequestHeader(name = PARAM_APP_KEY) String key,
+                               @RequestHeader(name = PARAM_APP_TOKEN) String token,
+                               @ApiParam(value = "文件后缀:png、jpg") @RequestParam String fileSuffix,
+                               @ApiParam(value = "文件MD5") @RequestParam(required = false) String fileMd5) throws Exception {
+        return faceVerifyService.getPhotoSign(key, token, fileSuffix, fileMd5);
+    }
+
+    @ApiOperation(value = "执行人脸识别接口")
+    @PostMapping("/compare")
+    public Result compare(@RequestHeader(name = PARAM_APP_KEY) String key,
+                          @RequestHeader(name = PARAM_APP_TOKEN) String token,
+                          @ApiParam(value = "文件访问地址") @RequestParam String fileUrl,
+                          @ApiParam(value = "照片签名标识") @RequestParam(required = false) String signIdentifier) throws Exception {
+        return faceVerifyService.compare(key, token, fileUrl, signIdentifier);
+    }
+
+    @ApiOperation(value = "保存抓拍照片信息接口")
+    @PostMapping("/saveCaptureInfo")
+    public Result saveCaptureInfo(@RequestHeader(name = PARAM_APP_KEY) String key,
+                                  @RequestHeader(name = PARAM_APP_TOKEN) String token,
+                                  @RequestBody CaptureInfo captureInfo) throws Exception {
+        return faceVerifyService.saveCaptureInfo(key, token, captureInfo);
+    }
+
+    @ApiOperation(value = "获取抓拍照片比对结果接口")
+    @PostMapping("/getCaptureResult")
+    public Result getCaptureResult(@RequestHeader(name = PARAM_APP_KEY) String key,
+                                   @RequestHeader(name = PARAM_APP_TOKEN) String token,
+                                   @ApiParam(value = "考试记录ID") @RequestParam Long examRecordDataId,
+                                   @ApiParam(value = "文件名") @RequestParam String fileName) throws Exception {
+        return faceVerifyService.getCaptureResult(key, token, examRecordDataId, fileName);
+    }
+
+}

+ 76 - 0
src/main/java/cn/com/qmth/examcloud/app/model/CaptureInfo.java

@@ -0,0 +1,76 @@
+package cn.com.qmth.examcloud.app.model;
+
+import cn.com.qmth.examcloud.api.commons.exchange.JsonSerializable;
+import io.swagger.annotations.ApiModelProperty;
+
+public class CaptureInfo implements JsonSerializable {
+
+    private static final long serialVersionUID = -7434669407796418900L;
+
+    @ApiModelProperty(value = "考试记录ID")
+    private Long examRecordDataId;
+
+    @ApiModelProperty(value = "文件访问地址")
+    private String fileUrl;
+
+    @ApiModelProperty(value = "是否存在虚拟摄像头")
+    private Boolean hasVirtualCamera;
+
+    @ApiModelProperty(value = "摄像头信息,Json格式")
+    private String cameraInfos;
+
+    @ApiModelProperty(value = "其它信息,Json格式")
+    private String extMsg;
+
+    @ApiModelProperty("照片签名标识")
+    private String signIdentifier;
+
+    public Long getExamRecordDataId() {
+        return examRecordDataId;
+    }
+
+    public void setExamRecordDataId(Long examRecordDataId) {
+        this.examRecordDataId = examRecordDataId;
+    }
+
+    public String getFileUrl() {
+        return fileUrl;
+    }
+
+    public void setFileUrl(String fileUrl) {
+        this.fileUrl = fileUrl;
+    }
+
+    public Boolean getHasVirtualCamera() {
+        return hasVirtualCamera;
+    }
+
+    public void setHasVirtualCamera(Boolean hasVirtualCamera) {
+        this.hasVirtualCamera = hasVirtualCamera;
+    }
+
+    public String getCameraInfos() {
+        return cameraInfos;
+    }
+
+    public void setCameraInfos(String cameraInfos) {
+        this.cameraInfos = cameraInfos;
+    }
+
+    public String getExtMsg() {
+        return extMsg;
+    }
+
+    public void setExtMsg(String extMsg) {
+        this.extMsg = extMsg;
+    }
+
+    public String getSignIdentifier() {
+        return signIdentifier;
+    }
+
+    public void setSignIdentifier(String signIdentifier) {
+        this.signIdentifier = signIdentifier;
+    }
+
+}

+ 21 - 0
src/main/java/cn/com/qmth/examcloud/app/service/FaceVerifyService.java

@@ -0,0 +1,21 @@
+package cn.com.qmth.examcloud.app.service;
+
+import cn.com.qmth.examcloud.app.model.CaptureInfo;
+import cn.com.qmth.examcloud.app.model.Result;
+
+/**
+ * 人脸识别、比对验证相关接口
+ */
+public interface FaceVerifyService {
+
+    Result faceCheckEnabled(String key, String token, Long examId) throws Exception;
+
+    Result getPhotoSign(String key, String token, String fileSuffix, String fileMd5) throws Exception;
+
+    Result compare(String key, String token, String fileUrl, String signIdentifier) throws Exception;
+
+    Result saveCaptureInfo(String key, String token, CaptureInfo captureInfo) throws Exception;
+
+    Result getCaptureResult(String key, String token, Long examRecordDataId, String fileName) throws Exception;
+
+}

+ 69 - 0
src/main/java/cn/com/qmth/examcloud/app/service/impl/FaceVerifyServiceImpl.java

@@ -0,0 +1,69 @@
+package cn.com.qmth.examcloud.app.service.impl;
+
+import cn.com.qmth.examcloud.app.core.SysProperty;
+import cn.com.qmth.examcloud.app.core.utils.HttpUtils;
+import cn.com.qmth.examcloud.app.model.CaptureInfo;
+import cn.com.qmth.examcloud.app.model.Constants;
+import cn.com.qmth.examcloud.app.model.Result;
+import cn.com.qmth.examcloud.app.service.FaceVerifyService;
+import cn.com.qmth.examcloud.commons.util.JsonMapper;
+import okhttp3.FormBody;
+import okhttp3.MediaType;
+import okhttp3.RequestBody;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+/**
+ * 人脸识别、比对验证相关接口
+ */
+@Service
+public class FaceVerifyServiceImpl implements FaceVerifyService {
+
+    private static final Logger log = LoggerFactory.getLogger(FaceVerifyServiceImpl.class);
+
+    @Autowired
+    private SysProperty sysProperty;
+
+    @Override
+    public Result faceCheckEnabled(String key, String token, Long examId) throws Exception {
+        final String requestUrl = String.format("%s/api/ecs_exam_work/exam/faceCheckEnabled/%s", sysProperty.getApiDomain(), examId);
+        return HttpUtils.doGet(requestUrl, key, token);
+    }
+
+    @Override
+    public Result getPhotoSign(String key, String token, String fileSuffix, String fileMd5) throws Exception {
+        final String requestUrl = String.format("%s/api/ecs_oe_student/examControl/getCapturePhotoYunSign?fileSuffix=%s&fileMd5=%s",
+                sysProperty.getApiDomain(), fileSuffix != null ? fileSuffix : "", fileMd5 != null ? fileMd5 : "");
+
+        return HttpUtils.doGet(requestUrl, key, token);
+    }
+
+    @Override
+    public Result compare(String key, String token, String fileUrl, String signIdentifier) throws Exception {
+        final String requestUrl = String.format("%s/api/ecs_oe_student_face/examCaptureQueue/compareFaceSync?fileUrl=%s&signIdentifier=%s",
+                sysProperty.getApiDomain(), fileUrl != null ? fileUrl : "", signIdentifier != null ? signIdentifier : "");
+
+        RequestBody formBody = new FormBody.Builder().build();
+        return HttpUtils.doPost(requestUrl, formBody, key, token);
+    }
+
+    @Override
+    public Result saveCaptureInfo(String key, String token, CaptureInfo captureInfo) throws Exception {
+        final String requestUrl = String.format("%s/api/ecs_oe_student_face/examCaptureQueue/uploadExamCapture", sysProperty.getApiDomain());
+
+        String json = new JsonMapper().toJson(captureInfo);
+        RequestBody formBody = FormBody.create(MediaType.parse(Constants.CHARSET_JSON_UTF8), json);
+        return HttpUtils.doPost(requestUrl, formBody, key, token);
+    }
+
+    @Override
+    public Result getCaptureResult(String key, String token, Long examRecordDataId, String fileName) throws Exception {
+        final String requestUrl = String.format("%s/api/ecs_oe_student_face/examCaptureQueue/getExamCaptureResult?examRecordDataId=%s&fileName=%s",
+                sysProperty.getApiDomain(), examRecordDataId, fileName != null ? fileName : "");
+
+        return HttpUtils.doGet(requestUrl, key, token);
+    }
+
+}