feat:查询并发

This commit is contained in:
dzc committed 2025-12-11 16:05:45 +08:00
1 parent 6615fcaf77
commit fb3526b728
7 files changed
+84 -55

No files matched your search

@@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.member.controller.admin.thirdcallback;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import cn.iocoder.yudao.framework.common.util.date.DateUtils;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore;
import cn.iocoder.yudao.module.member.client.service.ThirdFaceVerifyService;
@@ -12,6 +13,7 @@ import cn.iocoder.yudao.module.member.dal.dataobject.comauth.ComAuthDO;
import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO;
import cn.iocoder.yudao.module.member.dal.mysql.comauth.ComAuthMapper;
import cn.iocoder.yudao.module.member.dal.mysql.user.MemberUserMapper;
import cn.iocoder.yudao.module.member.dal.redis.recent.MemberRecentRedisDAO;
import cn.iocoder.yudao.module.member.enums.auth.MemberComAuthStatusEnum;
import cn.iocoder.yudao.module.member.framework.web.config.ThirdAlConfig;
import cn.iocoder.yudao.module.member.service.user.MemberRecentTagService;
@@ -31,6 +33,13 @@ import java.time.LocalDateTime;
@Validated
@Slf4j
public class ThirdCallbackController {
/**
* 通知超时时间,单位:毫秒
*/
public static final long UPDATE_TIMEOUT_MILLIS = 120 * DateUtils.SECOND_MILLIS;
@Resource
private MemberRecentRedisDAO recentRedisDAO;
@Resource
private ThirdAlConfig thirdAlConfig;
@@ -48,49 +57,51 @@ public class ThirdCallbackController {
@GetMapping("/face-verify")
@Operation(summary = "人脸认证回调")
@PermitAll
@TenantIgnore
public void faceVerify(FaceVerifyCallbackReqVo query) {
log.info("人脸认证回调,params={}", JSONUtil.toJsonStr(query));
if (!ObjectUtil.isAllNotEmpty(query.getCallbackToken(), query.getCertifyId(), query.getPassed())) {
log.error("人脸认证回调,参数错误");
return;
}
// 检查token
if (ObjectUtil.notEqual(query.getCallbackToken(), thirdAlConfig.getFaceVerifyCallbackToken())) {
log.error("人脸认证回调,token校验错误,传入的token={}", query.getCallbackToken());
return;
}
String certifyId = query.getCertifyId();
// 查询认证订单
ComAuthDO auth = comAuthMapper.selectOne(new LambdaQueryWrapperX<ComAuthDO>()
.eq(ComAuthDO::getBizId, certifyId)
.last("limit 1")
);
if (ObjectUtil.isEmpty(auth)) {
log.error("人脸认证回调,认证订单不存在,authId={}", query.getCertifyId());
return;
}
// 手动查询
ThirdFindFaceVerifyReqVo dto = new ThirdFindFaceVerifyReqVo();
dto.setCertifyId(query.getCertifyId());
ThirdFindFaceVerifyResVo faceVerifyRes = thirdFaceVerifyService.findFaceVerify(dto);
if (ObjectUtil.isEmpty(faceVerifyRes)) {
log.error("人脸认证回调,主动查询,第三方接口无响应");
return;
}
ComAuthDO updateObj = new ComAuthDO();
updateObj.setFailReason(faceVerifyRes.getErrorMessage());
if (faceVerifyRes.isPassed()) {
updateObj.setAuthStatus(MemberComAuthStatusEnum.CHECK_PASS.getType());
memberRecentTagService.setPersonTag(auth.getAuthMemberId(), true);
}
if (faceVerifyRes.isNotPassed()) {
updateObj.setAuthStatus(MemberComAuthStatusEnum.CHECK_FAIL.getType());
}
updateObj.setId(auth.getId());
updateObj.setAuthTime(LocalDateTime.now());
updateObj.setFailReason("验证失败");
authMapper.updateById(updateObj);
public void faceVerify(FaceVerifyCallbackReqVo query) throws Exception {
// 加锁
recentRedisDAO.comAuthLock(query.getCertifyId(), UPDATE_TIMEOUT_MILLIS, () -> {
log.info("人脸认证回调,params={}", JSONUtil.toJsonStr(query));
if (!ObjectUtil.isAllNotEmpty(query.getCallbackToken(), query.getCertifyId(), query.getPassed())) {
log.error("人脸认证回调,参数错误");
return;
}
// 检查token
if (ObjectUtil.notEqual(query.getCallbackToken(), thirdAlConfig.getFaceVerifyCallbackToken())) {
log.error("人脸认证回调,token校验错误,传入的token={}", query.getCallbackToken());
return;
}
String certifyId = query.getCertifyId();
// 查询认证订单
ComAuthDO auth = comAuthMapper.selectOne(new LambdaQueryWrapperX<ComAuthDO>()
.eq(ComAuthDO::getBizId, certifyId)
.last("limit 1")
);
if (ObjectUtil.isEmpty(auth)) {
log.error("人脸认证回调,认证订单不存在,authId={}", query.getCertifyId());
return;
}
// 手动查询
ThirdFindFaceVerifyReqVo dto = new ThirdFindFaceVerifyReqVo();
dto.setCertifyId(query.getCertifyId());
ThirdFindFaceVerifyResVo faceVerifyRes = thirdFaceVerifyService.findFaceVerify(dto);
if (ObjectUtil.isEmpty(faceVerifyRes)) {
log.error("人脸认证回调,主动查询,第三方接口无响应");
return;
}
ComAuthDO updateObj = new ComAuthDO();
updateObj.setFailReason(faceVerifyRes.getErrorMessage());
if (faceVerifyRes.isPassed()) {
updateObj.setAuthStatus(MemberComAuthStatusEnum.CHECK_PASS.getType());
memberRecentTagService.setPersonTag(auth.getAuthMemberId(), true);
}
if (faceVerifyRes.isNotPassed()) {
updateObj.setAuthStatus(MemberComAuthStatusEnum.CHECK_FAIL.getType());
}
updateObj.setId(auth.getId());
updateObj.setAuthTime(LocalDateTime.now());
updateObj.setFailReason("验证失败");
authMapper.updateById(updateObj);
});
}
}
@@ -15,8 +15,8 @@ public class CreateWechatAuthReqVo {
@Schema(description = "会员编号")
private Long memberId;
@Schema(description = "认证图片")
@NotEmpty(message = "认证图片不能为空")
@Schema(description = "微信号")
@NotEmpty(message = "微信号不能为空")
private String wechatNumber;
@Schema(description = "微信二维码")
@@ -7,4 +7,6 @@ public interface RedisKeyConstants {
String MEMBER_RECENT_CFG = "member:recent:cfg:%d";
String MEMBER_COM_AUTH_CALLBACK = "member:com:auth:callback:%s";
}
@@ -19,7 +19,7 @@ public class MemberRecentRedisDAO {
private RedissonClient redissonClient;
public <V> V lock(Long id, Long timeoutMillis, Callable<V> callable) throws Exception {
String lockKey = formatKey(id);
String lockKey = String.format(RedisKeyConstants.MEMBER_RECENT_CFG, id);
RLock lock = redissonClient.getLock(lockKey);
try {
lock.lock(timeoutMillis, TimeUnit.MILLISECONDS);
@@ -32,8 +32,16 @@ public class MemberRecentRedisDAO {
}
}
private static String formatKey(Long id) {
return String.format(RedisKeyConstants.MEMBER_RECENT_CFG, id);
}
public void comAuthLock(String id, Long timeoutMillis, Runnable runnable) throws Exception {
String lockKey = String.format(RedisKeyConstants.MEMBER_COM_AUTH_CALLBACK, id);
RLock lock = redissonClient.getLock(lockKey);
try {
lock.lock(timeoutMillis, TimeUnit.MILLISECONDS);
// 执行逻辑
runnable.run();
} finally {
lock.unlock();
}
}
}
@@ -15,6 +15,7 @@ import cn.iocoder.yudao.module.member.controller.admin.user.vo.MemberUserUpdateR
import cn.iocoder.yudao.module.member.controller.app.auth.vo.*;
import cn.iocoder.yudao.module.member.convert.auth.AuthConvert;
import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO;
import cn.iocoder.yudao.module.member.service.user.MemberRecentCfgService;
import cn.iocoder.yudao.module.member.service.user.MemberRecentTagService;
import cn.iocoder.yudao.module.member.service.user.MemberUserService;
import cn.iocoder.yudao.module.system.api.logger.LoginLogApi;
@@ -59,6 +60,8 @@ public class MemberAuthServiceImpl implements MemberAuthService {
private MemberUserService userService;
@Resource
private MemberRecentTagService memberRecentTagService;
@Resource
private MemberRecentCfgService memberRecentCfgService;
@Resource
private SmsCodeApi smsCodeApi;
@@ -258,6 +261,8 @@ public class MemberAuthServiceImpl implements MemberAuthService {
}
// 更新朋友圈用户新人tag
memberRecentTagService.createOrUpdateNewPersonTag(user.getId());
// 初始化用户朋友圈配置
memberRecentCfgService.getOrCreate(user.getId());
return serviceToken;
}
@@ -282,7 +287,8 @@ public class MemberAuthServiceImpl implements MemberAuthService {
// 更新朋友圈用户新人tag
memberRecentTagService.createOrUpdateNewPersonTag(user.getId());
// 初始化用户朋友圈配置
memberRecentCfgService.getOrCreate(user.getId());
return serviceToken;
}
@@ -763,8 +763,10 @@ public class RecentServiceImpl implements RecentService {
}
// 查询用户最新的位置(根据位置的查询)
LocationDO locationDO = locationService.getCurrentUserLastLocation();
resultQuery.setCurrentLat(locationDO.getLat());
resultQuery.setCurrentLng(locationDO.getLon());
if (ObjectUtil.isNotEmpty(locationDO)) {
resultQuery.setCurrentLat(locationDO.getLat());
resultQuery.setCurrentLng(locationDO.getLon());
}
// 排除黑名单
List<Long> blackUserIdList = operationService.getBlackUserIdList(operationUser.getId());
if (ObjectUtil.isNotEmpty(blackUserIdList)) {
@@ -90,7 +90,7 @@
order by a.create_time desc , a.id desc
</if>
<!-- 动态-附近 -->
<if test="dto.sceneBizType == '2'.toString() ">
<if test="dto.sceneBizType == '2'.toString() and dto.currentLat != null and dto.currentLng != null ">
order by a.create_time asc , distance desc
</if>
</when>
@@ -102,7 +102,7 @@
<select id="pageUserJoin" resultType="cn.iocoder.yudao.module.member.controller.admin.recent.vo.RecentPageResVo">
select u.id as memberId,
<if test="dto.currentLat != null and dto.currentLng != null ">
<if test="dto.currentLat != null and dto.currentLng != null">
(6371 * acos(
cos(radians(#{dto.currentLat})) *
cos(radians(u.lat)) *
@@ -147,7 +147,7 @@
</if>
</where>
group by u.id
<if test="dto.distanceIsNotNull != null and dto.distanceIsNotNull == true ">
<if test="dto.distanceIsNotNull != null and dto.distanceIsNotNull == true and dto.currentLat != null and dto.currentLng != null">
having distance is not null
</if>
<choose>