Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
Y
yd-user
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
xingmin
yd-user
Commits
74801049
Commit
74801049
authored
Oct 16, 2026
by
zhangxingmin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
push
parent
a945cf0b
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
44 additions
and
14 deletions
+44
-14
yd-user-api/src/main/java/com/yd/user/api/service/impl/ApiScanLoginServiceImpl.java
+11
-3
yd-user-api/src/main/java/com/yd/user/api/service/impl/ApiThirdPartyScanLoginServiceImpl.java
+25
-9
yd-user-api/src/main/java/com/yd/user/api/utils/WeChatApiUtil.java
+8
-2
No files found.
yd-user-api/src/main/java/com/yd/user/api/service/impl/ApiScanLoginServiceImpl.java
View file @
74801049
...
...
@@ -74,7 +74,7 @@ public class ApiScanLoginServiceImpl implements ApiScanLoginService {
String
qrId
=
UUID
.
randomUUID
().
toString
().
replace
(
"-"
,
""
);
// 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. 调用微信接口生成带参临时二维码
String
ticket
=
weChatApiUtil
.
createTemporaryQrCode
(
...
...
@@ -129,6 +129,10 @@ public class ApiScanLoginServiceImpl implements ApiScanLoginService {
log
.
warn
(
"分享扫码回调参数缺失,openid={}, eventKey={}"
,
openid
,
eventKey
);
return
;
}
// 防御性去掉 qrscene_ 前缀(未关注用户扫码关注时微信会加)
if
(
eventKey
.
startsWith
(
"qrscene_"
))
{
eventKey
=
eventKey
.
substring
(
"qrscene_"
.
length
());
}
// 2. 解析 EventKey,格式:bizType:qrId:tenantBizId:projectBizId:userId
String
[]
parts
=
eventKey
.
split
(
":"
);
...
...
@@ -168,7 +172,7 @@ public class ApiScanLoginServiceImpl implements ApiScanLoginService {
// 5. 写入绑定关系表
// 先查询用户是否已存在绑定记录
UserThirdPartyBind
existBind
=
userThirdPartyBindService
.
queryBind
(
tenantBizId
,
projectBizId
,
unionid
,
openid
);
UserThirdPartyBind
existBind
=
userThirdPartyBindService
.
queryBind
(
tenantBizId
,
projectBizId
,
unionid
,
openid
);
if
(
existBind
!=
null
)
{
log
.
info
(
"该微信已绑定,无需重复绑定,openid={}, projectBizId={}"
,
openid
,
projectBizId
);
}
else
{
...
...
@@ -266,6 +270,10 @@ public class ApiScanLoginServiceImpl implements ApiScanLoginService {
log
.
warn
(
"登录扫码回调参数缺失,openid={}, eventKey={}"
,
openid
,
eventKey
);
return
;
}
// 防御性去掉 qrscene_ 前缀(未关注用户扫码关注时微信会加)
if
(
eventKey
.
startsWith
(
"qrscene_"
))
{
eventKey
=
eventKey
.
substring
(
"qrscene_"
.
length
());
}
// 2. 解析 EventKey,格式:bizType:qrId:tenantBizId:projectBizId
String
[]
parts
=
eventKey
.
split
(
":"
);
...
...
@@ -308,7 +316,7 @@ public class ApiScanLoginServiceImpl implements ApiScanLoginService {
}
// 6. 查询绑定关系
UserThirdPartyBind
bind
=
userThirdPartyBindService
.
queryBind
(
tenantBizId
,
projectBizId
,
unionid
,
openid
);
UserThirdPartyBind
bind
=
userThirdPartyBindService
.
queryBind
(
tenantBizId
,
projectBizId
,
unionid
,
openid
);
if
(
bind
==
null
)
{
log
.
info
(
"未找到绑定关系,unionid={}, projectBizId={}"
,
unionid
,
projectBizId
);
redisUtil
.
setCacheObject
(
ScanLoginConstants
.
REDIS_KEY_QR
+
qrId
,
...
...
yd-user-api/src/main/java/com/yd/user/api/service/impl/ApiThirdPartyScanLoginServiceImpl.java
View file @
74801049
...
...
@@ -82,6 +82,11 @@ public class ApiThirdPartyScanLoginServiceImpl implements ApiThirdPartyScanLogin
* 微信事件推送回调(POST)
* 从 XML 的 ToUserName 反查公众号配置,拿到 appId 后按 EventKey 中的 bizType 分流。
*
* 注意:
* 1. 非扫码事件(如菜单点击、文本消息等)直接返回 success,不处理也不重试
* 2. EventKey 为空时返回 success,避免微信重试推送
* 3. 未关注用户扫码关注,EventKey 会带 qrscene_ 前缀,这里统一去掉
*
* @param xml 微信XML事件内容
* @return "success"
*/
...
...
@@ -91,33 +96,44 @@ public class ApiThirdPartyScanLoginServiceImpl implements ApiThirdPartyScanLogin
String
toUserName
=
weChatApiUtil
.
getToUserName
(
xml
);
if
(
StringUtils
.
isBlank
(
toUserName
))
{
log
.
warn
(
"微信回调 ToUserName 为空,xml={}"
,
xml
);
return
"
fail
"
;
return
"
success
"
;
}
// 2. 用 ToUserName 反查公众号配置
ThirdPartyPlatform
platform
=
thirdPartyPlatformService
.
getByToUserName
(
toUserName
);
if
(
platform
==
null
)
{
log
.
warn
(
"未找到 ToUserName 对应的公众号,toUserName={}"
,
toUserName
);
return
"
fail
"
;
return
"
success
"
;
}
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
);
if
(
StringUtils
.
isBlank
(
eventKey
))
{
log
.
warn
(
"扫码
回调参数缺失,eventKey={}"
,
eventKey
);
return
"
fail
"
;
log
.
warn
(
"扫码
事件 EventKey 为空,appId={}, eventType={}"
,
appId
,
eventType
);
return
"
success
"
;
}
// 未关注用户扫码关注时,EventKey 带 qrscene_ 前缀,这里去掉
// 未关注用户扫码关注时,EventKey 带 qrscene_ 前缀,这里
防御性
去掉
if
(
eventKey
.
startsWith
(
"qrscene_"
))
{
eventKey
=
eventKey
.
substring
(
"qrscene_"
.
length
());
}
// 5. 分流
String
[]
parts
=
eventKey
.
split
(
":"
);
if
(
parts
.
length
<
1
)
{
log
.
warn
(
"
登录扫码
EventKey 格式错误:{}"
,
eventKey
);
return
"
fail
"
;
log
.
warn
(
"EventKey 格式错误:{}"
,
eventKey
);
return
"
success
"
;
}
String
bizType
=
parts
[
0
];
log
.
info
(
"微信回调识别公众号成功,toUserName={}, appId={}, eventType={}, bizType={}"
,
toUserName
,
appId
,
eventType
,
bizType
);
if
(
ScanLoginConstants
.
BIZ_TYPE_LOGIN
.
equals
(
bizType
))
{
scanLoginService
.
handleLoginWechatCallback
(
appId
,
xml
);
}
else
if
(
ScanLoginConstants
.
BIZ_TYPE_SHARE_BIND
.
equals
(
bizType
))
{
...
...
yd-user-api/src/main/java/com/yd/user/api/utils/WeChatApiUtil.java
View file @
74801049
...
...
@@ -188,12 +188,18 @@ public class WeChatApiUtil {
/**
* 解析微信 XML 获取 EventKey
* 注意:未关注用户扫码关注后,微信会在 EventKey 前加 "qrscene_" 前缀,
* 这里统一去掉,让上层拿到的都是纯场景值
*
* @param xml 微信回调 XML
* @return EventKey 字段值
* @return EventKey 字段值
(已去掉 qrscene_ 前缀)
*/
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
;
}
/**
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment