فهرست منبع

学生底照:去掉FaceToken绑定和验证机制,并改为百度人脸API验证。

deason 11 ماه پیش
والد
کامیت
3e275e485f

+ 7 - 0
examcloud-exchange-service/pom.xml

@@ -38,5 +38,12 @@
             <artifactId>examcloud-core-questions-api-client</artifactId>
             <version>${project.version}</version>
         </dependency>
+
+        <dependency>
+            <groupId>cn.com.qmth.examcloud.starters</groupId>
+            <artifactId>examcloud-face-verify-starter</artifactId>
+            <version>${project.version}</version>
+        </dependency>
     </dependencies>
+
 </project>

+ 80 - 70
examcloud-exchange-service/src/main/java/cn/com/qmth/examcloud/exchange/outer/service/impl/FaceServiceImpl.java

@@ -3,48 +3,32 @@ package cn.com.qmth.examcloud.exchange.outer.service.impl;
 import cn.com.qmth.examcloud.api.commons.security.bean.User;
 import cn.com.qmth.examcloud.api.commons.security.bean.UserType;
 import cn.com.qmth.examcloud.commons.exception.StatusException;
-import cn.com.qmth.examcloud.commons.util.HttpClientUtil;
-import cn.com.qmth.examcloud.commons.util.JsonUtil;
-import cn.com.qmth.examcloud.core.basic.api.FaceCloudService;
 import cn.com.qmth.examcloud.core.basic.api.StudentCloudService;
-import cn.com.qmth.examcloud.core.basic.api.bean.FacesetBean;
 import cn.com.qmth.examcloud.core.basic.api.bean.StudentBean;
 import cn.com.qmth.examcloud.core.basic.api.request.GetStudentReq;
-import cn.com.qmth.examcloud.core.basic.api.request.GetUsableFacesetListReq;
-import cn.com.qmth.examcloud.core.basic.api.request.SaveStudentFaceReq;
+import cn.com.qmth.examcloud.core.basic.api.request.UpdatePhotoPathReq;
 import cn.com.qmth.examcloud.core.basic.api.response.GetStudentResp;
-import cn.com.qmth.examcloud.core.basic.api.response.GetUsableFacesetListResp;
 import cn.com.qmth.examcloud.exchange.outer.service.FaceService;
 import cn.com.qmth.examcloud.reports.commons.bean.OperateReport;
 import cn.com.qmth.examcloud.reports.commons.enums.OperateContent;
 import cn.com.qmth.examcloud.reports.commons.util.ReportsUtil;
+import cn.com.qmth.examcloud.starters.face.verify.common.CommonUtils;
+import cn.com.qmth.examcloud.starters.face.verify.model.FaceResult;
+import cn.com.qmth.examcloud.starters.face.verify.model.param.FaceApiType;
+import cn.com.qmth.examcloud.starters.face.verify.model.param.FaceParam;
+import cn.com.qmth.examcloud.starters.face.verify.model.param.ImageBase64Parm;
+import cn.com.qmth.examcloud.starters.face.verify.model.param.ImageParm;
+import cn.com.qmth.examcloud.starters.face.verify.service.FaceVerifyService;
 import cn.com.qmth.examcloud.support.fss.FssFactory;
 import cn.com.qmth.examcloud.support.fss.model.FssFileInfo;
 import cn.com.qmth.examcloud.web.enums.HttpServletRequestAttribute;
 import cn.com.qmth.examcloud.web.support.ServletUtil;
-import com.alibaba.fastjson.JSON;
-import com.alibaba.fastjson.JSONArray;
-import com.alibaba.fastjson.JSONObject;
-import com.google.common.collect.Maps;
-import org.apache.commons.collections.CollectionUtils;
-import org.apache.http.HttpEntity;
-import org.apache.http.HttpStatus;
-import org.apache.http.client.methods.CloseableHttpResponse;
-import org.apache.http.client.methods.HttpPost;
-import org.apache.http.client.utils.URIBuilder;
-import org.apache.http.impl.client.CloseableHttpClient;
-import org.apache.http.impl.client.HttpClients;
-import org.apache.http.util.EntityUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
 
 import java.io.File;
