添加用户要求信息
This commit is contained in:
@@ -33,6 +33,6 @@ public class LoginController {
|
|||||||
public LoginVo smsLogin(@Validated @RequestBody SmsLoginDto dto,
|
public LoginVo smsLogin(@Validated @RequestBody SmsLoginDto dto,
|
||||||
HttpServletRequest request,
|
HttpServletRequest request,
|
||||||
HttpServletResponse response) {
|
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 = "验证码不能为空")
|
@NotBlank(message = "验证码不能为空")
|
||||||
private String code;
|
private String code;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 邀请码(可选)
|
||||||
|
*/
|
||||||
|
private String inviteCode;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -59,6 +59,9 @@ public class LoginServer {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private RedisServerTool redisServerTool;
|
private RedisServerTool redisServerTool;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private UserRegisterServer userRegisterServer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 发送短信验证码
|
* 发送短信验证码
|
||||||
*/
|
*/
|
||||||
@@ -76,7 +79,7 @@ public class LoginServer {
|
|||||||
* 短信验证码登录
|
* 短信验证码登录
|
||||||
*/
|
*/
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@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(mobileNumber, "手机号不能为空");
|
||||||
Assert.hasText(code, "验证码不能为空");
|
Assert.hasText(code, "验证码不能为空");
|
||||||
|
|
||||||
@@ -91,13 +94,7 @@ public class LoginServer {
|
|||||||
|
|
||||||
// 用户不存在则自动注册
|
// 用户不存在则自动注册
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
user = new User();
|
user = userRegisterServer.register(mobileNumber, inviteCode);
|
||||||
user.setMobileNumber(mobileNumber);
|
|
||||||
user.setNick("用户" + mobileNumber.substring(mobileNumber.length() - 4));
|
|
||||||
user.setStatus(0);
|
|
||||||
user.setIsDelete(0L);
|
|
||||||
user.setCreateTime(Instant.now());
|
|
||||||
userMapper.insert(user);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 检查用户状态
|
// 检查用户状态
|
||||||
|
|||||||
@@ -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 wechatUnionId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 邀请码
|
||||||
|
*/
|
||||||
|
private String inviteCode;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 状态 0 正常 1 禁用
|
* 状态 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