diff --git a/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/enums/MemberErrorCode.java b/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/enums/MemberErrorCode.java index 049e027..43f8b9a 100644 --- a/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/enums/MemberErrorCode.java +++ b/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/enums/MemberErrorCode.java @@ -63,6 +63,7 @@ public interface MemberErrorCode { ErrorCode RATING_SCORE_NOT_NULL = new ErrorCode(2_001_000_003, "评价分数不能为空"); ErrorCode VIEW_RECORD_NOT_EXISTS = new ErrorCode(2_001_000_004, "用户查看记录不存在"); ErrorCode COM_AUTH_NOT_EXISTS = new ErrorCode(2_001_000_005, "通用认证不存在"); + ErrorCode THIRD_AUTH_START_ERROR = new ErrorCode(2_001_000_006, "第三方认证发起失败"); //========== 用户图片、视频资源管理 1-004-013-000 ========== ErrorCode PHOTO_NOT_EXISTS = new ErrorCode(1_004_013_000, "用户资源不存在"); diff --git a/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/enums/MemberComAuthEnum.java b/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/enums/auth/MemberComAuthEnum.java similarity index 74% rename from yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/enums/MemberComAuthEnum.java rename to yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/enums/auth/MemberComAuthEnum.java index 903f580..faffc06 100644 --- a/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/enums/MemberComAuthEnum.java +++ b/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/enums/auth/MemberComAuthEnum.java @@ -1,6 +1,7 @@ -package cn.iocoder.yudao.module.member.enums; +package cn.iocoder.yudao.module.member.enums.auth; import cn.hutool.core.util.ObjectUtil; +import cn.iocoder.yudao.module.member.enums.MemberRecentOperateEnum; import lombok.AllArgsConstructor; import lombok.Getter; @@ -13,7 +14,8 @@ import java.util.List; @Getter @AllArgsConstructor public enum MemberComAuthEnum { - MEMBER_TRUE("1", "用户真实性认证"), + MAN_MEMBER_TRUE("1", "用户真实性认证(男性)"), + WOMAN_MEMBER_TRUE("2", "用户真实性认证(女性)"), ; private final String type; private final String description; diff --git a/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/enums/auth/MemberComAuthStatusEnum.java b/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/enums/auth/MemberComAuthStatusEnum.java new file mode 100644 index 0000000..e00f33b --- /dev/null +++ b/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/enums/auth/MemberComAuthStatusEnum.java @@ -0,0 +1,34 @@ +package cn.iocoder.yudao.module.member.enums.auth; + +import cn.hutool.core.util.ObjectUtil; +import cn.iocoder.yudao.module.member.enums.MemberRecentOperateEnum; +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.util.Arrays; +import java.util.List; + +/** + * 通用认证 - 审核状态 + */ +@Getter +@AllArgsConstructor +public enum MemberComAuthStatusEnum { + + WAIT_AUTH("1", "待认证"), + CHECK("2", "审核中"), + CHECK_PASS("3", "审核通过"), + CHECK_FAIL("4", "审核失败"), + ; + private final String type; + private final String description; + + public static boolean contains(MemberRecentOperateEnum operateEnum) { + return Arrays.asList(values()).stream().anyMatch(v -> ObjectUtil.equals(v.type, operateEnum.getType())); + } + + public static boolean contains(List operateEnumList) { + return operateEnumList.stream().anyMatch(MemberRecentOperateEnum::contains); + } + +} diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/client/service/ThirdAuthServiceImpl.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/client/service/ThirdAuthServiceImpl.java index fb28d0c..27b8c17 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/client/service/ThirdAuthServiceImpl.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/client/service/ThirdAuthServiceImpl.java @@ -44,8 +44,8 @@ public class ThirdAuthServiceImpl implements ThirdAuthService { if (clientInstance == null) { try { Config config = new Config(); - config.setAccessKeyId("LTAI5tJ7sSxB96XaY9T3Vq3D"); - config.setAccessKeySecret("EVXWFTS2SB6UkjUVFLhTDBfIvIXgI3"); + config.setAccessKeyId(thirdAlConfig.getAccessKeyId()); + config.setAccessKeySecret(thirdAlConfig.getAccessKeySecret()); config.setEndpoint("green-cip.cn-shanghai.aliyuncs.com"); //读取时超时时间,单位毫秒(ms) config.setReadTimeout(10_000); diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/client/service/ThirdFaceVerifyService.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/client/service/ThirdFaceVerifyService.java index d78c6e1..342e33a 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/client/service/ThirdFaceVerifyService.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/client/service/ThirdFaceVerifyService.java @@ -1,6 +1,8 @@ package cn.iocoder.yudao.module.member.client.service; +import cn.iocoder.yudao.module.member.client.vo.thirdfaceverify.ThirdFindFaceVerifyReqVo; +import cn.iocoder.yudao.module.member.client.vo.thirdfaceverify.ThirdFindFaceVerifyResVo; import cn.iocoder.yudao.module.member.client.vo.thirdfaceverify.ThirdFaceVerifyReqVO; import cn.iocoder.yudao.module.member.client.vo.thirdfaceverify.ThirdFaceVerifyResVO; @@ -12,8 +14,8 @@ public interface ThirdFaceVerifyService { ThirdFaceVerifyResVO faceVerify(ThirdFaceVerifyReqVO dto); /** - * 人脸识别回调 + * 查询人脸识别 */ - String callback(String code); + ThirdFindFaceVerifyResVo findFaceVerify(ThirdFindFaceVerifyReqVo code); } diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/client/service/ThirdFaceVerifyServiceImpl.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/client/service/ThirdFaceVerifyServiceImpl.java index f64271d..0980614 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/client/service/ThirdFaceVerifyServiceImpl.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/client/service/ThirdFaceVerifyServiceImpl.java @@ -1,13 +1,14 @@ package cn.iocoder.yudao.module.member.client.service; +import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.util.ObjectUtil; +import cn.iocoder.yudao.module.member.client.vo.thirdfaceverify.ThirdFindFaceVerifyReqVo; +import cn.iocoder.yudao.module.member.client.vo.thirdfaceverify.ThirdFindFaceVerifyResVo; import cn.iocoder.yudao.module.member.client.vo.thirdfaceverify.ThirdFaceVerifyReqVO; import cn.iocoder.yudao.module.member.client.vo.thirdfaceverify.ThirdFaceVerifyResVO; import cn.iocoder.yudao.module.member.framework.web.config.ThirdAlConfig; -import com.aliyun.cloudauth20190307.models.InitFaceVerifyRequest; -import com.aliyun.cloudauth20190307.models.InitFaceVerifyResponse; +import com.aliyun.cloudauth20190307.models.*; import com.aliyun.cloudauth20190307.Client; -import com.aliyun.cloudauth20190307.models.InitFaceVerifyResponseBody; import com.aliyun.teaopenapi.models.Config; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; @@ -31,13 +32,15 @@ public class ThirdFaceVerifyServiceImpl implements ThirdFaceVerifyService { private static final com.aliyun.credentials.Client credentialClient = new com.aliyun.credentials.Client(); + private static final List endpoints = Arrays.asList("cloudauth.cn-shanghai.aliyuncs.com", "cloudauth.cn-beijing.aliyuncs.com"); + /** * 人脸识别 */ @Override public ThirdFaceVerifyResVO faceVerify(ThirdFaceVerifyReqVO dto) { InitFaceVerifyRequest request = new InitFaceVerifyRequest(); - request.setSceneId(1000016045L); + request.setSceneId(thirdAlConfig.getFaceSceneId()); request.setProductCode("PV_FV"); request.setModel("MOVE_ACTION"); // 参数 @@ -63,16 +66,7 @@ public class ThirdFaceVerifyServiceImpl implements ThirdFaceVerifyService { return result; } - /** - * 人脸识别回调 - */ - @Override - public String callback(String code) { - return ""; - } - private InitFaceVerifyResponse initFaceVerifyAutoRoute(InitFaceVerifyRequest request) { - List endpoints = Arrays.asList("cloudauth.cn-shanghai.aliyuncs.com", "cloudauth.cn-beijing.aliyuncs.com"); InitFaceVerifyResponse lastResponse = null; for (String endpoint : endpoints) { try { @@ -106,4 +100,64 @@ public class ThirdFaceVerifyServiceImpl implements ThirdFaceVerifyService { runtime.connectTimeout = 10_000; return client.initFaceVerifyWithOptions(request, runtime); } + + + /** + * 查询人脸识别 + */ + @Override + public ThirdFindFaceVerifyResVo findFaceVerify(ThirdFindFaceVerifyReqVo code) { + DescribeFaceVerifyRequest request = new DescribeFaceVerifyRequest(); + request.setSceneId(thirdAlConfig.getFaceSceneId()); + request.setCertifyId(code.getCertifyId()); + DescribeFaceVerifyResponse response = describeFaceVerifyAutoRoute(request); + if (ObjectUtil.isEmpty(response)) { + log.error("|人脸识别|,第三方接口无响应"); + return null; + } + ThirdFindFaceVerifyResVo result = new ThirdFindFaceVerifyResVo(); + DescribeFaceVerifyResponseBody body = response.getBody(); + DescribeFaceVerifyResponseBody.DescribeFaceVerifyResponseBodyResultObject resultObject = body.getResultObject(); + BeanUtil.toBean(resultObject, ThirdFindFaceVerifyResVo.class); + return result; + } + + private DescribeFaceVerifyResponse describeFaceVerifyAutoRoute(DescribeFaceVerifyRequest request) { + DescribeFaceVerifyResponse lastResponse = null; + for (int i = 0; i < endpoints.size(); i++) { + try { + lastResponse = describeFaceVerify(endpoints.get(i), request); + if (ObjectUtil.isEmpty(lastResponse)) return null; + if (ObjectUtil.equals(lastResponse.getStatusCode(), 500)) { + continue; + } + DescribeFaceVerifyResponseBody body = lastResponse.getBody(); + if (ObjectUtil.equals(body.getCode(), "500")) { + continue; + } + return lastResponse; + } catch (Exception e) { + e.printStackTrace(); + if (i == endpoints.size() - 1) { + throw new RuntimeException(e); + } + } + } + return lastResponse; + } + + private DescribeFaceVerifyResponse describeFaceVerify(String endpoint, DescribeFaceVerifyRequest request) throws Exception { + Config config = new Config(); + config.setCredential(credentialClient); + config.setEndpoint(endpoint); + config.setAccessKeyId(thirdAlConfig.getAccessKeyId()); + config.setAccessKeySecret(thirdAlConfig.getAccessKeySecret()); + Client client = new Client(config); + RuntimeOptions runtime = new RuntimeOptions(); + runtime.readTimeout = 10_000; + runtime.connectTimeout = 10_000; + return client.describeFaceVerifyWithOptions(request, runtime); + } + + } diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/client/vo/thirdfaceverify/ThirdFaceVerifyResVO.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/client/vo/thirdfaceverify/ThirdFaceVerifyResVO.java index e60a99f..6130d84 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/client/vo/thirdfaceverify/ThirdFaceVerifyResVO.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/client/vo/thirdfaceverify/ThirdFaceVerifyResVO.java @@ -1,5 +1,6 @@ package cn.iocoder.yudao.module.member.client.vo.thirdfaceverify; +import cn.hutool.core.util.ObjectUtil; import lombok.Data; /** @@ -12,4 +13,12 @@ public class ThirdFaceVerifyResVO { private String certifyUrl; + public boolean isPass() { + return ObjectUtil.isAllNotEmpty(certifyId, certifyUrl); + } + + public boolean isFail() { + return !isPass(); + } + } diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/client/vo/thirdfaceverify/ThirdFindFaceVerifyReqVo.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/client/vo/thirdfaceverify/ThirdFindFaceVerifyReqVo.java new file mode 100644 index 0000000..eeeeb12 --- /dev/null +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/client/vo/thirdfaceverify/ThirdFindFaceVerifyReqVo.java @@ -0,0 +1,21 @@ +package cn.iocoder.yudao.module.member.client.vo.thirdfaceverify; + +import lombok.Data; + +/** + * 阿里云人脸认证callback req + */ +@Data +public class ThirdFindFaceVerifyReqVo { + + /** + * 认证场景ID + */ + private Long SceneId; + + /** + * 实人认证唯一标识 + */ + private String CertifyId; + +} diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/client/vo/thirdfaceverify/ThirdFindFaceVerifyResVo.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/client/vo/thirdfaceverify/ThirdFindFaceVerifyResVo.java new file mode 100644 index 0000000..3c01f07 --- /dev/null +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/client/vo/thirdfaceverify/ThirdFindFaceVerifyResVo.java @@ -0,0 +1,54 @@ +package cn.iocoder.yudao.module.member.client.vo.thirdfaceverify; + +import cn.hutool.core.util.ObjectUtil; +import lombok.Data; + +/** + * 阿里云人脸认证callback res + */ +@Data +public class ThirdFindFaceVerifyResVo { + + /** + * 认证结果,取值 + * T:通过 + * F:不通过 + */ + private String Passed; + + /** + * 认证结果描述 + * 200:成功 + */ + private String SubCode; + + /** + * 认证的主体信息,一般的认证场景返回为空 + */ + private String IdentityInfo; + + /** + * 设备Token + */ + private String DeviceToken; + + /** + * 人脸认证主体附件信息 + */ + private String MaterialInfo; + + /** + * 验证通过 + */ + public boolean isPassed() { + return ObjectUtil.equals("T", Passed); + } + + /** + * 验证未通过 + */ + public boolean isNotPassed() { + return ObjectUtil.equals("F", Passed); + } + +} diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/comauth/vo/ComAuthPageReqVO.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/comauth/vo/ComAuthPageReqVO.java index b005a1b..9482aee 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/comauth/vo/ComAuthPageReqVO.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/comauth/vo/ComAuthPageReqVO.java @@ -4,6 +4,7 @@ import lombok.*; import io.swagger.v3.oas.annotations.media.Schema; import cn.iocoder.yudao.framework.common.pojo.PageParam; import org.springframework.format.annotation.DateTimeFormat; + import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; @@ -36,6 +37,9 @@ public class ComAuthPageReqVO extends PageParam { @Schema(description = "认证状态", example = "2") private String authStatus; + @Schema(description = "认证失败原因") + private String failReason; + @Schema(description = "创建时间") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime[] createTime; diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/comauth/vo/ComAuthRespVO.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/comauth/vo/ComAuthRespVO.java index 7fd63be..12add50 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/comauth/vo/ComAuthRespVO.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/comauth/vo/ComAuthRespVO.java @@ -4,6 +4,7 @@ import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; import java.time.LocalDateTime; + import com.alibaba.excel.annotation.*; @Schema(description = "管理后台 - 用户认证 Response VO") @@ -43,6 +44,9 @@ public class ComAuthRespVO { @ExcelProperty("认证状态") private String authStatus; + @Schema(description = "认证失败原因") + private String failReason; + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) @ExcelProperty("创建时间") private LocalDateTime createTime; diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/thirdcallback/ThirdCallbackController.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/thirdcallback/ThirdCallbackController.java new file mode 100644 index 0000000..0896587 --- /dev/null +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/thirdcallback/ThirdCallbackController.java @@ -0,0 +1,76 @@ +package cn.iocoder.yudao.module.member.controller.admin.thirdcallback; + +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.json.JSONUtil; +import cn.iocoder.yudao.module.member.client.service.ThirdFaceVerifyService; +import cn.iocoder.yudao.module.member.client.vo.thirdfaceverify.ThirdFindFaceVerifyReqVo; +import cn.iocoder.yudao.module.member.client.vo.thirdfaceverify.ThirdFindFaceVerifyResVo; +import cn.iocoder.yudao.module.member.controller.admin.thirdcallback.vo.FaceVerifyCallbackReqVo; +import cn.iocoder.yudao.module.member.dal.dataobject.comauth.ComAuthDO; +import cn.iocoder.yudao.module.member.dal.mysql.comauth.ComAuthMapper; +import cn.iocoder.yudao.module.member.enums.auth.MemberComAuthStatusEnum; +import cn.iocoder.yudao.module.member.service.comauth.ComAuthService; +import io.swagger.v3.oas.annotations.Operation; +import lombok.extern.slf4j.Slf4j; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import javax.annotation.security.PermitAll; +import java.time.LocalDateTime; + +@RestController +@RequestMapping("/third-callback") +@Validated +@Slf4j +public class ThirdCallbackController { + + @Resource + private ComAuthService comAuthService; + @Resource + private ThirdFaceVerifyService thirdFaceVerifyService; + + @Resource + private ComAuthMapper authMapper; + + @GetMapping("/face-verify") + @Operation(summary = "人脸认证回调") + @PermitAll + public void faceVerify(FaceVerifyCallbackReqVo query) { + log.info("人脸认证回调,params={}", JSONUtil.toJsonStr(query)); + if (!ObjectUtil.isAllNotEmpty(query.getCallbackToken(), query.getCertifyId(), query.getPassed())) { + log.error("人脸认证回调,参数错误"); + return; + } + Long authId = Long.valueOf(query.getCertifyId()); + // 查询认证订单 + ComAuthDO auth = comAuthService.getAuth(authId); + if (ObjectUtil.isEmpty(auth)) { + log.error("人脸认证回调,认证订单不存在,authId={}", query.getCertifyId()); + return; + } + + // 手动查询 + ThirdFindFaceVerifyReqVo dto = new ThirdFindFaceVerifyReqVo(); + dto.setCertifyId(query.getCertifyId()); + ThirdFindFaceVerifyResVo faceVerifyRes = thirdFaceVerifyService.findFaceVerify(dto); + if (ObjectUtil.isEmpty(faceVerifyRes)) { + log.error("人脸认证回调,主动查询,第三方接口无响应"); + return; + } + ComAuthDO updateObj = new ComAuthDO(); + if (faceVerifyRes.isPassed()) { + updateObj.setAuthStatus(MemberComAuthStatusEnum.CHECK_PASS.getType()); + } + if (faceVerifyRes.isNotPassed()) { + updateObj.setAuthStatus(MemberComAuthStatusEnum.CHECK_FAIL.getType()); + } + updateObj.setId(authId); + updateObj.setAuthTime(LocalDateTime.now()); + updateObj.setFailReason("验证失败"); + authMapper.updateById(updateObj); + } + +} diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/thirdcallback/vo/FaceVerifyCallbackReqVo.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/thirdcallback/vo/FaceVerifyCallbackReqVo.java new file mode 100644 index 0000000..b538b0e --- /dev/null +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/thirdcallback/vo/FaceVerifyCallbackReqVo.java @@ -0,0 +1,27 @@ +package cn.iocoder.yudao.module.member.controller.admin.thirdcallback.vo; + +import lombok.Data; + +/** + * 人脸认证回调req + */ +@Data +public class FaceVerifyCallbackReqVo { + + /** + * 回调token + */ + private String callbackToken; + + /** + * 认证订单code(唯一) + */ + private String certifyId; + + /** + * 是否通过 + * 200通过 + */ + private String passed; + +} diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/comauth/AppComAuthController.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/comauth/AppComAuthController.java index 92bae82..f4950e3 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/comauth/AppComAuthController.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/comauth/AppComAuthController.java @@ -1,7 +1,9 @@ package cn.iocoder.yudao.module.member.controller.app.comauth; import cn.iocoder.yudao.framework.common.pojo.CommonResult; -import cn.iocoder.yudao.module.member.controller.app.comauth.vo.CreateMemberUserAuthReqVo; +import cn.iocoder.yudao.module.member.controller.admin.comauth.vo.ComAuthSaveReqVO; +import cn.iocoder.yudao.module.member.controller.app.comauth.vo.CreateManAuthReqVo; +import cn.iocoder.yudao.module.member.controller.app.comauth.vo.CreateWomanAuthReqVo; import cn.iocoder.yudao.module.member.dal.dataobject.comauth.ComAuthDO; import cn.iocoder.yudao.module.member.service.comauth.ComAuthService; import io.swagger.v3.oas.annotations.Operation; @@ -13,6 +15,7 @@ import javax.annotation.Resource; import javax.validation.Valid; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; +import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; @Tag(name = "用户 App - 用户认证") @RestController @@ -23,16 +26,31 @@ public class AppComAuthController { @Resource private ComAuthService comAuthService; - @PostMapping("/create") - @Operation(summary = "创建用户真实性认证") - public CommonResult createMemberUserAuth(@Valid @RequestBody CreateMemberUserAuthReqVo dto) { - return success(comAuthService.createMemberUserAuth(dto)); + @PostMapping("/create-man-auth") + @Operation(summary = "创建男性认证") + public CommonResult createManAuth(@Valid @RequestBody CreateManAuthReqVo dto) { + dto.setMemberId(getLoginUserId()); + return success(comAuthService.createManAuth(dto)); } - @PostMapping("/get") - @Operation(summary = "创建用户真实性认证") - public CommonResult getMemberUserAuth(@RequestParam("id") Long id) { - return success(comAuthService.getAuth(id)); + @PostMapping("/create-woman-auth") + @Operation(summary = "创建女性认证") + public CommonResult createWomanAuth(@Valid @RequestBody CreateWomanAuthReqVo dto) { + dto.setMemberId(getLoginUserId()); + return success(comAuthService.createWomanAuth(dto)); + } + + @PutMapping("/update") + @Operation(summary = "更新用户认证") + public CommonResult updateAuth(@Valid @RequestBody ComAuthSaveReqVO updateReqVO) { + comAuthService.updateAuth(updateReqVO); + return success(true); + } + + @GetMapping("/get") + @Operation(summary = "查询用户认证") + public CommonResult getMemberUserAuth() { + return success(comAuthService.getUserAuth(getLoginUserId())); } } diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/comauth/vo/CreateManAuthReqVo.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/comauth/vo/CreateManAuthReqVo.java new file mode 100644 index 0000000..eafe9b3 --- /dev/null +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/comauth/vo/CreateManAuthReqVo.java @@ -0,0 +1,25 @@ +package cn.iocoder.yudao.module.member.controller.app.comauth.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import javax.validation.constraints.NotNull; + +/** + * 男性认证创建 Request VO + */ +@Data +public class CreateManAuthReqVo { + + @Schema(description = "会员编号") + private Long memberId; + + @Schema(description = "认证图片或视频") + @NotNull(message = "认证图片或视频不能为空") + private String authPic; + + @Schema(description = "metaInfoJson") + @NotNull(message = "metaInfoJson不能为空") + private String metaInfoJson; + +} diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/comauth/vo/CreateMemberUserAuthReqVo.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/comauth/vo/CreateWomanAuthReqVo.java similarity index 81% rename from yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/comauth/vo/CreateMemberUserAuthReqVo.java rename to yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/comauth/vo/CreateWomanAuthReqVo.java index 6cddbde..7a0b327 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/comauth/vo/CreateMemberUserAuthReqVo.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/comauth/vo/CreateWomanAuthReqVo.java @@ -5,8 +5,11 @@ import lombok.Data; import javax.validation.constraints.NotNull; +/** + * 女性认证创建 Request VO + */ @Data -public class CreateMemberUserAuthReqVo { +public class CreateWomanAuthReqVo { @Schema(description = "会员编号") private Long memberId; @@ -33,7 +36,11 @@ public class CreateMemberUserAuthReqVo { @Schema(description = "认证图片或视频") @NotNull(message = "认证图片或视频不能为空") - private Long authPic; + private String authPic; + + @Schema(description = "MetaInfo") + @NotNull(message = "MetaInfo不能为空") + private String metaInfoJson; } diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/dataobject/comauth/ComAuthDO.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/dataobject/comauth/ComAuthDO.java index 6614d62..d4f754e 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/dataobject/comauth/ComAuthDO.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/dataobject/comauth/ComAuthDO.java @@ -41,7 +41,7 @@ public class ComAuthDO extends BaseDO { /** * 认证图片或视频 */ - private Long authPic; + private String authPic; /** * 认证额外信息(json) @@ -64,10 +64,28 @@ public class ComAuthDO extends BaseDO { private String authStatus; /** - * 用户真实性认证额外信息(json) + * 认证失败原因 + */ + private String failReason; + + /** + * 男性用户真实性认证额外信息(json) */ @Data - public static class MemberInfoAuthExtra { + public static class ManInfoAuthExtra { + + /** + * MetaInfo环境参数,客户端传入 + */ + private String metaInfoJson; + + } + + /** + * 女性用户真实性认证额外信息(json) + */ + @Data + public static class WomanInfoAuthExtra { /** * 身高(cm) @@ -94,6 +112,11 @@ public class ComAuthDO extends BaseDO { */ private String memberDesc; + /** + * MetaInfo环境参数,客户端传入 + */ + private String metaInfoJson; + } } \ No newline at end of file diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/framework/web/config/ThirdAlConfig.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/framework/web/config/ThirdAlConfig.java index e668c6f..e14ef50 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/framework/web/config/ThirdAlConfig.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/framework/web/config/ThirdAlConfig.java @@ -22,6 +22,11 @@ public class ThirdAlConfig { */ private String accessKeySecret; + /** + * 阿里云人脸识别场景ID + */ + private Long faceSceneId; + /** * 阿里云人脸识别回调地址 */ diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/comauth/ComAuthService.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/comauth/ComAuthService.java index 2c7c88a..77c41cc 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/comauth/ComAuthService.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/comauth/ComAuthService.java @@ -5,7 +5,8 @@ import javax.validation.*; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.member.controller.admin.comauth.vo.ComAuthPageReqVO; import cn.iocoder.yudao.module.member.controller.admin.comauth.vo.ComAuthSaveReqVO; -import cn.iocoder.yudao.module.member.controller.app.comauth.vo.CreateMemberUserAuthReqVo; +import cn.iocoder.yudao.module.member.controller.app.comauth.vo.CreateManAuthReqVo; +import cn.iocoder.yudao.module.member.controller.app.comauth.vo.CreateWomanAuthReqVo; import cn.iocoder.yudao.module.member.dal.dataobject.comauth.ComAuthDO; /** @@ -19,9 +20,14 @@ public interface ComAuthService { Long createAuth(@Valid ComAuthSaveReqVO createReqVO); /** - * 创建用户真实性认证 + * 创建男性认证 */ - Long createMemberUserAuth(@Valid CreateMemberUserAuthReqVo dto); + Long createManAuth(@Valid CreateManAuthReqVo dto); + + /** + * 创建女性认证 + */ + Long createWomanAuth(@Valid CreateWomanAuthReqVo dto); /** * 更新用户认证 @@ -38,6 +44,11 @@ public interface ComAuthService { */ ComAuthDO getAuth(Long id); + /** + * 获取当前用户认证信息 + */ + ComAuthDO getUserAuth(Long userId); + /** * 获得用户认证分页 */ diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/comauth/ComAuthServiceImpl.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/comauth/ComAuthServiceImpl.java index 564ffd8..ef9ae0c 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/comauth/ComAuthServiceImpl.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/comauth/ComAuthServiceImpl.java @@ -1,17 +1,28 @@ package cn.iocoder.yudao.module.member.service.comauth; +import cn.hutool.core.util.ObjectUtil; import cn.hutool.json.JSONUtil; +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; +import cn.iocoder.yudao.module.member.client.service.ThirdFaceVerifyService; +import cn.iocoder.yudao.module.member.client.vo.thirdfaceverify.ThirdFaceVerifyReqVO; +import cn.iocoder.yudao.module.member.client.vo.thirdfaceverify.ThirdFaceVerifyResVO; import cn.iocoder.yudao.module.member.controller.admin.comauth.vo.ComAuthPageReqVO; import cn.iocoder.yudao.module.member.controller.admin.comauth.vo.ComAuthSaveReqVO; -import cn.iocoder.yudao.module.member.controller.app.comauth.vo.CreateMemberUserAuthReqVo; +import cn.iocoder.yudao.module.member.controller.app.comauth.vo.CreateManAuthReqVo; +import cn.iocoder.yudao.module.member.controller.app.comauth.vo.CreateWomanAuthReqVo; import cn.iocoder.yudao.module.member.dal.dataobject.comauth.ComAuthDO; +import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO; import cn.iocoder.yudao.module.member.dal.mysql.comauth.ComAuthMapper; -import cn.iocoder.yudao.module.member.enums.MemberComAuthEnum; +import cn.iocoder.yudao.module.member.enums.auth.MemberComAuthEnum; import cn.iocoder.yudao.module.member.enums.MemberErrorCode; +import cn.iocoder.yudao.module.member.enums.auth.MemberComAuthStatusEnum; +import cn.iocoder.yudao.module.member.service.user.MemberUserService; +import cn.iocoder.yudao.module.system.enums.common.SexEnum; import org.springframework.stereotype.Service; import javax.annotation.Resource; +import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; @@ -23,8 +34,6 @@ import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionU /** * 用户认证 Service 实现类 - * - * @author 聊天交友 */ @Service @Validated @@ -33,6 +42,11 @@ public class ComAuthServiceImpl implements ComAuthService { @Resource private ComAuthMapper authMapper; + @Resource + private MemberUserService memberUserService; + @Resource + private ThirdFaceVerifyService thirdFaceVerifyService; + /** * 创建用户认证 */ @@ -46,27 +60,80 @@ public class ComAuthServiceImpl implements ComAuthService { } /** - * 创建用户真实性认证 + * 创建男性认证 */ @Override - public Long createMemberUserAuth(CreateMemberUserAuthReqVo dto) { + @Transactional(rollbackFor = Exception.class) + public Long createManAuth(CreateManAuthReqVo dto) { + // 新增 + ComAuthDO saveObj = new ComAuthDO(); + saveObj.setBizId(dto.getMemberId()); + saveObj.setBizType(MemberComAuthEnum.MAN_MEMBER_TRUE.getType()); + saveObj.setAuthStatus("WAITING"); + saveObj.setAuthStatus(MemberComAuthStatusEnum.WAIT_AUTH.getType()); + saveObj.setAuthPic(dto.getAuthPic()); + authMapper.insert(saveObj); // 额外信息 - ComAuthDO.MemberInfoAuthExtra memberInfoAuthExtra = new ComAuthDO.MemberInfoAuthExtra(); + ComAuthDO.ManInfoAuthExtra memberInfoAuthExtra = new ComAuthDO.ManInfoAuthExtra(); + memberInfoAuthExtra.setMetaInfoJson(dto.getMetaInfoJson()); + // 更新auth + String authExtraJson = JSONUtil.toJsonStr(memberInfoAuthExtra); + ComAuthDO updateObj = new ComAuthDO(); + updateObj.setId(saveObj.getId()); + updateObj.setAuthExtraJson(authExtraJson); + authMapper.updateById(updateObj); + // 发起认证 + startAuth(saveObj, authExtraJson); + return saveObj.getId(); + } + + /** + * 创建女性认证 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public Long createWomanAuth(CreateWomanAuthReqVo dto) { + // 新增auth + ComAuthDO saveObj = new ComAuthDO(); + saveObj.setBizId(dto.getMemberId()); + saveObj.setBizType(MemberComAuthEnum.WOMAN_MEMBER_TRUE.getType()); + saveObj.setAuthStatus(MemberComAuthStatusEnum.WAIT_AUTH.getType()); + saveObj.setAuthPic(dto.getAuthPic()); + authMapper.insert(saveObj); + // 额外信息 + ComAuthDO.WomanInfoAuthExtra memberInfoAuthExtra = new ComAuthDO.WomanInfoAuthExtra(); memberInfoAuthExtra.setMemberHeight(dto.getMemberHeight()); memberInfoAuthExtra.setMemberWeight(dto.getMemberWeight()); memberInfoAuthExtra.setMemberWechatNumber(dto.getMemberWechatNumber()); memberInfoAuthExtra.setMemberOcc(dto.getMemberOcc()); memberInfoAuthExtra.setMemberDesc(dto.getMemberDesc()); - // 新增 - ComAuthDO saveObj = new ComAuthDO(); - saveObj.setBizId(dto.getMemberId()); - saveObj.setBizType(MemberComAuthEnum.MEMBER_TRUE.getType()); - saveObj.setAuthExtraJson(JSONUtil.toJsonStr(memberInfoAuthExtra)); - saveObj.setAuthPic(dto.getAuthPic()); - authMapper.insert(saveObj); + memberInfoAuthExtra.setMetaInfoJson(dto.getMetaInfoJson()); + // 更新auth + String authExtraJson = JSONUtil.toJsonStr(memberInfoAuthExtra); + ComAuthDO updateObj = new ComAuthDO(); + updateObj.setId(saveObj.getId()); + updateObj.setAuthExtraJson(authExtraJson); + authMapper.updateById(updateObj); + // 发起认证 + startAuth(saveObj, authExtraJson); return saveObj.getId(); } + /** + * 发起认证 + */ + public void startAuth(ComAuthDO auth, String metaInfoJson) { + ThirdFaceVerifyReqVO dto = new ThirdFaceVerifyReqVO(); + dto.setCode(String.valueOf(auth.getId())); + dto.setMetaInfoJson(metaInfoJson); + dto.setFaceVerifyUrl(auth.getAuthPic()); + dto.setFaceVerifyUserId(auth.getAuthMemberId()); + ThirdFaceVerifyResVO thirdRes = thirdFaceVerifyService.faceVerify(dto); + if (ObjectUtil.isEmpty(thirdRes) || thirdRes.isFail()) { + throw exception(MemberErrorCode.THIRD_AUTH_START_ERROR); + } + } + /** * 更新用户认证 */ @@ -98,6 +165,20 @@ public class ComAuthServiceImpl implements ComAuthService { return authMapper.selectById(id); } + /** + * 获取当前用户认证信息 + */ + @Override + public ComAuthDO getUserAuth(Long userId) { + // 查询当前用户 + MemberUserDO user = memberUserService.getUser(userId); + if (ObjectUtil.isEmpty(user)) throw exception(MemberErrorCode.USER_NOT_EXISTS); + return authMapper.selectOne(new LambdaQueryWrapperX() + .eq(ComAuthDO::getAuthMemberId, userId) + .ne(ComAuthDO::getAuthStatus, MemberComAuthStatusEnum.WAIT_AUTH.getType()) + ); + } + /** * 获得用户认证分页 */ diff --git a/yudao-server/src/main/resources/application-dev.yaml b/yudao-server/src/main/resources/application-dev.yaml index 4120e94..8fa4d60 100644 --- a/yudao-server/src/main/resources/application-dev.yaml +++ b/yudao-server/src/main/resources/application-dev.yaml @@ -241,5 +241,6 @@ tx-map: al-config: access-key-id: LTAI5tJ7sSxB96XaY9T3Vq3D access-key-secret: EVXWFTS2SB6UkjUVFLhTDBfIvIXgI3 + face-scene-id: 1000016045 face-verify-callback-url: https://rj4jv5rwqs.by.takin.cc face-verify-callback-token: uVuYOzoiQBWPp4A5kPgTddZlKWoSQlzc \ No newline at end of file diff --git a/yudao-server/src/main/resources/application-local.yaml b/yudao-server/src/main/resources/application-local.yaml index 425ca8c..595ee00 100644 --- a/yudao-server/src/main/resources/application-local.yaml +++ b/yudao-server/src/main/resources/application-local.yaml @@ -263,5 +263,6 @@ tx-map: al-config: access-key-id: LTAI5tJ7sSxB96XaY9T3Vq3D access-key-secret: EVXWFTS2SB6UkjUVFLhTDBfIvIXgI3 + face-scene-id: 1000016045 face-verify-callback-url: https://rj4jv5rwqs.by.takin.cc face-verify-callback-token: uVuYOzoiQBWPp4A5kPgTddZlKWoSQlzc \ No newline at end of file diff --git a/yudao-server/src/main/resources/application-prod.yaml b/yudao-server/src/main/resources/application-prod.yaml index f73e2f0..886150e 100644 --- a/yudao-server/src/main/resources/application-prod.yaml +++ b/yudao-server/src/main/resources/application-prod.yaml @@ -253,5 +253,6 @@ tx-map: al-config: access-key-id: LTAI5tJ7sSxB96XaY9T3Vq3D access-key-secret: EVXWFTS2SB6UkjUVFLhTDBfIvIXgI3 + face-scene-id: 1000016045 face-verify-callback-url: https://rj4jv5rwqs.by.takin.cc face-verify-callback-token: uVuYOzoiQBWPp4A5kPgTddZlKWoSQlzc \ No newline at end of file