From 1a0f5e9e16e9baed4449607d44bf2850647a62bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E8=89=AF=28004796=29?= Date: Mon, 29 Apr 2024 15:00:17 +0800 Subject: [PATCH] init --- .../app/AuthOrderAppController.java | 35 ++---- .../java/com/ruoyi/xq/domain/UserInfo.java | 8 ++ .../xq/dto/app/user/vo/CurrentUserInfoVo.java | 15 +++ .../common/faceauth/CommitAuthRecordResp.java | 10 ++ .../ruoyi/xq/enums/face/TokenStatusEnum.java | 19 ++++ .../ruoyi/xq/manager/CurrentUserManager.java | 4 + .../xq/service/CardAuthRecordService.java | 8 ++ .../impl/CardAuthRecordServiceImpl.java | 101 ++++++++++++++++++ .../ruoyi/xq/tencent/TencentAuthClient.java | 101 ++++++++---------- 9 files changed, 220 insertions(+), 81 deletions(-) create mode 100644 ruoyi-xq/src/main/java/com/ruoyi/xq/dto/common/faceauth/CommitAuthRecordResp.java create mode 100644 ruoyi-xq/src/main/java/com/ruoyi/xq/enums/face/TokenStatusEnum.java diff --git a/ruoyi-xq/src/main/java/com/ruoyi/xq/controller/app/AuthOrderAppController.java b/ruoyi-xq/src/main/java/com/ruoyi/xq/controller/app/AuthOrderAppController.java index cd1ca90..512089c 100644 --- a/ruoyi-xq/src/main/java/com/ruoyi/xq/controller/app/AuthOrderAppController.java +++ b/ruoyi-xq/src/main/java/com/ruoyi/xq/controller/app/AuthOrderAppController.java @@ -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 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 getDetectInfo(@RequestParam String bizToken) { + CommitAuthRecordResp commitAuthRecordResp = cardAuthRecordService.commitAuthRecord(bizToken); + return R.ok(commitAuthRecordResp); } - /** - * 实名核身是否通过 - * - * @param bizToken - * @return - */ - @Operation(summary = "实名核身是否通过") - @GetMapping(value = "/faceDetectIsPass") - public R> faceDetectIsPass(@RequestParam String bizToken) { - boolean b = TencentAuthClient.faceDetectIsPass(bizToken); - Map map = new HashMap<>(); - map.put("result",b); - return R.ok(map); - } } diff --git a/ruoyi-xq/src/main/java/com/ruoyi/xq/domain/UserInfo.java b/ruoyi-xq/src/main/java/com/ruoyi/xq/domain/UserInfo.java index a520df6..897f3ce 100644 --- a/ruoyi-xq/src/main/java/com/ruoyi/xq/domain/UserInfo.java +++ b/ruoyi-xq/src/main/java/com/ruoyi/xq/domain/UserInfo.java @@ -91,6 +91,14 @@ public class UserInfo implements Serializable { * 毕业院校 */ private String graduateSchool; + /** + * 身份证 + */ + private String idCard; + /** + * 真实姓名 + */ + private String realName; /** * 兴趣爱好 */ diff --git a/ruoyi-xq/src/main/java/com/ruoyi/xq/dto/app/user/vo/CurrentUserInfoVo.java b/ruoyi-xq/src/main/java/com/ruoyi/xq/dto/app/user/vo/CurrentUserInfoVo.java index a7e055d..724e755 100644 --- a/ruoyi-xq/src/main/java/com/ruoyi/xq/dto/app/user/vo/CurrentUserInfoVo.java +++ b/ruoyi-xq/src/main/java/com/ruoyi/xq/dto/app/user/vo/CurrentUserInfoVo.java @@ -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; /** * 相册 */ diff --git a/ruoyi-xq/src/main/java/com/ruoyi/xq/dto/common/faceauth/CommitAuthRecordResp.java b/ruoyi-xq/src/main/java/com/ruoyi/xq/dto/common/faceauth/CommitAuthRecordResp.java new file mode 100644 index 0000000..b55ba7e --- /dev/null +++ b/ruoyi-xq/src/main/java/com/ruoyi/xq/dto/common/faceauth/CommitAuthRecordResp.java @@ -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; +} diff --git a/ruoyi-xq/src/main/java/com/ruoyi/xq/enums/face/TokenStatusEnum.java b/ruoyi-xq/src/main/java/com/ruoyi/xq/enums/face/TokenStatusEnum.java new file mode 100644 index 0000000..7ac70c2 --- /dev/null +++ b/ruoyi-xq/src/main/java/com/ruoyi/xq/enums/face/TokenStatusEnum.java @@ -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; + } +} diff --git a/ruoyi-xq/src/main/java/com/ruoyi/xq/manager/CurrentUserManager.java b/ruoyi-xq/src/main/java/com/ruoyi/xq/manager/CurrentUserManager.java index e681653..3280b2e 100644 --- a/ruoyi-xq/src/main/java/com/ruoyi/xq/manager/CurrentUserManager.java +++ b/ruoyi-xq/src/main/java/com/ruoyi/xq/manager/CurrentUserManager.java @@ -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()); diff --git a/ruoyi-xq/src/main/java/com/ruoyi/xq/service/CardAuthRecordService.java b/ruoyi-xq/src/main/java/com/ruoyi/xq/service/CardAuthRecordService.java index 7648c02..188ee1b 100644 --- a/ruoyi-xq/src/main/java/com/ruoyi/xq/service/CardAuthRecordService.java +++ b/ruoyi-xq/src/main/java/com/ruoyi/xq/service/CardAuthRecordService.java @@ -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 { + CreateAuthResp createAuthRecord(String orderNo, String redirectUrl); + + CommitAuthRecordResp commitAuthRecord(String bizToken); + + boolean updateCardRecordSuccess(CardAuthRecord cardAuthRecord, GetDetectInfoEnhancedResponse detectInfo); } diff --git a/ruoyi-xq/src/main/java/com/ruoyi/xq/service/impl/CardAuthRecordServiceImpl.java b/ruoyi-xq/src/main/java/com/ruoyi/xq/service/impl/CardAuthRecordServiceImpl.java index d4279b2..7a62adc 100644 --- a/ruoyi-xq/src/main/java/com/ruoyi/xq/service/impl/CardAuthRecordServiceImpl.java +++ b/ruoyi-xq/src/main/java/com/ruoyi/xq/service/impl/CardAuthRecordServiceImpl.java @@ -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 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; + } } diff --git a/ruoyi-xq/src/main/java/com/ruoyi/xq/tencent/TencentAuthClient.java b/ruoyi-xq/src/main/java/com/ruoyi/xq/tencent/TencentAuthClient.java index 85409a1..3888105 100644 --- a/ruoyi-xq/src/main/java/com/ruoyi/xq/tencent/TencentAuthClient.java +++ b/ruoyi-xq/src/main/java/com/ruoyi/xq/tencent/TencentAuthClient.java @@ -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));