Commit 74801049 by zhangxingmin

push

parent a945cf0b
...@@ -74,7 +74,7 @@ public class ApiScanLoginServiceImpl implements ApiScanLoginService { ...@@ -74,7 +74,7 @@ public class ApiScanLoginServiceImpl implements ApiScanLoginService {
String qrId = UUID.randomUUID().toString().replace("-", ""); String qrId = UUID.randomUUID().toString().replace("-", "");
// 3. 构造 scene_str自定义参数,格式:bizType:qrId:tenantBizId:projectBizId:userId // 3. 构造 scene_str自定义参数,格式:bizType:qrId:tenantBizId:projectBizId:userId
String sceneStr = ScanLoginConstants.BIZ_TYPE_SHARE_BIND + ":" + qrId + ":" +request.getTenantBizId() + ":" +request.getProjectBizId() + ":" + request.getUserId(); String sceneStr = ScanLoginConstants.BIZ_TYPE_SHARE_BIND + ":" + qrId + ":" + request.getTenantBizId() + ":" + request.getProjectBizId() + ":" + request.getUserId();
// 4. 调用微信接口生成带参临时二维码 // 4. 调用微信接口生成带参临时二维码
String ticket = weChatApiUtil.createTemporaryQrCode( String ticket = weChatApiUtil.createTemporaryQrCode(
...@@ -129,6 +129,10 @@ public class ApiScanLoginServiceImpl implements ApiScanLoginService { ...@@ -129,6 +129,10 @@ public class ApiScanLoginServiceImpl implements ApiScanLoginService {
log.warn("分享扫码回调参数缺失,openid={}, eventKey={}", openid, eventKey); log.warn("分享扫码回调参数缺失,openid={}, eventKey={}", openid, eventKey);
return; return;
} }
// 防御性去掉 qrscene_ 前缀(未关注用户扫码关注时微信会加)
if (eventKey.startsWith("qrscene_")) {
eventKey = eventKey.substring("qrscene_".length());
}
// 2. 解析 EventKey,格式:bizType:qrId:tenantBizId:projectBizId:userId // 2. 解析 EventKey,格式:bizType:qrId:tenantBizId:projectBizId:userId
String[] parts = eventKey.split(":"); String[] parts = eventKey.split(":");
...@@ -168,7 +172,7 @@ public class ApiScanLoginServiceImpl implements ApiScanLoginService { ...@@ -168,7 +172,7 @@ public class ApiScanLoginServiceImpl implements ApiScanLoginService {
// 5. 写入绑定关系表 // 5. 写入绑定关系表
// 先查询用户是否已存在绑定记录 // 先查询用户是否已存在绑定记录
UserThirdPartyBind existBind = userThirdPartyBindService.queryBind(tenantBizId,projectBizId,unionid,openid); UserThirdPartyBind existBind = userThirdPartyBindService.queryBind(tenantBizId, projectBizId, unionid, openid);
if (existBind != null) { if (existBind != null) {
log.info("该微信已绑定,无需重复绑定,openid={}, projectBizId={}", openid, projectBizId); log.info("该微信已绑定,无需重复绑定,openid={}, projectBizId={}", openid, projectBizId);
} else { } else {
...@@ -266,6 +270,10 @@ public class ApiScanLoginServiceImpl implements ApiScanLoginService { ...@@ -266,6 +270,10 @@ public class ApiScanLoginServiceImpl implements ApiScanLoginService {
log.warn("登录扫码回调参数缺失,openid={}, eventKey={}", openid, eventKey); log.warn("登录扫码回调参数缺失,openid={}, eventKey={}", openid, eventKey);
return; return;
} }
// 防御性去掉 qrscene_ 前缀(未关注用户扫码关注时微信会加)
if (eventKey.startsWith("qrscene_")) {
eventKey = eventKey.substring("qrscene_".length());
}
// 2. 解析 EventKey,格式:bizType:qrId:tenantBizId:projectBizId // 2. 解析 EventKey,格式:bizType:qrId:tenantBizId:projectBizId
String[] parts = eventKey.split(":"); String[] parts = eventKey.split(":");
...@@ -308,7 +316,7 @@ public class ApiScanLoginServiceImpl implements ApiScanLoginService { ...@@ -308,7 +316,7 @@ public class ApiScanLoginServiceImpl implements ApiScanLoginService {
} }
// 6. 查询绑定关系 // 6. 查询绑定关系
UserThirdPartyBind bind = userThirdPartyBindService.queryBind(tenantBizId,projectBizId,unionid,openid); UserThirdPartyBind bind = userThirdPartyBindService.queryBind(tenantBizId, projectBizId, unionid, openid);
if (bind == null) { if (bind == null) {
log.info("未找到绑定关系,unionid={}, projectBizId={}", unionid, projectBizId); log.info("未找到绑定关系,unionid={}, projectBizId={}", unionid, projectBizId);
redisUtil.setCacheObject(ScanLoginConstants.REDIS_KEY_QR + qrId, redisUtil.setCacheObject(ScanLoginConstants.REDIS_KEY_QR + qrId,
......
...@@ -82,6 +82,11 @@ public class ApiThirdPartyScanLoginServiceImpl implements ApiThirdPartyScanLogin ...@@ -82,6 +82,11 @@ public class ApiThirdPartyScanLoginServiceImpl implements ApiThirdPartyScanLogin
* 微信事件推送回调(POST) * 微信事件推送回调(POST)
* 从 XML 的 ToUserName 反查公众号配置,拿到 appId 后按 EventKey 中的 bizType 分流。 * 从 XML 的 ToUserName 反查公众号配置,拿到 appId 后按 EventKey 中的 bizType 分流。
* *
* 注意:
* 1. 非扫码事件(如菜单点击、文本消息等)直接返回 success,不处理也不重试
* 2. EventKey 为空时返回 success,避免微信重试推送
* 3. 未关注用户扫码关注,EventKey 会带 qrscene_ 前缀,这里统一去掉
*
* @param xml 微信XML事件内容 * @param xml 微信XML事件内容
* @return "success" * @return "success"
*/ */
...@@ -91,33 +96,44 @@ public class ApiThirdPartyScanLoginServiceImpl implements ApiThirdPartyScanLogin ...@@ -91,33 +96,44 @@ public class ApiThirdPartyScanLoginServiceImpl implements ApiThirdPartyScanLogin
String toUserName = weChatApiUtil.getToUserName(xml); String toUserName = weChatApiUtil.getToUserName(xml);
if (StringUtils.isBlank(toUserName)) { if (StringUtils.isBlank(toUserName)) {
log.warn("微信回调 ToUserName 为空,xml={}", xml); log.warn("微信回调 ToUserName 为空,xml={}", xml);
return "fail"; return "success";
} }
// 2. 用 ToUserName 反查公众号配置 // 2. 用 ToUserName 反查公众号配置
ThirdPartyPlatform platform = thirdPartyPlatformService.getByToUserName(toUserName); ThirdPartyPlatform platform = thirdPartyPlatformService.getByToUserName(toUserName);
if (platform == null) { if (platform == null) {
log.warn("未找到 ToUserName 对应的公众号,toUserName={}", toUserName); log.warn("未找到 ToUserName 对应的公众号,toUserName={}", toUserName);
return "fail"; return "success";
} }
String appId = platform.getAppId(); String appId = platform.getAppId();
log.info("微信回调识别公众号成功,toUserName={}, appId={}", toUserName, appId);
// 3. 解析 EventKey 并分流处理 // 3. 判断事件类型,只有 SCAN 或 subscribe 才处理
String eventType = weChatApiUtil.getEventType(xml);
if (!"SCAN".equalsIgnoreCase(eventType) && !"subscribe".equalsIgnoreCase(eventType)) {
log.info("非扫码事件,eventType={}, 忽略处理", eventType);
return "success";
}
// 4. 解析 EventKey
String eventKey = weChatApiUtil.getEventKey(xml); String eventKey = weChatApiUtil.getEventKey(xml);
if (StringUtils.isBlank(eventKey)) { if (StringUtils.isBlank(eventKey)) {
log.warn("扫码回调参数缺失,eventKey={}", eventKey); log.warn("扫码事件 EventKey 为空,appId={}, eventType={}", appId, eventType);
return "fail"; return "success";
} }
// 未关注用户扫码关注时,EventKey 带 qrscene_ 前缀,这里去掉 // 未关注用户扫码关注时,EventKey 带 qrscene_ 前缀,这里防御性去掉
if (eventKey.startsWith("qrscene_")) { if (eventKey.startsWith("qrscene_")) {
eventKey = eventKey.substring("qrscene_".length()); eventKey = eventKey.substring("qrscene_".length());
} }
// 5. 分流
String[] parts = eventKey.split(":"); String[] parts = eventKey.split(":");
if (parts.length < 1) { if (parts.length < 1) {
log.warn("登录扫码 EventKey 格式错误:{}", eventKey); log.warn("EventKey 格式错误:{}", eventKey);
return "fail"; return "success";
} }
String bizType = parts[0]; String bizType = parts[0];
log.info("微信回调识别公众号成功,toUserName={}, appId={}, eventType={}, bizType={}",
toUserName, appId, eventType, bizType);
if (ScanLoginConstants.BIZ_TYPE_LOGIN.equals(bizType)) { if (ScanLoginConstants.BIZ_TYPE_LOGIN.equals(bizType)) {
scanLoginService.handleLoginWechatCallback(appId, xml); scanLoginService.handleLoginWechatCallback(appId, xml);
} else if (ScanLoginConstants.BIZ_TYPE_SHARE_BIND.equals(bizType)) { } else if (ScanLoginConstants.BIZ_TYPE_SHARE_BIND.equals(bizType)) {
......
...@@ -188,12 +188,18 @@ public class WeChatApiUtil { ...@@ -188,12 +188,18 @@ public class WeChatApiUtil {
/** /**
* 解析微信 XML 获取 EventKey * 解析微信 XML 获取 EventKey
* 注意:未关注用户扫码关注后,微信会在 EventKey 前加 "qrscene_" 前缀,
* 这里统一去掉,让上层拿到的都是纯场景值
* *
* @param xml 微信回调 XML * @param xml 微信回调 XML
* @return EventKey 字段值 * @return EventKey 字段值(已去掉 qrscene_ 前缀)
*/ */
public String getEventKey(String xml) { public String getEventKey(String xml) {
return getXmlField(xml, "EventKey"); String eventKey = getXmlField(xml, "EventKey");
if (StringUtils.isNotBlank(eventKey) && eventKey.startsWith("qrscene_")) {
eventKey = eventKey.substring("qrscene_".length());
}
return eventKey;
} }
/** /**
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment