|
@@ -0,0 +1,149 @@
|
|
|
+package com.leromro.core.controller;
|
|
|
+
|
|
|
+
|
|
|
+import cn.hutool.core.util.IdUtil;
|
|
|
+import cn.hutool.core.util.StrUtil;
|
|
|
+import com.alibaba.fastjson2.JSONObject;
|
|
|
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
|
|
+import com.leromro.common.config.RuoYiConfig;
|
|
|
+import com.leromro.common.core.controller.BaseController;
|
|
|
+import com.leromro.common.core.domain.R;
|
|
|
+import com.leromro.common.core.domain.entity.SysUser;
|
|
|
+import com.leromro.common.utils.EIDUtil;
|
|
|
+import com.leromro.common.utils.file.ImageUtils;
|
|
|
+import com.leromro.core.service.IVolunteerFaceRecordService;
|
|
|
+import com.leromro.system.service.ISysUserService;
|
|
|
+import com.tencentcloudapi.common.exception.TencentCloudSDKException;
|
|
|
+import com.tencentcloudapi.common.Credential;
|
|
|
+import com.tencentcloudapi.faceid.v20180301.FaceidClient;
|
|
|
+import com.tencentcloudapi.faceid.v20180301.models.*;
|
|
|
+import io.swagger.annotations.Api;
|
|
|
+import io.swagger.annotations.ApiOperation;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
+import org.dromara.x.file.storage.core.FileInfo;
|
|
|
+import org.dromara.x.file.storage.core.FileStorageService;
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+import org.springframework.web.bind.annotation.GetMapping;
|
|
|
+import org.springframework.web.bind.annotation.RequestMapping;
|
|
|
+import org.springframework.web.bind.annotation.RestController;
|
|
|
+
|
|
|
+/**
|
|
|
+ * 腾讯人脸核身
|
|
|
+ */
|
|
|
+@Slf4j
|
|
|
+@RestController
|
|
|
+@Api(tags = "腾讯人脸核身")
|
|
|
+@RequestMapping({"/face"})
|
|
|
+public class TencentFaceController extends BaseController {
|
|
|
+
|
|
|
+ private static final String SECRET_ID = "AKIDkPr57wb6Peiu02zoW3RhmEUXNzOaaNwI"; // TODO 您账号的腾讯云密钥
|
|
|
+ private static final String SECRET_KEY = "D2d1EE0Zv4zhCTWLyOaYKtELSRDpE2qb"; // TODO 您账号的腾讯云密钥
|
|
|
+ private static final String REGION = "ap-chongqing";
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private FileStorageService fileStorageService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private ISysUserService systemUserService;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取token
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ @GetMapping("/getEidToken")
|
|
|
+ @ApiOperation(value = "获取token", notes = "获取token")
|
|
|
+ public R<String> getEidToken() {
|
|
|
+ // Step 1. 初始化客户端实例
|
|
|
+ Credential credential = new Credential(SECRET_ID, SECRET_KEY);
|
|
|
+ FaceidClient faceidClient = new FaceidClient(credential, REGION);
|
|
|
+ // Step 2. 使用Tencent Cloud API SDK组装请求体,填充参数
|
|
|
+ GetEidTokenRequest request = new GetEidTokenRequest();
|
|
|
+ request.setMerchantId("00EI2505271335530207"); // 商户ID,请在控制台查看已经申请的商户ID
|
|
|
+ GetEidTokenConfig config = new GetEidTokenConfig();
|
|
|
+ config.setInputType("1"); // 传身份证正反面OCR。
|
|
|
+ request.setConfig(config);
|
|
|
+ try {
|
|
|
+ // Step 3. 调用接口
|
|
|
+ GetEidTokenResponse response = faceidClient.GetEidToken(request);
|
|
|
+ System.out.println("SDK response: " + GetEidTokenResponse.toJsonString(response));
|
|
|
+ return R.ok(response.getEidToken());
|
|
|
+ } catch (TencentCloudSDKException e) {
|
|
|
+ // 调用接口异常在这里处理
|
|
|
+ System.err.println("invoke error, code: " + e.getErrorCode() + "message: " + e.getMessage());
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ return R.fail("获取token失败");
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取人脸核身结果
|
|
|
+ */
|
|
|
+ @GetMapping("/getEidResult")
|
|
|
+ @ApiOperation(value = "获取人脸核身结果", notes = "获取人脸核身结果")
|
|
|
+ public R<String> getEidResult(String eidToken) {
|
|
|
+ // 初始化修改信息
|
|
|
+ LambdaUpdateWrapper<SysUser> updateWrapper = new LambdaUpdateWrapper<SysUser>().eq(SysUser::getUserId, getUserId());
|
|
|
+ // Step 1. 初始化客户端实例
|
|
|
+ Credential credential = new Credential(SECRET_ID, SECRET_KEY);
|
|
|
+ FaceidClient faceidClient = new FaceidClient(credential, REGION);
|
|
|
+ // Step 2. 使用Tencent Cloud API SDK组装请求体,填充参数
|
|
|
+ GetEidResultRequest request = new GetEidResultRequest();
|
|
|
+ request.setEidToken(eidToken); // 通过GetEidResult接口获取到的EidToken
|
|
|
+ request.setInfoType("0"); // 指定拉取的结果信息
|
|
|
+ try {
|
|
|
+ // Step 3. 调用接口
|
|
|
+ GetEidResultResponse response = faceidClient.GetEidResult(request);
|
|
|
+ System.out.println("SDKResponse: " + GetEidResultResponse.toJsonString(response));
|
|
|
+ /** 解密用户姓名和身份证信息 */
|
|
|
+ // 上述2.3 查看并保留私钥过程中获取到的priv内容,去掉冒号,即为PrivateKey的值
|
|
|
+ String PrivateKeyHex = "4157f6f7151a1d192f9bee771e37c1e5deae53916408ae098968c0d0fa770dce";
|
|
|
+ // GetEidResult接口返回的DesKey字段值
|
|
|
+ String DesKey = response.getEidInfo().getDesKey();
|
|
|
+ // GetEidResult接口返回的UserInfo字段值
|
|
|
+ String UserInfo = response.getEidInfo().getUserInfo();
|
|
|
+ // 调用EIDUtil解密用户信息
|
|
|
+ byte[] b = EIDUtil.decodeUserInfo(PrivateKeyHex, DesKey, UserInfo);
|
|
|
+ JSONObject jsonObject = JSONObject.parseObject(new String(b));
|
|
|
+ String name = jsonObject.getString("name");
|
|
|
+ String idNum = jsonObject.getString("idnum");
|
|
|
+ if (StrUtil.isBlank(idNum) || StrUtil.isBlank(name)){
|
|
|
+ throw new Exception("身份证姓名信息解析错误");
|
|
|
+ }
|
|
|
+ updateWrapper.set(SysUser::getName, name).set(SysUser::getIdCard, idNum);
|
|
|
+ String OcrFront = RuoYiConfig.getUploadPath()+"/face/"+ IdUtil.getSnowflakeNextIdStr() +".jpg";
|
|
|
+ String OcrBack = RuoYiConfig.getUploadPath()+"/face/"+ IdUtil.getSnowflakeNextIdStr() +".jpg";
|
|
|
+ String facePicture = RuoYiConfig.getUploadPath()+"/face/"+ IdUtil.getSnowflakeNextIdStr() +".jpg";
|
|
|
+ //提取身份证人像面
|
|
|
+ ImageUtils.base64ToImage(response.getIdCardData().getOcrFront(), OcrFront);
|
|
|
+ if (StrUtil.isNotBlank(OcrFront)){
|
|
|
+ FileInfo fileInfo = fileStorageService.of(OcrFront).upload();
|
|
|
+ updateWrapper.set(SysUser::getIdCardPictureFront, fileInfo.getUrl());
|
|
|
+ }
|
|
|
+ //提取身份证国徽面
|
|
|
+ ImageUtils.base64ToImage(response.getIdCardData().getOcrBack(), OcrBack);
|
|
|
+ if (StrUtil.isNotBlank(OcrBack)){
|
|
|
+ FileInfo fileInfo = fileStorageService.of(OcrBack).upload();
|
|
|
+ updateWrapper.set(SysUser::getIdCardPictureBack, fileInfo.getUrl());
|
|
|
+ }
|
|
|
+ //提取人脸照片
|
|
|
+ ImageUtils.base64ToImage(response.getBestFrame().getBestFrame(), facePicture);
|
|
|
+ if (StrUtil.isNotBlank(facePicture)){
|
|
|
+ FileInfo fileInfo = fileStorageService.of(facePicture).upload();
|
|
|
+ updateWrapper.set(SysUser::getFacePicture, fileInfo.getUrl());
|
|
|
+ }
|
|
|
+ //保存
|
|
|
+ updateWrapper.set(SysUser::getIsFaceApprove, 1);
|
|
|
+ systemUserService.update(updateWrapper);
|
|
|
+ return R.ok("校验成功");
|
|
|
+ } catch (TencentCloudSDKException e) {
|
|
|
+ // 调用接口异常在这里处理
|
|
|
+ System.err.println("invoke error, code: " + e.getErrorCode() + "message: " + e.getMessage());
|
|
|
+ return R.fail("人脸认证失败:"+e.getMessage());
|
|
|
+ } catch (Exception e){
|
|
|
+ return R.fail("人脸认证失败:"+e.getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+}
|