添加用户要求信息
This commit is contained in:
@@ -33,6 +33,6 @@ public class LoginController {
|
||||
public LoginVo smsLogin(@Validated @RequestBody SmsLoginDto dto,
|
||||
HttpServletRequest request,
|
||||
HttpServletResponse response) {
|
||||
return loginServer.smsLogin(dto.getMobileNumber(), dto.getCode(), request, response);
|
||||
return loginServer.smsLogin(dto.getMobileNumber(), dto.getCode(), dto.getInviteCode(), request, response);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,4 +17,9 @@ public class SmsLoginDto {
|
||||
|
||||
@NotBlank(message = "验证码不能为空")
|
||||
private String code;
|
||||
|
||||
/**
|
||||
* 邀请码(可选)
|
||||
*/
|
||||
private String inviteCode;
|
||||
}
|
||||
|
||||
@@ -59,6 +59,9 @@ public class LoginServer {
|
||||
@Autowired
|
||||
private RedisServerTool redisServerTool;
|
||||
|
||||
@Autowired
|
||||
private UserRegisterServer userRegisterServer;
|
||||
|
||||
/**
|
||||
* 发送短信验证码
|
||||
*/
|
||||
@@ -76,7 +79,7 @@ public class LoginServer {
|
||||
* 短信验证码登录
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public LoginVo smsLogin(String mobileNumber, String code, HttpServletRequest request, HttpServletResponse response) {
|
||||
public LoginVo smsLogin(String mobileNumber, String code, String inviteCode, HttpServletRequest request, HttpServletResponse response) {
|
||||
Assert.hasText(mobileNumber, "手机号不能为空");
|
||||
Assert.hasText(code, "验证码不能为空");
|
||||
|
||||
@@ -91,13 +94,7 @@ public class LoginServer {
|
||||
|
||||
// 用户不存在则自动注册
|
||||
if (user == null) {
|
||||
user = new User();
|
||||
user.setMobileNumber(mobileNumber);
|
||||
user.setNick("用户" + mobileNumber.substring(mobileNumber.length() - 4));
|
||||
user.setStatus(0);
|
||||
user.setIsDelete(0L);
|
||||
user.setCreateTime(Instant.now());
|
||||
userMapper.insert(user);
|
||||
user = userRegisterServer.register(mobileNumber, inviteCode);
|
||||
}
|
||||
|
||||
// 检查用户状态
|
||||
|
||||
@@ -0,0 +1,126 @@
|
||||
package org.jiayunet.server;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.jiayunet.exception.BusinessException;
|
||||
import org.jiayunet.exception.BusinessExpCodeEnum;
|
||||
import org.jiayunet.mapper.UserInviteMapper;
|
||||
import org.jiayunet.mapper.UserMapper;
|
||||
import org.jiayunet.pojo.po.User;
|
||||
import org.jiayunet.pojo.po.UserInvite;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.security.SecureRandom;
|
||||
import java.time.Instant;
|
||||
|
||||
/**
|
||||
* 用户注册服务
|
||||
*
|
||||
* @author zk
|
||||
*/
|
||||
@Service
|
||||
@Slf4j
|
||||
public class UserRegisterServer {
|
||||
|
||||
/**
|
||||
* 邀请码字符集(大写字母+数字)
|
||||
*/
|
||||
private static final String INVITE_CODE_CHARS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||
|
||||
/**
|
||||
* 邀请码长度
|
||||
*/
|
||||
private static final int INVITE_CODE_LENGTH = 10;
|
||||
|
||||
/**
|
||||
* 安全随机数生成器
|
||||
*/
|
||||
private static final SecureRandom RANDOM = new SecureRandom();
|
||||
|
||||
@Autowired
|
||||
private UserMapper userMapper;
|
||||
|
||||
@Autowired
|
||||
private UserInviteMapper userInviteMapper;
|
||||
|
||||
/**
|
||||
* 注册新用户
|
||||
*
|
||||
* @param mobileNumber 手机号
|
||||
* @param inviteCode 邀请码(可选)
|
||||
* @return 新注册的用户
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public User register(String mobileNumber, String inviteCode) {
|
||||
// 创建用户
|
||||
User user = new User();
|
||||
user.setMobileNumber(mobileNumber);
|
||||
user.setNick("用户" + mobileNumber.substring(mobileNumber.length() - 4));
|
||||
user.setInviteCode(generateInviteCode());
|
||||
user.setStatus(0);
|
||||
user.setIsDelete(0L);
|
||||
user.setCreateTime(Instant.now());
|
||||
userMapper.insert(user);
|
||||
|
||||
// 绑定邀请关系
|
||||
if (StringUtils.hasText(inviteCode)) {
|
||||
bindInvite(user, inviteCode);
|
||||
}
|
||||
|
||||
return user;
|
||||
}
|
||||
|
||||
/**
|
||||
* 绑定邀请关系
|
||||
*/
|
||||
private void bindInvite(User user, String inviteCode) {
|
||||
// 查找邀请人
|
||||
User inviter = userMapper.selectOne(
|
||||
new LambdaQueryWrapper<User>()
|
||||
.eq(User::getInviteCode, inviteCode)
|
||||
);
|
||||
|
||||
if (inviter == null) {
|
||||
log.warn("邀请码无效 inviteCode:{} userId:{}", inviteCode, user.getId());
|
||||
return;
|
||||
}
|
||||
|
||||
// 不能自己邀请自己
|
||||
if (inviter.getId().equals(user.getId())) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 记录邀请关系
|
||||
UserInvite invite = new UserInvite();
|
||||
invite.setUserId(user.getId());
|
||||
invite.setInviterId(inviter.getId());
|
||||
invite.setInviteCode(inviteCode);
|
||||
invite.setCreateTime(Instant.now());
|
||||
userInviteMapper.insert(invite);
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成10位邀请码(大写字母+数字),确保唯一
|
||||
*/
|
||||
private String generateInviteCode() {
|
||||
for (int i = 0; i < 3; i++) {
|
||||
StringBuilder sb = new StringBuilder(INVITE_CODE_LENGTH);
|
||||
for (int j = 0; j < INVITE_CODE_LENGTH; j++) {
|
||||
sb.append(INVITE_CODE_CHARS.charAt(RANDOM.nextInt(INVITE_CODE_CHARS.length())));
|
||||
}
|
||||
String code = sb.toString();
|
||||
// 检查是否已存在
|
||||
Long count = userMapper.selectCount(
|
||||
new LambdaQueryWrapper<User>().eq(User::getInviteCode, code)
|
||||
);
|
||||
if (count == 0) {
|
||||
return code;
|
||||
}
|
||||
log.warn("邀请码碰撞 code:{} 第{}次重试", code, i + 1);
|
||||
}
|
||||
throw new BusinessException(BusinessExpCodeEnum.UNKNOWN_ERROR, "邀请码生成失败,请重试");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package org.jiayunet.mapper;
|
||||
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.jiayunet.pojo.po.UserInvite;
|
||||
|
||||
/**
|
||||
* 用户邀请记录Mapper
|
||||
*
|
||||
* @author zk
|
||||
*/
|
||||
@Mapper
|
||||
public interface UserInviteMapper extends CommonMapper<UserInvite> {
|
||||
|
||||
}
|
||||
@@ -79,6 +79,11 @@ public class User {
|
||||
*/
|
||||
private String wechatUnionId;
|
||||
|
||||
/**
|
||||
* 邀请码
|
||||
*/
|
||||
private String inviteCode;
|
||||
|
||||
/**
|
||||
* 状态 0 正常 1 禁用
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
package org.jiayunet.pojo.po;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.Instant;
|
||||
|
||||
/**
|
||||
* 用户邀请记录表
|
||||
*
|
||||
* @author zk
|
||||
*/
|
||||
@Data
|
||||
@TableName(value = "bg_user_invite")
|
||||
public class UserInvite {
|
||||
|
||||
@TableId(type = IdType.ASSIGN_ID)
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 被邀请人ID
|
||||
*/
|
||||
private Long userId;
|
||||
|
||||
/**
|
||||
* 邀请人ID
|
||||
*/
|
||||
private Long inviterId;
|
||||
|
||||
/**
|
||||
* 使用的邀请码
|
||||
*/
|
||||
private String inviteCode;
|
||||
|
||||
/**
|
||||
* 邀请时间
|
||||
*/
|
||||
private Instant createTime;
|
||||
}
|
||||
Reference in New Issue
Block a user