新增实名认证

This commit is contained in:
liaozetao
2024-01-10 16:58:07 +08:00
parent 968ab0b8d2
commit 1517ce9e31
22 changed files with 1216 additions and 453 deletions

View File

@@ -332,7 +332,7 @@ public enum BusiStatus implements BusiStatusInterface {
QUEUE_MODEL_CLOSED(1505, "排麥模式已關閉"),
NEED_CERTIFICATION(10108, "為了保護財產安全,請先進行實名認證"),
ID_CARD_BIND_LIMIT(10109, "您的身份證綁定的賬號過多"),
ID_CARD_BIND_LIMIT(10109, "该身份信息已超过最大认证次数"),
USER_HAS_BIND_ID(10110, "該用戶已經進行了身份認證"),
WITHDRAW_NEED_CERTIFICATION(10111, "提現金額過大,需要進行身份認證"),
MODIFY_BIND_TIMES_LIMITS(10112, "修改實名信息的次數超過限制"),

View File

@@ -8,26 +8,26 @@ import javax.servlet.http.HttpServletRequest;
public class IPUtils {
public static String getRealIpAddress(HttpServletRequest request) {
String ip = request.getHeader("x-forwarded-for");
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_CLIENT_IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_X_FORWARDED_FOR");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}
if (ip != null) {
String[] arr = ip.split(",");
ip = arr[0].trim();
arr = ip.split(":");
if(arr.length > 4){
if (arr.length > 4) {
ip = "127.0.0.1";
}
}

View File

@@ -0,0 +1,44 @@
package com.accompany.common.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/**
* @author: liaozetao
* @date: 2024/1/10 11:29
* @description:
*/
@Component
@ConfigurationProperties(prefix = "aliyun.financial-face")
public class AliYunFinancialFaceConfig {
public static String accessKeyId;
public static String accessKeySecret;
public static String endpoints;
public static Long sceneId;
public static String callbackUrl;
public static void setAccessKeyId(String accessKeyId) {
AliYunFinancialFaceConfig.accessKeyId = accessKeyId;
}
public static void setAccessKeySecret(String accessKeySecret) {
AliYunFinancialFaceConfig.accessKeySecret = accessKeySecret;
}
public static void setEndpoints(String endpoints) {
AliYunFinancialFaceConfig.endpoints = endpoints;
}
public static void setSceneId(Long sceneId) {
AliYunFinancialFaceConfig.sceneId = sceneId;
}
public static void setCallbackUrl(String callbackUrl) {
AliYunFinancialFaceConfig.callbackUrl = callbackUrl;
}
}

View File

@@ -0,0 +1,46 @@
package com.accompany.common.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/**
* @author: liaozetao
* @date: 2024/1/10 10:02
* @description:
*/
@Component
@ConfigurationProperties(prefix = "yi-dun-cert")
public class YiDunCertConfig {
/**
* 密钥
*/
public static String secretId;
/**
* 密钥key
*/
public static String secretKey;
/**
* 人脸核身
*/
public static String businessId;
/**
* 人脸核身
*/
public static String auditUrl = "https://verify.dun.163.com/v1/liveperson/audit";
public static void setSecretId(String secretId) {
YiDunCertConfig.secretId = secretId;
}
public static void setSecretKey(String secretKey) {
YiDunCertConfig.secretKey = secretKey;
}
public static void setBusinessId(String businessId) {
YiDunCertConfig.businessId = businessId;
}
}

View File

@@ -1982,6 +1982,10 @@ public class Constant {
*/
public static final String WITHDRAW_UPDATE_NUM = "withdraw_update_num";
/**
* 实名认证次数
*/
public static final String CERTIFICATION_COUNT = "certification_count";
}
public static class ActiveMq {
@@ -3481,9 +3485,9 @@ public class Constant {
public static final Long USER_CERTIFICATION_GOLD = 20000L;
/**
* 一个身份证号只能绑定个账号
* 一个身份证号只能绑定个账号
**/
public static final Integer ID_CARD_BIND_USER_LIMIT = 5;
public static final Integer ID_CARD_BIND_USER_LIMIT = 2;
// public static final String APP_KEY = PropertyUtil.getProperty("cert_app_key");
//
// public static final String APP_SECRET = PropertyUtil.getProperty("cert_app_secret");

View File

@@ -385,6 +385,9 @@ public enum RedisKey {
//身份证绑定的账号数
id_card_bind_user_count,
certify_user_count,
user_certify,
sms_user_certify_count,

View File

@@ -0,0 +1,16 @@
package com.accompany.business.dto.certification;
import lombok.AllArgsConstructor;
import lombok.Data;
import java.io.Serializable;
@Data
@AllArgsConstructor
public class CertifyInfo implements Serializable {
/**
* 认证URL
*/
private String certifyUrl;
}

View File

@@ -0,0 +1,37 @@
package com.accompany.business.dto.certification;
import lombok.Data;
@Data
public class FacialPictureFront {
/**
* @Desc 人脸攻击分
*/
private String faceAttackScore;
/**
* @Desc 活体人脸质量分数
*/
private String qualityScore;
/**
* @Desc 人脸比对分数
*/
private String verifyScore;
/**
* @Desc 照片https地址有效期15分钟从查询时开始计时
*/
private String pictureUrl;
/**
* @Desc 照片存放客户上海区域的OSS里此为照片的bucket名
*/
private String ossBucketName;
/**
* @Desc 照片存放客户上海区域的OSS里此为照片的文件名
*/
private String ossObjectName;
}

View File

@@ -0,0 +1,22 @@
package com.accompany.business.dto.certification;
import lombok.Data;
@Data
public class FinancialResult {
/**
* @Desc 是否为攻击攻击为T非攻击为F。
*/
private String faceAttack;
/**
* @Desc 是否有脸部遮挡有脸部遮挡为T否则为F。
*/
private String faceOcclusion;
/**
* @Desc 认证的照片信息
*/
private FacialPictureFront facialPictureFront;
}

View File

@@ -0,0 +1,70 @@
package com.accompany.business.dto.yidun;
import lombok.Data;
import java.util.List;
/**
* @author: liaozetao
* @date: 2024/1/10 10:42
* @description:
*/
@Data
public class YiDunLivePersonResponseDto extends YiDunResultDto {
/**
* 最终结果1-通过(活体+姓名身份证号+人脸比对全部通过) 2-不通过原因见reasonType0-待定
*/
private Integer status;
/**
* 权威数据源人脸比对是否通过1-通过 2-不通过 0-待定
*/
private Integer faceMatched;
/**
* 权威数据源人脸照与身份证头像的相似度得分,未检测为-1正常检测取值范围为0-1相似度越高分值越大。默认判断阈值为0.851faceMatched字段采用此阈值可自定义该阀值
*/
private Integer similarityScore;
/**
* 原因详情
* 2-活体通过,姓名身份证号一致,人脸比对非同一人
* 3-活体通过,姓名身份证号不一致
* 4-活体不通过
* 5-活体检测超时或出现异常
* 6-活体通过,查无此身份证
* 7-活体通过,库中无此身份证照片
* 8-活体通过,人脸照过大
* 9-活体通过,权威数据源出现异常
* 10-疑似攻击,建议拦截
* 11-检测对象为未成年人
*/
private Integer reasonType;
/**
* 本次请求数据标识,可以根据该标识查询数据最新结果
*/
private String taskId;
/**
* 正面照图片类型1-URL2-BASE64
*/
private Integer picType;
/**
* 活体检测抓取的头像正面照,请在72小时内下载存储超期失效
*/
private String avatar;
/**
* 活体检测抓取的动作照。仅支持客户端SDK 2.2.1及以上版本返回。请在72小时内下载存储超期失效
*/
private List<String> actionImages;
/**
* 本次请求是否收费标识1代表收费0代表不收费
*/
private Integer isPayed;
}

View File

@@ -0,0 +1,22 @@
package com.accompany.business.dto.yidun;
import lombok.Data;
/**
* @author: liaozetao
* @date: 2024/1/10 11:02
* @description:
*/
@Data
public class YiDunResultDto {
/**
* 响应码
*/
private Integer code;
/**
* 响应体
*/
private String msg;
}

View File

@@ -94,6 +94,12 @@
</exclusion>
</exclusions>
</dependency>
<!-- 金融级实人认证 -->
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>cloudauth20190307</artifactId>
<version>${cloudauth20190307.version}</version>
</dependency>
</dependencies>
</project>

View File

@@ -1,156 +1,231 @@
package com.accompany.business.service.certification;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.accompany.business.constant.withdraw.WithdrawAccountTypeConstant;
import com.accompany.business.model.UserCertifyRecord;
import com.accompany.business.model.UserCertifyRecordExample;
import com.accompany.business.model.withdraw.WithdrawUser;
import com.accompany.business.model.withdraw.WithdrawUserAccount;
import com.accompany.business.mybatismapper.UserCertifyRecordMapper;
import com.accompany.business.mybatismapper.withdraw.WithdrawUserAccountMapper;
import com.accompany.business.service.user.UsersService;
import com.accompany.common.constant.AppEnum;
import com.accompany.common.constant.Constant;
import com.accompany.common.constant.SmsTypeEnum;
import com.accompany.common.device.DeviceInfo;
import com.accompany.common.exception.ApiException;
import com.accompany.common.redis.RedisKey;
import com.accompany.common.status.BusiStatus;
import com.accompany.common.utils.DateTimeUtil;
import com.accompany.common.utils.GetTimeUtils;
import com.accompany.common.utils.IPUtils;
import com.accompany.core.exception.ServiceException;
import com.accompany.core.model.Users;
import com.accompany.core.mybatismapper.AccountLoginRecordMapper;
import com.accompany.core.mybatismapper.UsersMapper;
import com.accompany.core.service.base.BaseService;
import com.accompany.core.service.SysConfService;
import com.accompany.core.service.common.JedisService;
import com.accompany.core.util.StringUtils;
import com.accompany.sms.service.SmsService;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.UUID;
;
@Slf4j
public abstract class AbstractCertifyService {
public abstract class AbstractCertifyService extends BaseService {
@Autowired
protected UserCertifyRecordMapper userCertifyRecordMapper;
@Autowired
private AccountLoginRecordMapper accountLoginRecordMapper;
@Autowired
private WithdrawUserAccountMapper withdrawUserAccountMapper;
@Autowired
protected SmsService smsService;
@Autowired
protected UserCertifyRecordMapper userCertifyRecordMapper;
@Autowired
private AccountLoginRecordMapper accountLoginRecordMapper;
@Autowired
protected UsersMapper usersMapper;
@Autowired
protected UsersService usersService;
protected UsersService usersService;
/**
* 发送短信验证码
* @param phone
* @param uid
* @param ip
* @param deviceInfo
* @throws Exception
*/
public void sendCertificationCode(String phone, Long uid, String ip, DeviceInfo deviceInfo) throws Exception {
if (deviceInfo == null || StringUtils.isBlank(deviceInfo.getDeviceId())) {
String app = deviceInfo != null?deviceInfo.getApp(): "";
deviceInfo = new DeviceInfo();
deviceInfo.setDeviceId(getDeviceId(uid));
deviceInfo.setApp(app);
}
// 用户未传入手机号,或手机号中含有*,则去用户信息中查实际的手机号
if(StringUtils.isBlank(phone) || phone.contains("*")) {
Users users = usersService.getUsersByUid(uid);
phone = users.getPhone();
}
@Autowired
protected SmsService smsService;
//判断用户是否超出限额(一个用户身份认证一天只能发十次验证码)
String userLimit = jedisService.hget(RedisKey.sms_user_certify_count.getKey(), uid.toString());
if (StringUtils.isNotBlank(userLimit) && Integer.parseInt(userLimit) > Constant.USER_CERTIFY_LIMIT_TIMES) {
throw new ServiceException(BusiStatus.SMS_DEVICE_LIMIT);
}
smsService.sendSmsCode(phone, SmsTypeEnum.CERTIFICATION.value,deviceInfo,ip, null);
}
@Autowired
protected JedisService jedisService;
protected String getDeviceId(Long uid) {
return accountLoginRecordMapper.getLastDeviceId(uid);
}
@Autowired
protected SysConfService sysConfService;
/**
* 增加用户发送验证码次数
* @param uid
*/
public void increaseUserCount(String uid) {
String key = RedisKey.sms_user_certify_count.getKey();
long expireTime = GetTimeUtils.getTimesnight(24).getTime() / 1000 - 1;
jedisService.hincr(key,uid);
jedisService.expireAt(key, expireTime);
}
/**
* 发送短信验证码
*
* @param phone
* @param uid
* @param ip
* @param deviceInfo
*/
public void sendCertificationCode(String phone, Long uid, String ip, DeviceInfo deviceInfo) {
if (deviceInfo == null || StringUtils.isBlank(deviceInfo.getDeviceId())) {
String app = deviceInfo != null ? deviceInfo.getApp() : "";
deviceInfo = new DeviceInfo();
deviceInfo.setDeviceId(getDeviceId(uid));
deviceInfo.setApp(app);
}
// 用户未传入手机号,或手机号中含有*,则去用户信息中查实际的手机号
if (StringUtils.isBlank(phone) || phone.contains("*")) {
Users users = usersService.getUsersByUid(uid);
phone = users.getPhone();
}
//判断用户是否超出限额(一个用户身份认证一天只能发十次验证码)
String userLimit = jedisService.hget(RedisKey.sms_user_certify_count.getKey(), uid.toString());
if (StringUtils.isNotBlank(userLimit) && Integer.parseInt(userLimit) > Constant.USER_CERTIFY_LIMIT_TIMES) {
throw new ServiceException(BusiStatus.SMS_DEVICE_LIMIT);
}
smsService.sendSmsCode(phone, SmsTypeEnum.CERTIFICATION.value, deviceInfo, ip, null);
}
/**
* 校验请求合法性
* @param users
* @param phone
* @param code
* @param identityNumber
* @throws Exception
*/
protected void verify(Users users, String phone, String code, String identityNumber) throws Exception {
if (users == null) {
throw new ServiceException(BusiStatus.USERNOTEXISTS);
}
protected String getDeviceId(Long uid) {
return accountLoginRecordMapper.getLastDeviceId(uid);
}
//验证码验证
boolean verify = smsService.verifySmsCode(phone,code);
if (!verify) {
throw new ServiceException(BusiStatus.SMSCODEERROR);
}
/**
* 增加用户发送验证码次数
*
* @param uid
*/
public void increaseUserCount(String uid) {
String key = RedisKey.sms_user_certify_count.getKey();
long expireTime = GetTimeUtils.getTimesnight(24).getTime() / 1000 - 1;
jedisService.hincr(key, uid);
jedisService.expireAt(key, expireTime);
}
//身份证绑定账号验证
String bindAccount = jedisService.hget(RedisKey.id_card_bind_user_count.getKey(), identityNumber);
if (StringUtils.isNotBlank(bindAccount) && Integer.parseInt(bindAccount) >= Constant.usersCertification.ID_CARD_BIND_USER_LIMIT) {
throw new ServiceException(BusiStatus.ID_CARD_BIND_LIMIT);
}
protected void verify(Long uid, String phone, String code, String username, String identityNumber) {
List<WithdrawUserAccount> withdrawUserAccounts = withdrawUserAccountMapper.selectList(Wrappers.<WithdrawUserAccount>lambdaQuery()
.eq(WithdrawUserAccount::getUid, uid)
.eq(WithdrawUserAccount::getAccountType, WithdrawAccountTypeConstant.CHINA_UNION_PAY));
if (CollectionUtil.isEmpty(withdrawUserAccounts)) {
throw new ApiException("请绑定大陆银联提现账户");
}
WithdrawUserAccount withdrawUserAccount = withdrawUserAccounts.get(0);
String name = withdrawUserAccount.getName();
String idCardNo = withdrawUserAccount.getIdCardNo();
if (StrUtil.isEmpty(name) || StrUtil.isEmpty(idCardNo)) {
throw new ApiException("认证身份信息与绑定的提现账户身份信息不同");
}
if (!name.equals(username) || !idCardNo.equals(identityNumber)) {
throw new ApiException("认证身份信息与绑定的提现账户身份信息不同");
}
String userCountStr = jedisService.hget(RedisKey.certify_user_count.getKey(DateTimeUtil.convertDate(new Date(), DateTimeUtil.DEFAULT_DATE_PATTERN)), String.valueOf(uid));
int certificationCount = sysConfService.getIntValueById(Constant.SysConfId.CERTIFICATION_COUNT);
if (certificationCount == 0) {
certificationCount = 5;
}
if (StrUtil.isNotEmpty(userCountStr) && Integer.parseInt(userCountStr) >= certificationCount) {
throw new ApiException("超过当日最大认证次数,请明天再试");
}
verify(usersService.getUsersByUid(uid), phone, code, identityNumber);
}
// 2020-03-04 实名认证修改次数超过限制,实名认证后,用户有一次修改认证信息的机会
if(users.getCertifyModifyTimes() != null && users.getCertifyModifyTimes() >= 1) {
throw new ServiceException(BusiStatus.MODIFY_BIND_TIMES_LIMITS);
}
}
/**
* 校验请求合法性
*
* @param users
* @param phone
* @param code
* @param identityNumber
* @throws Exception
*/
protected void verify(Users users, String phone, String code, String identityNumber) {
if (users == null) {
throw new ApiException(BusiStatus.USERNOTEXISTS);
}
//验证码验证
boolean verify = smsService.verifySmsCode(phone, code);
if (!verify) {
throw new ApiException(BusiStatus.SMSCODEERROR);
}
//身份证绑定账号验证
String bindAccount = jedisService.hget(RedisKey.id_card_bind_user_count.getKey(), identityNumber);
if (StrUtil.isNotEmpty(bindAccount) && Integer.parseInt(bindAccount) >= Constant.usersCertification.ID_CARD_BIND_USER_LIMIT) {
throw new ApiException(BusiStatus.ID_CARD_BIND_LIMIT);
}
// 2020-03-04 实名认证修改次数超过限制,实名认证后,用户有一次修改认证信息的机会
if (users.getCertifyModifyTimes() != null && users.getCertifyModifyTimes() >= 1) {
throw new ApiException(BusiStatus.MODIFY_BIND_TIMES_LIMITS);
}
}
/**
* 构建身份认证记录
* @param uid
* @param name
* @param identityNum
* @param phone
* @param code
* @param deviceInfo
* @param ip
* @return
*/
protected UserCertifyRecord buildUserCertifyRecord(Long uid, String name, String identityNum, String phone, String code, DeviceInfo deviceInfo, String ip) {
UserCertifyRecord userCertifyRecord = new UserCertifyRecord();
if (deviceInfo == null || StringUtils.isBlank(deviceInfo.getDeviceId())) {
deviceInfo = new DeviceInfo();
deviceInfo.setDeviceId(getDeviceId(uid));
}
userCertifyRecord.setTicket(UUID.randomUUID().toString());
userCertifyRecord.setDeviceId(deviceInfo.getDeviceId());
userCertifyRecord.setIp(ip);
userCertifyRecord.setUid(uid);
userCertifyRecord.setName(name);
userCertifyRecord.setIdCardNum(identityNum);
userCertifyRecord.setCreatetime(Calendar.getInstance().getTime());
userCertifyRecord.setPhone(phone);
userCertifyRecord.setVerifyCode(code);
return userCertifyRecord;
}
/**
* 构建身份认证记录
*
* @param uid
* @param name
* @param identityNum
* @param phone
* @param code
* @param deviceInfo
* @param ip
* @return
*/
protected UserCertifyRecord buildUserCertifyRecord(Long uid, String name, String identityNum, String phone, String code, DeviceInfo deviceInfo, String ip) {
UserCertifyRecord userCertifyRecord = new UserCertifyRecord();
if (deviceInfo == null || StringUtils.isBlank(deviceInfo.getDeviceId())) {
deviceInfo = new DeviceInfo();
deviceInfo.setDeviceId(getDeviceId(uid));
}
userCertifyRecord.setTicket(UUID.randomUUID().toString());
userCertifyRecord.setDeviceId(deviceInfo.getDeviceId());
userCertifyRecord.setIp(ip);
userCertifyRecord.setUid(uid);
userCertifyRecord.setName(name);
userCertifyRecord.setIdCardNum(identityNum);
userCertifyRecord.setCreatetime(Calendar.getInstance().getTime());
userCertifyRecord.setPhone(phone);
userCertifyRecord.setVerifyCode(code);
return userCertifyRecord;
}
/**
* 增加用户实名认证记录
*
* @param record
*/
protected void addUserCertifyRecord(UserCertifyRecord record) {
this.userCertifyRecordMapper.insert(record);
}
protected UserCertifyRecord updateUserCertifyRecord(Long uid, String token, Byte status, String qualityScore) {
UserCertifyRecord record = this.getUserCertifyRecord(uid, token);
record.setUpdateTime(Calendar.getInstance().getTime());
record.setBindStatus(status);
userCertifyRecordMapper.updateByPrimaryKeySelective(record);
return record;
}
private UserCertifyRecord getUserCertifyRecord(Long uid, String token) {
UserCertifyRecordExample example = new UserCertifyRecordExample();
example.createCriteria().andUidEqualTo(uid).andTokenEqualTo(token);
List<UserCertifyRecord> records = userCertifyRecordMapper.selectByExample(example);
if (CollectionUtil.isEmpty(records)) {
throw new ApiException(BusiStatus.NOTEXISTS);
}
return records.get(0);
}
/**
* 保存用户信息到数据库和缓存
*
* @param users
*/
protected void updateUsersInDBAndCache(Users users) {
@@ -162,6 +237,7 @@ public abstract class AbstractCertifyService extends BaseService {
/**
* 更新用户缓存
*
* @param uid
*/
protected void refreshUserCache(Long uid) {
@@ -170,4 +246,69 @@ public abstract class AbstractCertifyService extends BaseService {
jedisService.hdel(RedisKey.user_summary.getKey(), uid.toString());
}
protected String getIpAddress() {
String ipAddress = StrUtil.EMPTY;
try {
ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
if (requestAttributes != null) {
HttpServletRequest request = requestAttributes.getRequest();
ipAddress = IPUtils.getRealIpAddress(request);
}
} catch (Exception e) {
log.error(e.getMessage(), e);
}
return ipAddress;
}
public void increaseBindCount(String identityNum) {
String key = RedisKey.id_card_bind_user_count.getKey();
jedisService.hincr(key, identityNum);
}
/**
* 减少一次实名认证绑定次数
*
* @param identityNum
*/
public void decreaseBindCount(String identityNum) {
String key = RedisKey.id_card_bind_user_count.getKey();
jedisService.hincrBy(key, identityNum, -1L);
}
public void updateCertifyResult(Long uid, String certifyId, Integer certType, Byte bindStatus, boolean isSuccess) {
Users users = usersService.getUsersByUid(uid);
if (users == null) {
log.info("user is null");
return;
}
String idCardNum = users.getIdCardNum();
String realName = users.getRealName();
// 如果已经实名认证过,则不给修改
if (StringUtils.isNotBlank(idCardNum) && StringUtils.isNotBlank(realName)) {
log.info("idCardNum : {}, realName : {} is exists.", idCardNum, realName);
return;
}
UserCertifyRecord record = getUserCertifyRecord(uid, certifyId);
if (record == null) {
log.error("updateCertifyResult record is null");
return;
}
Date now = new Date();
record.setBindStatus(bindStatus);
if (certType != null) {
record.setCertifyType(String.valueOf(certType));
}
record.setUpdateTime(now);
userCertifyRecordMapper.updateByPrimaryKeySelective(record);
if (isSuccess) {
// 设置实名信息
users.setRealName(record.getName());
users.setIdCardNum(record.getIdCardNum());
users.setUpdateTime(now);
this.updateUsersInDBAndCache(users);
// 增加身份证绑定次数
this.increaseBindCount(record.getIdCardNum());
}
}
}

View File

@@ -0,0 +1,78 @@
package com.accompany.business.service.certification;
import com.accompany.business.dto.certification.CertifyInfo;
import com.accompany.business.model.UserCertifyRecord;
import com.accompany.business.service.certification.aliyun.FinancialFaceVerify;
import com.accompany.common.device.DeviceInfo;
import com.accompany.common.exception.ApiException;
import com.accompany.common.redis.RedisKey;
import com.accompany.common.utils.DESUtils;
import com.accompany.common.utils.DateTimeUtil;
import com.accompany.core.base.DeviceInfoContextHolder;
import com.accompany.core.util.KeyStore;
import com.aliyun.cloudauth20190307.models.DescribeFaceVerifyResponse;
import com.aliyun.cloudauth20190307.models.InitFaceVerifyResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Date;
/**
* @author: liaozetao
* @date: 2024/1/10 14:21
* @description:
*/
@Slf4j
@Service
public class FinancialFaceVerifyService extends AbstractCertifyService {
private static final String CERTIFY_RESULT_FOR_SUCCESS = "T";
private static final String CERTIFY_RESULT_FOR_FAILURE = "F";
@Autowired
private FinancialFaceVerify financialFaceVerify;
public CertifyInfo initFace(Long uid, String encryptUsername, String encryptIdentityNumber, String encryptPhone, String code, String metaInfo, Integer certType, String returnUrl) {
String username;
String identityNumber;
String phone;
try {
username = DESUtils.DESAndBase64Decrypt(encryptUsername, KeyStore.DES_ENCRYPT_KEY);
identityNumber = DESUtils.DESAndBase64Decrypt(encryptIdentityNumber, KeyStore.DES_ENCRYPT_KEY);
phone = DESUtils.DESAndBase64Decrypt(encryptPhone, KeyStore.DES_ENCRYPT_KEY);
} catch (Exception e) {
log.error("解密信息时出现异常", e);
throw new ApiException("解密異常");
}
DeviceInfo deviceInfo = DeviceInfoContextHolder.get();
String deviceId = deviceInfo.getDeviceId();
String ipAddress = getIpAddress();
//校验
verify(uid, phone, code, username, identityNumber);
UserCertifyRecord record = buildUserCertifyRecord(uid, username, identityNumber, phone, code, deviceInfo, ipAddress);
String ticket = record.getTicket();
InitFaceVerifyResponse.InitFaceVerifyResponseResultObject result = financialFaceVerify.initFaceVerify(ticket, username, identityNumber, returnUrl, metaInfo, phone, ipAddress, uid, certType, deviceId);
if (result == null) {
throw new ApiException("认证失败");
}
String certifyId = result.getCertifyId();
record.setToken(certifyId);
addUserCertifyRecord(record);
//验证次数加一
jedisService.hincrBy(RedisKey.certify_user_count.getKey(DateTimeUtil.convertDate(new Date(), DateTimeUtil.DEFAULT_DATE_PATTERN)), String.valueOf(uid), 1L);
return new CertifyInfo(result.getCertifyUrl());
}
public void callback(Long uid, String certifyId, Integer certType, String deviceId) {
DescribeFaceVerifyResponse.DescribeFaceVerifyResponseResultObject responseResultObject = financialFaceVerify.describeFaceVerify(certifyId);
if (responseResultObject == null) {
log.error("callback responseResultObject is null, uid : {}, certifyId : {}, certType : {}, deviceId : {}", uid, certifyId, certType, deviceId);
throw new ApiException("认证失败");
}
String passed = responseResultObject.getPassed();
updateCertifyResult(uid, certifyId, certType, Byte.valueOf(passed), CERTIFY_RESULT_FOR_SUCCESS.equals(passed));
}
}

View File

@@ -4,10 +4,9 @@ import com.accompany.business.model.UserCertifyRecord;
import com.accompany.business.model.UserCertifyRecordExample;
import com.accompany.business.service.user.UsersService;
import com.accompany.common.config.AliyunRPCertifyConfig;
import com.accompany.common.utils.DESUtils;
import com.accompany.common.device.DeviceInfo;
import com.accompany.common.redis.RedisKey;
import com.accompany.common.status.BusiStatus;
import com.accompany.common.utils.DESUtils;
import com.accompany.core.exception.ServiceException;
import com.accompany.core.model.Users;
import com.accompany.core.util.StringUtils;
@@ -18,6 +17,7 @@ import com.aliyuncs.cloudauth.model.v20180916.*;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.profile.DefaultProfile;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.springframework.beans.factory.annotation.Autowired;
@@ -38,259 +38,233 @@ import java.util.UUID;
* @Date 2019-01-24
* @Description 阿里云实人认证
*/
@Slf4j
@Service
public class RealPeopleCertifyService extends AbstractCertifyService {
/** -1 未认证, 0 认证中, 1 认证通过, 2 认证不通过 */
public static final Byte CERTIFY_RESULT_PENDING = -1;
public static final Byte CERTIFY_RESULT_SUCCESS = 2;
public static final Byte CERTIFY_RESULT_FAILED = 1;
public static final Byte CERTIFY_RESULT_DELETE = 3;
/**
* -1 未认证, 0 认证中, 1 认证通过, 2 认证不通过
*/
public static final Byte CERTIFY_RESULT_PENDING = -1;
public static final Byte CERTIFY_RESULT_SUCCESS = 2;
public static final Byte CERTIFY_RESULT_FAILED = 1;
public static final Byte CERTIFY_RESULT_DELETE = 3;
@Autowired
private UsersService userService;
@Bean
@Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS)
public IAcsClient getIAcsClient() {
@Bean
@Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS)
public IAcsClient getIAcsClient() {
// DefaultProfile profile = DefaultProfile.getProfile(aliyunCertRegion, aliyunCertAccessKeyId, aliyunCertAccessKeySecret);
DefaultProfile profile = DefaultProfile.getProfile(AliyunRPCertifyConfig.regionId,
AliyunRPCertifyConfig.accessKeyId, AliyunRPCertifyConfig.accessKeySecret);
return new DefaultAcsClient(profile);
}
DefaultProfile profile = DefaultProfile.getProfile(AliyunRPCertifyConfig.regionId, AliyunRPCertifyConfig.accessKeyId, AliyunRPCertifyConfig.accessKeySecret);
return new DefaultAcsClient(profile);
}
public String getAliyunRPBasicToken(Long uid) throws ClientException {
//认证ID, 由使用方指定, 发起不同的认证任务需要更换不同的认证ID
String ticketId = UUID.randomUUID().toString();
public String getAliyunRPBasicToken(Long uid) throws ClientException {
//认证ID, 由使用方指定, 发起不同的认证任务需要更换不同的认证ID
String ticketId = UUID.randomUUID().toString();
//1. 服务端发起认证请求, 获取到token
//GetVerifyToken接口文档https://help.aliyun.com/document_detail/57050.html
GetVerifyTokenRequest getVerifyTokenRequest = new GetVerifyTokenRequest();
getVerifyTokenRequest.setBiz(AliyunRPCertifyConfig.bizCode);
getVerifyTokenRequest.setTicketId(ticketId);
//1. 服务端发起认证请求, 获取到token
//GetVerifyToken接口文档https://help.aliyun.com/document_detail/57050.html
GetVerifyTokenRequest getVerifyTokenRequest = new GetVerifyTokenRequest();
getVerifyTokenRequest.setBiz(AliyunRPCertifyConfig.bizCode);
getVerifyTokenRequest.setTicketId(ticketId);
GetVerifyTokenResponse response = getIAcsClient().getAcsResponse(getVerifyTokenRequest);
//token默认30分钟时效每次发起认证时都必须实时获取
return response.getData().getVerifyToken().getToken();
}
GetVerifyTokenResponse response = getIAcsClient().getAcsResponse(getVerifyTokenRequest);
//token默认30分钟时效每次发起认证时都必须实时获取
return response.getData().getVerifyToken().getToken();
}
public String getAliyunRPBioOnlyToken(Long uid, String username, String identificationNumber, String phone, String code, DeviceInfo device, String ip)
throws Exception {
public String getAliyunRPBioOnlyToken(Long uid, String username, String identificationNumber, String phone, String code, DeviceInfo device, String ip) throws Exception {
//用户信息验证
Users users = userService.getUsersByUid(uid);
verify(users, phone, code, identificationNumber);
//用户信息验证
Users users = userService.getUsersByUid(uid);
verify(users, phone, code, identificationNumber);
UserCertifyRecord record = buildUserCertifyRecord(uid, username, identificationNumber, phone, code, device, ip);
GetVerifyTokenRequest request = buildRPBioGetVerifyTokenRequest(record.getTicket(), username, identificationNumber);
GetVerifyTokenResponse response = getIAcsClient().getAcsResponse(request);
String token = response.getData().getVerifyToken().getToken();
UserCertifyRecord record = buildUserCertifyRecord(uid, username, identificationNumber, phone, code, device, ip);
GetVerifyTokenRequest request = buildRPBioGetVerifyTokenRequest(record.getTicket(), username, identificationNumber);
GetVerifyTokenResponse response = getIAcsClient().getAcsResponse(request);
String token = response.getData().getVerifyToken().getToken();
record.setToken(token);
addUserCertifyRecord(record);
record.setToken(token);
addUserCertifyRecord(record);
//token默认30分钟时效每次发起认证时都必须实时获取
return token;
}
//token默认30分钟时效每次发起认证时都必须实时获取
return token;
}
private GetVerifyTokenRequest buildRPBioGetVerifyTokenRequest(String ticketId, String username, String identificationNumber) {
GetVerifyTokenRequest getVerifyTokenRequest = new GetVerifyTokenRequest();
getVerifyTokenRequest.setBiz(AliyunRPCertifyConfig.bizCode);
getVerifyTokenRequest.setTicketId(ticketId);
getVerifyTokenRequest.setMethod(MethodType.POST);
private GetVerifyTokenRequest buildRPBioGetVerifyTokenRequest(String ticketId, String username, String identificationNumber) {
GetVerifyTokenRequest getVerifyTokenRequest = new GetVerifyTokenRequest();
getVerifyTokenRequest.setBiz(AliyunRPCertifyConfig.bizCode);
getVerifyTokenRequest.setTicketId(ticketId);
getVerifyTokenRequest.setMethod(MethodType.POST);
//通过binding参数传入业务已经采集的认证资料其中姓名、身份证号为必要字段
//若需要binding图片资料请控制单张图片大小在 2M 内,避免拉取超时
getVerifyTokenRequest.setBinding("{\"Name\": \"" + username + "\",\"IdentificationNumber\": \"" + identificationNumber + "\"}");
//通过binding参数传入业务已经采集的认证资料其中姓名、身份证号为必要字段
//若需要binding图片资料请控制单张图片大小在 2M 内,避免拉取超时
getVerifyTokenRequest.setBinding("{\"Name\": \"" + username + "\",\"IdentificationNumber\": \"" + identificationNumber + "\"}");
return getVerifyTokenRequest;
}
return getVerifyTokenRequest;
}
@Transactional(rollbackFor = Exception.class)
@Transactional(rollbackFor = Exception.class)
public void updateCertifyResult(Long uid, String token, Byte statusCode) {
UserCertifyRecordExample example = new UserCertifyRecordExample();
example.createCriteria().andUidEqualTo(uid).andTokenEqualTo(token);
example.setOrderByClause(" createTime desc ");
List<UserCertifyRecord> records = this.userCertifyRecordMapper.selectByExample(example);
if (CollectionUtils.isEmpty(records)) {
throw new ServiceException(BusiStatus.NOTEXISTS);
}
//根据 'createTime' 逆序,此时拿到的是最新的记录
UserCertifyRecord record = records.get(0);
if(!record.getUid().equals(uid)) {
throw new ServiceException(BusiStatus.ILLEGAL_USER);
}
//根据 'createTime' 逆序,此时拿到的是最新的记录
UserCertifyRecord record = records.get(0);
if (!record.getUid().equals(uid)) {
throw new ServiceException(BusiStatus.ILLEGAL_USER);
}
// 验证是否验证成功
if(!verifySuccess(record.getTicket())) {
throw new ServiceException(BusiStatus.CERTIFY_FAIL);
}
Users user = userService.getUsersByUid(uid);
// 如果已经实名认证过,则不给修改 2021年06月08日
if (StringUtils.isNotBlank(user.getIdCardNum())
&& StringUtils.isNotBlank(user.getRealName())) {
throw new ServiceException(BusiStatus.BUSIERROR);
}
// 如果用户之前已实名,需要删除之前的实名信息
if(CERTIFY_RESULT_SUCCESS.equals(statusCode) && StringUtils.isNotBlank(user.getIdCardNum())
&& StringUtils.isNotBlank(user.getRealName())) {
int result = deleteSuccessRecordByUidId(uid);
if(result > 0) {
int times = 1;
if(user.getCertifyModifyTimes() != null) {
times += user.getCertifyModifyTimes();
}
user.setCertifyModifyTimes(times);
}
}
if (!verifySuccess(record.getTicket())) {
throw new ServiceException(BusiStatus.CERTIFY_FAIL);
}
Users user = userService.getUsersByUid(uid);
// 如果已经实名认证过,则不给修改 2021年06月08日
if (StringUtils.isNotBlank(user.getIdCardNum()) && StringUtils.isNotBlank(user.getRealName())) {
throw new ServiceException(BusiStatus.BUSIERROR);
}
// 如果用户之前已实名,需要删除之前的实名信息
if (CERTIFY_RESULT_SUCCESS.equals(statusCode) && StringUtils.isNotBlank(user.getIdCardNum()) && StringUtils.isNotBlank(user.getRealName())) {
int result = deleteSuccessRecordByUidId(uid);
if (result > 0) {
int times = 1;
if (user.getCertifyModifyTimes() != null) {
times += user.getCertifyModifyTimes();
}
user.setCertifyModifyTimes(times);
}
}
record.setBindStatus(statusCode);
record.setUpdateTime(Calendar.getInstance().getTime());
this.userCertifyRecordMapper.updateByPrimaryKeySelective(record);
if (CERTIFY_RESULT_SUCCESS.equals(statusCode)) {
// 设置实名信息
user.setRealName(record.getName());
user.setIdCardNum(record.getIdCardNum());
user.setUpdateTime(new Date());
this.updateUsersInDBAndCache(user);
user.setRealName(record.getName());
user.setIdCardNum(record.getIdCardNum());
user.setUpdateTime(new Date());
this.updateUsersInDBAndCache(user);
// 增加身份证绑定次数
this.increaseBindCount(record.getIdCardNum());
}
}
public void increaseBindCount(String identityNum) {
String key = RedisKey.id_card_bind_user_count.getKey();
jedisService.hincr(key,identityNum);
}
public void updateAliyunCertResult(String ticketId) {
GetStatusRequest getStatusRequest = new GetStatusRequest();
getStatusRequest.setBiz(AliyunRPCertifyConfig.bizCode);
getStatusRequest.setTicketId(ticketId);
int statusCode = CERTIFY_RESULT_PENDING;
try {
GetStatusResponse response = getIAcsClient().getAcsResponse(getStatusRequest);
statusCode = response.getData().getStatusCode();
} catch (ClientException e) {
log.error("实名认证失败, ticketId={}", ticketId, e);
}
//认证通过or认证不通过
if (CERTIFY_RESULT_SUCCESS == statusCode || CERTIFY_RESULT_FAILED == statusCode) {
GetMaterialsRequest getMaterialsRequest = new GetMaterialsRequest();
getMaterialsRequest.setBiz(AliyunRPCertifyConfig.bizCode);
getMaterialsRequest.setTicketId(ticketId);
try {
GetMaterialsResponse response = getIAcsClient().getAcsResponse(getMaterialsRequest);
// TODO: 后续业务处理
} catch (ClientException e) {
log.error("实名认证失败, ticketId={}", ticketId, e);
}
}
}
/**
* 减少一次实名认证绑定次数
* @param identityNum
*/
public void decreaseBindCount(String identityNum) {
String key = RedisKey.id_card_bind_user_count.getKey();
jedisService.hincrBy(key,identityNum, -1L);
}
/**
* 根据用户id 删除一条实名认证成功的记录
*
* @param uid
* @return
*/
public int deleteSuccessRecordByUidId(Long uid) {
UserCertifyRecordExample example = new UserCertifyRecordExample();
example.createCriteria().andUidEqualTo(uid).andBindStatusEqualTo(CERTIFY_RESULT_SUCCESS);
List<UserCertifyRecord> list = userCertifyRecordMapper.selectByExample(example);
if (CollectionUtils.isEmpty(list)) {
return 0;
}
UserCertifyRecord record = list.get(0);
//将状态设置为删除
UserCertifyRecord updateRecord = new UserCertifyRecord();
updateRecord.setRecordId(record.getRecordId());
updateRecord.setBindStatus(RealPeopleCertifyService.CERTIFY_RESULT_DELETE);
updateRecord.setUpdateTime(new Date());
int result = userCertifyRecordMapper.updateByPrimaryKeySelective(updateRecord);
//删除成功后,要减去绑定的次数
if (result > 0) {
Users user = userService.getUsersByUid(record.getUid());
user.setRealName("");
user.setIdCardNum("");
user.setUpdateTime(new Date());
this.updateUsersInDBAndCache(user);
decreaseBindCount(record.getIdCardNum());
}
return result;
}
public void updateAliyunCertResult(String ticketId) {
GetStatusRequest getStatusRequest = new GetStatusRequest();
getStatusRequest.setBiz(AliyunRPCertifyConfig.bizCode);
getStatusRequest.setTicketId(ticketId);
public String smsCodeAuth(Long uid, String phone, String code) throws Exception {
if (StringUtils.isBlank(phone) || phone.contains("*")) {
Users users = userService.getUsersByUid(uid);
phone = users.getPhone();
}
//验证码验证
boolean verify = smsService.verifySmsCode(phone, code);
if (!verify) {
throw new ServiceException(BusiStatus.SMSCODEERROR);
}
String text = String.format("%s,%s,%s", System.currentTimeMillis(), uid, phone);
return DESUtils.DESAndBase64UrlEncrypt(text, DESUtils.DEFAULT_SECRET_KEY);
}
int statusCode = CERTIFY_RESULT_PENDING;
try {
GetStatusResponse response = getIAcsClient().getAcsResponse(getStatusRequest);
statusCode = response.getData().getStatusCode();
} catch (ClientException e) {
logger.error("实名认证失败, ticketId={}", ticketId, e);
}
public boolean verifyAuth(Long uid, String auth) throws Exception {
String text = DESUtils.DESAndBase64UrlDecrypt(auth, DESUtils.DEFAULT_SECRET_KEY);
String[] array = text.split(",");
if (array.length < 3) {
return false;
}
Long time = NumberUtils.toLong(array[0]);
Long decryptUid = NumberUtils.toLong(array[1]);
String phone = array[2];
if (!decryptUid.equals(uid)) {
return false;
}
// 验证时间与本次发起请求的时候大于10分钟表示需要重新验证
long sub = System.currentTimeMillis() - time;
if (sub > 10 * 60 * 1000) {
return false;
}
return true;
}
//认证通过or认证不通过
if (CERTIFY_RESULT_SUCCESS == statusCode || CERTIFY_RESULT_FAILED == statusCode) {
GetMaterialsRequest getMaterialsRequest = new GetMaterialsRequest();
getMaterialsRequest.setBiz(AliyunRPCertifyConfig.bizCode);
getMaterialsRequest.setTicketId(ticketId);
try {
GetMaterialsResponse response = getIAcsClient().getAcsResponse(getMaterialsRequest);
// TODO: 后续业务处理
} catch (ClientException e) {
logger.error("实名认证失败, ticketId={}", ticketId, e);
}
}
}
/**
* 根据用户id 删除一条实名认证成功的记录
* @param uid
* @return
*/
public int deleteSuccessRecordByUidId(Long uid) {
UserCertifyRecordExample example = new UserCertifyRecordExample();
example.createCriteria()
.andUidEqualTo(uid)
.andBindStatusEqualTo(CERTIFY_RESULT_SUCCESS);
List<UserCertifyRecord> list = userCertifyRecordMapper.selectByExample(example);
if(CollectionUtils.isEmpty(list)) {
return 0;
}
UserCertifyRecord record = list.get(0);
//将状态设置为删除
UserCertifyRecord updateRecord = new UserCertifyRecord();
updateRecord.setRecordId(record.getRecordId());
updateRecord.setBindStatus(RealPeopleCertifyService.CERTIFY_RESULT_DELETE);
updateRecord.setUpdateTime(new Date());
int result = userCertifyRecordMapper.updateByPrimaryKeySelective(updateRecord);
//删除成功后,要减去绑定的次数
if(result > 0) {
Users user = userService.getUsersByUid(record.getUid());
user.setRealName("");
user.setIdCardNum("");
user.setUpdateTime(new Date());
this.updateUsersInDBAndCache(user);
decreaseBindCount(record.getIdCardNum());
}
return result;
}
public String smsCodeAuth(Long uid, String phone, String code) throws Exception {
if(StringUtils.isBlank(phone) || phone.contains("*")) {
Users users = userService.getUsersByUid(uid);
phone = users.getPhone();
}
//验证码验证
boolean verify = smsService.verifySmsCode(phone, code);
if (!verify) {
throw new ServiceException(BusiStatus.SMSCODEERROR);
}
String text = String.format("%s,%s,%s", System.currentTimeMillis(), uid, phone);
return DESUtils.DESAndBase64UrlEncrypt(text, DESUtils.DEFAULT_SECRET_KEY);
}
public boolean verifyAuth(Long uid, String auth) throws Exception {
String text = DESUtils.DESAndBase64UrlDecrypt(auth, DESUtils.DEFAULT_SECRET_KEY);
String[] array = text.split(",");
if(array.length < 3) {
return false;
}
Long time = NumberUtils.toLong(array[0]);
Long decryptUid = NumberUtils.toLong(array[1]);
String phone = array[2];
if(!decryptUid.equals(uid)) {
return false;
}
// 验证时间与本次发起请求的时候大于10分钟表示需要重新验证
long sub = System.currentTimeMillis() - time;
if(sub > 10 * 60 * 1000) {
return false;
}
return true;
}
public boolean verifySuccess(String ticket) {
GetStatusRequest getStatusRequest = new GetStatusRequest();
getStatusRequest.setBiz(AliyunRPCertifyConfig.bizCode);
getStatusRequest.setTicketId(ticket);
getStatusRequest.setMethod(MethodType.POST);
try {
GetStatusResponse response = getIAcsClient().getAcsResponse(getStatusRequest);
logger.info("实名认证结果查询ticket:{},response data:{}", ticket, JSON.toJSONString(response.getData()));
if (null != response && response.getData() != null) {
Integer statusCode = response.getData().getStatusCode();
// -1: 未认证0认证中1认证通过2认证不通过
if (null != statusCode && statusCode == 1) {
return true;
}
}
} catch (Exception e) {
logger.error("查询实名认证结果失败:{}", ExceptionUtils.getStackTrace(e));
}
return false;
}
public boolean verifySuccess(String ticket) {
GetStatusRequest getStatusRequest = new GetStatusRequest();
getStatusRequest.setBiz(AliyunRPCertifyConfig.bizCode);
getStatusRequest.setTicketId(ticket);
getStatusRequest.setMethod(MethodType.POST);
try {
GetStatusResponse response = getIAcsClient().getAcsResponse(getStatusRequest);
log.info("实名认证结果查询ticket:{},response data:{}", ticket, JSON.toJSONString(response.getData()));
if (null != response && response.getData() != null) {
Integer statusCode = response.getData().getStatusCode();
// -1: 未认证0认证中1认证通过2认证不通过
if (null != statusCode && statusCode == 1) {
return true;
}
}
} catch (Exception e) {
log.error("查询实名认证结果失败:{}", ExceptionUtils.getStackTrace(e));
}
return false;
}
}

View File

@@ -0,0 +1,28 @@
package com.accompany.business.service.certification;
import com.accompany.business.dto.yidun.YiDunLivePersonResponseDto;
import com.accompany.common.config.YiDunCertConfig;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* @author: liaozetao
* @date: 2024/1/10 10:35
* @description:
*/
@Slf4j
@Service
public class YiDunLivePersonCertifyService extends AbstractCertifyService {
@Autowired
private YiDunCertConfig yiDunCertConfig;
private YiDunLivePersonResponseDto livePersonAudit(String cardNo, String name, String token, String needAvatar, String picType, String dataId) {
return null;
}
public String personAudit(Long uid, String username, String identityNumber, String phone, String code) {
return null;
}
}

View File

@@ -0,0 +1,71 @@
package com.accompany.business.service.certification.aliyun;
import com.accompany.common.config.AliYunFinancialFaceConfig;
import com.accompany.common.exception.ApiException;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.aliyun.cloudauth20190307.models.DescribeFaceVerifyRequest;
import com.aliyun.cloudauth20190307.models.DescribeFaceVerifyResponse;
import com.aliyun.cloudauth20190307.models.InitFaceVerifyRequest;
import com.aliyun.cloudauth20190307.models.InitFaceVerifyResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
@Slf4j
@Component
public class FinancialFaceVerify {
private static final String ID_PRO = "ID_PRO";
private static final String IDENTITY_CARD = "IDENTITY_CARD";
private static final String MULTI_ACTION = "MULTI_ACTION";
public InitFaceVerifyResponse.InitFaceVerifyResponseResultObject initFaceVerify(String outerOrderNo, String certName, String certNo, String returnUrl, String metaInfo, String mobile, String ip, Long userId, Integer certType, String deviceId) {
String callbackUrl = AliYunFinancialFaceConfig.callbackUrl + "?uid=" + userId + "&certType=" + certType + "&deviceId=" + deviceId;
InitFaceVerifyRequest initFaceVerifyRequest = new InitFaceVerifyRequest();
initFaceVerifyRequest.setSceneId(AliYunFinancialFaceConfig.sceneId);
initFaceVerifyRequest.setOuterOrderNo(outerOrderNo);
initFaceVerifyRequest.setProductCode(ID_PRO);
initFaceVerifyRequest.setModel(MULTI_ACTION);
initFaceVerifyRequest.setCertType(IDENTITY_CARD);
initFaceVerifyRequest.setCertName(certName);
initFaceVerifyRequest.setCertNo(certNo);
initFaceVerifyRequest.setReturnUrl(returnUrl);
initFaceVerifyRequest.setMetaInfo(metaInfo);
initFaceVerifyRequest.setMobile(mobile);
initFaceVerifyRequest.setIp(ip);
initFaceVerifyRequest.setUserId(String.valueOf(userId));
initFaceVerifyRequest.setCallbackUrl(callbackUrl);
log.info("initFaceVerify request : {}", JSONObject.toJSONString(initFaceVerifyRequest));
FinancialFaceVerifyClient financialFaceVerifyClient = new FinancialFaceVerifyClient(AliYunFinancialFaceConfig.accessKeyId, AliYunFinancialFaceConfig.accessKeySecret, AliYunFinancialFaceConfig.endpoints);
InitFaceVerifyResponse response = financialFaceVerifyClient.initFaceVerify(initFaceVerifyRequest);
log.info("initFaceVerify response data: {}", JSON.toJSONString(response));
if (String.valueOf(HttpStatus.OK.value()).equals(response.getCode())) {
return response.getResultObject();
} else {
throw new ApiException(Integer.parseInt(response.getCode()), response.getMessage());
}
}
public DescribeFaceVerifyResponse.DescribeFaceVerifyResponseResultObject describeFaceVerify(String certifyId) {
try {
DescribeFaceVerifyRequest describeFaceVerifyRequest = new DescribeFaceVerifyRequest();
describeFaceVerifyRequest.setSceneId(AliYunFinancialFaceConfig.sceneId);
describeFaceVerifyRequest.setCertifyId(certifyId);
log.info("describeFaceVerify describeFaceVerifyRequest : {}", JSONObject.toJSONString(describeFaceVerifyRequest));
FinancialFaceVerifyClient financialFaceVerifyClient = new FinancialFaceVerifyClient(AliYunFinancialFaceConfig.accessKeyId, AliYunFinancialFaceConfig.accessKeySecret, AliYunFinancialFaceConfig.endpoints);
DescribeFaceVerifyResponse response = financialFaceVerifyClient.describeFaceVerify(describeFaceVerifyRequest);
log.info("FinancialFaceVerify describeFaceVerify response data: {}", JSON.toJSONString(response));
if (String.valueOf(HttpStatus.OK.value()).equals(response.getCode())) {
return response.getResultObject();
}
} catch (Exception e) {
log.error(e.getMessage(), e);
}
return null;
}
}

View File

@@ -0,0 +1,104 @@
package com.accompany.business.service.certification.aliyun;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.aliyun.cloudauth20190307.Client;
import com.aliyun.cloudauth20190307.models.DescribeFaceVerifyRequest;
import com.aliyun.cloudauth20190307.models.DescribeFaceVerifyResponse;
import com.aliyun.cloudauth20190307.models.InitFaceVerifyRequest;
import com.aliyun.cloudauth20190307.models.InitFaceVerifyResponse;
import com.aliyun.tearpc.models.Config;
import com.aliyun.teautil.models.RuntimeOptions;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
/**
* @author: liaozetao
* @date: 2022/12/23 18:05
* @description:
*/
@Slf4j
public class FinancialFaceVerifyClient {
private final String accessKeyId;
private final String accessKeySecret;
private final String endpoints;
private static final int READ_TIMEOUT = 10000;
private static final int CONNECT_TIMEOUT = 10000;
public FinancialFaceVerifyClient(String accessKeyId, String accessKeySecret, String endpoints) {
this.accessKeyId = accessKeyId;
this.accessKeySecret = accessKeySecret;
this.endpoints = endpoints;
}
public InitFaceVerifyResponse initFaceVerify(InitFaceVerifyRequest initFaceVerifyRequest) {
if (StrUtil.isEmpty(endpoints)) {
return null;
}
InitFaceVerifyResponse response = null;
String[] endpointArray = endpoints.split(StrUtil.COMMA);
for (String endpoint : endpointArray) {
try {
Client client = initClient(endpoint.trim());
// 创建RuntimeObject实例并设置运行参数。
RuntimeOptions runtime = new RuntimeOptions();
runtime.readTimeout = READ_TIMEOUT;
runtime.connectTimeout = CONNECT_TIMEOUT;
InitFaceVerifyResponse initFaceVerifyResponse = client.initFaceVerify(initFaceVerifyRequest, runtime);
if (initFaceVerifyResponse == null) {
continue;
}
//服务端错误,切换到下个区域调用。
if (!(String.valueOf(HttpStatus.INTERNAL_SERVER_ERROR.value()).equals(initFaceVerifyResponse.getCode()))) {
response = initFaceVerifyResponse;
break;
}
} catch (Exception e) {
log.error(e.getMessage(), e);
}
}
return response;
}
private Client initClient(String endpoint) throws Exception {
Config config = new Config();
config.setAccessKeyId(accessKeyId);
config.setAccessKeySecret(accessKeySecret);
config.setEndpoint(endpoint);
return new Client(config);
}
public DescribeFaceVerifyResponse describeFaceVerify(DescribeFaceVerifyRequest describeFaceVerifyRequest) {
if (StrUtil.isEmpty(endpoints)) {
return null;
}
DescribeFaceVerifyResponse response = null;
String[] endpointArray = endpoints.split(StrUtil.COMMA);
for (String endpoint : endpointArray) {
try {
Client client = initClient(endpoint.trim());
// 创建RuntimeObject实例并设置运行参数。
RuntimeOptions runtime = new RuntimeOptions();
runtime.readTimeout = READ_TIMEOUT;
runtime.connectTimeout = CONNECT_TIMEOUT;
DescribeFaceVerifyResponse describeFaceVerifyResponse = client.describeFaceVerify(describeFaceVerifyRequest, runtime);
if (describeFaceVerifyResponse == null) {
continue;
}
//服务端错误,切换到下个区域调用。
if (!(String.valueOf(HttpStatus.INTERNAL_SERVER_ERROR.value()).equals(describeFaceVerifyResponse.getCode()))) {
response = describeFaceVerifyResponse;
break;
}
} catch (Exception e) {
log.error(e.getMessage(), e);
}
}
return response;
}
}

View File

@@ -12,16 +12,19 @@ package com.accompany.business.service.netease;
import cn.hutool.core.util.StrUtil;
import com.accompany.business.dto.yidun.AntispamDto;
import com.accompany.business.dto.yidun.YiDunLivePersonResponseDto;
import com.accompany.business.dto.yidun.YidunCheckRes;
import com.accompany.business.dto.yidun.YidunLabelsDto;
import com.accompany.business.sensitvienew.SensitiveConstant;
import com.accompany.business.sensitvienew.SensitiveFilterUtil;
import com.accompany.common.config.YiDunCertConfig;
import com.accompany.common.config.YidunCheckConfig;
import com.accompany.common.constant.Constant;
import com.accompany.common.utils.UUIDUtil;
import com.accompany.core.util.HttpClient4Utils;
import com.accompany.core.util.YidunGeneralUtils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.Consts;
import org.springframework.stereotype.Service;
@@ -135,4 +138,23 @@ public class YidunCheckUtil {
return null;
}
public static YiDunLivePersonResponseDto livePersonAudit(String cardNo, String name, String token, String needAvatar, String picType, String dataId) {
Map<String, String> params = YidunGeneralUtils.getCommonParams(YiDunCertConfig.secretId, YiDunCertConfig.businessId,
"v5.1", "MD5");
params.put("cardNo", cardNo);
params.put("name", name);
params.put("token", token);
params.put("needAvatar", needAvatar);
params.put("picType", picType);
params.put("dataId", UUIDUtil.get());
YidunGeneralUtils.sign(params, YiDunCertConfig.secretKey);
log.info("yiDun livePersonAudit params : {}", JSONObject.toJSONString(params));
String response = HttpClient4Utils.sendPost(HttpClient4Utils.httpClient, YiDunCertConfig.auditUrl, params, Consts.UTF_8);
log.info("yiDun livePersonAudit response : {}", response);
if (StrUtil.isEmpty(response)) {
return new YiDunLivePersonResponseDto();
}
return JSONObject.parseObject(response, YiDunLivePersonResponseDto.class);
}
}

View File

@@ -85,6 +85,9 @@ public class WithdrawUserAccountServiceImpl extends ServiceImpl<WithdrawUserAcco
WithdrawUserAccount userAccount = getById(id);
if (userAccount != null) {
Integer updateNum = userAccount.getUpdateNum();
if (updateNum != null && updateNum == 0) {
throw new ApiException("不允許修改");
}
if (updateNum != null) {
updateNum -= 1;
account.setUpdateNum(updateNum);

View File

@@ -1,6 +1,11 @@
package com.accompany.business.controller.certification;
import com.accompany.business.common.BaseController;
import com.accompany.business.dto.certification.CertifyInfo;
import com.accompany.business.service.certification.FinancialFaceVerifyService;
import com.accompany.business.service.certification.YiDunLivePersonCertifyService;
import com.accompany.common.annotation.H5Authorization;
import com.accompany.common.status.BusiStatusInterface;
import com.accompany.common.utils.DESUtils;
import com.accompany.common.utils.IPUtils;
import com.accompany.core.util.KeyStore;
@@ -16,13 +21,15 @@ import com.accompany.common.annotation.Authorization;
import com.accompany.common.device.DeviceInfo;
import com.accompany.common.result.BusiResult;
import com.accompany.common.status.BusiStatus;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
@@ -34,146 +41,210 @@ import java.util.concurrent.TimeUnit;
* @date 2018-12-21
* @description 用户实名认证
*/
@Api(tags = "实名认证")
@Slf4j
@RestController
@RequestMapping("/certification")
public class UserCertificationController extends BaseController {
private static final transient Logger logger = LoggerFactory.getLogger(UserCertificationController.class);
private static final transient Logger logger = LoggerFactory.getLogger(UserCertificationController.class);
/**接口限频,每秒十次**/
private RateLimiter certificationLimit = RateLimiter.create(10);
/**
* 接口限频,每秒十次
**/
private final RateLimiter certificationLimit = RateLimiter.create(10);
private Gson gson = new Gson();
private Gson gson = new Gson();
@Autowired
private TwoFactorCertifyService twoFactorCertifyService;
@Autowired
private TwoFactorCertifyService twoFactorCertifyService;
@Autowired
private RealPeopleCertifyService realPeopleCertifyService;
@Autowired
private RealPeopleCertifyService realPeopleCertifyService;
@Authorization
@RequestMapping(value = "/send/code", method = RequestMethod.POST)
public BusiResult sendCertificationCode(String phone, Long uid, HttpServletRequest request) throws Exception {
phone = DESUtils.DESAndBase64Decrypt(phone, KeyStore.DES_ENCRYPT_KEY);
String deviceInfoStr = request.getParameter("deviceInfo");
DeviceInfo deviceInfo = gson.fromJson(deviceInfoStr, DeviceInfo.class);
logger.info("sendCertificationCode(), phone={}, type={}, uid={}, device={}", phone, uid, deviceInfo);
@Autowired
private YiDunLivePersonCertifyService yiDunLivePersonCertifyService;
if (!certificationLimit.tryAcquire(5, TimeUnit.SECONDS)) {
return new BusiResult(BusiStatus.SERVER_BUSY);
}
String ip = IPUtils.getRealIpAddress(request);
try{
this.twoFactorCertifyService.sendCertificationCode(phone, uid, ip, deviceInfo);
}catch (ServiceException e){
logger.error("serviceException,get sms code failed, phone={}, type={}, uid={}, device={}, message:{}",
phone, uid, deviceInfo, e.getMessage());
return new BusiResult(e.getBusiStatus());
}catch (Exception e){
logger.error("get sms code failed, phone={}, type={}, uid={}, device={}",phone,uid,deviceInfo,e);
return new BusiResult(BusiStatus.SERVERERROR);
}
return new BusiResult(BusiStatus.SUCCESS);
}
@Authorization
@RequestMapping(value = "/isCertify")
public BusiResult isCertifyUser(Long uid) {
logger.info("isCertifyUser(),uid={}", uid);
Boolean result = twoFactorCertifyService.isCertifyUser(uid);
return new BusiResult(BusiStatus.SUCCESS, result);
}
/**
* 2020-03-04 接口添加是否可以实名认证的判断
* 实名认证后,用户有一次机会可以修改实名认证信息
* @param uid
* @return
*/
@Authorization
@RequestMapping(value = "/hasCertify")
public BusiResult hasCertifyUser(Long uid, String auth) throws Exception {
logger.info("hasCertifyUser(),vuid={}", uid);
if(null == uid) {
return new BusiResult(BusiStatus.PARAMERROR);
}
boolean authResult = false;
if(StringUtils.isNotBlank(auth)) {
authResult = realPeopleCertifyService.verifyAuth(uid, auth);
}
Map<String, Object> data = new HashMap<>(8);
data.put("hasCertify", twoFactorCertifyService.isCertifyUser(uid));
data.put("canCertify", twoFactorCertifyService.canCertify(uid));
data.put("authResult", authResult);
return new BusiResult(BusiStatus.SUCCESS, data);
}
/**
* 获取用户实人认证 TOKEN
* @param uid
* @return
*/
@Authorization
@RequestMapping(value = "/token", method = RequestMethod.GET)
public BusiResult getToken(@RequestParam Long uid, @RequestParam String username, @RequestParam String identityNumber, @RequestParam String phone,
@RequestParam String code, HttpServletRequest request) throws ClientException {
try {
username = DESUtils.DESAndBase64Decrypt(username, KeyStore.DES_ENCRYPT_KEY);
identityNumber = DESUtils.DESAndBase64Decrypt(identityNumber, KeyStore.DES_ENCRYPT_KEY);
phone = DESUtils.DESAndBase64Decrypt(phone, KeyStore.DES_ENCRYPT_KEY);
} catch (Exception e) {
logger.error("解密信息时出现异常", e);
throw new ServiceException(BusiStatus.SERVER_BUSY);
}
Map<String, String> data = Maps.newHashMap();
DeviceInfo deviceInfo = getDeviceInfo(request);
String ip = IPUtils.getRealIpAddress(request);
try{
data.put("token", this.realPeopleCertifyService.getAliyunRPBioOnlyToken(uid, username, identityNumber, phone, code, deviceInfo, ip));
}catch(ServiceException e){
logger.error("serviceException,failed to get certification token[uid:{}, username:{}, idNo:{}, phone:{}, code:{}], message:{}",
uid, username, identityNumber, phone, code, e.getMessage());
return new BusiResult(e.getBusiStatus());
}catch (Exception e){
logger.error("failed to get certification token[uid:{}, username:{}, idNo:{}, phone:{}, code:{}]", uid, username, identityNumber, phone, code, e);
return new BusiResult((BusiStatus.SERVERERROR));
}
return new BusiResult(BusiStatus.SUCCESS, data);
}
@Autowired
private FinancialFaceVerifyService financialFaceVerifyService;
@Authorization
@RequestMapping(value = "/notify", method = RequestMethod.POST)
public BusiResult getCertificationResult(@RequestParam Long uid, @RequestParam String token, @RequestParam Byte statusCode) {
logger.info("收到认证结果通知uid:{}, token:{}, statusCode:{}", uid, token, statusCode);
this.realPeopleCertifyService.updateCertifyResult(uid, token, statusCode);
return new BusiResult(BusiStatus.SUCCESS);
@RequestMapping(value = "/send/code", method = RequestMethod.POST)
public BusiResult<Void> sendCertificationCode(String phone, Long uid, HttpServletRequest request) throws Exception {
phone = DESUtils.DESAndBase64Decrypt(phone, KeyStore.DES_ENCRYPT_KEY);
String deviceInfoStr = request.getParameter("deviceInfo");
DeviceInfo deviceInfo = gson.fromJson(deviceInfoStr, DeviceInfo.class);
logger.info("sendCertificationCode(), phone={}, uid={}, device={}", phone, uid, deviceInfo);
if (!certificationLimit.tryAcquire(5, TimeUnit.SECONDS)) {
return BusiResult.fail(BusiStatus.SERVER_BUSY);
}
String ip = IPUtils.getRealIpAddress(request);
try {
this.twoFactorCertifyService.sendCertificationCode(phone, uid, ip, deviceInfo);
} catch (ServiceException e) {
logger.error("serviceException,get sms code failed, phone={}, uid={}, device={}, message:{}",
phone, uid, deviceInfo, e.getMessage(), e);
return BusiResult.fail(e.getBusiStatus(), e.getMessage());
} catch (Exception e) {
logger.error("get sms code failed, phone={}, uid={}, device={}", phone, uid, deviceInfo, e);
return BusiResult.fail(BusiStatus.SERVERERROR);
}
return BusiResult.success();
}
/**
* 短信验证码校验:
* 2020-03-05 用户修改实名信息时,需要
* @param uid
* @param phone
* @param code
* @return
*/
@Authorization
@RequestMapping(value = "/isCertify")
public BusiResult isCertifyUser(Long uid) {
logger.info("isCertifyUser(),uid={}", uid);
Boolean result = twoFactorCertifyService.isCertifyUser(uid);
return new BusiResult(BusiStatus.SUCCESS, result);
}
/**
* 2020-03-04 接口添加是否可以实名认证的判断
* 实名认证后,用户有一次机会可以修改实名认证信息
*
* @param uid
* @return
*/
@Authorization
@RequestMapping(value = "/hasCertify")
public BusiResult hasCertifyUser(Long uid, String auth) throws Exception {
logger.info("hasCertifyUser(),vuid={}", uid);
if (null == uid) {
return new BusiResult(BusiStatus.PARAMERROR);
}
boolean authResult = false;
if (StringUtils.isNotBlank(auth)) {
authResult = realPeopleCertifyService.verifyAuth(uid, auth);
}
Map<String, Object> data = new HashMap<>(8);
data.put("hasCertify", twoFactorCertifyService.isCertifyUser(uid));
data.put("canCertify", twoFactorCertifyService.canCertify(uid));
data.put("authResult", authResult);
return new BusiResult(BusiStatus.SUCCESS, data);
}
/**
* 获取用户实人认证 TOKEN
*
* @param uid
* @return
*/
@Authorization
@RequestMapping(value = "/token", method = RequestMethod.GET)
public BusiResult getToken(@RequestParam Long uid, @RequestParam String username, @RequestParam String identityNumber, @RequestParam String phone,
@RequestParam String code, HttpServletRequest request) throws ClientException {
try {
username = DESUtils.DESAndBase64Decrypt(username, KeyStore.DES_ENCRYPT_KEY);
identityNumber = DESUtils.DESAndBase64Decrypt(identityNumber, KeyStore.DES_ENCRYPT_KEY);
phone = DESUtils.DESAndBase64Decrypt(phone, KeyStore.DES_ENCRYPT_KEY);
} catch (Exception e) {
logger.error("解密信息时出现异常", e);
throw new ServiceException(BusiStatus.SERVER_BUSY);
}
Map<String, String> data = Maps.newHashMap();
DeviceInfo deviceInfo = getDeviceInfo(request);
String ip = IPUtils.getRealIpAddress(request);
try {
data.put("token", this.realPeopleCertifyService.getAliyunRPBioOnlyToken(uid, username, identityNumber, phone, code, deviceInfo, ip));
} catch (ServiceException e) {
logger.error("serviceException,failed to get certification token[uid:{}, username:{}, idNo:{}, phone:{}, code:{}], message:{}",
uid, username, identityNumber, phone, code, e.getMessage());
return new BusiResult(e.getBusiStatus());
} catch (Exception e) {
logger.error("failed to get certification token[uid:{}, username:{}, idNo:{}, phone:{}, code:{}]", uid, username, identityNumber, phone, code, e);
return new BusiResult((BusiStatus.SERVERERROR));
}
return new BusiResult(BusiStatus.SUCCESS, data);
}
@PostMapping("/notify")
public BusiResult<Void> getCertificationResult(@RequestParam Long uid, @RequestParam String token, @RequestParam Byte statusCode) {
logger.info("收到认证结果通知uid:{}, token:{}, statusCode:{}", uid, token, statusCode);
this.realPeopleCertifyService.updateCertifyResult(uid, token, statusCode);
return BusiResult.success();
}
/**
* 短信验证码校验:
* 2020-03-05 用户修改实名信息时,需要
*
* @param uid
* @param phone
* @param code
* @return
*/
@Authorization
@RequestMapping(value = "/smsCode/auth", method = RequestMethod.POST)
public BusiResult auth(@RequestParam Long uid, @RequestParam String phone, @RequestParam String code) throws Exception {
Map<String, Object> data = new HashMap<>();
Map<String, Object> data = new HashMap<>();
String result = realPeopleCertifyService.smsCodeAuth(uid, phone, code);
String result = realPeopleCertifyService.smsCodeAuth(uid, phone, code);
data.put("result", true);
data.put("auth", result);
data.put("result", true);
data.put("auth", result);
return new BusiResult(BusiStatus.SUCCESS, data);
}
@ApiOperation("人脸核身")
@PostMapping("/live/person/audit")
public BusiResult<String> personAudit(@RequestParam("uid") Long uid,
@RequestParam("username") String username,
@RequestParam("identityNumber") String identityNumber,
@RequestParam("phone") String phone,
@RequestParam("code") String code) {
return BusiResult.success(yiDunLivePersonCertifyService.personAudit(uid, username, identityNumber, phone, code));
}
/**
* 金融级实人认证发起
*
* @param uid
* @param username
* @param identityNumber
* @param phone
* @param code
* @param metaInfo
* @param certType
* @return
*/
@ApiOperation("金融级实人认证发起")
@ApiImplicitParams({
@ApiImplicitParam(name = "uid", value = "用户UID", required = true),
@ApiImplicitParam(name = "username", value = "真实姓名", required = true),
@ApiImplicitParam(name = "identityNumber", value = "身份证", required = true),
@ApiImplicitParam(name = "phone", value = "手机号码", required = true),
@ApiImplicitParam(name = "code", value = "短信验证码", required = true),
@ApiImplicitParam(name = "metaInfo", value = "MetaInfo环境参数", required = true),
@ApiImplicitParam(name = "certType", value = "业务类型0 提现)", required = true),
@ApiImplicitParam(name = "returnUrl", value = "回调链接", required = true),
})
@PostMapping("initFace")
public BusiResult<CertifyInfo> initFace(@RequestParam("uid") Long uid,
@RequestParam("username") String username,
@RequestParam("identityNumber") String identityNumber,
@RequestParam("phone") String phone,
@RequestParam("code") String code,
@RequestParam("metaInfo") String metaInfo,
@RequestParam(value = "certType", defaultValue = "0") Integer certType,
@RequestParam("returnUrl") String returnUrl) {
return BusiResult.success(financialFaceVerifyService.initFace(uid, username, identityNumber, phone, code, metaInfo, certType, returnUrl));
}
@GetMapping("/callback")
public BusiResult<Void> callback(@RequestParam("uid") Long uid,
@RequestParam("certifyId") String certifyId,
@RequestParam("certType") Integer certType,
@RequestParam("deviceId") String deviceId) {
log.info("callback uid : {}, certifyId : {}, certType : {}, deviceId : {}", uid, certifyId, certType, deviceId);
financialFaceVerifyService.callback(uid, certifyId, certType, deviceId);
return BusiResult.success();
}
}

View File

@@ -102,6 +102,7 @@
<bitwalker.version>1.20</bitwalker.version>
<sa-token.version>1.34.0</sa-token.version>
<pinyin4j.version>2.5.1</pinyin4j.version>
<cloudauth20190307.version>1.0.1</cloudauth20190307.version>
</properties>
<dependencyManagement>