|
|
package com.gym.service;
|
|
|
|
|
|
import com.gym.model.User;
|
|
|
import com.gym.repository.UserRepository;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
|
|
|
import java.time.LocalDateTime;
|
|
|
import java.util.List;
|
|
|
import java.util.Optional;
|
|
|
|
|
|
// 添加日志
|
|
|
import org.slf4j.Logger;
|
|
|
import org.slf4j.LoggerFactory;
|
|
|
|
|
|
@Service
|
|
|
public class UserService {
|
|
|
|
|
|
// 添加日志
|
|
|
private static final Logger logger = LoggerFactory.getLogger(UserService.class);
|
|
|
|
|
|
@Autowired
|
|
|
private UserRepository userRepository;
|
|
|
|
|
|
/**
|
|
|
* 用户注册
|
|
|
* @param user 用户信息
|
|
|
* @return 注册成功的用户(不包含密码)
|
|
|
*/
|
|
|
public User register(User user) {
|
|
|
logger.info("开始用户注册: username={}, email={}", user.getUsername(), user.getEmail());
|
|
|
|
|
|
try {
|
|
|
// 1. 验证必填字段
|
|
|
if (user.getUsername() == null || user.getUsername().isEmpty()) {
|
|
|
logger.error("用户名为空");
|
|
|
throw new RuntimeException("用户名不能为空");
|
|
|
}
|
|
|
if (user.getPassword() == null || user.getPassword().isEmpty()) {
|
|
|
logger.error("密码为空");
|
|
|
throw new RuntimeException("密码不能为空");
|
|
|
}
|
|
|
if (user.getEmail() == null || user.getEmail().isEmpty()) {
|
|
|
logger.error("邮箱为空");
|
|
|
throw new RuntimeException("邮箱不能为空");
|
|
|
}
|
|
|
|
|
|
// 2. 检查用户名和邮箱是否已存在
|
|
|
if (userRepository.existsByUsername(user.getUsername())) {
|
|
|
logger.error("用户名已存在: {}", user.getUsername());
|
|
|
throw new RuntimeException("用户名已存在");
|
|
|
}
|
|
|
if (userRepository.existsByEmail(user.getEmail())) {
|
|
|
logger.error("邮箱已存在: {}", user.getEmail());
|
|
|
throw new RuntimeException("邮箱已存在");
|
|
|
}
|
|
|
|
|
|
// 3. 设置默认值
|
|
|
if (user.getRole() == null || user.getRole().isEmpty()) {
|
|
|
user.setRole("MEMBER");
|
|
|
logger.debug("设置默认角色: MEMBER");
|
|
|
}
|
|
|
|
|
|
user.setCreateTime(LocalDateTime.now());
|
|
|
user.setIsActive(true);
|
|
|
user.setPoints(0);
|
|
|
|
|
|
// 4. 密码处理(直接使用原始值,不移除空格)
|
|
|
logger.debug("原始密码长度: {}", user.getPassword().length());
|
|
|
// user.setPassword(user.getPassword()); // 直接使用原始值,不需要额外设置
|
|
|
|
|
|
// 5. 验证角色是否有效
|
|
|
String role = user.getRole().toUpperCase();
|
|
|
if (!role.equals("ADMIN") && !role.equals("COACH") && !role.equals("MEMBER")) {
|
|
|
logger.warn("无效的角色: {}, 使用默认角色: MEMBER", role);
|
|
|
user.setRole("MEMBER");
|
|
|
} else {
|
|
|
user.setRole(role);
|
|
|
}
|
|
|
|
|
|
// 6. 保存到数据库
|
|
|
User savedUser = userRepository.save(user);
|
|
|
logger.info("用户注册成功: id={}, username={}, role={}", savedUser.getId(), savedUser.getUsername(), savedUser.getRole());
|
|
|
|
|
|
// 7. 返回用户信息(清除密码)
|
|
|
savedUser.setPassword(null);
|
|
|
return savedUser;
|
|
|
|
|
|
} catch (Exception e) {
|
|
|
logger.error("用户注册失败: {}", e.getMessage(), e);
|
|
|
throw new RuntimeException("注册失败: " + e.getMessage());
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 用户登录
|
|
|
* @param username 用户名
|
|
|
* @param password 密码
|
|
|
* @return 登录成功的用户信息(不包含密码)
|
|
|
*/
|
|
|
public Optional<User> login(String username, String password) {
|
|
|
logger.info("用户尝试登录: username={}", username);
|
|
|
|
|
|
try {
|
|
|
// 1. 查找用户
|
|
|
Optional<User> userOpt = userRepository.findByUsername(username);
|
|
|
|
|
|
if (!userOpt.isPresent()) {
|
|
|
logger.warn("用户不存在: {}", username);
|
|
|
return Optional.empty();
|
|
|
}
|
|
|
|
|
|
User user = userOpt.get();
|
|
|
|
|
|
// 2. 检查用户是否激活
|
|
|
if (user.getIsActive() == null || !user.getIsActive()) {
|
|
|
logger.warn("账号已被禁用: username={}", username);
|
|
|
throw new RuntimeException("账号已被禁用");
|
|
|
}
|
|
|
|
|
|
// 3. 验证密码(直接比较原始值,不移除空格)
|
|
|
if (user.getPassword() == null || !user.getPassword().equals(password)) {
|
|
|
logger.warn("密码错误: username={}", username);
|
|
|
logger.debug("数据库密码: '{}'", user.getPassword());
|
|
|
logger.debug("输入密码: '{}'", password);
|
|
|
logger.debug("密码长度比较 - 数据库: {}, 输入: {}",
|
|
|
user.getPassword() != null ? user.getPassword().length() : "null",
|
|
|
password != null ? password.length() : "null");
|
|
|
return Optional.empty();
|
|
|
}
|
|
|
|
|
|
// 4. 更新最后登录时间
|
|
|
user.setLastLogin(LocalDateTime.now());
|
|
|
userRepository.save(user);
|
|
|
logger.info("用户登录成功: username={}, role={}", username, user.getRole());
|
|
|
|
|
|
// 5. 返回用户信息(清除密码)
|
|
|
user.setPassword(null);
|
|
|
return Optional.of(user);
|
|
|
|
|
|
} catch (Exception e) {
|
|
|
logger.error("登录过程出错: {}", e.getMessage(), e);
|
|
|
throw new RuntimeException("登录失败: " + e.getMessage());
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 获取所有用户
|
|
|
* @return 用户列表
|
|
|
*/
|
|
|
public List<User> getAllUsers() {
|
|
|
logger.debug("获取所有用户");
|
|
|
List<User> users = userRepository.findAll();
|
|
|
// 清除密码
|
|
|
users.forEach(user -> user.setPassword(null));
|
|
|
return users;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 根据角色获取用户
|
|
|
* @param role 角色
|
|
|
* @return 用户列表
|
|
|
*/
|
|
|
public List<User> getUsersByRole(String role) {
|
|
|
logger.debug("根据角色获取用户: role={}", role);
|
|
|
List<User> users = userRepository.findByRole(role.toUpperCase());
|
|
|
// 清除密码
|
|
|
users.forEach(user -> user.setPassword(null));
|
|
|
return users;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 根据ID获取用户
|
|
|
* @param id 用户ID
|
|
|
* @return 用户信息
|
|
|
*/
|
|
|
public Optional<User> getUserById(Long id) {
|
|
|
logger.debug("根据ID获取用户: id={}", id);
|
|
|
Optional<User> userOpt = userRepository.findById(id);
|
|
|
userOpt.ifPresent(user -> user.setPassword(null));
|
|
|
return userOpt;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 更新用户信息
|
|
|
* @param id 用户ID
|
|
|
* @param updatedUser 更新的用户信息
|
|
|
* @return 更新后的用户
|
|
|
*/
|
|
|
public User updateUser(Long id, User updatedUser) {
|
|
|
logger.info("更新用户信息: id={}", id);
|
|
|
|
|
|
return userRepository.findById(id)
|
|
|
.map(user -> {
|
|
|
// 记录原始信息
|
|
|
logger.debug("原始用户信息: realName={}, email={}, phone={}",
|
|
|
user.getRealName(), user.getEmail(), user.getPhone());
|
|
|
|
|
|
// 只更新允许修改的字段(不移除空格,保持原始值)
|
|
|
if (updatedUser.getRealName() != null && !updatedUser.getRealName().isEmpty()) {
|
|
|
user.setRealName(updatedUser.getRealName());
|
|
|
}
|
|
|
if (updatedUser.getEmail() != null && !updatedUser.getEmail().isEmpty()) {
|
|
|
// 检查邮箱是否重复(除了自己)
|
|
|
String newEmail = updatedUser.getEmail();
|
|
|
Optional<User> existingUser = userRepository.findByEmail(newEmail);
|
|
|
if (existingUser.isPresent() && !existingUser.get().getId().equals(id)) {
|
|
|
logger.error("邮箱已被其他用户使用: email={}", newEmail);
|
|
|
throw new RuntimeException("邮箱已被其他用户使用");
|
|
|
}
|
|
|
user.setEmail(newEmail);
|
|
|
}
|
|
|
if (updatedUser.getPhone() != null) {
|
|
|
user.setPhone(updatedUser.getPhone());
|
|
|
}
|
|
|
if (updatedUser.getAge() != null) {
|
|
|
user.setAge(updatedUser.getAge());
|
|
|
}
|
|
|
if (updatedUser.getHeight() != null) {
|
|
|
user.setHeight(updatedUser.getHeight());
|
|
|
}
|
|
|
if (updatedUser.getWeight() != null) {
|
|
|
user.setWeight(updatedUser.getWeight());
|
|
|
}
|
|
|
if (updatedUser.getFitnessGoal() != null) {
|
|
|
user.setFitnessGoal(updatedUser.getFitnessGoal());
|
|
|
}
|
|
|
if (updatedUser.getGender() != null) {
|
|
|
user.setGender(updatedUser.getGender());
|
|
|
}
|
|
|
if (updatedUser.getQualification() != null) {
|
|
|
user.setQualification(updatedUser.getQualification());
|
|
|
}
|
|
|
if (updatedUser.getSpecialty() != null) {
|
|
|
user.setSpecialty(updatedUser.getSpecialty());
|
|
|
}
|
|
|
|
|
|
// 保存更新
|
|
|
User savedUser = userRepository.save(user);
|
|
|
logger.info("用户信息更新成功: id={}", id);
|
|
|
|
|
|
// 清除密码
|
|
|
savedUser.setPassword(null);
|
|
|
return savedUser;
|
|
|
})
|
|
|
.orElseThrow(() -> {
|
|
|
logger.error("用户不存在: id={}", id);
|
|
|
return new RuntimeException("用户不存在");
|
|
|
});
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 删除用户(软删除)
|
|
|
* @param id 用户ID
|
|
|
*/
|
|
|
public void deleteUser(Long id) {
|
|
|
logger.info("软删除用户: id={}", id);
|
|
|
|
|
|
userRepository.findById(id).ifPresentOrElse(
|
|
|
user -> {
|
|
|
user.setIsActive(false);
|
|
|
userRepository.save(user);
|
|
|
logger.info("用户软删除成功: id={}, username={}", id, user.getUsername());
|
|
|
},
|
|
|
() -> {
|
|
|
logger.error("用户不存在,无法删除: id={}", id);
|
|
|
throw new RuntimeException("用户不存在");
|
|
|
}
|
|
|
);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 检查用户名是否可用
|
|
|
* @param username 用户名
|
|
|
* @return true表示可用,false表示已存在
|
|
|
*/
|
|
|
public boolean isUsernameAvailable(String username) {
|
|
|
boolean available = !userRepository.existsByUsername(username);
|
|
|
logger.debug("检查用户名可用性: username={}, available={}", username, available);
|
|
|
return available;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 添加积分
|
|
|
* @param userId 用户ID
|
|
|
* @param points 要添加的积分数
|
|
|
* @return 更新后的用户
|
|
|
*/
|
|
|
public User addPoints(Long userId, Integer points) {
|
|
|
logger.info("为用户添加积分: userId={}, points={}", userId, points);
|
|
|
|
|
|
if (points <= 0) {
|
|
|
logger.error("积分必须为正数: points={}", points);
|
|
|
throw new RuntimeException("积分必须为正数");
|
|
|
}
|
|
|
|
|
|
return userRepository.findById(userId)
|
|
|
.map(user -> {
|
|
|
int oldPoints = user.getPoints() != null ? user.getPoints() : 0;
|
|
|
user.setPoints(oldPoints + points);
|
|
|
|
|
|
User savedUser = userRepository.save(user);
|
|
|
logger.info("积分添加成功: userId={}, 原积分={}, 新积分={}",
|
|
|
userId, oldPoints, savedUser.getPoints());
|
|
|
|
|
|
// 清除密码
|
|
|
savedUser.setPassword(null);
|
|
|
return savedUser;
|
|
|
})
|
|
|
.orElseThrow(() -> {
|
|
|
logger.error("用户不存在: id={}", userId);
|
|
|
return new RuntimeException("用户不存在");
|
|
|
});
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 根据邮箱查找用户
|
|
|
* @param email 邮箱
|
|
|
* @return 用户信息
|
|
|
*/
|
|
|
public Optional<User> getUserByEmail(String email) {
|
|
|
logger.debug("根据邮箱查找用户: email={}", email);
|
|
|
Optional<User> userOpt = userRepository.findByEmail(email);
|
|
|
userOpt.ifPresent(user -> user.setPassword(null));
|
|
|
return userOpt;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 获取活跃用户
|
|
|
* @return 活跃用户列表
|
|
|
*/
|
|
|
public List<User> getActiveUsers() {
|
|
|
logger.debug("获取活跃用户");
|
|
|
List<User> users = userRepository.findByIsActiveTrue();
|
|
|
users.forEach(user -> user.setPassword(null));
|
|
|
return users;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 重置用户密码(管理员功能)
|
|
|
* @param userId 用户ID
|
|
|
* @param newPassword 新密码
|
|
|
* @return 更新后的用户
|
|
|
*/
|
|
|
public User resetPassword(Long userId, String newPassword) {
|
|
|
logger.info("重置用户密码: userId={}", userId);
|
|
|
|
|
|
if (newPassword == null || newPassword.isEmpty()) {
|
|
|
logger.error("新密码不能为空");
|
|
|
throw new RuntimeException("新密码不能为空");
|
|
|
}
|
|
|
|
|
|
return userRepository.findById(userId)
|
|
|
.map(user -> {
|
|
|
// 直接存储原始密码
|
|
|
user.setPassword(newPassword);
|
|
|
User savedUser = userRepository.save(user);
|
|
|
logger.info("密码重置成功: userId={}, username={}", userId, user.getUsername());
|
|
|
|
|
|
// 清除密码
|
|
|
savedUser.setPassword(null);
|
|
|
return savedUser;
|
|
|
})
|
|
|
.orElseThrow(() -> {
|
|
|
logger.error("用户不存在: id={}", userId);
|
|
|
return new RuntimeException("用户不存在");
|
|
|
});
|
|
|
}
|
|
|
} |