package com.rongyichuang.auth.service;
|
|
import com.rongyichuang.auth.dto.LoginRequest;
|
import com.rongyichuang.auth.dto.LoginResponse;
|
import com.rongyichuang.auth.dto.PhoneDecryptResponse;
|
import com.rongyichuang.auth.dto.WxLoginRequest;
|
import com.rongyichuang.auth.dto.WxLoginResponse;
|
import com.rongyichuang.auth.entity.WxLoginRecord;
|
import com.rongyichuang.auth.util.JwtUtil;
|
import com.rongyichuang.service.WechatApiService;
|
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
import com.fasterxml.jackson.databind.JsonMappingException;
|
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;
|
import javax.crypto.Cipher;
|
import javax.crypto.spec.IvParameterSpec;
|
import javax.crypto.spec.SecretKeySpec;
|
import java.util.Base64;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
/**
|
* 认证服务类
|
*/
|
@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;
|
|
@Autowired
|
private WxLoginRecordService wxLoginRecordService;
|
|
@Autowired
|
private WechatApiService wechatApiService;
|
|
/**
|
* 用户登录
|
*/
|
public LoginResponse login(LoginRequest loginRequest) {
|
logger.info("用户登录尝试,手机号: {}", loginRequest.getPhone());
|
|
// 1. 通过手机号查询用户
|
Optional<User> 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<Employee> employeeOpt = employeeRepository.findByUserId(user.getId());
|
Optional<Judge> judgeOpt = judgeRepository.findByUserId(user.getId());
|
Optional<Player> playerOpt = playerRepository.findByUserId(user.getId());
|
|
// 5. 检查是否有权限(必须关联员工、评委或学员中的至少一个)
|
// 注意:Web登录暂时不支持学员角色,只允许员工和评委登录
|
if (employeeOpt.isEmpty() && judgeOpt.isEmpty()) {
|
logger.warn("用户没有权限,未关联员工或评委,手机号: {}", loginRequest.getPhone());
|
throw new BadCredentialsException("没有权限");
|
}
|
|
// 7. 生成JWT token
|
String token = jwtUtil.generateToken(user.getId(), user.getPhone());
|
|
// 8. 确定主要角色类型(优先级:employee > judge > player)
|
String userType;
|
if (employeeOpt.isPresent()) {
|
userType = "employee";
|
} else if (judgeOpt.isPresent()) {
|
userType = "judge";
|
} else {
|
userType = "player";
|
}
|
|
// 9. 构建用户信息
|
LoginResponse.UserInfo userInfo = new LoginResponse.UserInfo(
|
user.getId(),
|
user.getName(),
|
user.getPhone(),
|
userType
|
);
|
|
// 10. 设置所有关联的角色信息
|
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()
|
));
|
if (employeeOpt.isEmpty() && judgeOpt.isEmpty()) {
|
logger.info("学员登录成功,ID: {}, 姓名: {}", player.getId(), player.getName());
|
}
|
}
|
|
return new LoginResponse(token, userInfo);
|
}
|
|
/**
|
* 微信登录
|
*/
|
public WxLoginResponse wxLogin(WxLoginRequest wxLoginRequest) throws JsonProcessingException, JsonMappingException {
|
logger.info("=== 开始微信登录流程 ===");
|
logger.info("登录时间: {}", java.time.LocalDateTime.now());
|
logger.info("请求参数详情:");
|
logger.info("- code: {}", wxLoginRequest.getCode());
|
logger.info("- code长度: {}", wxLoginRequest.getCode() != null ? wxLoginRequest.getCode().length() : 0);
|
logger.info("- wxOpenid: {}", wxLoginRequest.getWxOpenid());
|
logger.info("- wxUnionid: {}", wxLoginRequest.getWxUnionid());
|
logger.info("- phone: {}", wxLoginRequest.getPhone());
|
logger.info("- loginIp: {}", wxLoginRequest.getLoginIp());
|
logger.info("- deviceInfo: {}", wxLoginRequest.getDeviceInfo());
|
logger.info("- phoneAuthorized: {}", wxLoginRequest.getPhoneAuthorized());
|
|
// 1. 通过code调用微信API获取openid和unionid
|
WechatApiService.WechatUserInfo wechatUserInfo = null;
|
if (wxLoginRequest.getCode() != null && !wxLoginRequest.getCode().trim().isEmpty()) {
|
logger.info("步骤1: 调用微信API获取用户信息");
|
logger.info("使用code: {}", wxLoginRequest.getCode());
|
|
try {
|
wechatUserInfo = wechatApiService.getWechatUserInfo(wxLoginRequest.getCode());
|
|
// 将从微信API获取的信息设置到请求对象中
|
wxLoginRequest.setWxOpenid(wechatUserInfo.getOpenid());
|
wxLoginRequest.setWxUnionid(wechatUserInfo.getUnionid());
|
wxLoginRequest.setSessionKey(wechatUserInfo.getSessionKey());
|
|
logger.info("✅ 从微信API获取用户信息成功");
|
logger.info("- openid: {}", wechatUserInfo.getOpenid());
|
logger.info("- unionid: {}", wechatUserInfo.getUnionid());
|
logger.info("- sessionKey长度: {}", wechatUserInfo.getSessionKey() != null ? wechatUserInfo.getSessionKey().length() : 0);
|
|
} catch (Exception e) {
|
logger.error("❌ 调用微信API失败");
|
logger.error("异常信息: {}", e.getMessage());
|
logger.error("异常堆栈:", e);
|
throw e;
|
}
|
} else {
|
logger.warn("⚠️ 微信登录code为空,将使用请求中的openid和unionid");
|
logger.info("请求中的openid: {}", wxLoginRequest.getWxOpenid());
|
logger.info("请求中的unionid: {}", wxLoginRequest.getWxUnionid());
|
}
|
|
User user = null;
|
boolean isNewUser = false;
|
|
logger.info("步骤2: 查找或创建用户");
|
|
// 2. 首先尝试通过openid查找用户
|
if (wxLoginRequest.getWxOpenid() != null && !wxLoginRequest.getWxOpenid().trim().isEmpty()) {
|
logger.info("尝试通过openid查找用户: {}", wxLoginRequest.getWxOpenid());
|
|
try {
|
Optional<User> userOpt = userRepository.findByWxOpenid(wxLoginRequest.getWxOpenid());
|
if (userOpt.isPresent()) {
|
user = userOpt.get();
|
logger.info("✅ 通过openid找到用户");
|
logger.info("- 用户ID: {}", user.getId());
|
logger.info("- 用户姓名: {}", user.getName());
|
logger.info("- 用户手机号: {}", user.getPhone());
|
logger.info("- 用户unionid: {}", user.getWxUnionid());
|
} else {
|
logger.info("❌ 通过openid未找到用户");
|
}
|
} catch (Exception e) {
|
logger.error("❌ 通过openid查找用户时发生异常: {}", e.getMessage());
|
logger.error("异常堆栈:", e);
|
}
|
} else {
|
logger.warn("⚠️ openid为空,跳过openid查找");
|
}
|
|
// 3. 如果通过openid没找到,尝试通过unionid查找
|
if (user == null && wxLoginRequest.getWxUnionid() != null && !wxLoginRequest.getWxUnionid().trim().isEmpty()) {
|
logger.info("尝试通过unionid查找用户: {}", wxLoginRequest.getWxUnionid());
|
|
try {
|
Optional<User> userOpt = userRepository.findByWxUnionid(wxLoginRequest.getWxUnionid());
|
if (userOpt.isPresent()) {
|
user = userOpt.get();
|
logger.info("✅ 通过unionid找到用户");
|
logger.info("- 用户ID: {}", user.getId());
|
logger.info("- 用户姓名: {}", user.getName());
|
logger.info("- 用户手机号: {}", user.getPhone());
|
logger.info("- 用户openid: {}", user.getWxOpenid());
|
|
// 更新用户的openid(如果之前没有)
|
if (user.getWxOpenid() == null || user.getWxOpenid().trim().isEmpty()) {
|
logger.info("用户openid为空,需要更新");
|
user.setWxOpenid(wxLoginRequest.getWxOpenid());
|
try {
|
userRepository.save(user);
|
logger.info("✅ 成功更新用户openid,用户ID: {}", user.getId());
|
} catch (Exception e) {
|
logger.error("❌ 更新用户openid失败: {}", e.getMessage());
|
logger.error("异常堆栈:", e);
|
}
|
} else {
|
logger.info("用户openid已存在,无需更新");
|
}
|
} else {
|
logger.info("❌ 通过unionid未找到用户");
|
}
|
} catch (Exception e) {
|
logger.error("❌ 通过unionid查找用户时发生异常: {}", e.getMessage());
|
logger.error("异常堆栈:", e);
|
}
|
} else {
|
logger.warn("⚠️ unionid为空或用户已找到,跳过unionid查找");
|
}
|
|
// 4. 如果都没找到,创建新用户
|
if (user == null) {
|
logger.info("未找到现有用户,开始创建新用户");
|
logger.info("新用户信息:");
|
logger.info("- openid: {}", wxLoginRequest.getWxOpenid());
|
logger.info("- unionid: {}", wxLoginRequest.getWxUnionid());
|
logger.info("- phone: {}", wxLoginRequest.getPhone());
|
|
try {
|
user = new User();
|
user.setWxOpenid(wxLoginRequest.getWxOpenid());
|
user.setWxUnionid(wxLoginRequest.getWxUnionid());
|
user.setName("微信用户"); // 默认名称,后续可以更新
|
user.setPhone(wxLoginRequest.getPhone()); // 如果有授权手机号
|
|
user = userRepository.save(user);
|
isNewUser = true;
|
|
logger.info("✅ 成功创建新的微信用户");
|
logger.info("- 新用户ID: {}", user.getId());
|
logger.info("- 新用户姓名: {}", user.getName());
|
logger.info("- 新用户手机号: {}", user.getPhone());
|
|
} catch (Exception e) {
|
logger.error("❌ 创建新用户失败");
|
logger.error("异常信息: {}", e.getMessage());
|
logger.error("异常堆栈:", e);
|
throw new RuntimeException("创建新用户失败: " + e.getMessage(), e);
|
}
|
}
|
|
// 5. 记录登录信息到新表
|
logger.info("步骤3: 记录登录信息");
|
WxLoginRecord loginRecord = null;
|
try {
|
loginRecord = wxLoginRecordService.createLoginRecord(
|
wxLoginRequest.getWxOpenid(),
|
wxLoginRequest.getWxUnionid(),
|
user.getId(),
|
wxLoginRequest.getLoginIp(),
|
wxLoginRequest.getDeviceInfo(),
|
wxLoginRequest.getSessionKey(),
|
wxLoginRequest.getPhoneAuthorized()
|
);
|
logger.info("✅ 成功创建登录记录,记录ID: {}", loginRecord.getId());
|
} catch (Exception e) {
|
logger.error("❌ 创建登录记录失败: {}", e.getMessage());
|
logger.error("异常堆栈:", e);
|
throw new RuntimeException("创建登录记录失败: " + e.getMessage(), e);
|
}
|
|
// 6. 查找关联的员工、评委和学员信息
|
logger.info("步骤4: 查找用户关联的角色信息");
|
logger.info("查找用户ID: {}", user.getId());
|
|
Optional<Employee> employeeOpt = Optional.empty();
|
Optional<Judge> judgeOpt = Optional.empty();
|
Optional<Player> playerOpt = Optional.empty();
|
|
try {
|
employeeOpt = employeeRepository.findByUserId(user.getId());
|
logger.info("员工角色查找结果: {}", employeeOpt.isPresent() ? "找到" : "未找到");
|
if (employeeOpt.isPresent()) {
|
Employee employee = employeeOpt.get();
|
logger.info("- 员工ID: {}", employee.getId());
|
logger.info("- 员工姓名: {}", employee.getName());
|
logger.info("- 员工角色ID: {}", employee.getRoleId());
|
}
|
} catch (Exception e) {
|
logger.error("❌ 查找员工角色时发生异常: {}", e.getMessage());
|
logger.error("异常堆栈:", e);
|
}
|
|
try {
|
judgeOpt = judgeRepository.findByUserId(user.getId());
|
logger.info("评委角色查找结果: {}", judgeOpt.isPresent() ? "找到" : "未找到");
|
if (judgeOpt.isPresent()) {
|
Judge judge = judgeOpt.get();
|
logger.info("- 评委ID: {}", judge.getId());
|
logger.info("- 评委姓名: {}", judge.getName());
|
logger.info("- 评委职称: {}", judge.getTitle());
|
logger.info("- 评委公司: {}", judge.getCompany());
|
}
|
} catch (Exception e) {
|
logger.error("❌ 查找评委角色时发生异常: {}", e.getMessage());
|
logger.error("异常堆栈:", e);
|
}
|
|
try {
|
playerOpt = playerRepository.findByUserId(user.getId());
|
logger.info("学员角色查找结果: {}", playerOpt.isPresent() ? "找到" : "未找到");
|
if (playerOpt.isPresent()) {
|
Player player = playerOpt.get();
|
logger.info("- 学员ID: {}", player.getId());
|
logger.info("- 学员姓名: {}", player.getName());
|
logger.info("- 学员手机号: {}", player.getPhone());
|
}
|
} catch (Exception e) {
|
logger.error("❌ 查找学员角色时发生异常: {}", e.getMessage());
|
logger.error("异常堆栈:", e);
|
}
|
|
// 6. 生成JWT token
|
logger.info("步骤5: 生成JWT token");
|
String tokenIdentifier = user.getPhone() != null ? user.getPhone() : user.getWxOpenid();
|
logger.info("Token标识符: {}", tokenIdentifier);
|
|
String token = null;
|
try {
|
token = jwtUtil.generateToken(user.getId(), tokenIdentifier);
|
logger.info("✅ 成功生成JWT token,长度: {}", token != null ? token.length() : 0);
|
} catch (Exception e) {
|
logger.error("❌ 生成JWT token失败: {}", e.getMessage());
|
logger.error("异常堆栈:", e);
|
throw new RuntimeException("生成JWT token失败: " + e.getMessage(), e);
|
}
|
|
// 7. 确定主要角色类型(优先级:employee > judge > player)
|
logger.info("步骤6: 确定用户主要角色类型");
|
String userType;
|
if (employeeOpt.isPresent()) {
|
userType = "employee";
|
logger.info("用户主要角色: 员工");
|
} else if (judgeOpt.isPresent()) {
|
userType = "judge";
|
logger.info("用户主要角色: 评委");
|
} else if (playerOpt.isPresent()) {
|
userType = "player";
|
logger.info("用户主要角色: 学员");
|
} else {
|
userType = "user"; // 普通微信用户
|
logger.info("用户主要角色: 普通微信用户");
|
}
|
|
// 8. 构建用户信息
|
logger.info("步骤7: 构建用户信息响应");
|
LoginResponse.UserInfo userInfo = null;
|
try {
|
userInfo = new LoginResponse.UserInfo(
|
user.getId(),
|
user.getName(),
|
user.getPhone(),
|
userType
|
);
|
logger.info("✅ 成功构建基础用户信息");
|
logger.info("- 用户ID: {}", user.getId());
|
logger.info("- 用户姓名: {}", user.getName());
|
logger.info("- 用户手机号: {}", user.getPhone());
|
logger.info("- 用户类型: {}", userType);
|
} catch (Exception e) {
|
logger.error("❌ 构建基础用户信息失败: {}", e.getMessage());
|
logger.error("异常堆栈:", e);
|
throw new RuntimeException("构建基础用户信息失败: " + e.getMessage(), e);
|
}
|
|
// 9. 设置所有关联的角色信息
|
logger.info("步骤8: 设置角色详细信息");
|
|
if (employeeOpt.isPresent()) {
|
try {
|
Employee employee = employeeOpt.get();
|
userInfo.setEmployee(new LoginResponse.EmployeeInfo(
|
employee.getId(),
|
employee.getName(),
|
employee.getRoleId(),
|
employee.getDescription()
|
));
|
logger.info("✅ 设置员工信息成功");
|
logger.info("- 员工ID: {}", employee.getId());
|
logger.info("- 员工姓名: {}", employee.getName());
|
logger.info("- 员工角色ID: {}", employee.getRoleId());
|
logger.info("员工微信登录成功,ID: {}, 姓名: {}", employee.getId(), employee.getName());
|
} catch (Exception e) {
|
logger.error("❌ 设置员工信息失败: {}", e.getMessage());
|
logger.error("异常堆栈:", e);
|
}
|
}
|
|
if (judgeOpt.isPresent()) {
|
try {
|
Judge judge = judgeOpt.get();
|
userInfo.setJudge(new LoginResponse.JudgeInfo(
|
judge.getId(),
|
judge.getName(),
|
judge.getTitle(),
|
judge.getCompany(),
|
judge.getDescription()
|
));
|
logger.info("✅ 设置评委信息成功");
|
logger.info("- 评委ID: {}", judge.getId());
|
logger.info("- 评委姓名: {}", judge.getName());
|
logger.info("- 评委职称: {}", judge.getTitle());
|
logger.info("- 评委公司: {}", judge.getCompany());
|
|
if (employeeOpt.isEmpty()) {
|
logger.info("评委微信登录成功,ID: {}, 姓名: {}", judge.getId(), judge.getName());
|
}
|
} catch (Exception e) {
|
logger.error("❌ 设置评委信息失败: {}", e.getMessage());
|
logger.error("异常堆栈:", e);
|
}
|
}
|
|
if (playerOpt.isPresent()) {
|
try {
|
Player player = playerOpt.get();
|
userInfo.setPlayer(new LoginResponse.PlayerInfo(
|
player.getId(),
|
player.getName(),
|
player.getPhone(),
|
player.getDescription()
|
));
|
logger.info("✅ 设置学员信息成功");
|
logger.info("- 学员ID: {}", player.getId());
|
logger.info("- 学员姓名: {}", player.getName());
|
logger.info("- 学员手机号: {}", player.getPhone());
|
|
if (employeeOpt.isEmpty() && judgeOpt.isEmpty()) {
|
logger.info("学员微信登录成功,ID: {}, 姓名: {}", player.getId(), player.getName());
|
}
|
} catch (Exception e) {
|
logger.error("❌ 设置学员信息失败: {}", e.getMessage());
|
logger.error("异常堆栈:", e);
|
}
|
}
|
|
logger.info("=== 微信登录流程完成 ===");
|
logger.info("登录结果:");
|
logger.info("- 是否新用户: {}", isNewUser);
|
logger.info("- 登录记录ID: {}", loginRecord != null ? loginRecord.getId() : "null");
|
logger.info("- Token长度: {}", token != null ? token.length() : 0);
|
logger.info("- 用户类型: {}", userType);
|
logger.info("完成时间: {}", java.time.LocalDateTime.now());
|
|
return new WxLoginResponse(token, userInfo, isNewUser, loginRecord.getId(), wxLoginRequest.getSessionKey());
|
}
|
|
/**
|
* 解密微信手机号
|
*/
|
public PhoneDecryptResponse decryptPhoneNumber(String encryptedData, String iv, String sessionKey) {
|
logger.info("=== 开始解密微信手机号 ===");
|
logger.info("解密时间: {}", java.time.LocalDateTime.now());
|
logger.info("encryptedData长度: {}", encryptedData != null ? encryptedData.length() : 0);
|
logger.info("iv长度: {}", iv != null ? iv.length() : 0);
|
logger.info("sessionKey长度: {}", sessionKey != null ? sessionKey.length() : 0);
|
|
try {
|
// 1. Base64解码
|
byte[] encryptedBytes = Base64.getDecoder().decode(encryptedData);
|
byte[] ivBytes = Base64.getDecoder().decode(iv);
|
byte[] sessionKeyBytes = Base64.getDecoder().decode(sessionKey);
|
|
logger.info("Base64解码成功");
|
logger.info("encryptedBytes长度: {}", encryptedBytes.length);
|
logger.info("ivBytes长度: {}", ivBytes.length);
|
logger.info("sessionKeyBytes长度: {}", sessionKeyBytes.length);
|
|
// 2. AES解密
|
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
|
SecretKeySpec secretKeySpec = new SecretKeySpec(sessionKeyBytes, "AES");
|
IvParameterSpec ivParameterSpec = new IvParameterSpec(ivBytes);
|
cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec);
|
|
byte[] decryptedBytes = cipher.doFinal(encryptedBytes);
|
String decryptedData = new String(decryptedBytes, "UTF-8");
|
|
logger.info("AES解密成功");
|
logger.info("解密后数据长度: {}", decryptedData.length());
|
logger.info("解密后数据: {}", decryptedData);
|
|
// 3. 解析JSON
|
ObjectMapper objectMapper = new ObjectMapper();
|
WechatPhoneInfo phoneInfo = objectMapper.readValue(decryptedData, WechatPhoneInfo.class);
|
|
logger.info("JSON解析成功");
|
logger.info("手机号: {}", phoneInfo.getPhoneNumber());
|
logger.info("纯手机号: {}", phoneInfo.getPurePhoneNumber());
|
logger.info("国家代码: {}", phoneInfo.getCountryCode());
|
|
PhoneDecryptResponse response = new PhoneDecryptResponse(
|
phoneInfo.getPhoneNumber(),
|
phoneInfo.getPurePhoneNumber(),
|
phoneInfo.getCountryCode()
|
);
|
|
logger.info("✅ 微信手机号解密成功");
|
return response;
|
|
} catch (Exception e) {
|
logger.error("❌ 微信手机号解密失败", e);
|
String friendlyMessage = getDecryptFriendlyErrorMessage(e);
|
throw new RuntimeException(friendlyMessage, e);
|
}
|
}
|
|
/**
|
* 使用新版API通过code直接获取手机号
|
*/
|
public PhoneDecryptResponse getPhoneNumberByCode(String code) {
|
logger.info("=== 开始使用新版API获取手机号 ===");
|
logger.info("获取时间: {}", java.time.LocalDateTime.now());
|
logger.info("输入code: {}", code);
|
|
try {
|
// 调用微信API服务获取手机号
|
WechatApiService.WechatPhoneInfo phoneInfo = wechatApiService.getPhoneNumberByCode(code);
|
|
logger.info("✅ 新版API获取手机号成功");
|
logger.info("手机号: {}", phoneInfo.getPhoneNumber());
|
logger.info("纯手机号: {}", phoneInfo.getPurePhoneNumber());
|
logger.info("国家代码: {}", phoneInfo.getCountryCode());
|
|
PhoneDecryptResponse response = new PhoneDecryptResponse(
|
phoneInfo.getPhoneNumber(),
|
phoneInfo.getPurePhoneNumber(),
|
phoneInfo.getCountryCode()
|
);
|
|
return response;
|
|
} catch (Exception e) {
|
logger.error("❌ 新版API获取手机号失败", e);
|
// 直接传递WechatApiService的友好错误信息
|
throw new RuntimeException(e.getMessage(), e);
|
}
|
}
|
|
/**
|
* 微信手机号信息
|
*/
|
@JsonIgnoreProperties(ignoreUnknown = true)
|
public static class WechatPhoneInfo {
|
private String phoneNumber;
|
private String purePhoneNumber;
|
private String countryCode;
|
|
public String getPhoneNumber() {
|
return phoneNumber;
|
}
|
|
public void setPhoneNumber(String phoneNumber) {
|
this.phoneNumber = phoneNumber;
|
}
|
|
public String getPurePhoneNumber() {
|
return purePhoneNumber;
|
}
|
|
public void setPurePhoneNumber(String purePhoneNumber) {
|
this.purePhoneNumber = purePhoneNumber;
|
}
|
|
public String getCountryCode() {
|
return countryCode;
|
}
|
|
public void setCountryCode(String countryCode) {
|
this.countryCode = countryCode;
|
}
|
}
|
|
/**
|
* 根据解密异常提供友好的错误信息
|
*/
|
private String getDecryptFriendlyErrorMessage(Exception e) {
|
String errorMessage = e.getMessage();
|
|
if (e instanceof IllegalArgumentException) {
|
if (errorMessage.contains("Illegal base64 character")) {
|
return "授权数据格式错误,请重新获取手机号授权";
|
}
|
}
|
|
if (e instanceof javax.crypto.BadPaddingException) {
|
return "授权数据已过期或无效,请重新获取手机号授权";
|
}
|
|
if (e instanceof javax.crypto.IllegalBlockSizeException) {
|
return "授权数据长度错误,请重新获取手机号授权";
|
}
|
|
if (e instanceof java.security.InvalidKeyException) {
|
return "会话密钥无效,请重新登录后再试";
|
}
|
|
if (e instanceof com.fasterxml.jackson.core.JsonParseException) {
|
return "授权数据解析失败,请重新获取手机号授权";
|
}
|
|
if (errorMessage.contains("sessionKey")) {
|
return "会话已过期,请重新登录后再试";
|
}
|
|
if (errorMessage.contains("encryptedData")) {
|
return "授权数据无效,请重新获取手机号授权";
|
}
|
|
return "手机号解密失败,请重新获取手机号授权";
|
}
|
}
|