代码优化

This commit is contained in:
2025-10-13 10:43:08 +08:00
parent b6818b179c
commit bc3ed2d872
40 changed files with 3189 additions and 788 deletions
@@ -4,6 +4,7 @@ import com.emotion.dto.request.LoginRequest;
import com.emotion.dto.request.RegisterRequest;
import com.emotion.dto.response.AuthResponse;
import com.emotion.dto.response.CaptchaResponse;
import com.emotion.dto.response.SmsCodeResponse;
import com.emotion.dto.response.UserInfoResponse;
import com.emotion.entity.User;
import com.emotion.exception.AuthException;
@@ -61,34 +62,36 @@ public class AuthServiceImpl implements AuthService {
private TokenUtil tokenUtil;
private static final String CAPTCHA_PREFIX = "captcha:";
private static final String SMS_CODE_PREFIX = "sms_code:";
private static final String TOKEN_PREFIX = "token:";
private static final String REFRESH_TOKEN_PREFIX = "refresh_token:";
private static final int CAPTCHA_EXPIRE_MINUTES = 5;
private static final int SMS_CODE_EXPIRE_MINUTES = 5;
private static final int TOKEN_EXPIRE_HOURS = 24;
private static final int REFRESH_TOKEN_EXPIRE_DAYS = 7;
private static final String DEFAULT_SMS_CODE = "123456";
private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
@Override
public AuthResponse login(LoginRequest request) {
// 验证验证码
if (!validateCaptcha(request.getCaptchaKey(), request.getCaptcha())) {
// 验证短信验证码
if (!validateSmsCode(request.getPhone(), request.getSmsCode())) {
throw new CaptchaException("验证码错误或已过期");
}
// 根据号查询用户
User user = userService.getByAccount(request.getAccount());
// 根据手机号查询用户
User user = userService.getByPhone(request.getPhone());
// 如果用户不存在,则自动注册
if (user == null) {
throw new AuthException("账号不存在");
}
// 验证密码(这里应该使用加密后的密码比较)
if (!verifyPassword(request.getPassword(), user.getPassword())) {
throw new AuthException("密码错误");
}
// 检查用户状态
if (user.getStatus() != 1) {
throw new AuthException("账号已被禁用");
log.info("用户不存在,自动注册: phone={}", request.getPhone());
user = autoRegisterUser(request.getPhone());
} else {
// 检查用户状态
if (user.getStatus() != 1) {
throw new AuthException("账号已被禁用");
}
log.info("用户登录: phone={}, userId={}", request.getPhone(), user.getId());
}
// 生成令牌
@@ -111,61 +114,31 @@ public class AuthServiceImpl implements AuthService {
@Override
public AuthResponse register(RegisterRequest request) {
// 验证验证码
if (!validateCaptcha(request.getCaptchaKey(), request.getCaptcha())) {
// 验证短信验证码
if (!validateSmsCode(request.getPhone(), request.getSmsCode())) {
throw new CaptchaException("验证码错误或已过期");
}
// 验证密码确认
if (!request.getPassword().equals(request.getConfirmPassword())) {
throw new BusinessException("密码与确认密码不一致");
// 检查手机号是否已存在
if (userService.getByPhone(request.getPhone()) != null) {
throw new BusinessException("手机号已被注册");
}
// 检查账号是否已存在
if (userService.getByAccount(request.getAccount()) != null) {
throw new BusinessException("账号已存在");
}
// 生成随机用户名:开心 + 6位随机大小写字母和数字
String username = generateRandomUsername();
// 检查邮箱是否已存在(只有当邮箱不为空时才检查)
if (StringUtils.hasText(request.getEmail()) && userService.getByEmail(request.getEmail()) != null) {
throw new BusinessException("邮箱已被使用");
}
// 检查手机号是否已存在(只有当手机号不为空时才检查)
if (StringUtils.hasText(request.getPhone()) && userService.getByPhone(request.getPhone()) != null) {
throw new BusinessException("手机号已被使用");
}
// 处理用户名:如果为空则使用账号
String username = StringUtils.hasText(request.getUsername()) ? request.getUsername() : request.getAccount();
// 处理邮箱:如果为空字符串则设为null
String email = StringUtils.hasText(request.getEmail()) ? request.getEmail() : null;
// 处理手机号:如果为空字符串则设为null
String phone = StringUtils.hasText(request.getPhone()) ? request.getPhone() : null;
// 使用手机号作为账号
String account = request.getPhone();
// 创建用户(密码在UserService中加密,这里不需要预先加密)
User user = userService.createUser(
request.getAccount(),
account,
username,
request.getPassword(),
email,
phone
null, // 邮箱为空
request.getPhone()
);
// 设置昵称(如果昵称为空则使用用户名)
if (StringUtils.hasText(request.getNickname())) {
user.setNickname(request.getNickname());
} else if (StringUtils.hasText(username)) {
user.setNickname(username);
}
// 如果有昵称变更,更新用户信息
if (StringUtils.hasText(user.getNickname())) {
userService.updateById(user);
}
// 生成令牌
String accessToken = generateAccessToken(user);
String refreshToken = generateRefreshToken(user);
@@ -178,6 +151,7 @@ public class AuthServiceImpl implements AuthService {
response.setUserInfo(convertToUserInfoResponse(user));
response.setLoginTime(LocalDateTime.now().format(DATE_TIME_FORMATTER));
log.info("用户注册成功: phone={}, username={}", request.getPhone(), username);
return response;
}
@@ -510,4 +484,132 @@ public class AuthServiceImpl implements AuthService {
User user = userService.getByPhone(phone);
return user != null;
}
@Override
public SmsCodeResponse sendSmsCode(String phone) {
// 验证手机号格式
if (!StringUtils.hasText(phone) || !phone.matches("^1[3-9]\\d{9}$")) {
throw new BusinessException("手机号格式不正确");
}
// 检查手机号是否已注册,用于提示信息
boolean isRegistered = existsByPhone(phone);
String message;
if (isRegistered) {
message = "验证码已发送,用于登录验证,有效期" + SMS_CODE_EXPIRE_MINUTES + "分钟";
} else {
message = "验证码已发送,用于注册验证,有效期" + SMS_CODE_EXPIRE_MINUTES + "分钟";
}
// TODO: 接入真实的短信服务商(阿里云、腾讯云等)
// 目前使用固定验证码 123456
String code = DEFAULT_SMS_CODE;
// 将验证码存储到Redis,有效期5分钟
String key = SMS_CODE_PREFIX + phone;
redisTemplate.opsForValue().set(key, code, SMS_CODE_EXPIRE_MINUTES, TimeUnit.MINUTES);
log.info("发送短信验证码: phone={}, code={}, isRegistered={}", phone, code, isRegistered);
// 构建响应
return SmsCodeResponse.builder()
.code(code) // 开发环境返回验证码,生产环境应该删除此行
.expiresIn((long) SMS_CODE_EXPIRE_MINUTES * 60)
.message(message)
.build();
}
@Override
public boolean validateSmsCode(String phone, String code) {
if (!StringUtils.hasText(phone) || !StringUtils.hasText(code)) {
return false;
}
String key = SMS_CODE_PREFIX + phone;
String storedCode = (String) redisTemplate.opsForValue().get(key);
if (storedCode == null) {
log.warn("短信验证码不存在或已过期: phone={}", phone);
return false;
}
boolean isValid = storedCode.equals(code);
// 验证成功后删除验证码(一次性使用)
if (isValid) {
redisTemplate.delete(key);
log.info("短信验证码验证成功: phone={}", phone);
} else {
log.warn("短信验证码错误: phone={}, expected={}, actual={}", phone, storedCode, code);
}
return isValid;
}
/**
* 生成随机用户名
* 格式:开心 + 6位随机大小写字母和数字
*
* @return 随机用户名
*/
private String generateRandomUsername() {
String chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
Random random = new Random();
StringBuilder sb = new StringBuilder("开心");
for (int i = 0; i < 6; i++) {
int index = random.nextInt(chars.length());
sb.append(chars.charAt(index));
}
return sb.toString();
}
/**
* 自动注册用户(用于登录时用户不存在的情况)
*
* @param phone 手机号
* @return 新创建的用户
*/
private User autoRegisterUser(String phone) {
// 生成随机用户名:开心 + 6位随机大小写字母和数字
String username = generateRandomUsername();
// 使用手机号作为账号
String account = phone;
// 生成随机密码(用户可以后续修改)
String randomPassword = generateRandomPassword();
// 创建用户
User user = userService.createUser(
account,
username,
randomPassword,
null, // 邮箱为空
phone
);
log.info("自动注册用户成功: phone={}, username={}, userId={}", phone, username, user.getId());
return user;
}
/**
* 生成随机密码
* 格式:8位随机大小写字母和数字
*
* @return 随机密码
*/
private String generateRandomPassword() {
String chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
Random random = new Random();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 8; i++) {
int index = random.nextInt(chars.length());
sb.append(chars.charAt(index));
}
return sb.toString();
}
}
@@ -245,6 +245,69 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
return this.updateById(user);
}
@Override
public User getByAccount(String account) {
if (!StringUtils.hasText(account)) {
return null;
}
LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(User::getAccount, account)
.eq(User::getIsDeleted, 0);
return this.getOne(wrapper);
}
@Override
public User getByEmail(String email) {
if (!StringUtils.hasText(email)) {
return null;
}
LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(User::getEmail, email)
.eq(User::getIsDeleted, 0);
return this.getOne(wrapper);
}
@Override
public User getByPhone(String phone) {
if (!StringUtils.hasText(phone)) {
return null;
}
LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(User::getPhone, phone)
.eq(User::getIsDeleted, 0);
return this.getOne(wrapper);
}
@Override
public User createUser(String account, String username, String password, String email, String phone) {
User user = new User();
user.setAccount(account);
user.setUsername(username);
user.setNickname(username); // 默认昵称与用户名相同
user.setPassword(passwordEncoder.encode(password)); // 加密密码
user.setEmail(email);
user.setPhone(phone);
user.setMemberLevel("free"); // 默认免费会员
user.setStatus(1); // 默认启用
user.setIsVerified(0); // 默认未验证
user.setLastActiveTime(LocalDateTime.now());
this.save(user);
return user;
}
@Override
public void updateLastActiveTime(String userId, LocalDateTime lastActiveTime) {
if (!StringUtils.hasText(userId) || lastActiveTime == null) {
return;
}
User user = this.getById(userId);
if (user != null && user.getIsDeleted() == 0) {
user.setLastActiveTime(lastActiveTime);
this.updateById(user);
}
}
/**
* 转换为响应对象
*/