Commit 3dd40094 authored by gaoyingwei's avatar gaoyingwei

修改 实名认证

parent f43f81fc
......@@ -243,4 +243,35 @@ public class AppMemInfoController extends CyPaginationController<MemInfo> {
return image; // 无需旋转
}
}
@CyOpeLogAnno(title = "system-会员表管理-校验实名认证信息", businessType = CyLogTypeEnum.UPDATE)
@Operation(summary="校验实名认证信息", description="校验实名认证信息")
@Parameters({@Parameter(name = "businessId", description = "businessId", required = false, schema = @Schema(type = "string"))})
@PutMapping("/checkIdCard/{userId:\\w+}")
@CyEncryptSm4Anno
public CyResult checkIdCard(@PathVariable int userId, @RequestBody MemInfo memInfo, BindingResult bindingResult) {
memInfo.setUserId(userId);
CyPersistModel data = memInfoServiceImpl.checkIdCard(memInfo);
return CyResultGenUtil.builder(data,
CyMessCons.MESSAGE_ALERT_SUCCESS,
CyMessCons.MESSAGE_ALERT_ERROR,
memInfo);
}
@CyOpeLogAnno(title = "system-会员表管理-修改会员表", businessType = CyLogTypeEnum.UPDATE)
@Operation(summary="修改会员表", description="修改会员表")
@Parameters({@Parameter(name = "businessId", description = "businessId", required = false, schema = @Schema(type = "string"))})
@PutMapping("/updateIdCard/{userId:\\w+}")
@CyEncryptSm4Anno
public CyResult updateIdCard(@PathVariable int userId, @RequestBody MemInfo memInfo, BindingResult bindingResult) {
memInfo.setUserId(userId);
CyPersistModel data = memInfoServiceImpl.updateIdCard(memInfo);
return CyResultGenUtil.builder(data,
CyMessCons.MESSAGE_ALERT_SUCCESS,
CyMessCons.MESSAGE_ALERT_ERROR,
memInfo);
}
}
......@@ -7,26 +7,39 @@ import org.springframework.stereotype.Component;
@Data
@Component
@ConfigurationProperties(prefix = "faceverfiy.ali")
@ConfigurationProperties(prefix = "faceverfiy")
public class FaceVerifyAliComp {
/**
* 场景id
*/
public Long sceneId;
private Long sceneId;
//访问密钥 ID
public String accessKeyId;
private String accessKeyId;
//访问密钥
public String accessKeySecret;
private String accessKeySecret;
//区域
public String[] endpoints;
private String[] endpoints;
//后端回调地址
public String callbackUrl;
private String callbackUrl;
//认证结束后回跳页面的链接地址
public String returnUrl;
private String returnUrl;
// 1. 同一个身份证 每天允许失败的次数
private int idCardDayCount;
// 2. 同一个身份证 每分钟允许失败的次数
private int idCardMinCount;
// 3. 同一ip 每天允许失败的次数
private int ipDayCount;
// 4. 同一ip 每分钟允许失败的次数
private int ipMinCount;
}
package org.rcisoft.business.faceVerify.bean;
/**
* Created with family.
* author: cy
* Date: 2024/5/25
* Time: 8:43 AM
* description:
*/
public class FaceVerifyRedisBean {
public static final String FACEVERIFY_USER = "faceVerify:user:";
/**
* @desc 身份证号每分钟 / 每天 失败次数
*
* @sample faceVerify:idCard:min:{idCard}
* @sample faceVerify:idCard:day:{idCard}
*/
public static final String FACEVERIFY_IDCARD_MINUTES = "faceVerify:idCard:min:";
public static final String FACEVERIFY_IDCARD_DAY= "faceVerify:idCard:day:";
/**
* @desc 同一ip 每分钟 / 每天 失败次数
*
* @sample faceVerify:ip:min:{ip}
* @sample faceVerify:ip:day:{ip}
* **/
public static final String FACEVERIFY_IP_MINUTES = "faceVerify:ip:min:";
public static final String FACEVERIFY_IP_DAY = "faceVerify:ip:day:";
}
......@@ -35,8 +35,8 @@ public class FaceVerifyController extends CyPaginationController<MemInfo> {
@CyOpeLogAnno(title = "system-发起认证请求", businessType = CyLogTypeEnum.OTHER)
@Operation(summary="发起认证请求", description="发起认证请求")
@PostMapping(value = "/initFaceVerify")
public CyResult initFaceVerify(@RequestBody InitFaceVerifyRequest dto, HttpServletRequest request) {
Map<String,String> data = faceVerifyService.initFaceVerify(request,dto);
public CyResult initFaceVerify(@RequestBody MemInfo info, HttpServletRequest request) {
Map<String,String> data = faceVerifyService.initFaceVerify(request,info);
return CyResultGenUtil.builder(new CyPersistModel(1),
CyMessCons.MESSAGE_ALERT_SUCCESS,
CyMessCons.MESSAGE_ALERT_ERROR,
......
......@@ -13,7 +13,7 @@ public interface FaceVerifyService {
* @param memInfo
* @return
*/
Map<String,String> initFaceVerify(HttpServletRequest request,InitFaceVerifyRequest dto);
Map<String,String> initFaceVerify(HttpServletRequest request,MemInfo memInfo);
/**
* 获取认证详细数据
......
package org.rcisoft.business.faceVerify.service.impl;
import com.alibaba.fastjson.JSON;
import com.aliyun.cloudauth20190307.Client;
import com.aliyun.cloudauth20190307.models.DescribeFaceVerifyRequest;
import com.aliyun.cloudauth20190307.models.DescribeFaceVerifyResponse;
......@@ -11,6 +12,7 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.rcisoft.business.faceVerify.bean.FaceVerifyAliComp;
import org.rcisoft.business.faceVerify.bean.FaceVerifyRedisBean;
import org.rcisoft.business.faceVerify.service.FaceVerifyService;
import org.rcisoft.business.memInfo.dao.MemInfoRepository;
import org.rcisoft.business.memInfo.entity.MemInfo;
......@@ -18,6 +20,7 @@ import org.rcisoft.business.memInfo.service.MemInfoService;
import org.rcisoft.core.exception.CyServiceException;
import org.rcisoft.core.jwt.util.CyJwtUtil;
import org.rcisoft.core.model.CyPersistModel;
import org.rcisoft.core.service.CyRedisService;
import org.rcisoft.core.util.CyAESUtils;
import org.rcisoft.core.util.CyUserUtil;
import org.springframework.beans.factory.annotation.Autowired;
......@@ -41,63 +44,71 @@ public class FaceVerifyServiceImpl extends ServiceImpl<MemInfoRepository, MemInf
private MemInfoRepository memInfoRepository;
@Autowired
private CyJwtUtil cyJwtUtil;
@Autowired
private CyRedisService cyRedisServiceImpl;
/**
* 发起认证请求
* @param MetaInfo
* @param memInfo
* @return
*/
@Override
public Map<String,String> initFaceVerify(HttpServletRequest httpServletRequest,InitFaceVerifyRequest dto) {
MemInfo memInfo = memInfoRepository.getInfoByUserId(CyUserUtil.getAuthenBusinessId());
String idCard = CyAESUtils.decrypt(memInfo.getMemIdcard());
String name = CyAESUtils.decrypt(memInfo.getMemRealName());
Map<String,String> map = new HashMap<>();
InitFaceVerifyRequest request = new InitFaceVerifyRequest();
// 场景ID+L。
request.setSceneId(faceVerifyAliComp.getSceneId());
// 设置商户请求的唯一标识。(请自己生成一个不超过32位数的数字及字母字符串)
LocalDateTime now = LocalDateTime.now();
String timestamp = now.format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
String uuid = UUID.randomUUID().toString().replace("-", "");
String outerOrderNo = timestamp + uuid.substring(0, 14);
request.setOuterOrderNo(outerOrderNo);
// 认证方案。
request.setProductCode("ID_PRO");
// 模式。LIVENESS(默认):眨眼动作活体检测。
request.setModel("LIVENESS");
// 不同证件类型,取值均为IDENTITY_CARD。
request.setCertType("IDENTITY_CARD");
// 您的终端用户的真实姓名。
request.setCertName(name);
// 您的终端用户的证件号码。
request.setCertNo(idCard);
// MetaInfo环境参数,此参数应由前端js获取并传入。
request.setMetaInfo(dto.getMetaInfo());
// 认证结束后回跳页面的链接地址。。
request.setReturnUrl(faceVerifyAliComp.getReturnUrl());
request.setCallbackUrl(faceVerifyAliComp.getCallbackUrl());
request.setCallbackToken(cyJwtUtil.getToken(httpServletRequest));
public Map<String,String> initFaceVerify(HttpServletRequest httpServletRequest,MemInfo memInfo) {
// MemInfo memInfo = memInfoRepository.getInfoByUserId(CyUserUtil.getAuthenBusinessId());
// String idCard = CyAESUtils.decrypt(memInfo.getMemIdcard());
// String name = CyAESUtils.decrypt(memInfo.getMemRealName());
Object detail = cyRedisServiceImpl.get(FaceVerifyRedisBean.FACEVERIFY_USER+CyUserUtil.getAuthenBusinessId());
if (detail!=null) {
MemInfo info = JSON.parseObject(JSON.toJSONString(detail), MemInfo.class);
String idCard = info.getMemIdcard();
String name = info.getMemRealName();
Map<String, String> map = new HashMap<>();
InitFaceVerifyRequest request = new InitFaceVerifyRequest();
// 场景ID+L。
request.setSceneId(faceVerifyAliComp.getSceneId());
// 设置商户请求的唯一标识。(请自己生成一个不超过32位数的数字及字母字符串)
LocalDateTime now = LocalDateTime.now();
String timestamp = now.format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
String uuid = UUID.randomUUID().toString().replace("-", "");
String outerOrderNo = timestamp + uuid.substring(0, 14);
request.setOuterOrderNo(outerOrderNo);
// 认证方案。
request.setProductCode("ID_PRO");
// 模式。LIVENESS(默认):眨眼动作活体检测。
request.setModel("LIVENESS");
// 不同证件类型,取值均为IDENTITY_CARD。
request.setCertType("IDENTITY_CARD");
// 您的终端用户的真实姓名。
request.setCertName(name);
// 您的终端用户的证件号码。
request.setCertNo(idCard);
// MetaInfo环境参数,此参数应由前端js获取并传入。
request.setMetaInfo(memInfo.getMetaInfo());
// 认证结束后回跳页面的链接地址。。
request.setReturnUrl(faceVerifyAliComp.getReturnUrl());
request.setCallbackUrl(faceVerifyAliComp.getCallbackUrl());
request.setCallbackToken(cyJwtUtil.getToken(httpServletRequest));
InitFaceVerifyResponse response = initFaceVerifyAutoRoute(request);
log.info("requestId:"+response.getBody().getCode());
log.info("certifyId:"+response.getBody().getResultObject().getCertifyId());
if ("200".equals(response.getBody().getCode())){
map.put("requestId",response.getBody().getRequestId());
map.put("certifyId",response.getBody().getResultObject().getCertifyId());
map.put("certifyUrl",response.getBody().getResultObject().getCertifyUrl());
} else {
log.error("发起认证请求失败:"+response.getBody().getMessage());
throw new CyServiceException("发起认证请求失败");
}
return map;
InitFaceVerifyResponse response = initFaceVerifyAutoRoute(request);
log.info("requestId:" + response.getBody().getCode());
log.info("certifyId:" + response.getBody().getResultObject().getCertifyId());
if ("200".equals(response.getBody().getCode())) {
map.put("requestId", response.getBody().getRequestId());
map.put("certifyId", response.getBody().getResultObject().getCertifyId());
map.put("certifyUrl", response.getBody().getResultObject().getCertifyUrl());
} else {
log.error("发起认证请求失败:" + response.getBody().getMessage());
throw new CyServiceException("发起认证请求失败");
}
return map;
} else
throw new CyServiceException("参数错误,请重新发起验证");
}
private InitFaceVerifyResponse initFaceVerifyAutoRoute(InitFaceVerifyRequest request) {
// 第一个为主区域Endpoint,第二个为备区域Endpoint。
List<String> endpoints = List.of(faceVerifyAliComp.endpoints);
List<String> endpoints = List.of(faceVerifyAliComp.getEndpoints());
InitFaceVerifyResponse lastResponse = null;
for (int i=0; i<endpoints.size(); i++) {
try {
......@@ -184,6 +195,12 @@ public class FaceVerifyServiceImpl extends ServiceImpl<MemInfoRepository, MemInf
// map.put("passed", response.getBody().getResultObject().getPassed());
// map.put("subCode", response.getBody().getResultObject().getSubCode());
if ("T".equals(response.getBody().getResultObject().getPassed())) {
Object detail = cyRedisServiceImpl.get(FaceVerifyRedisBean.FACEVERIFY_USER+userId);
if (detail!=null) {
MemInfo info = JSON.parseObject(JSON.toJSONString(detail), MemInfo.class);
memInfo.setMemIdcard(CyAESUtils.encrypt(info.getMemIdcard()));
memInfo.setMemRealName(CyAESUtils.encrypt(info.getMemRealName()));
}
memInfo.setMemRealAuthen("1");
memInfo.setMemRealAuthenDate(new Date());
memInfoRepository.updateById(memInfo);
......@@ -198,7 +215,7 @@ public class FaceVerifyServiceImpl extends ServiceImpl<MemInfoRepository, MemInf
private DescribeFaceVerifyResponse describeFaceVerifyAutoRoute(DescribeFaceVerifyRequest request) {
// 第一个为主区域Endpoint,第二个为备区域Endpoint。
List<String> endpoints = List.of(faceVerifyAliComp.endpoints);
List<String> endpoints = List.of(faceVerifyAliComp.getEndpoints());
DescribeFaceVerifyResponse lastResponse = null;
for (int i = 0; i < endpoints.size(); i++) {
try {
......@@ -258,6 +275,12 @@ public class FaceVerifyServiceImpl extends ServiceImpl<MemInfoRepository, MemInf
MemInfo memInfo = memInfoRepository.getInfoByUserId(userId);
//认证成功
if ("0".equals(memInfo.getMemRealAuthen()) && "200".equals(passed)) {
Object detail = cyRedisServiceImpl.get(FaceVerifyRedisBean.FACEVERIFY_USER+userId);
if (detail!=null) {
MemInfo info = JSON.parseObject(JSON.toJSONString(detail), MemInfo.class);
memInfo.setMemIdcard(CyAESUtils.encrypt(info.getMemIdcard()));
memInfo.setMemRealName(CyAESUtils.encrypt(info.getMemRealName()));
}
memInfo.setMemRealAuthen("1");
memInfo.setMemRealAuthenDate(new Date());
memInfoRepository.updateById(memInfo);
......
......@@ -194,20 +194,6 @@ public class MemInfoController extends CyPaginationController<MemInfo> {
return CyResultGenUtil.genSuccessResult(memInfoServiceImpl.getArticle(articleExamStatus));
}
@PreAuthorize("@cyPerm.hasPerm('mem:info:update')")
@CyOpeLogAnno(title = "system-会员表管理-修改会员表", businessType = CyLogTypeEnum.UPDATE)
@Operation(summary="修改会员表", description="修改会员表")
@Parameters({@Parameter(name = "businessId", description = "businessId", required = false, schema = @Schema(type = "string"))})
@PutMapping("/updateIdCard/{userId:\\w+}")
// @CyEncryptSm4Anno
public CyResult updateIdCard(@PathVariable int userId, @RequestBody MemInfo memInfo, BindingResult bindingResult) {
memInfo.setUserId(userId);
CyPersistModel data = memInfoServiceImpl.updateIdCard(memInfo);
return CyResultGenUtil.builder(data,
CyMessCons.MESSAGE_ALERT_SUCCESS,
CyMessCons.MESSAGE_ALERT_ERROR,
memInfo);
}
}
......@@ -482,5 +482,13 @@ public class MemInfo extends CyIdIncreEntity<MemInfo> {
*/
@TableField(exist = false)
private String memWxCodeStr;
/**
* @desc 实名认证前端获取信息
* @column metaInfo
* @default
*/
@TableField(exist = false)
private String metaInfo;
}
......@@ -92,5 +92,7 @@ public interface MemInfoService {
ArticleExamStatus getArticle(ArticleExamStatus articleExamStatus );
CyPersistModel checkIdCard(MemInfo memInfo);
CyPersistModel updateIdCard(MemInfo memInfo);
}
......@@ -5,21 +5,24 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jakarta.servlet.http.HttpServletRequest;
import org.apache.commons.lang3.StringUtils;
import org.rcisoft.business.cmsActivity.entity.CmsActivity;
import org.rcisoft.business.faceVerify.bean.FaceVerifyAliComp;
import org.rcisoft.business.faceVerify.bean.FaceVerifyRedisBean;
import org.rcisoft.business.memInfo.bean.MemberGenerateBean;
import org.rcisoft.business.memInfo.entity.ArticleExamStatus;
import org.rcisoft.business.memInfo.entity.opmArticleDTO;
import org.rcisoft.business.memInfo.entity.peopleNumberDTO;
import org.rcisoft.core.constant.CyDelStaCons;
import org.rcisoft.core.constant.CyFlagStaCons;
import org.rcisoft.core.constant.CySmsLoginCons;
import org.rcisoft.core.exception.CyServiceException;
import org.rcisoft.core.util.CyAESUtils;
import org.rcisoft.core.util.CyIdGenUtil;
import org.rcisoft.core.util.CyUserUtil;
import org.rcisoft.core.result.enums.CyResSysExcEnum;
import org.rcisoft.core.service.CyRedisService;
import org.rcisoft.core.util.*;
import org.rcisoft.core.aop.CyPageUtilAsp;
import org.rcisoft.core.model.CyPersistModel;
import org.rcisoft.core.util.CyEpExcelUtil;
import org.rcisoft.business.memInfo.dao.MemInfoRepository;
import org.rcisoft.business.memInfo.entity.MemInfo;
import org.rcisoft.business.memInfo.service.MemInfoService;
......@@ -45,6 +48,8 @@ import java.util.*;
import java.util.stream.Collectors;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
/**
* Created by cy on 2024年12月20日 下午3:35:34.
......@@ -67,7 +72,10 @@ public class MemInfoServiceImpl extends ServiceImpl<MemInfoRepository,MemInfo>
CyIdGenUtil cyIdGenUtil;
@Autowired
MemberGenerateBean memberGenerateBean;
@Autowired
private FaceVerifyAliComp faceVerifyAliComp;
@Autowired
private CyRedisService cyRedisServiceImpl;
@Value("${cy.init.password}")
private String password;
......@@ -420,23 +428,82 @@ public class MemInfoServiceImpl extends ServiceImpl<MemInfoRepository,MemInfo>
*/
@Transactional(propagation = Propagation.REQUIRED,isolation = Isolation.DEFAULT)
@Override
public CyPersistModel updateIdCard(MemInfo memInfo){
public CyPersistModel checkIdCard(MemInfo memInfo){
MemInfo info = baseMapper.getInfoByUserId(String.valueOf(memInfo.getUserId()));
if ("1".equals(info.getMemRealAuthen()))
throw new CyServiceException("用户已实名,无需再次实名认证");
//手机号、身份证存储加密
if (StringUtils.isNotBlank(memInfo.getMemIdcard()))
info.setMemIdcard(CyAESUtils.encrypt(memInfo.getMemIdcard()));
if (StringUtils.isNotBlank(memInfo.getMemRealName()))
info.setMemRealName(CyAESUtils.encrypt(memInfo.getMemRealName()));
// if (StringUtils.isNotBlank(memInfo.getMemIdcard()))
// info.setMemIdcard(CyAESUtils.encrypt(memInfo.getMemIdcard()));
// if (StringUtils.isNotBlank(memInfo.getMemRealName()))
// info.setMemRealName(CyAESUtils.encrypt(memInfo.getMemRealName()));
//身份证、手机号验重
SysUserRbacDTO sysUserRbacDTO = baseMapper.checkIdcardRepeat(memInfo.getUserId(),memInfo.getMemIdcard());
if (sysUserRbacDTO != null) {
throw new CyServiceException(UserInfoExceptionEnums.ID_NUMBER_EXISTS);
}
//验证失败次数
//获取ip
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
String ip = CyAddressUtils.IpUtils.getIpAddr(request);
//1. 同一IP,每分钟失败次数
Object captcha = cyRedisServiceImpl.get(FaceVerifyRedisBean.FACEVERIFY_IP_MINUTES + ip);
if (captcha != null) {
int count = (int)captcha;
if (count >= faceVerifyAliComp.getIpMinCount())
throw new CyServiceException("实名认证发起频繁,请稍后重试");
}
//2. 同一IP,每天失败次数
captcha = cyRedisServiceImpl.get(FaceVerifyRedisBean.FACEVERIFY_IP_DAY + ip);
if (captcha != null) {
int count = (int)captcha;
if (count >= faceVerifyAliComp.getIpDayCount())
throw new CyServiceException("实名认证发起频繁,请稍后重试");
}
//3. 同一身份证,每分钟失败次数
captcha = cyRedisServiceImpl.get(FaceVerifyRedisBean.FACEVERIFY_IDCARD_MINUTES + memInfo.getMemIdcard());
if (captcha != null) {
int count = (int)captcha;
if (count >= faceVerifyAliComp.getIdCardMinCount())
throw new CyServiceException("实名认证发起频繁,请稍后重试");
}
//4. 同一身份证,每天失败次数
captcha = cyRedisServiceImpl.get(FaceVerifyRedisBean.FACEVERIFY_IDCARD_DAY + memInfo.getMemIdcard());
if (captcha != null) {
int count = (int)captcha;
if (count >= faceVerifyAliComp.getIdCardDayCount())
throw new CyServiceException("实名认证发起频繁,请稍后重试");
}
cyRedisServiceImpl.set(FaceVerifyRedisBean.FACEVERIFY_USER+memInfo.getUserId(),memInfo,3600L);
return new CyPersistModel(1);
}
/**
* 修改 会员表
* @param memInfo
* @return
*/
@Transactional(propagation = Propagation.REQUIRED,isolation = Isolation.DEFAULT)
@Override
public CyPersistModel updateIdCard(MemInfo memInfo){
//手机号、身份证存储加密
if (StringUtils.isNotBlank(memInfo.getMemPhone()))
memInfo.setMemPhone(CyAESUtils.encrypt(memInfo.getMemPhone()));
memInfo.setMemIdcard(null);
memInfo.setMemRealName(null);
//身份证、手机号验重
SysUserRbacDTO sysUserRbacDTO = baseMapper.checkPhoneRepeat(memInfo.getUserId(),memInfo.getMemPhone());
if (sysUserRbacDTO != null) {
throw new CyServiceException(UserInfoExceptionEnums.PHONE_EXISTS);
}
//修改sys_user
SysUserRbac userRbac = sysUserRbacRepository.selectById(memInfo.getUserId());
userRbac.setIdNumber(memInfo.getMemIdcard());
SysUserRbac userRbac = new SysUserRbac();
userRbac.setBusinessId(memInfo.getUserId());
userRbac.setPhone(memInfo.getMemPhone());
userRbac.setSex(memInfo.getMemSex());
userRbac.setNickName(memInfo.getMemNickName());
sysUserRbacRepository.updateById(userRbac);
int line = baseMapper.updateById(info);
int line = baseMapper.updateById(memInfo);
log.debug(CyUserUtil.getAuthenUsername()+"修改了ID为"+ memInfo.getBusinessId()+"的会员表信息");
return new CyPersistModel(line);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment