package com.rongyichuang.auth.service; import com.rongyichuang.auth.dto.LoginRequest; import com.rongyichuang.auth.dto.LoginResponse; import com.rongyichuang.auth.util.JwtUtil; import com.rongyichuang.employee.entity.Employee; import com.rongyichuang.employee.repository.EmployeeRepository; import com.rongyichuang.judge.entity.Judge; import com.rongyichuang.judge.repository.JudgeRepository; import com.rongyichuang.player.entity.Player; import com.rongyichuang.player.repository.PlayerRepository; import com.rongyichuang.user.entity.User; import com.rongyichuang.user.repository.UserRepository; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.authentication.BadCredentialsException; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Service; import java.util.Optional; /** * 认证服务类 */ @Service public class AuthService { private static final Logger logger = LoggerFactory.getLogger(AuthService.class); @Autowired private UserRepository userRepository; @Autowired private EmployeeRepository employeeRepository; @Autowired private JudgeRepository judgeRepository; @Autowired private PlayerRepository playerRepository; @Autowired private PasswordEncoder passwordEncoder; @Autowired private JwtUtil jwtUtil; /** * 用户登录 */ public LoginResponse login(LoginRequest loginRequest) { logger.info("用户登录尝试,手机号: {}", loginRequest.getPhone()); // 1. 通过手机号查询用户 Optional userOpt = userRepository.findByPhone(loginRequest.getPhone()); if (userOpt.isEmpty()) { logger.warn("用户不存在,手机号: {}", loginRequest.getPhone()); throw new BadCredentialsException("用户不存在"); } User user = userOpt.get(); // 2. 检查密码是否为空 if (user.getPassword() == null || user.getPassword().trim().isEmpty()) { logger.warn("用户密码为空,手机号: {}", loginRequest.getPhone()); throw new BadCredentialsException("密码不正确"); } // 3. 验证密码 if (!passwordEncoder.matches(loginRequest.getPassword(), user.getPassword())) { logger.warn("密码验证失败,手机号: {}", loginRequest.getPhone()); throw new BadCredentialsException("密码不正确"); } // 4. 查找关联的员工、评委和学员信息 Optional employeeOpt = employeeRepository.findByUserId(user.getId()); Optional judgeOpt = judgeRepository.findByUserId(user.getId()); Optional playerOpt = playerRepository.findByUserId(user.getId()); // 5. 检查是否有权限(必须关联员工、评委或学员中的至少一个) // 注意:Web登录暂时不支持学员角色,只允许员工和评委登录 if (employeeOpt.isEmpty() && judgeOpt.isEmpty()) { logger.warn("用户没有权限,未关联员工或评委,手机号: {}", loginRequest.getPhone()); throw new BadCredentialsException("没有权限"); } // 6. 生成JWT token String token = jwtUtil.generateToken(user.getId(), user.getPhone()); // 7. 确定主要角色类型(优先级:employee > judge > player) String userType; if (employeeOpt.isPresent()) { userType = "employee"; } else if (judgeOpt.isPresent()) { userType = "judge"; } else { userType = "player"; } // 8. 构建用户信息 LoginResponse.UserInfo userInfo = new LoginResponse.UserInfo( user.getId(), user.getName(), user.getPhone(), userType ); // 9. 设置所有关联的角色信息 if (employeeOpt.isPresent()) { Employee employee = employeeOpt.get(); userInfo.setEmployee(new LoginResponse.EmployeeInfo( employee.getId(), employee.getName(), employee.getRoleId(), employee.getDescription() )); logger.info("员工登录成功,ID: {}, 姓名: {}", employee.getId(), employee.getName()); } if (judgeOpt.isPresent()) { Judge judge = judgeOpt.get(); userInfo.setJudge(new LoginResponse.JudgeInfo( judge.getId(), judge.getName(), judge.getTitle(), judge.getCompany(), judge.getDescription() )); if (employeeOpt.isEmpty()) { logger.info("评委登录成功,ID: {}, 姓名: {}", judge.getId(), judge.getName()); } } if (playerOpt.isPresent()) { Player player = playerOpt.get(); userInfo.setPlayer(new LoginResponse.PlayerInfo( player.getId(), player.getName(), player.getPhone(), player.getDescription(), player.getAuditState() )); if (employeeOpt.isEmpty() && judgeOpt.isEmpty()) { logger.info("学员登录成功,ID: {}, 姓名: {}", player.getId(), player.getName()); } } return new LoginResponse(token, userInfo); } }