-import java.net.URI;
-import java.util.List;
-import java.util.Map;
 
 /**
  * 类注释
@@ -59,19 +43,22 @@ public class FaceServiceImpl implements FaceService {
     private static final Logger LOG = LoggerFactory.getLogger(FaceServiceImpl.class);
 
     @Autowired
-    StudentCloudService studentCloudService;
+    private FaceVerifyService faceVerifyService;
 
     @Autowired
-    FaceCloudService faceCloudService;
+    private StudentCloudService studentCloudService;
 
-    @Value("${examcloud.face.verify.facePlusKey}")
-    private String apiKey;
+    // @Autowired
+    // private FaceCloudService faceCloudService;
 
-    @Value("${examcloud.face.verify.facePlusSecret}")
-    private String apiSecret;
+    // @Value("${examcloud.face.verify.facePlusKey}")
+    // private String apiKey;
+
+    // @Value("${examcloud.face.verify.facePlusSecret}")
+    // private String apiSecret;
 
     @Override
-    public void processFace(Long rootOrgId, String identityNumber, String fileSuffix, File file,
+    public void processFace(Long rootOrgId, String identityNumber, String fileSuffix, File photoFile,
                             String operator) {
 
         GetStudentReq req = new GetStudentReq();
@@ -79,54 +66,81 @@ public class FaceServiceImpl implements FaceService {
         req.setRootOrgId(rootOrgId);
         GetStudentResp resp = studentCloudService.getStudent(req);
         StudentBean student = resp.getStudentInfo();
-        identityNumber = student.getIdentityNumber();
+
+        // 人脸识别验证
+        this.faceDetect(photoFile, identityNumber);
 
         // 路径规则:/student_base_photo/{rootOrgId}/{userId}/{timeMillis}{fileSuffix}
         String filePath = String.format("/student_base_photo/%s/%s/%s%s", rootOrgId, student.getId(), System.currentTimeMillis(), fileSuffix);
-        FssFileInfo result = FssFactory.getInstance().writeFile(filePath, file, null);
-        String photoUrl = result.getFileUrl();
+        FssFileInfo result = FssFactory.getInstance().writeFile(filePath, photoFile, null);
+
+        // String photoUrl = result.getFileUrl();
+        // String faceToken = detect(photoUrl);
+        // Map<String, Object> map = addFaceToken2Faceset(rootOrgId, faceToken);
+        // String facesetToken = (String) map.get("facesetToken");
+        // Long faceCount = (Long) map.get("faceCount");
+        // SaveStudentFaceReq request = new SaveStudentFaceReq();
+        // request.setFacesetToken(facesetToken);
+        // request.setFaceToken(faceToken);
+        // request.setOperator(operator);
+        // String photoName = photoUrl.substring(photoUrl.lastIndexOf("/") + 1);
+        // request.setPhotoName(photoName);
+        // request.setRootOrgId(rootOrgId);
+        // request.setStudentId(student.getId());
+        // request.setFaceCount(faceCount);
+        // request.setPhotoTreatyPath(result.getFilePath());
+        // faceCloudService.saveStudentFace(request);
+
+        UpdatePhotoPathReq request = new UpdatePhotoPathReq();
+        request.setStudentId(student.getId());
+        request.setPhotoPath(filePath);
+        studentCloudService.updatePhotoPath(request);
 
-        String faceToken = detect(photoUrl);
+        LOG.warn("更新学生底照完成!studentId:{} identityNumber:{} operator:{} photoUrl:{}",
+                student.getId(), identityNumber, operator, result.getFileUrl());
 
-        Map<String, Object> map = addFaceToken2Faceset(rootOrgId, faceToken);
+        //操作日志
+        User accessUser = (User) ServletUtil.getRequest().getAttribute(HttpServletRequestAttribute.$_ACCESS_USER.name());
+        if (accessUser != null) {
+            ReportsUtil.report(new OperateReport(rootOrgId, accessUser.getUserId(), student.getId(), null
+                    , UserType.COMMON, OperateContent.STUDENT_PHOTO_IMPORT.getDesc()));
+        }
+    }
 
-        String facesetToken = (String) map.get("facesetToken");
-        Long faceCount = (Long) map.get("faceCount");
+    private void faceDetect(File photoFile, String identityNumber) {
+        String imageBase64 = CommonUtils.toBase64(photoFile);
 
-        SaveStudentFaceReq request = new SaveStudentFaceReq();
-        request.setFacesetToken(facesetToken);
-        request.setFaceToken(faceToken);
-        request.setOperator(operator);
-        String photoName = photoUrl.substring(photoUrl.lastIndexOf("/") + 1);
-        request.setPhotoName(photoName);
-        request.setRootOrgId(rootOrgId);
-        request.setStudentId(student.getId());
-        request.setFaceCount(faceCount);
-        request.setPhotoTreatyPath(result.getFilePath());
+        try {
+            ImageParm basePhoto = new ImageBase64Parm(imageBase64);
+            FaceResult result = faceVerifyService.faceDetect(FaceParam.builder().images(basePhoto).apiType(FaceApiType.PRIVATE_BAIDU_API));
 
-        faceCloudService.saveStudentFace(request);
+            if (result.isFacePass()) {
+                LOG.warn("人脸检测通过!identityNumber:{} photoPath:{}", identityNumber, photoFile.getAbsolutePath());
+                return;
+            }
 
-        //操作日志
-        User accessUser = (User) ServletUtil.getRequest()
-                .getAttribute(HttpServletRequestAttribute.$_ACCESS_USER.name());
-        Long operateUserId = null;
-        if (null != accessUser) {
-            operateUserId = accessUser.getUserId();
+            if (result.isApiNeedRetry()) {
+                LOG.warn("人脸检测接口异常!identityNumber:{} photoPath:{} err:{}", identityNumber, photoFile.getAbsolutePath(), result.getError());
+                throw new StatusException("620008", "人脸检测接口异常,请稍后重试!");
+            }
+
+            LOG.warn("人脸检测失败!identityNumber:{} photoPath:{} err:{}", identityNumber, photoFile.getAbsolutePath(), result.getError());
+
+            basePhoto = null;
+            imageBase64 = null;
+        } catch (Exception e) {
+            LOG.error("人脸检测错误!identityNumber:{} photoPath:{} err:{}", identityNumber, photoFile.getAbsolutePath(), e.getMessage());
         }
-        ReportsUtil.report(new OperateReport(rootOrgId, operateUserId, student.getId(), null, UserType.COMMON,
-                OperateContent.STUDENT_PHOTO_IMPORT.getDesc()));
 
+        throw new StatusException("620005", "人脸检测失败!");
     }
 
     /**
      * 方法注释
      *
-     * @param rootOrgId
-     * @param faceToken
-     * @return
      * @author WANGWEI
      */
