fix(system): 优化微信登录接口的响应处理和异常处理
- 改进了微信手机号和 access_token 获取接口的响应清理逻辑 - 增加了对响应格式的验证和错误处理 -优化了缓存 access_token 的存储和解析 - 提升了代码的健壮性和错误提示的详细性
This commit is contained in:
@@ -77,6 +77,40 @@ public class WxLoginController extends BaseController {
|
|||||||
return success("操作成功", getAccessToken());
|
return success("操作成功", getAccessToken());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ApiOperation("清理并统一AccessToken存储格式")
|
||||||
|
@PostMapping("/cleanAccessTokenFormat")
|
||||||
|
public ApiResult<String> cleanAccessTokenFormat() {
|
||||||
|
String key = ACCESS_TOKEN_KEY.concat(":").concat(getTenantId().toString());
|
||||||
|
String value = redisTemplate.opsForValue().get(key);
|
||||||
|
|
||||||
|
if (value != null) {
|
||||||
|
try {
|
||||||
|
// 尝试解析为JSON
|
||||||
|
JSONObject response = JSON.parseObject(value);
|
||||||
|
String accessToken = response.getString("access_token");
|
||||||
|
if (StrUtil.isNotBlank(accessToken)) {
|
||||||
|
return success("AccessToken格式已经是标准JSON格式", accessToken);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
// 如果是字符串格式,转换为JSON格式
|
||||||
|
if (StrUtil.isNotBlank(value) && !value.startsWith("{")) {
|
||||||
|
JSONObject tokenData = new JSONObject();
|
||||||
|
tokenData.put("access_token", value);
|
||||||
|
tokenData.put("expires_in", 7200); // 默认2小时
|
||||||
|
|
||||||
|
// 重新存储为JSON格式
|
||||||
|
redisTemplate.opsForValue().set(key, tokenData.toJSONString(), 7000L, TimeUnit.SECONDS);
|
||||||
|
return success("已将字符串格式转换为JSON格式", value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果没有缓存或格式异常,重新获取
|
||||||
|
redisTemplate.delete(key);
|
||||||
|
String newToken = getAccessToken();
|
||||||
|
return success("已重新获取并统一格式", newToken);
|
||||||
|
}
|
||||||
|
|
||||||
@ApiOperation("获取微信openId")
|
@ApiOperation("获取微信openId")
|
||||||
@Transactional(rollbackFor = {Exception.class})
|
@Transactional(rollbackFor = {Exception.class})
|
||||||
@PostMapping("/getOpenId")
|
@PostMapping("/getOpenId")
|
||||||
@@ -112,9 +146,9 @@ public class WxLoginController extends BaseController {
|
|||||||
redisTemplate.delete(key);
|
redisTemplate.delete(key);
|
||||||
throw new BusinessException("授权失败,请重试");
|
throw new BusinessException("授权失败,请重试");
|
||||||
}
|
}
|
||||||
// 查询是否存在
|
|
||||||
|
|
||||||
User user = userService.getAdminByPhone(userParam);
|
User user = null;
|
||||||
|
|
||||||
// 超级管理员验证
|
// 超级管理员验证
|
||||||
if (userParam.getIsSuperAdmin() != null) {
|
if (userParam.getIsSuperAdmin() != null) {
|
||||||
final LoginParam loginParam = new LoginParam();
|
final LoginParam loginParam = new LoginParam();
|
||||||
@@ -124,23 +158,21 @@ public class WxLoginController extends BaseController {
|
|||||||
if (!CollectionUtils.isEmpty(adminsByPhone)) {
|
if (!CollectionUtils.isEmpty(adminsByPhone)) {
|
||||||
user = adminsByPhone.get(0);
|
user = adminsByPhone.get(0);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
// 不存在则注册
|
|
||||||
if (user == null) {
|
|
||||||
if ((userParam.getOpenid() == null || userParam.getOpenid().isEmpty()) && userParam.getAuthCode() != null) {
|
|
||||||
UserParam userParam2 = new UserParam();
|
|
||||||
userParam2.setCode(userParam.getAuthCode());
|
|
||||||
JSONObject result = getOpenIdByCode(userParam2);
|
|
||||||
System.out.println("userInfo res:" + result);
|
|
||||||
String openid = result.getString("openid");
|
|
||||||
// String unionid = result.getString("unionid");
|
|
||||||
userParam.setOpenid(openid);
|
|
||||||
}
|
|
||||||
userParam.setPhone(phone);
|
|
||||||
user = addUser(userParam);
|
|
||||||
user.setRecommend(1);
|
|
||||||
} else {
|
} else {
|
||||||
// 存在则检查绑定上级
|
// 先查询管理员用户
|
||||||
|
user = userService.getAdminByPhone(userParam);
|
||||||
|
|
||||||
|
// 如果不是管理员,再查询普通用户
|
||||||
|
if (user == null) {
|
||||||
|
user = userService.getByPhone(phone, getTenantId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果用户存在,直接登录
|
||||||
|
if (user != null) {
|
||||||
|
System.out.println("用户已存在,直接登录: " + user.getPhone());
|
||||||
|
|
||||||
|
// 检查绑定上级关系
|
||||||
if (userParam.getSceneType() != null && userParam.getSceneType().equals("save_referee") && userParam.getRefereeId() != null && userParam.getRefereeId() != 0) {
|
if (userParam.getSceneType() != null && userParam.getSceneType().equals("save_referee") && userParam.getRefereeId() != null && userParam.getRefereeId() != 0) {
|
||||||
UserReferee check = userRefereeService.check(user.getUserId(), userParam.getRefereeId());
|
UserReferee check = userRefereeService.check(user.getUserId(), userParam.getRefereeId());
|
||||||
if (check == null) {
|
if (check == null) {
|
||||||
@@ -150,14 +182,52 @@ public class WxLoginController extends BaseController {
|
|||||||
userRefereeService.save(userReferee);
|
userRefereeService.save(userReferee);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 签发token
|
||||||
|
String access_token = JwtUtil.buildToken(new JwtSubject(user.getUsername(), user.getTenantId()),
|
||||||
|
configProperties.getTokenExpireTime(), configProperties.getTokenKey());
|
||||||
|
loginRecordService.saveAsync(user.getUsername(), LoginRecord.TYPE_LOGIN, null, user.getTenantId(), request);
|
||||||
|
|
||||||
|
return success("登录成功", new LoginResult(access_token, user));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 用户不存在,注册新用户
|
||||||
|
System.out.println("用户不存在,注册新用户: " + phone);
|
||||||
|
|
||||||
|
try {
|
||||||
|
if ((userParam.getOpenid() == null || userParam.getOpenid().isEmpty()) && userParam.getAuthCode() != null) {
|
||||||
|
UserParam userParam2 = new UserParam();
|
||||||
|
userParam2.setCode(userParam.getAuthCode());
|
||||||
|
JSONObject result = getOpenIdByCode(userParam2);
|
||||||
|
System.out.println("userInfo res:" + result);
|
||||||
|
String openid = result.getString("openid");
|
||||||
|
userParam.setOpenid(openid);
|
||||||
|
}
|
||||||
|
userParam.setPhone(phone);
|
||||||
|
user = addUser(userParam);
|
||||||
|
user.setRecommend(1);
|
||||||
|
|
||||||
|
// 签发token
|
||||||
|
String access_token = JwtUtil.buildToken(new JwtSubject(user.getUsername(), user.getTenantId()),
|
||||||
|
configProperties.getTokenExpireTime(), configProperties.getTokenKey());
|
||||||
|
loginRecordService.saveAsync(user.getUsername(), LoginRecord.TYPE_REGISTER, null, user.getTenantId(), request);
|
||||||
|
|
||||||
|
return success("注册并登录成功", new LoginResult(access_token, user));
|
||||||
|
|
||||||
|
} catch (BusinessException e) {
|
||||||
|
// 如果注册时提示手机号已存在,说明存在并发情况,重新查询用户并登录
|
||||||
|
if (e.getMessage().contains("手机号已存在")) {
|
||||||
|
System.out.println("注册时发现手机号已存在,重新查询用户进行登录");
|
||||||
|
user = userService.getByPhone(phone, getTenantId());
|
||||||
|
if (user != null) {
|
||||||
|
String access_token = JwtUtil.buildToken(new JwtSubject(user.getUsername(), user.getTenantId()),
|
||||||
|
configProperties.getTokenExpireTime(), configProperties.getTokenKey());
|
||||||
|
loginRecordService.saveAsync(user.getUsername(), LoginRecord.TYPE_LOGIN, null, user.getTenantId(), request);
|
||||||
|
return success("登录成功", new LoginResult(access_token, user));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw e;
|
||||||
}
|
}
|
||||||
// 签发token
|
|
||||||
String access_token = JwtUtil.buildToken(new JwtSubject(user.getUsername(), user.getTenantId()),
|
|
||||||
configProperties.getTokenExpireTime(), configProperties.getTokenKey());
|
|
||||||
loginRecordService.saveAsync(user.getUsername(), LoginRecord.TYPE_REGISTER, null, user.getTenantId(), request);
|
|
||||||
// 附加体育中心项目用户信息
|
|
||||||
// user.setBookingUser();
|
|
||||||
return success("登录成功", new LoginResult(access_token, user));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ApiOperation("微信授权手机号码并更新")
|
@ApiOperation("微信授权手机号码并更新")
|
||||||
@@ -372,14 +442,20 @@ public class WxLoginController extends BaseController {
|
|||||||
String value = redisTemplate.opsForValue().get(key);
|
String value = redisTemplate.opsForValue().get(key);
|
||||||
if (value != null) {
|
if (value != null) {
|
||||||
try {
|
try {
|
||||||
// 解析access_token
|
// 尝试解析为JSON格式
|
||||||
JSONObject response = JSON.parseObject(value);
|
JSONObject response = JSON.parseObject(value);
|
||||||
String accessToken = response.getString("access_token");
|
String accessToken = response.getString("access_token");
|
||||||
if (StrUtil.isNotBlank(accessToken)) {
|
if (StrUtil.isNotBlank(accessToken)) {
|
||||||
System.out.println("从缓存获取access_token: " + accessToken);
|
System.out.println("从缓存获取access_token(JSON格式): " + accessToken);
|
||||||
return accessToken;
|
return accessToken;
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
// 如果JSON解析失败,可能是旧的字符串格式,直接使用
|
||||||
|
if (StrUtil.isNotBlank(value) && !value.startsWith("{")) {
|
||||||
|
System.out.println("从缓存获取access_token(字符串格式): " + value);
|
||||||
|
System.out.println("检测到旧格式的access_token,将在下次更新时统一为JSON格式");
|
||||||
|
return value;
|
||||||
|
}
|
||||||
System.err.println("解析缓存的access_token失败: " + e.getMessage());
|
System.err.println("解析缓存的access_token失败: " + e.getMessage());
|
||||||
// 缓存数据异常,删除缓存,重新获取
|
// 缓存数据异常,删除缓存,重新获取
|
||||||
redisTemplate.delete(key);
|
redisTemplate.delete(key);
|
||||||
@@ -437,9 +513,16 @@ public class WxLoginController extends BaseController {
|
|||||||
|
|
||||||
String accessToken = response.getString("access_token");
|
String accessToken = response.getString("access_token");
|
||||||
if (StrUtil.isNotBlank(accessToken)) {
|
if (StrUtil.isNotBlank(accessToken)) {
|
||||||
|
// 构造标准的JSON格式存储对象
|
||||||
|
JSONObject tokenData = new JSONObject();
|
||||||
|
tokenData.put("access_token", accessToken);
|
||||||
|
tokenData.put("expires_in", response.get("expires_in"));
|
||||||
|
|
||||||
// 存入缓存,设置过期时间为7000秒(约2小时,微信access_token有效期为2小时)
|
// 存入缓存,设置过期时间为7000秒(约2小时,微信access_token有效期为2小时)
|
||||||
redisTemplate.opsForValue().set(key, cleanResult, 7000L, TimeUnit.SECONDS);
|
// 统一使用JSON格式存储,确保格式一致性
|
||||||
|
redisTemplate.opsForValue().set(key, tokenData.toJSONString(), 7000L, TimeUnit.SECONDS);
|
||||||
System.out.println("获取新的access_token成功: " + accessToken);
|
System.out.println("获取新的access_token成功: " + accessToken);
|
||||||
|
System.out.println("已统一存储为JSON格式: " + tokenData.toJSONString());
|
||||||
return accessToken;
|
return accessToken;
|
||||||
} else {
|
} else {
|
||||||
System.err.println("响应中没有access_token字段: " + cleanResult);
|
System.err.println("响应中没有access_token字段: " + cleanResult);
|
||||||
|
|||||||
Reference in New Issue
Block a user