fix(wx): 修复微信公众号扫码关注及登录流程中的数据处理问题
- 调整默认角色分配,从guest改为user以提升用户权限合理性 - 完善扫码关注事件的用户信息处理流程,确保unionid和subscribe状态正确管理 - 修复用户角色绑定逻辑,处理无角色或无效角色时重新分配默认角色 - 优化扫码登录状态更新日志打印,提升信息可读性 - 修正用户注册流程中角色获取失败时的默认角色设置 - 增加生成微信扫码登录二维码接口的稳定性和错误处理 - 统一日志输出格式,增加关键节点日志便于问题追踪 - 清理微信消息
This commit is contained in:
@@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user