package com.cyksj.service.user.impl; import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.cyksj.common.EnvCommonService; import com.cyksj.common.exception.BusinessRuntimeException; import com.cyksj.common.snowflake.Sequence; import com.cyksj.common.util.Jsons; import com.cyksj.common.util.StringUtil; import com.cyksj.mapper.UserCertRecordMapper; import com.cyksj.mapper.UserMapper; import com.cyksj.model.dto.UserWxIndentDto; import com.cyksj.model.entity.User; import com.cyksj.model.entity.UserCertRecord; import com.cyksj.model.request.UserIndentCertReq; import com.cyksj.model.response.WxCertAuthTokenResp; import com.cyksj.redis.RedisService; import com.cyksj.service.user.UserBindRelationService; import com.cyksj.service.user.UserIdentCertService; import com.tencentcloudapi.common.Credential; import com.tencentcloudapi.common.profile.ClientProfile; import com.tencentcloudapi.common.profile.HttpProfile; import com.tencentcloudapi.faceid.v20180301.FaceidClient; import com.tencentcloudapi.faceid.v20180301.models.*; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import java.util.List; /** * 项目名: yhlxj2 * 文件名: UserIdentCertServiceImpl * 创建者: JavaZou * 创建时间:2024/2/21 10:21 */ @Service @RequiredArgsConstructor @Slf4j public class UserIdentCertServiceImpl implements UserIdentCertService { private final UserBindRelationService userBindRelationService; private final UserCertRecordMapper userCertRecordMapper; private final UserMapper userMapper; private final RedisService redisService; private final EnvCommonService envCommonService; private final static Sequence SEQUENCE = new Sequence(0); private static final String TENCENT_SECRET_ID = "AKIDBB3jEqR0Y95zpfTix1vd6fMqAIahc4Ka"; private static final String TENCENT_SECRET_KEY = "c6YtNm63rcQ1QdiGmEbmEPSTPF3e4KQK"; private static final String ruleId = "1"; private static final String REDIRECT_URL = "applets/user/cert/auth/result/"; @Override public Boolean checkCertRecord(long userId) { List userIdList = userBindRelationService.getRelationUserIdList(userId, null); Integer count = userCertRecordMapper.selectCount(Wrappers.lambdaQuery(UserCertRecord.class) .in(UserCertRecord::getUserId, userIdList)); return count > 0 ? true : false; } @Override public UserCertRecord getUserCertRecord(long userId) { List userIdList = userBindRelationService.getRelationUserIdList(userId, null); UserCertRecord record = userCertRecordMapper.selectOne(Wrappers.lambdaQuery(UserCertRecord.class) .in(UserCertRecord::getUserId, userIdList) .select(UserCertRecord::getName, UserCertRecord::getIdent, UserCertRecord::getCreatedTime) .last("limit 1")); if (record == null) { return null; } record.setIdent(StringUtil.deIndent(record.getIdent())); return record; } @Override public String bindWxUser(long userId) { User user = userMapper.selectById(userId); if (StrUtil.isNotBlank(user.getOpenId())) { return null; } String state = StringUtil.randomString(6); redisService.set(RedisService.key.WX_INDENT_BIND_KEY.getEnvName() + state, userId, RedisService.key.WX_INDENT_BIND_KEY.getTimeout()); return state; } @Override public WxCertAuthTokenResp wxH5IndentCert(UserIndentCertReq indentCertReq) throws Exception { Long userId = indentCertReq.getUserId(); String redirectUrl = indentCertReq.getRedirectUrl(); List userIdList = userBindRelationService.getRelationUserIdList(userId, null); // String bindState = indentCertReq.getBindState(); // if (userIdList.size() == 1 && StrUtil.isNotEmpty(bindState)) { // User user = userMapper.selectById(userId); // if (StrUtil.isEmpty(user.getOpenId())) { // String key = RedisService.key.WX_INDENT_BIND_KEY.getEnvName() + bindState; // Object bindInfo = redisService.get(key); // if (bindInfo == null) { // throw BusinessRuntimeException.getInstance("认证信息已失效,请重新操作.."); // } // Long bindUserId = Long.parseLong(bindInfo.toString()); // User bindUser = userMapper.selectById(bindUserId); // //绑定微信端用户 // UserBindInfoReq request = new UserBindInfoReq(); // request.setType(StrUtil.isNotBlank(bindUser.getLoginPhone()) ? 1 : 2); // request.setUserId(userId); // request.setAccount(request.getType() == 1 ? bindUser.getLoginPhone() : bindUser.getEmail()); // bindTaskService.bindOtherAccount(request); // userIdList = userBindRelationService.getRelationUserIdList(userId, null); // redisService.del(key); // } // } Integer count = userCertRecordMapper.selectCount(Wrappers.lambdaQuery(UserCertRecord.class) .in(UserCertRecord::getUserId, userIdList)); if (count > 0) throw BusinessRuntimeException.getInstance("您已完成认证了.."); Credential cred = new Credential(TENCENT_SECRET_ID, TENCENT_SECRET_KEY); // 实例化一个http选项,可选的,没有特殊需求可以跳过 HttpProfile httpProfile = new HttpProfile(); httpProfile.setEndpoint("faceid.tencentcloudapi.com"); // 实例化一个client选项,可选的,没有特殊需求可以跳过 ClientProfile clientProfile = new ClientProfile(); clientProfile.setHttpProfile(httpProfile); // 实例化要请求产品的client对象,clientProfile是可选的 FaceidClient client = new FaceidClient(cred, "", clientProfile); // 实例化一个请求对象,每个接口都会对应一个request对象 DetectAuthRequest req = new DetectAuthRequest(); req.setRuleId(ruleId); Long mappingId = SEQUENCE.nextId(); req.setRedirectUrl(envCommonService.getHost() + REDIRECT_URL + mappingId); // 返回的resp是一个DetectAuthResponse的实例,与请求对象对应 DetectAuthResponse resp = client.DetectAuth(req); log.info("微信h5核身认证,返回:{}", Jsons.toJson(resp)); WxCertAuthTokenResp tokenResp = new WxCertAuthTokenResp(); BeanUtil.copyProperties(resp, tokenResp); UserWxIndentDto userWxIndentDto = new UserWxIndentDto(); userWxIndentDto.setUserId(userId); userWxIndentDto.setRedirectUrl(redirectUrl); userWxIndentDto.setBizToken(tokenResp.getBizToken()); redisService.set(mappingId.toString(), Jsons.toJson(userWxIndentDto), 60 * 60 * 24L); return tokenResp; } @Override public void wxH5IndentCertResult(UserWxIndentDto userWxIndentDto) throws Exception { Long userId = userWxIndentDto.getUserId(); Credential cred = new Credential(TENCENT_SECRET_ID, TENCENT_SECRET_KEY); // 实例化一个http选项,可选的,没有特殊需求可以跳过 HttpProfile httpProfile = new HttpProfile(); httpProfile.setEndpoint("faceid.tencentcloudapi.com"); // 实例化一个client选项,可选的,没有特殊需求可以跳过 ClientProfile clientProfile = new ClientProfile(); clientProfile.setHttpProfile(httpProfile); // 实例化要请求产品的client对象,clientProfile是可选的 FaceidClient client = new FaceidClient(cred, "", clientProfile); // 实例化一个请求对象,每个接口都会对应一个request对象 GetDetectInfoEnhancedRequest req = new GetDetectInfoEnhancedRequest(); req.setBizToken(userWxIndentDto.getBizToken()); req.setRuleId(ruleId); // 返回的resp是一个GetDetectInfoEnhancedResponse的实例,与请求对象对应 GetDetectInfoEnhancedResponse resp = client.GetDetectInfoEnhanced(req); DetectInfoText text = resp.getText(); if (text.getErrCode() == 0) { UserCertRecord certRecord = new UserCertRecord(); String ocrIdCard = text.getOcrIdCard(); Integer count = userCertRecordMapper.selectCount(Wrappers.lambdaQuery(UserCertRecord.class) .eq(UserCertRecord::getIdent, ocrIdCard)); if (count > 0) { throw BusinessRuntimeException.getInstance("该身份证号已被其他账号绑定"); } if (count == 0) { certRecord.setIdent(text.getOcrIdCard()); certRecord.setName(text.getOcrName()); certRecord.setSex(text.getOcrGender()); certRecord.setUserId(userId); certRecord.setAddr(text.getOcrAddress()); userCertRecordMapper.insert(certRecord); } } } }