Forráskód Böngészése

人脸核身基本代码

wangwl 3 hónapja%!(EXTRA string=óta)
szülő
commit
fe766237ae

+ 24 - 0
leromro-common/src/main/java/com/leromro/common/core/domain/entity/SysUser.java

@@ -169,6 +169,30 @@ public class SysUser extends BaseEntity
     @ApiModelProperty("纬度")
     private String latitude;
 
+    @TableField("name")
+    @ApiModelProperty("真实姓名")
+    private String name;
+
+    @TableField("id_card")
+    @ApiModelProperty("身份证号")
+    private String idCard;
+
+    @TableField("face_picture")
+    @ApiModelProperty("志愿者人脸照片")
+    private String facePicture;
+
+    @TableField("id_card_picture_front")
+    @ApiModelProperty("身份证正面照片")
+    private String idCardPictureFront;
+
+    @TableField("id_card_picture_back")
+    @ApiModelProperty("身份证背面照片")
+    private String idCardPictureBack;
+
+    @TableField("is_face_approve")
+    @ApiModelProperty("是否人脸核身0否1是")
+    private String isFaceApprove;
+
     // 当前积分
     private Long point;
 

+ 43 - 0
leromro-common/src/main/java/com/leromro/common/utils/file/ImageUtils.java

@@ -1,11 +1,17 @@
 package com.leromro.common.utils.file;
 
+import java.awt.image.BufferedImage;
 import java.io.ByteArrayInputStream;
+import java.io.File;
 import java.io.FileInputStream;
 import java.io.InputStream;
 import java.net.URL;
 import java.net.URLConnection;
 import java.util.Arrays;
+import java.util.Base64;
+
+import cn.hutool.core.util.StrUtil;
+import lombok.extern.slf4j.Slf4j;
 import org.apache.poi.util.IOUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -13,6 +19,8 @@ import com.leromro.common.config.RuoYiConfig;
 import com.leromro.common.constant.Constants;
 import com.leromro.common.utils.StringUtils;
 
+import javax.imageio.ImageIO;
+
 /**
  * 图片处理工具类
  *
@@ -95,4 +103,39 @@ public class ImageUtils
             IOUtils.closeQuietly(in);
         }
     }
+
+    /**
+     * 将base64转为图片
+     */
+    public static String base64ToImage(String base64String, String outputFilePath){
+        try {
+            if (StrUtil.isBlank(base64String)){
+                throw new IllegalArgumentException("base64String 不能为空");
+            }
+            // 1. 去除可能存在的 data:image/png;base64, 前缀
+            if (base64String.startsWith("data:image")) {
+                base64String = base64String.split(",")[1];
+            }
+
+            // 2. Base64 解码
+            byte[] imageBytes = Base64.getDecoder().decode(base64String);
+
+            // 3. 转换为 BufferedImage
+            ByteArrayInputStream bis = new ByteArrayInputStream(imageBytes);
+            BufferedImage bufferedImage = ImageIO.read(bis);
+            bis.close();
+            if (bufferedImage == null) {
+                throw new IllegalArgumentException("无法识别该 Base64 图片数据");
+            }
+            // 4. 保存为文件
+            File outputFile = new File(outputFilePath);
+            String formatName = "png"; // 默认格式为 png,也可以是 jpg/jpeg 等
+            ImageIO.write(bufferedImage, formatName, outputFile);
+            System.out.println("图片已保存至:" + outputFile.getAbsolutePath());
+            return outputFilePath;
+        }catch (Exception e){
+            System.err.println("图片保存失败:" + e.getMessage());
+            return null;
+        }
+    }
 }

+ 55 - 5
leromro-core/src/main/java/com/leromro/core/controller/TencentFaceController.java

@@ -1,9 +1,19 @@
 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;
@@ -11,6 +21,9 @@ 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;
@@ -22,12 +35,18 @@ import org.springframework.web.bind.annotation.RestController;
 @RestController
 @Api(tags = "腾讯人脸核身")
 @RequestMapping({"/face"})
-public class TencentFaceController {
+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
@@ -63,6 +82,8 @@ public class TencentFaceController {
     @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);
@@ -84,16 +105,45 @@ public class TencentFaceController {
             // 调用EIDUtil解密用户信息
             byte[] b = EIDUtil.decodeUserInfo(PrivateKeyHex, DesKey, UserInfo);
             JSONObject jsonObject = JSONObject.parseObject(new String(b));
-            String name = jsonObject.getString("name");     // 王文龙
+            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());
-            e.printStackTrace();
+            return R.fail("人脸认证失败:"+e.getMessage());
         } catch (Exception e){
-            e.printStackTrace();
+            return R.fail("人脸认证失败:"+e.getMessage());
         }
-        return R.fail("人脸认证失败");
     }
+
+
 }

+ 7 - 0
leromro-system/src/main/resources/mapper/system/SysUserMapper.xml

@@ -41,6 +41,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         <result property="serviceCentreId"       column="service_centre_id"       />
         <result property="referrerAreaId"       column="referrer_area_id"       />
         <result property="areaId"       column="area_id"       />
+		<result property="name"    column="name"    />
+		<result property="idCard"    column="id_card"    />
+		<result property="idCardPictureFront"    column="id_card_picture_front"    />
+		<result property="idCardPictureBack"    column="id_card_picture_back"    />
+		<result property="facePicture"    column="face_picture"    />
+		<result property="isFaceApprove"    column="is_face_approve"    />
         <association property="dept"    javaType="SysDept"         resultMap="deptResult" />
         <collection  property="roles"   javaType="java.util.List"  resultMap="RoleResult" />
     </resultMap>
@@ -71,6 +77,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
                u.province_code as province_code, u.province_name as province_name, u.city_code as city_code, u.city_name as city_name, u.district_code as district_code,
                u.referrer_user_id ,u.referrer_service_centre_id,u.service_centre_id,u.referrer_area_id,u.area_id,
                u.district_name as district_name,u.point ,u.freeze_point,
+               u.name,u.id_card,u.is_face_approve,
         d.dept_id, d.parent_id, d.ancestors, d.dept_name, d.order_num, d.leader, d.status as dept_status,d.area_type as area_type,
         r.role_id, r.role_name, r.role_key, r.role_sort, r.data_scope, r.status as role_status,d.area_type
         from sys_user u