fix(wx): 修复微信公众号扫码关注及登录流程中的数据处理问题

- 调整默认角色分配,从guest改为user以提升用户权限合理性
- 完善扫码关注事件的用户信息处理流程,确保unionid和subscribe状态正确管理
- 修复用户角色绑定逻辑,处理无角色或无效角色时重新分配默认角色
- 优化扫码登录状态更新日志打印,提升信息可读性
- 修正用户注册流程中角色获取失败时的默认角色设置
- 增加生成微信扫码登录二维码接口的稳定性和错误处理
- 统一日志输出格式,增加关键节点日志便于问题追踪
- 清理微信消息
This commit is contained in:
2026-04-07 01:53:21 +08:00
parent e73e0fb6b5
commit 181801abdb
2 changed files with 51 additions and 51 deletions

View File

@@ -13,5 +13,5 @@
}
]
},
"lastUpdated": 1775497010453
"lastUpdated": 1775497544505
}

View File

@@ -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<UserOauth>()
@@ -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<UserOauth> 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<UserOauth>()
.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<UserRole> userRoles = userRoleService.list(new LambdaQueryWrapper<UserRole>()
.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");
}
}