debug:微信用户注册加锁

This commit is contained in:
磷叶 2024-10-25 15:07:09 +08:00
parent f85e151b3b
commit 9c7c87b3f9
9 changed files with 84 additions and 41 deletions

View File

@ -24,7 +24,9 @@ public enum RedisLockKey {
PREPAY_DEPOSIT("prepay_deposit", "支付押金"),
ADD_RECHARGE_ORDER("add_recharge_order", "创建充值订单"),
PAY_BILL_SUCCESS("pay_bill_success", "支付订单成功处理"),
RECOVER_DEVICE_BALANCE("recover_device_balance", "恢复设备余额");
RECOVER_DEVICE_BALANCE("recover_device_balance", "恢复设备余额"),
ADD_USER_WX_OPEN_ID("add_user_wx_open_id", "微信注册用户"),
ADD_USER_MOBILE("add_user_mobile", "手机号注册用户");
private final String key;

View File

@ -260,7 +260,6 @@ public class SysLoginService
/**
* 微信登录
*/
@Transactional
public String wxLogin(WxLoginBody body) {
// 通过openId查询用户

View File

@ -32,4 +32,7 @@ public class SmUserQuery extends SmUser {
@ApiModelProperty("用户手机号精准匹配")
private String eqPhonenumber;
@ApiModelProperty("排除的用户ID")
private Long excludeUserId;
}

View File

@ -64,7 +64,7 @@ public interface SmUserMapper
*/
public int deleteSmUserByUserIds(Long[] userIds);
Integer selectCount(SmUserQuery dto);
int selectCount(SmUserQuery dto);
int addBalance(@Param("userId") Long userId, @Param("amount") BigDecimal amount);

View File

@ -88,6 +88,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="limitRefund != null "> and limit_refund = #{limitRefund}</if>
<if test="readMchLicence != null "> and read_mch_licence = #{readMchLicence}</if>
<if test="showBillMobile != null "> and show_bill_mobile = #{showBillMobile}</if>
<if test="excludeUserId != null">and su.user_id != #{excludeUserId}</if>
<if test="tenantDeviceId != null">
and su.user_id in (
select sdt.tenant_id
@ -126,7 +127,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<select id="selectSmUserByWxOpenId" resultMap="SmUserResult">
<include refid="selectSmUserVo"/>
where su.wx_open_id = #{openId} and su.del_flag = '0'
where su.wx_open_id = #{openId} and su.del_flag = '0' limit 1
</select>
<select id="selectSimpleById" resultMap="SmUserResult">

View File

@ -85,7 +85,7 @@ public interface ISmUserService
* @param dto
* @return
*/
Integer selectCount(SmUserQuery dto);
int selectCount(SmUserQuery dto);
/**
* 根据手机号查询用户

View File

@ -1,6 +1,7 @@
package com.ruoyi.ss.user.service;
import com.ruoyi.common.core.domain.ValidateResult;
import com.ruoyi.common.core.domain.entity.SmUser;
import com.ruoyi.ss.user.domain.SmUserVo;
import java.util.List;
@ -36,12 +37,19 @@ public interface UserValidator {
/**
* 校验手机号
* @param vo
*
* @param userId
* @param mobile
*/
void checkMobile(SmUserVo vo);
void checkMobile(Long userId, String mobile);
/**
* 后校验
*/
void afterCheck(SmUserVo vo);
/**
* 插入前校验
*/
void checkBeforeInsert(SmUser smUser);
}

View File

@ -4,6 +4,8 @@ import com.ruoyi.common.auth.wx.WxAuthService;
import com.ruoyi.common.constant.CacheConstants;
import com.ruoyi.common.core.domain.entity.SmUser;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.core.redis.RedisLock;
import com.ruoyi.common.core.redis.enums.RedisLockKey;
import com.ruoyi.common.enums.UserType;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.DateUtils;
@ -111,6 +113,9 @@ public class SmUserServiceImpl implements ISmUserService
@Autowired
private IRiskService riskService;
@Autowired
private RedisLock redisLock;
/**
* 查询普通用户信息
*
@ -154,7 +159,7 @@ public class SmUserServiceImpl implements ISmUserService
}
@Override
public Integer selectCount(SmUserQuery dto) {
public int selectCount(SmUserQuery dto) {
return smUserMapper.selectCount(dto);
}
@ -562,7 +567,7 @@ public class SmUserServiceImpl implements ISmUserService
// 后校验
SmUserVo vo = this.selectSmUserByUserId(userId);
userValidator.checkMobile(vo);
userValidator.checkMobile(vo.getUserId(), vo.getPhonenumber());
return update;
});
@ -639,9 +644,11 @@ public class SmUserServiceImpl implements ISmUserService
* @return 结果
*/
@Override
@Transactional
public int insertSmUser(SmUser smUser)
{
// 前置校验
userValidator.checkBeforeInsert(smUser);
// 设置用户默认信息
if (StringUtils.hasText(smUser.getPassword())) {
smUser.setPassword(SecurityUtils.encryptPassword(smUser.getPassword()));
@ -653,17 +660,35 @@ public class SmUserServiceImpl implements ISmUserService
smUser.setServiceRate(serviceRate);
}
Integer result = transactionTemplate.execute(status -> {
int insert = smUserMapper.insertSmUser(smUser);
ServiceUtil.assertion(insert != 1, "新增用户失败,请刷新后重试");
// 若有wxOpenId则加锁
if (StringUtils.hasText(smUser.getWxOpenId())) {
ServiceUtil.assertion(!redisLock.lock(RedisLockKey.ADD_USER_WX_OPEN_ID, smUser.getWxOpenId()), "请勿频繁注册相同的微信openId");
}
try {
// 若有手机号则加锁
if (StringUtils.hasText(smUser.getPhonenumber())) {
ServiceUtil.assertion(!redisLock.lock(RedisLockKey.ADD_USER_MOBILE, smUser.getPhonenumber()), "请勿频繁注册相同的手机号");
}
try {
Integer result = transactionTemplate.execute(status -> {
// 插入数据
int insert = smUserMapper.insertSmUser(smUser);
ServiceUtil.assertion(insert != 1, "新增用户失败,请刷新后重试");
SmUserVo vo = this.selectSmUserByUserId(smUser.getUserId());
userValidator.afterCheck(vo);
// 后校验
SmUserVo vo = this.selectSmUserByUserId(smUser.getUserId());
userValidator.afterCheck(vo);
return insert;
});
return insert;
});
return result == null ? 0 : result;
return result == null ? 0 : result;
} finally {
redisLock.unlock(RedisLockKey.ADD_USER_MOBILE, smUser.getPhonenumber());
}
} finally {
redisLock.unlock(RedisLockKey.ADD_USER_WX_OPEN_ID, smUser.getWxOpenId());
}
}
// 根据微信openId查询信息

View File

@ -2,6 +2,7 @@ package com.ruoyi.ss.user.service.impl;
import com.ruoyi.common.core.domain.BaseValidator;
import com.ruoyi.common.core.domain.ValidateResult;
import com.ruoyi.common.core.domain.entity.SmUser;
import com.ruoyi.common.enums.UserStatus;
import com.ruoyi.common.utils.ServiceUtil;
import com.ruoyi.common.utils.StringUtils;
@ -18,7 +19,6 @@ import org.springframework.util.CollectionUtils;
import java.math.BigDecimal;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
/**
* @author wjh
@ -45,7 +45,7 @@ public class UserValidatorImpl extends BaseValidator implements UserValidator {
}
SmUserQuery query = new SmUserQuery();
query.setUserIds(userIds);
Integer userCount = userService.selectCount(query);
int userCount = userService.selectCount(query);
return userCount == new HashSet<Long>(userIds).size();
}
@ -98,18 +98,15 @@ public class UserValidatorImpl extends BaseValidator implements UserValidator {
}
@Override
public void checkMobile(SmUserVo vo) {
if (vo == null) {
public void checkMobile(Long userId, String mobile) {
if (StringUtils.isBlank(mobile)) {
return;
}
// 校验手机是否重复
if (StringUtils.hasText(vo.getPhonenumber())) {
SmUserQuery query = new SmUserQuery();
query.setEqPhonenumber(vo.getPhonenumber());
Integer repeatCount = userService.selectCount(query);
ServiceUtil.assertion(repeatCount > 1, "用户手机号重复");
}
SmUserQuery query = new SmUserQuery();
query.setEqPhonenumber(mobile);
query.setExcludeUserId(userId);
int repeatCount = userService.selectCount(query);
ServiceUtil.assertion(repeatCount > 0, "用户手机号重复");
}
@Override
@ -119,16 +116,25 @@ public class UserValidatorImpl extends BaseValidator implements UserValidator {
}
// 校验手机号
this.checkMobile(vo);
this.checkMobile(vo.getUserId(), vo.getPhonenumber());
// 校验openId
this.checkOpenId(vo);
this.checkOpenId(vo.getUserId(), vo.getWxOpenId());
// 校验代理商服务费
this.checkAgentServiceRate(vo);
}
@Override
public void checkBeforeInsert(SmUser data) {
ServiceUtil.assertion(data == null, "新增用户数据不允许为空");
// 手机号校验
this.checkMobile(data.getUserId(), data.getPhonenumber());
// 微信openId校验
this.checkOpenId(data.getUserId(), data.getWxOpenId());
}
private void checkAgentServiceRate(SmUserVo vo) {
if (vo == null) {
return;
@ -149,15 +155,14 @@ public class UserValidatorImpl extends BaseValidator implements UserValidator {
}
// 判断微信openId是否重复
private void checkOpenId(SmUserVo vo) {
if (vo == null) {
return;
}
if (StringUtils.hasText(vo.getWxOpenId())) {
SmUserQuery query = new SmUserQuery();
query.setWxOpenId(vo.getWxOpenId());
Integer repeatCount = userService.selectCount(query);
ServiceUtil.assertion(repeatCount > 1, "用户微信OpenId重复");
private void checkOpenId(Long userId, String wxOpenId) {
if (StringUtils.isBlank(wxOpenId)) {
return ;
}
SmUserQuery query = new SmUserQuery();
query.setWxOpenId(wxOpenId);
query.setExcludeUserId(userId);
int repeatCount = userService.selectCount(query);
ServiceUtil.assertion(repeatCount > 0, "用户微信OpenId重复");
}
}