This commit is contained in:
张良(004796)
2024-04-29 15:00:17 +08:00
parent 6669ab0414
commit 1a0f5e9e16
9 changed files with 220 additions and 81 deletions

View File

@@ -6,21 +6,18 @@ import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.helper.LoginHelper;
import com.ruoyi.xq.domain.AuthOrder;
import com.ruoyi.xq.dto.app.pay.OrderCreateVo;
import com.ruoyi.xq.dto.common.faceauth.CommitAuthRecordResp;
import com.ruoyi.xq.enums.common.SystemConfigEnum;
import com.ruoyi.xq.manager.SystemConfigManager;
import com.ruoyi.xq.service.AuthOrderService;
import com.ruoyi.xq.service.CardAuthRecordService;
import com.ruoyi.xq.tencent.CreateAuthResp;
import com.ruoyi.xq.tencent.TencentAuthClient;
import com.tencentcloudapi.faceid.v20180301.models.GetDetectInfoEnhancedResponse;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.commons.collections4.map.HashedMap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
import java.util.Map;
import java.math.BigDecimal;
import java.util.Map;
@@ -33,6 +30,8 @@ public class AuthOrderAppController {
private AuthOrderService authOrderService;
@Autowired
private SystemConfigManager systemCOnfigManager;
@Autowired
private CardAuthRecordService cardAuthRecordService;
@PostMapping("/order/create")
@Operation(summary = "生成VIP订单")
@@ -64,9 +63,9 @@ public class AuthOrderAppController {
*/
@Operation(summary = "实名核身鉴权")
@GetMapping(value = "/detectAuth")
public R<?> detectAuth(String extra,String redirectUrl) {
CreateAuthResp token = TencentAuthClient.createToken(extra, redirectUrl);
return R.ok(token);
public R<CreateAuthResp> detectAuth(String orderNo,String redirectUrl) {
CreateAuthResp authRecord = cardAuthRecordService.createAuthRecord(orderNo, redirectUrl);
return R.ok(authRecord);
}
/**
@@ -77,23 +76,9 @@ public class AuthOrderAppController {
*/
@Operation(summary = "获取实名核身结果信息")
@GetMapping(value = "/getDetectInfo")
public R<?> getDetectInfo(@RequestParam String bizToken) {
GetDetectInfoEnhancedResponse detectInfo = TencentAuthClient.getDetectInfo(bizToken);
return R.ok(detectInfo);
public R<CommitAuthRecordResp> getDetectInfo(@RequestParam String bizToken) {
CommitAuthRecordResp commitAuthRecordResp = cardAuthRecordService.commitAuthRecord(bizToken);
return R.ok(commitAuthRecordResp);
}
/**
* 实名核身是否通过
*
* @param bizToken
* @return
*/
@Operation(summary = "实名核身是否通过")
@GetMapping(value = "/faceDetectIsPass")
public R<Map<String,Boolean>> faceDetectIsPass(@RequestParam String bizToken) {
boolean b = TencentAuthClient.faceDetectIsPass(bizToken);
Map<String,Boolean> map = new HashMap<>();
map.put("result",b);
return R.ok(map);
}
}

View File

@@ -91,6 +91,14 @@ public class UserInfo implements Serializable {
* 毕业院校
*/
private String graduateSchool;
/**
* 身份证
*/
private String idCard;
/**
* 真实姓名
*/
private String realName;
/**
* 兴趣爱好
*/

View File

@@ -94,6 +94,21 @@ public class CurrentUserInfoVo {
*/
@Schema(description = "交换微信次数")
private Integer wxTransNum = 0;
/**
* 身份证
*/
@Schema(description = "身份证")
private String idCard;
/**
* 真实姓名
*/
@Schema(description = "真实姓名")
private String realName;
/**
* 民族
*/
@Schema(description = "民族")
private String nation;
/**
* 相册
*/

View File

@@ -0,0 +1,10 @@
package com.ruoyi.xq.dto.common.faceauth;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
public class CommitAuthRecordResp {
@Schema(description = "人脸核身结果")
private boolean faceSuccess;
}

View File

@@ -0,0 +1,19 @@
package com.ruoyi.xq.enums.face;
import lombok.Getter;
@Getter
public enum TokenStatusEnum {
CREATE(0,"未处理"),
SUCCESS(1,"成功"),
FAIL(2,"失败"),
TIME_OUT(3,"失效"),
;
private final Integer code;
private final String text;
TokenStatusEnum(Integer code, String text) {
this.code = code;
this.text = text;
}
}

View File

@@ -122,6 +122,10 @@ public class CurrentUserManager {
vo.setVipType(user.getVipType());
vo.setVipTimeout(user.getVipTimeout());
}
UserInfo userInfo = userInfoService.getByUserId(userId);
vo.setIdCard(userInfo.getIdCard());
vo.setNation(userInfo.getNation());
vo.setRealName(userInfo.getRealName());
UserExtend userExtend = userExtendService.getByUserId(userId);
vo.setIncomeCoin(userExtend.getIncomeCoin());
vo.setWxTransNum(userExtend.getWxTransNum());

View File

@@ -2,6 +2,9 @@ package com.ruoyi.xq.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.xq.domain.CardAuthRecord;
import com.ruoyi.xq.dto.common.faceauth.CommitAuthRecordResp;
import com.ruoyi.xq.tencent.CreateAuthResp;
import com.tencentcloudapi.faceid.v20180301.models.GetDetectInfoEnhancedResponse;
/**
* 实名认证管理Service接口
@@ -10,4 +13,9 @@ import com.ruoyi.xq.domain.CardAuthRecord;
* @date 2024-04-29
*/
public interface CardAuthRecordService extends IService<CardAuthRecord> {
CreateAuthResp createAuthRecord(String orderNo, String redirectUrl);
CommitAuthRecordResp commitAuthRecord(String bizToken);
boolean updateCardRecordSuccess(CardAuthRecord cardAuthRecord, GetDetectInfoEnhancedResponse detectInfo);
}

View File

@@ -1,10 +1,29 @@
package com.ruoyi.xq.service.impl;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.spring.SpringUtils;
import com.ruoyi.xq.domain.AuthOrder;
import com.ruoyi.xq.domain.CardAuthRecord;
import com.ruoyi.xq.domain.UserAuth;
import com.ruoyi.xq.domain.UserInfo;
import com.ruoyi.xq.dto.common.faceauth.CommitAuthRecordResp;
import com.ruoyi.xq.enums.common.AuditEnum;
import com.ruoyi.xq.enums.face.TokenStatusEnum;
import com.ruoyi.xq.enums.pay.PayStatusEnum;
import com.ruoyi.xq.mapper.CardAuthRecordMapper;
import com.ruoyi.xq.service.AuthOrderService;
import com.ruoyi.xq.service.CardAuthRecordService;
import com.ruoyi.xq.service.UserAuthService;
import com.ruoyi.xq.service.UserInfoService;
import com.ruoyi.xq.tencent.CreateAuthResp;
import com.ruoyi.xq.tencent.TencentAuthClient;
import com.tencentcloudapi.common.exception.TencentCloudSDKException;
import com.tencentcloudapi.faceid.v20180301.models.GetDetectInfoEnhancedResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
/**
* 实名认证管理Service业务层处理
@@ -15,4 +34,86 @@ import org.springframework.stereotype.Service;
@Service
public class CardAuthRecordServiceImpl extends ServiceImpl<CardAuthRecordMapper,CardAuthRecord> implements CardAuthRecordService {
@Autowired
private AuthOrderService authOrderService;
@Autowired
private UserAuthService userAuthService;
@Autowired
private UserInfoService userInfoService;
@Override
public CreateAuthResp createAuthRecord(String orderNo, String redirectUrl){
AuthOrder authOrder = authOrderService.getByOrderNo(orderNo);
if(authOrder == null || PayStatusEnum.PAY.getCode().equals(authOrder.getPayStatus())){
throw new ServiceException("请支付后再进行实名认证");
}
CreateAuthResp token;
try {
token = TencentAuthClient.createToken(orderNo, redirectUrl);
} catch (TencentCloudSDKException e) {
log.error("发起实名认证异常",e);
throw new ServiceException("云服务异常,发起实名认证失败");
}
CardAuthRecord cardAuthRecord = new CardAuthRecord();
cardAuthRecord.setUserId(authOrder.getUserId());
cardAuthRecord.setUsercode(authOrder.getUsercode());
cardAuthRecord.setBizToken(token.getBizToken());
cardAuthRecord.setTokenStatus(0);
this.save(cardAuthRecord);
return token;
}
@Override
public CommitAuthRecordResp commitAuthRecord(String bizToken){
CardAuthRecord cardAuthRecord = this.getOne(Wrappers.lambdaQuery(CardAuthRecord.class)
.eq(CardAuthRecord::getBizToken, bizToken).last("limit 1"));
if(cardAuthRecord == null){
throw new ServiceException("未找到对应的实名认证");
}
GetDetectInfoEnhancedResponse detectInfo;
try {
detectInfo = TencentAuthClient.getDetectInfo(bizToken);
} catch (TencentCloudSDKException e) {
log.error("查询实名认证异常",e);
throw new ServiceException("实名认证结果获取失败");
}
CardAuthRecordService bean = SpringUtils.getBean(CardAuthRecordService.class);
boolean success = bean.updateCardRecordSuccess(cardAuthRecord, detectInfo);
CommitAuthRecordResp commitAuthRecordResp = new CommitAuthRecordResp();
commitAuthRecordResp.setFaceSuccess(success);
return commitAuthRecordResp;
}
@Override
@Transactional(rollbackFor = Exception.class)
public boolean updateCardRecordSuccess(CardAuthRecord cardAuthRecord, GetDetectInfoEnhancedResponse detectInfo){
boolean pass = TencentAuthClient.faceDetectIsPass(detectInfo);
CardAuthRecord updateRecord = new CardAuthRecord();
updateRecord.setId(cardAuthRecord.getId());
if(!pass){
updateRecord.setTokenStatus(TokenStatusEnum.FAIL.getCode());
}else{
updateRecord.setTokenStatus(TokenStatusEnum.SUCCESS.getCode());
}
if(detectInfo.getText() != null){
updateRecord.setIdCard(detectInfo.getText().getIdCard());
updateRecord.setName(detectInfo.getText().getName());
if(detectInfo.getText().getOcrNation() != null){
updateRecord.setNation(detectInfo.getText().getOcrNation()+"");
}
}
this.updateById(updateRecord);
if(pass){
userAuthService.update(Wrappers.lambdaUpdate(UserAuth.class)
.eq(UserAuth::getUserId, cardAuthRecord.getUsercode())
.set(UserAuth::getCardNumAuth, AuditEnum.SUCCESS.getCode()));
userAuthService.checkAuthNum(cardAuthRecord.getUserId());
userInfoService.update(Wrappers.lambdaUpdate(UserInfo.class)
.eq(UserInfo::getUserId, cardAuthRecord.getUserId())
.set(UserInfo::getIdCard, detectInfo.getText().getIdCard())
.set(UserInfo::getRealName, detectInfo.getText().getName()));
}
return pass;
}
}

View File

@@ -23,8 +23,7 @@ public class TencentAuthClient {
private final static String SECRET_KEY = "DapskQxS7gBXlsqgP0a0KXXK8oy45INf";
public static boolean faceDetectIsPass(String bizToken) {
GetDetectInfoEnhancedResponse resp = getDetectInfo(bizToken);
public static boolean faceDetectIsPass(GetDetectInfoEnhancedResponse resp) {
if (!Objects.isNull(resp)) {
DetectInfoText text = resp.getText();
return !Objects.isNull(text) && text.getErrCode().intValue() == 0;
@@ -38,66 +37,56 @@ public class TencentAuthClient {
*
* @return
*/
public static GetDetectInfoEnhancedResponse getDetectInfo(String bizToken) {
public static GetDetectInfoEnhancedResponse getDetectInfo(String bizToken) throws TencentCloudSDKException {
GetDetectInfoEnhancedResponse resp = null;
try {
Credential cred = new Credential(SECRET_ID, SECRET_KEY);
HttpProfile httpProfile = new HttpProfile();
httpProfile.setEndpoint("faceid.tencentcloudapi.com");
httpProfile.setConnTimeout(10); // 请求连接超时时间,单位为秒(默认60秒)
httpProfile.setWriteTimeout(10); // 设置写入超时时间,单位为秒(默认0秒)
httpProfile.setReadTimeout(10);
ClientProfile clientProfile = new ClientProfile();
clientProfile.setHttpProfile(httpProfile);
FaceidClient client = new FaceidClient(cred, "", clientProfile);
GetDetectInfoEnhancedRequest req = new GetDetectInfoEnhancedRequest();
req.setBizToken(bizToken);
req.setInfoType("0");
req.setRuleId("1");
resp = client.GetDetectInfoEnhanced(req);
} catch (TencentCloudSDKException e) {
e.printStackTrace();
}
return resp;
Credential cred = new Credential(SECRET_ID, SECRET_KEY);
HttpProfile httpProfile = new HttpProfile();
httpProfile.setEndpoint("faceid.tencentcloudapi.com");
httpProfile.setConnTimeout(10); // 请求连接超时时间,单位为秒(默认60秒)
httpProfile.setWriteTimeout(10); // 设置写入超时时间,单位为秒(默认0秒)
httpProfile.setReadTimeout(10);
ClientProfile clientProfile = new ClientProfile();
clientProfile.setHttpProfile(httpProfile);
FaceidClient client = new FaceidClient(cred, "", clientProfile);
GetDetectInfoEnhancedRequest req = new GetDetectInfoEnhancedRequest();
req.setBizToken(bizToken);
req.setInfoType("0");
req.setRuleId("1");
return client.GetDetectInfoEnhanced(req);
}
public static CreateAuthResp createToken(String extra,String redirectUrl){
try{
// 实例化一个认证对象,入参需要传入腾讯云账户 SecretId 和 SecretKey此处还需注意密钥对的保密
// 代码泄露可能会导致 SecretId 和 SecretKey 泄露并威胁账号下所有资源的安全性。以下代码示例仅供参考建议采用更安全的方式来使用密钥请参见https://cloud.tencent.com/document/product/1278/85305
// 密钥可前往官网控制台 https://console.cloud.tencent.com/cam/capi 进行获取
Credential cred = new Credential(SECRET_ID, SECRET_KEY);
// 实例化一个http选项可选的没有特殊需求可以跳过
HttpProfile httpProfile = new HttpProfile();
httpProfile.setEndpoint("faceid.tencentcloudapi.com");
httpProfile.setConnTimeout(10); // 请求连接超时时间,单位为秒(默认60秒)
httpProfile.setWriteTimeout(10); // 设置写入超时时间,单位为秒(默认0秒)
httpProfile.setReadTimeout(10);
// 实例化一个client选项可选的没有特殊需求可以跳过
ClientProfile clientProfile = new ClientProfile();
clientProfile.setHttpProfile(httpProfile);
// 实例化要请求产品的client对象,clientProfile是可选的
FaceidClient client = new FaceidClient(cred, "", clientProfile);
// 实例化一个请求对象,每个接口都会对应一个request对象
DetectAuthRequest req = new DetectAuthRequest();
req.setRuleId("1");
// 透传参数
req.setExtra(extra);
// 跳转的URL
req.setRedirectUrl(redirectUrl);
// 返回的resp是一个DetectAuthResponse的实例与请求对象对应
DetectAuthResponse resp = client.DetectAuth(req);
// 输出json格式的字符串回包
System.out.println(AbstractModel.toJsonString(resp));
return JsonUtils.parseObject(AbstractModel.toJsonString(resp), CreateAuthResp.class);
} catch (TencentCloudSDKException e) {
System.out.println(e.toString());
}
return null;
public static CreateAuthResp createToken(String extra,String redirectUrl) throws TencentCloudSDKException {
// 实例化一个认证对象,入参需要传入腾讯云账户 SecretId 和 SecretKey此处还需注意密钥对的保密
// 代码泄露可能会导致 SecretId 和 SecretKey 泄露并威胁账号下所有资源的安全性。以下代码示例仅供参考建议采用更安全的方式来使用密钥请参见https://cloud.tencent.com/document/product/1278/85305
// 密钥可前往官网控制台 https://console.cloud.tencent.com/cam/capi 进行获取
Credential cred = new Credential(SECRET_ID, SECRET_KEY);
// 实例化一个http选项可选的没有特殊需求可以跳过
HttpProfile httpProfile = new HttpProfile();
httpProfile.setEndpoint("faceid.tencentcloudapi.com");
httpProfile.setConnTimeout(10); // 请求连接超时时间,单位为秒(默认60秒)
httpProfile.setWriteTimeout(10); // 设置写入超时时间,单位为秒(默认0秒)
httpProfile.setReadTimeout(10);
// 实例化一个client选项可选的没有特殊需求可以跳过
ClientProfile clientProfile = new ClientProfile();
clientProfile.setHttpProfile(httpProfile);
// 实例化要请求产品的client对象,clientProfile是可选的
FaceidClient client = new FaceidClient(cred, "", clientProfile);
// 实例化一个请求对象,每个接口都会对应一个request对象
DetectAuthRequest req = new DetectAuthRequest();
req.setRuleId("1");
// 透传参数
req.setExtra(extra);
// 跳转的URL
req.setRedirectUrl(redirectUrl);
// 返回的resp是一个DetectAuthResponse的实例与请求对象对应
DetectAuthResponse resp = client.DetectAuth(req);
// 输出json格式的字符串回包
System.out.println(AbstractModel.toJsonString(resp));
return JsonUtils.parseObject(AbstractModel.toJsonString(resp), CreateAuthResp.class);
}
public static void main(String[] args) {
public static void main(String[] args) throws TencentCloudSDKException {
// createToken(null,null);
GetDetectInfoEnhancedResponse detectInfo = getDetectInfo("09792FA0-C269-401F-B8DB-E68B680E0728");
System.out.println(JSON.toJSONString(detectInfo));