AdminAuthService.java 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. package com.xuekairui.user.service;
  2. import com.xuekairui.common.BusinessException;
  3. import com.xuekairui.common.ErrorCode;
  4. import com.xuekairui.common.RandomUtil;
  5. import com.xuekairui.user.dto.LoginResponse;
  6. import com.xuekairui.user.entity.Admin;
  7. import com.xuekairui.user.mapper.AdminMapper;
  8. import com.xuekairui.user.security.TokenVersionCache;
  9. import com.xuekairui.user.util.JwtUtil;
  10. import com.xuekairui.user.util.PasswordUtil;
  11. import lombok.RequiredArgsConstructor;
  12. import lombok.extern.slf4j.Slf4j;
  13. import org.springframework.stereotype.Service;
  14. import org.springframework.transaction.annotation.Transactional;
  15. import java.time.LocalDateTime;
  16. /**
  17. * 管理员认证服务(操作 t_admin 表,与普通用户 AuthService 隔离)
  18. */
  19. @Slf4j
  20. @Service
  21. @RequiredArgsConstructor
  22. public class AdminAuthService {
  23. private final AdminMapper adminMapper;
  24. private final JwtUtil jwtUtil;
  25. private final PasswordUtil passwordUtil;
  26. private final TokenVersionCache tokenVersionCache;
  27. private static final int RESET_LEN = 10;
  28. /**
  29. * 管理员密码登录(按用户名或手机号)
  30. */
  31. @Transactional
  32. public LoginResponse passwordLogin(String account, String password, String ip) {
  33. Admin admin = adminMapper.selectByUsername(account);
  34. if (admin == null) {
  35. admin = adminMapper.selectByPhone(account);
  36. }
  37. if (admin == null) {
  38. throw new BusinessException(ErrorCode.USER_NOT_FOUND);
  39. }
  40. if (admin.getPassword() == null || admin.getPassword().isEmpty()) {
  41. throw new BusinessException(ErrorCode.PASSWORD_NOT_SET);
  42. }
  43. if (!passwordUtil.matches(password, admin.getPassword())) {
  44. throw new BusinessException(ErrorCode.PASSWORD_INCORRECT);
  45. }
  46. if (admin.getStatus() != null && admin.getStatus() == 0) {
  47. throw new BusinessException(ErrorCode.USER_DISABLED);
  48. }
  49. return buildLoginResponse(admin, ip);
  50. }
  51. /**
  52. * 构建管理员登录响应(递增 tokenVersion,签发 Token)
  53. */
  54. private LoginResponse buildLoginResponse(Admin admin, String ip) {
  55. String roleCode = admin.getRole() != null ? admin.getRole() : "ADMIN";
  56. // 管理员允许多设备:最多5台
  57. long oldVersion = admin.getTokenVersion() != null ? admin.getTokenVersion() : 0L;
  58. long newVersion = oldVersion + 1;
  59. admin.setTokenVersion(newVersion);
  60. String accessToken = jwtUtil.generateAccessToken(admin.getId(), roleCode, "PC", newVersion);
  61. String refreshToken = jwtUtil.generateRefreshToken(admin.getId(), "PC");
  62. admin.setRefreshTokenHash(JwtUtil.hashToken(refreshToken));
  63. admin.setRefreshTokenStatus("ACTIVE");
  64. admin.setLastLoginTime(LocalDateTime.now());
  65. admin.setLastLoginIp(ip);
  66. adminMapper.updateById(admin);
  67. tokenVersionCache.putVersion(admin.getId(), true, newVersion);
  68. boolean hadPreviousSession = oldVersion >= 5;
  69. return LoginResponse.builder()
  70. .userId(admin.getId())
  71. .accessToken(accessToken)
  72. .refreshToken(refreshToken)
  73. .expiresIn(jwtUtil.getExpirationInSeconds(roleCode))
  74. .needBindPhone(false)
  75. .newUser(false)
  76. .role(roleCode)
  77. .kickedPreviousSession(hadPreviousSession)
  78. .build();
  79. }
  80. /**
  81. * 管理员自行修改密码(需验旧密码)
  82. */
  83. @Transactional
  84. public void setPassword(Long adminId, String oldPassword, String newPassword) {
  85. Admin admin = adminMapper.selectById(adminId);
  86. if (admin == null) {
  87. throw new BusinessException(ErrorCode.USER_NOT_FOUND);
  88. }
  89. if (admin.getPassword() != null && !admin.getPassword().isEmpty()
  90. && oldPassword != null && !passwordUtil.matches(oldPassword, admin.getPassword())) {
  91. throw new BusinessException(ErrorCode.OLD_PASSWORD_INCORRECT);
  92. }
  93. admin.setPassword(passwordUtil.encode(newPassword));
  94. adminMapper.updateById(admin);
  95. }
  96. /**
  97. * 重置管理员密码为随机密码,返回明文
  98. */
  99. @Transactional
  100. public String resetPassword(Long adminId) {
  101. Admin admin = adminMapper.selectById(adminId);
  102. if (admin == null) {
  103. throw new BusinessException(ErrorCode.USER_NOT_FOUND);
  104. }
  105. String rawPwd = RandomUtil.generateCode(RESET_LEN);
  106. admin.setPassword(passwordUtil.encode(rawPwd));
  107. adminMapper.updateById(admin);
  108. tokenVersionCache.putVersion(adminId, true,
  109. (admin.getTokenVersion() != null ? admin.getTokenVersion() : 0L) + 1);
  110. return rawPwd;
  111. }
  112. }