-    private Map<String, Object> addFaceToken2Faceset(Long rootOrgId, String faceToken) {
+    /*private Map<String, Object> addFaceToken2Faceset(Long rootOrgId, String faceToken) {
 
         Map<String, Object> info = Maps.newHashMap();
         info.put("rootOrgId", rootOrgId);
@@ -189,16 +203,14 @@ public class FaceServiceImpl implements FaceService {
                 HttpClientUtil.close(httpResponse);
             }
         }
-    }
+    }*/
 
     /**
      * 方法注释
      *
-     * @param rootOrgId
-     * @return
      * @author WANGWEI
      */
-    private String getFacesetToken(Long rootOrgId) {
+    /*private String getFacesetToken(Long rootOrgId) {
 
         GetUsableFacesetListReq req = new GetUsableFacesetListReq();
         req.setRootOrgId(rootOrgId);
@@ -211,16 +223,14 @@ public class FaceServiceImpl implements FaceService {
 
         FacesetBean facesetBean = facesetBeanList.get(0);
         return facesetBean.getFacesetToken();
-    }
+    }*/
 
     /**
      * 方法注释
      *
-     * @param photoUrl
-     * @return
      * @author WANGWEI
      */
-    private String detect(String photoUrl) {
+    /*private String detect(String photoUrl) {
         int times = 0;
         String faceToken = null;
         while (true) {
@@ -272,6 +282,6 @@ public class FaceServiceImpl implements FaceService {
                 HttpClientUtil.close(httpResponse);
             }
         }
-    }
+    }*/
 
 }