package com.weiwojc.service.impl; import com.weiwojc.mapper.UserMapper; import com.weiwojc.model.dto.UserLoginDTO; import com.weiwojc.model.dto.UserRegisterDTO; import com.weiwojc.model.entity.User; import com.weiwojc.service.UserService; import com.weiwojc.utils.JwtUtils; import com.weiwojc.utils.PasswordUtils; import lombok.RequiredArgsConstructor; import org.springframework.security.authentication.BadCredentialsException; import org.springframework.security.authentication.LockedException; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.time.LocalDateTime; import java.util.UUID; @Service @RequiredArgsConstructor public class UserServiceImpl implements UserService { private final UserMapper userMapper; private final JwtUtils jwtUtils; @Override @Transactional public User register(UserRegisterDTO registerDTO) { // 检查账号名是否已存在 User existingUser = userMapper.findByUsername(registerDTO.getAccountName()); if (existingUser != null) { throw new RuntimeException("账号名已存在"); } // 创建新用户 User user = new User(); user.setUuid(UUID.randomUUID().toString()); user.setUsername(registerDTO.getAccountName()); user.setNickname(registerDTO.getNickname()); // 生成加密密码 String salt = PasswordUtils.generateSalt(); String hashedPassword = PasswordUtils.hashPassword(registerDTO.getPassword(), salt); user.setPasswordHash(hashedPassword); user.setPasswordSalt(salt); // 保存盐值 // 设置其他字段 user.setStatus(1); // 正常状态 user.setRegisteredAt(LocalDateTime.now()); user.setUpdatedAt(LocalDateTime.now()); // 保存用户 userMapper.insert(user); return user; } @Override public String login(UserLoginDTO loginDTO) { User user = userMapper.findByUsername(loginDTO.getAccountName()); if (user == null) { throw new BadCredentialsException("账号名或密码错误"); } // 检查账户状态 if (user.getStatus() == 0) { throw new LockedException("账户已被禁用"); } // 检查是否被锁定 if (isUserLocked(user.getUserId())) { throw new LockedException("账户已被锁定,请稍后再试"); } // 验证密码 if (!PasswordUtils.verifyPassword(loginDTO.getPassword(), user.getPasswordHash())) { // 增加登录失败次数 incrementLoginAttempts(user.getUsername()); throw new BadCredentialsException("账号名或密码错误"); } // 重置登录失败次数 resetLoginAttempts(user.getUsername()); // 更新最后登录时间 updateLastLogin(user.getUserId()); // 生成JWT令牌 return jwtUtils.generateToken(user); } @Override public User getUserInfo(Long userId) { return userMapper.findById(userId); } @Override public void updateLastLogin(Long userId) { userMapper.updateLastLogin(userId, LocalDateTime.now()); } @Override public boolean isUserLocked(Long userId) { User user = userMapper.findById(userId); if (user == null) { return false; } // 检查账户锁定状态 if (user.getLockedUntil() != null && LocalDateTime.now().isBefore(user.getLockedUntil())) { return true; } return false; } @Override public void incrementLoginAttempts(String username) { User user = userMapper.findByUsername(username); if (user != null) { int attempts = user.getLoginAttempts() == null ? 0 : user.getLoginAttempts(); attempts++; LocalDateTime lockedUntil = null; // 如果失败次数达到5次,锁定30分钟 if (attempts >= 5) { lockedUntil = LocalDateTime.now().plusMinutes(30); } userMapper.updateLoginAttempts(user.getUserId(), attempts, lockedUntil); } } @Override public void resetLoginAttempts(String username) { userMapper.resetLoginAttempts(username); } }