From 0b88c39cabf1da22ffb479f80cf057a34530be05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B5=B5=E5=BF=A0=E6=9E=97?= <170083662@qq.com> Date: Thu, 4 Sep 2025 23:18:01 +0800 Subject: [PATCH] =?UTF-8?q?fix(system):=20=E4=BC=98=E5=8C=96=E5=BE=AE?= =?UTF-8?q?=E4=BF=A1=E7=99=BB=E5=BD=95=E6=8E=A5=E5=8F=A3=E7=9A=84=E5=93=8D?= =?UTF-8?q?=E5=BA=94=E5=A4=84=E7=90=86=E5=92=8C=E5=BC=82=E5=B8=B8=E5=A4=84?= =?UTF-8?q?=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 改进了微信手机号和 access_token 获取接口的响应清理逻辑 - 增加了对响应格式的验证和错误处理 -优化了缓存 access_token 的存储和解析 - 提升了代码的健壮性和错误提示的详细性 --- .../system/controller/WxLoginController.java | 139 ++++++++++++++---- 1 file changed, 111 insertions(+), 28 deletions(-) diff --git a/src/main/java/com/gxwebsoft/common/system/controller/WxLoginController.java b/src/main/java/com/gxwebsoft/common/system/controller/WxLoginController.java index 32c3a3a..1dde8e6 100644 --- a/src/main/java/com/gxwebsoft/common/system/controller/WxLoginController.java +++ b/src/main/java/com/gxwebsoft/common/system/controller/WxLoginController.java @@ -77,6 +77,40 @@ public class WxLoginController extends BaseController { return success("操作成功", getAccessToken()); } + @ApiOperation("清理并统一AccessToken存储格式") + @PostMapping("/cleanAccessTokenFormat") + public ApiResult 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") @Transactional(rollbackFor = {Exception.class}) @PostMapping("/getOpenId") @@ -112,9 +146,9 @@ public class WxLoginController extends BaseController { redisTemplate.delete(key); throw new BusinessException("授权失败,请重试"); } - // 查询是否存在 - User user = userService.getAdminByPhone(userParam); + User user = null; + // 超级管理员验证 if (userParam.getIsSuperAdmin() != null) { final LoginParam loginParam = new LoginParam(); @@ -124,23 +158,21 @@ public class WxLoginController extends BaseController { if (!CollectionUtils.isEmpty(adminsByPhone)) { 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 { - // 存在则检查绑定上级 + // 先查询管理员用户 + 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) { UserReferee check = userRefereeService.check(user.getUserId(), userParam.getRefereeId()); if (check == null) { @@ -150,14 +182,52 @@ public class WxLoginController extends BaseController { 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("微信授权手机号码并更新") @@ -372,14 +442,20 @@ public class WxLoginController extends BaseController { String value = redisTemplate.opsForValue().get(key); if (value != null) { try { - // 解析access_token + // 尝试解析为JSON格式 JSONObject response = JSON.parseObject(value); String accessToken = response.getString("access_token"); if (StrUtil.isNotBlank(accessToken)) { - System.out.println("从缓存获取access_token: " + accessToken); + System.out.println("从缓存获取access_token(JSON格式): " + accessToken); return accessToken; } } 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()); // 缓存数据异常,删除缓存,重新获取 redisTemplate.delete(key); @@ -437,9 +513,16 @@ public class WxLoginController extends BaseController { String accessToken = response.getString("access_token"); 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小时) - 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("已统一存储为JSON格式: " + tokenData.toJSONString()); return accessToken; } else { System.err.println("响应中没有access_token字段: " + cleanResult);