From 181801abdb13e1d09520f2097cbbee22c05ee048 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B5=B5=E5=BF=A0=E6=9E=97?= <170083662@qq.com> Date: Tue, 7 Apr 2026 01:53:21 +0800 Subject: [PATCH] =?UTF-8?q?fix(wx):=20=E4=BF=AE=E5=A4=8D=E5=BE=AE=E4=BF=A1?= =?UTF-8?q?=E5=85=AC=E4=BC=97=E5=8F=B7=E6=89=AB=E7=A0=81=E5=85=B3=E6=B3=A8?= =?UTF-8?q?=E5=8F=8A=E7=99=BB=E5=BD=95=E6=B5=81=E7=A8=8B=E4=B8=AD=E7=9A=84?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E5=A4=84=E7=90=86=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 调整默认角色分配,从guest改为user以提升用户权限合理性 - 完善扫码关注事件的用户信息处理流程,确保unionid和subscribe状态正确管理 - 修复用户角色绑定逻辑,处理无角色或无效角色时重新分配默认角色 - 优化扫码登录状态更新日志打印,提升信息可读性 - 修正用户注册流程中角色获取失败时的默认角色设置 - 增加生成微信扫码登录二维码接口的稳定性和错误处理 - 统一日志输出格式,增加关键节点日志便于问题追踪 - 清理微信消息 --- .workbuddy/expert-history.json | 2 +- .../controller/WxOfficialController.java | 100 +++++++++--------- 2 files changed, 51 insertions(+), 51 deletions(-) diff --git a/.workbuddy/expert-history.json b/.workbuddy/expert-history.json index 5ded824..0216a4e 100644 --- a/.workbuddy/expert-history.json +++ b/.workbuddy/expert-history.json @@ -13,5 +13,5 @@ } ] }, - "lastUpdated": 1775497010453 + "lastUpdated": 1775497544505 } \ No newline at end of file diff --git a/src/main/java/com/gxwebsoft/common/system/controller/WxOfficialController.java b/src/main/java/com/gxwebsoft/common/system/controller/WxOfficialController.java index 6a5b7d1..36651e6 100644 --- a/src/main/java/com/gxwebsoft/common/system/controller/WxOfficialController.java +++ b/src/main/java/com/gxwebsoft/common/system/controller/WxOfficialController.java @@ -76,11 +76,11 @@ public class WxOfficialController extends BaseController { private static final String QRCODE_CREATE_URL = "https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token="; // 查看二维码接口 private static final String QRCODE_SHOW_URL = "https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket="; - + // 微信服务器配置(从配置文件读取或使用默认值) private static final String TOKEN = "gxwebsoft"; private static final String ENCODING_AES_KEY = "ARve4au5GF2fE2cT13xpaHhuqS2yjE34gpVe8IZwd4C"; - + @Resource private UserService userService; @Resource @@ -135,11 +135,11 @@ public class WxOfficialController extends BaseController { System.out.println("========== 接收微信消息 =========="); System.out.println("tenantId = " + tenantId); System.out.println("msg_signature = " + msg_signature); - + // 从请求中获取XML数据 String xmlData = IOUtils.toString(request.getInputStream(), "UTF-8"); System.out.println("原始xmlData = " + xmlData); - + // 如果有加密参数,进行解密 if (StrUtil.isNotBlank(msg_signature) && StrUtil.isNotBlank(xmlData) && xmlData.contains("Encrypt")) { try { @@ -160,40 +160,40 @@ public class WxOfficialController extends BaseController { return "error"; } } - + // 解析XML数据 Document document = XmlUtil.parseXml(xmlData); Element rootElement = XmlUtil.getRootElement(document); - + // 获取消息类型 Element msgTypeElement = XmlUtil.getElement(rootElement, "MsgType"); String msgType = msgTypeElement != null ? msgTypeElement.getTextContent() : ""; System.out.println("msgType = " + msgType); - + // 获取事件类型(如果是事件消息) Element eventElement = XmlUtil.getElement(rootElement, "Event"); String event = eventElement != null ? eventElement.getTextContent() : ""; System.out.println("event = " + event); - + // 获取事件KEY(用于判断是否是扫码事件) Element eventKeyElement = XmlUtil.getElement(rootElement, "EventKey"); String eventKey = eventKeyElement != null ? eventKeyElement.getTextContent() : ""; System.out.println("eventKey = " + eventKey); - + // 获取用户openid Element FromUserName = XmlUtil.getElement(rootElement, "FromUserName"); String openId = FromUserName != null ? FromUserName.getTextContent() : ""; System.out.println("openId = " + openId); - + // 获取 ticket(扫码事件专用) Element ticketElement = XmlUtil.getElement(rootElement, "Ticket"); String ticket = ticketElement != null ? ticketElement.getTextContent() : ""; System.out.println("ticket = " + ticket); - + // 处理扫码关注事件 if ("event".equals(msgType) && ("subscribe".equals(event) || "SCAN".equals(event))) { System.out.println("========== 处理扫码关注事件 =========="); - + // 获取扫码的 token(从 EventKey 中提取,格式:qrscene_xxx 或直接是 xxx) String token = ""; if (StrUtil.isNotBlank(eventKey)) { @@ -204,7 +204,7 @@ public class WxOfficialController extends BaseController { } } System.out.println("扫码登录token = " + token); - + // 获取用户信息 if (StrUtil.isNotBlank(openId)) { // 获取用户基本信息(UnionID机制) @@ -214,26 +214,26 @@ public class WxOfficialController extends BaseController { final String subscribe = jsonObject.getString("subscribe"); System.out.println("unionid = " + unionid); System.out.println("subscribe = " + subscribe); - + Integer userId = processWxUser(tenantId, openId, unionid, subscribe); - + // 如果有关联的扫码登录token,完成登录 if (StrUtil.isNotBlank(token) && userId != null && userId > 0) { completeQrLogin(token, userId, tenantId); } } } - + // 返回 success 表示处理成功 return "success"; } - + /** * 处理微信用户(关注/注册/登录) */ private Integer processWxUser(Integer tenantId, String openId, String unionid, String subscribe) { Integer userId = 0; - + // 关注操作 if (subscribe != null && subscribe.equals("1")) { final int count = userOauthService.count(new LambdaQueryWrapper() @@ -241,7 +241,7 @@ public class WxOfficialController extends BaseController { .eq(UserOauth::getUnionid, unionid) .eq(UserOauth::getTenantId, tenantId)); System.out.println("已绑定用户数量 = " + count); - + if (count == 0) { // 检查其他平台是否有注册过 final List list = userOauthService.list( @@ -249,7 +249,7 @@ public class WxOfficialController extends BaseController { .eq(UserOauth::getUnionid, unionid) .eq(UserOauth::getDeleted, 0)); final int size = list.size(); - + // 新用户注册 if (size == 0) { User user = new User(); @@ -263,7 +263,7 @@ public class WxOfficialController extends BaseController { user.setRecommend(0); final RoleParam roleParam = new RoleParam(); roleParam.setTenantId(tenantId); - roleParam.setRoleCode("guest"); + roleParam.setRoleCode("user"); Role role = roleService.getByRoleCode(roleParam); user.setRoleId(role.getRoleId()); if (userService.saveUser(user)) { @@ -285,7 +285,7 @@ public class WxOfficialController extends BaseController { } System.out.println("新微信公众号用户 userId = " + userId); } - + // 更新 if (!CollectionUtils.isEmpty(list)) { for (UserOauth item : list) { @@ -295,7 +295,7 @@ public class WxOfficialController extends BaseController { } System.out.println("其他平台有注册过 userId = " + userId); } - + // 保存第三方用户记录 final UserOauth userOauth = new UserOauth(); userOauth.setOauthType(MP_OFFICIAL); @@ -338,10 +338,10 @@ public class WxOfficialController extends BaseController { } } } - + return userId; } - + /** * 完成扫码登录 */ @@ -385,10 +385,10 @@ public class WxOfficialController extends BaseController { } redisUtil.set(redisKey, qrLoginData, ttlSeconds, TimeUnit.SECONDS); - log.info("扫码登录状态已更新,token={}, userId={}, status={}, needBindPhone={}, message={}, ttlSeconds={}", - token, userId, qrLoginData.getStatus(), qrLoginData.getNeedBindPhone(), + log.info("扫码登录状态已更新,token={}, userId={}, status={}, needBindPhone={}, message={}, ttlSeconds={}", + token, userId, qrLoginData.getStatus(), qrLoginData.getNeedBindPhone(), qrLoginData.getMessage(), ttlSeconds); - System.out.println("扫码登录完成,token=" + token + ", userId=" + userId + + System.out.println("扫码登录完成,token=" + token + ", userId=" + userId + ", status=" + qrLoginData.getStatus() + ", message=" + qrLoginData.getMessage()); } catch (Exception e) { log.error("完成扫码登录失败", e); @@ -400,32 +400,32 @@ public class WxOfficialController extends BaseController { JwtSubject jwtSubject = new JwtSubject(user.getUsername(), user.getTenantId()); return JwtUtil.buildToken(jwtSubject, configProperties.getTokenExpireTime(), configProperties.getTokenKey()); } - + @Operation(summary = "生成微信扫码登录二维码") @GetMapping("/qrcode/{token}") public ApiResult generateQrCode(@PathVariable("token") String token) { try { // 生成带参数的二维码,scene 为 token String url = QRCODE_CREATE_URL + getAccessToken(); - + // 创建临时二维码(有效期7天),scene_str 最大32个可见字符 JSONObject params = new JSONObject(); params.put("action_info", new JSONObject().put("scene", new JSONObject().put("scene_str", token))); params.put("action_name", "QR_STR_SCENE"); params.put("expire_seconds", 604800); // 7天有效期 - + String result = HttpRequest.post(url) .body(params.toJSONString()) .timeout(10000) .execute().body(); - + System.out.println("生成二维码结果: " + result); - + JSONObject jsonResult = JSONObject.parseObject(result); if (jsonResult.containsKey("ticket")) { String ticket = jsonResult.getString("ticket"); String qrCodeUrl = QRCODE_SHOW_URL + java.net.URLEncoder.encode(ticket, "UTF-8"); - + return success(qrCodeUrl); } else { return fail("生成二维码失败: " + result); @@ -644,7 +644,7 @@ public class WxOfficialController extends BaseController { new LambdaQueryWrapper() .eq(UserOauth::getUnionid, unionid) .eq(UserOauth::getDeleted, 0)); - + if (!CollectionUtils.isEmpty(list)) { for (UserOauth item : list) { if (item.getUserId() != null) { @@ -654,7 +654,7 @@ public class WxOfficialController extends BaseController { } System.out.println("数据不一致:通过unionid找到其他平台的用户 userId = " + userId); } - + // 如果没找到用户,创建一个新用户 if (userId == 0) { User user = new User(); @@ -666,7 +666,7 @@ public class WxOfficialController extends BaseController { user.setPassword(userService.encodePassword(CommonUtil.randomUUID16())); user.setTenantId(tenantId); user.setRecommend(0); - + // 尝试获取"user"角色,不行就用"guest",再不行用默认6 Role role = null; try { @@ -685,9 +685,9 @@ public class WxOfficialController extends BaseController { System.out.println("获取guest角色也失败,使用默认角色ID 6"); } } - + user.setRoleId(role != null ? role.getRoleId() : 6); - + if (userService.saveUser(user)) { userId = user.getUserId(); // 添加用户角色 @@ -707,7 +707,7 @@ public class WxOfficialController extends BaseController { } System.out.println("数据不一致:创建新用户 userId = " + userId); } - + // 创建oauth记录 final UserOauth userOauth = new UserOauth(); userOauth.setOauthType(MP_OFFICIAL); @@ -717,7 +717,7 @@ public class WxOfficialController extends BaseController { userOauth.setTenantId(tenantId); boolean save = userOauthService.save(userOauth); System.out.println("创建oauth记录修复数据不一致,结果 = " + save); - + return userId; } @@ -730,10 +730,10 @@ public class WxOfficialController extends BaseController { List userRoles = userRoleService.list(new LambdaQueryWrapper() .eq(UserRole::getUserId, user.getUserId()) .eq(UserRole::getTenantId, tenantId)); - + if (CollectionUtils.isEmpty(userRoles)) { System.out.println("用户 " + user.getUserId() + " 没有角色绑定,尝试分配角色"); - + // 获取合适的角色 Role role = null; // 先尝试获取"user"角色 @@ -753,20 +753,20 @@ public class WxOfficialController extends BaseController { System.out.println("获取guest角色也失败,使用默认角色ID 6"); } } - + Integer roleId = role != null ? role.getRoleId() : 6; - + // 创建用户角色绑定 final UserRole userRole = new UserRole(); userRole.setUserId(user.getUserId()); userRole.setTenantId(tenantId); userRole.setRoleId(roleId); userRoleService.save(userRole); - + // 更新用户的roleId user.setRoleId(roleId); userService.updateUser(user); - + System.out.println("为用户 " + user.getUserId() + " 分配了角色ID: " + roleId); } else { // 检查角色的有效性 @@ -783,7 +783,7 @@ public class WxOfficialController extends BaseController { break; } } - + if (!hasValidRole) { System.out.println("用户 " + user.getUserId() + " 的角色绑定无效,重新分配"); // 重新分配角色(简化逻辑,使用默认角色ID 6) @@ -792,10 +792,10 @@ public class WxOfficialController extends BaseController { userRole.setTenantId(tenantId); userRole.setRoleId(6); userRoleService.save(userRole); - + user.setRoleId(6); userService.updateUser(user); - + System.out.println("重新为用户 " + user.getUserId() + " 分配了默认角色ID: 6"); } }