Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
Y
yd-notice
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-notice
Commits
82141c7e
Commit
82141c7e
authored
Aug 28, 2026
by
zhangxingmin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
push
parent
b1b8fd85
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
43 additions
and
54 deletions
+43
-54
yd-notice-api/src/main/java/com/yd/notice/api/service/impl/ApiSubscribeRecordServiceImpl.java
+43
-54
No files found.
yd-notice-api/src/main/java/com/yd/notice/api/service/impl/ApiSubscribeRecordServiceImpl.java
View file @
82141c7e
...
@@ -14,7 +14,6 @@ import com.yd.notice.service.model.NotificationTemplate;
...
@@ -14,7 +14,6 @@ import com.yd.notice.service.model.NotificationTemplate;
import
com.yd.notice.service.model.SubscribeRecord
;
import
com.yd.notice.service.model.SubscribeRecord
;
import
com.yd.notice.service.service.INotificationTemplateService
;
import
com.yd.notice.service.service.INotificationTemplateService
;
import
com.yd.notice.service.service.ISubscribeRecordService
;
import
com.yd.notice.service.service.ISubscribeRecordService
;
import
com.yd.notice.service.utils.SfpTokenUtil
;
import
lombok.extern.slf4j.Slf4j
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.core.env.Environment
;
import
org.springframework.core.env.Environment
;
...
@@ -32,7 +31,9 @@ import javax.annotation.Resource;
...
@@ -32,7 +31,9 @@ import javax.annotation.Resource;
import
javax.servlet.http.HttpServletRequest
;
import
javax.servlet.http.HttpServletRequest
;
import
java.time.LocalDateTime
;
import
java.time.LocalDateTime
;
import
java.util.ArrayList
;
import
java.util.ArrayList
;
import
java.util.HashMap
;
import
java.util.List
;
import
java.util.List
;
import
java.util.Map
;
/**
/**
* 小程序订阅记录 API 服务实现类
* 小程序订阅记录 API 服务实现类
...
@@ -57,26 +58,28 @@ public class ApiSubscribeRecordServiceImpl implements ApiSubscribeRecordService
...
@@ -57,26 +58,28 @@ public class ApiSubscribeRecordServiceImpl implements ApiSubscribeRecordService
private
Environment
env
;
private
Environment
env
;
/**
/**
* 根据当前环境获取
SFP API
基础地址
* 根据当前环境获取
ajb 服务
基础地址
*/
*/
private
String
get
SfpApi
BaseUrl
()
{
private
String
get
Ajb
BaseUrl
()
{
String
activeProfile
=
env
.
getProperty
(
"spring.profiles.active"
,
"dev"
);
String
activeProfile
=
env
.
getProperty
(
"spring.profiles.active"
,
"dev"
);
log
.
info
(
"当前环境: {}, 获取 SFP API 地址"
,
activeProfile
);
log
.
info
(
"当前环境: {}, 获取 ajb 服务地址"
,
activeProfile
);
if
(
"prod"
.
equalsIgnoreCase
(
activeProfile
))
{
if
(
"prod"
.
equalsIgnoreCase
(
activeProfile
)
||
"production"
.
equalsIgnoreCase
(
activeProfile
))
{
return
"https://hoservice.ydhomeoffice.cn/hoserviceApi"
;
// 生产环境
// 生产环境 ajb 服务地址(请根据实际部署确认)
return
"https://hoservice.ydhomeoffice.cn/hoserviceApi"
;
}
else
{
}
else
{
return
"https://mdev.anjibao.cn/sfpApi"
;
// 测试/开发环境
// 测试/开发环境
return
"https://mdev.anjibao.cn/sfpApi"
;
}
}
}
}
/**
/**
* 从请求头中获取 Token,
解析出 SFP 用户 ID,再调用 SFP 接口获取用户的 wxOpenId
* 从请求头中获取 Token,
通过远程解析获取用户的完整信息(包含 openid 和 userId)
*
*
* @return
用户的 openid
* @return
QuerySfpUserResponse 用户信息
* @throws RuntimeException 如果获取失败
* @throws RuntimeException 如果获取失败
*/
*/
private
String
getOpenid
FromToken
()
{
private
QuerySfpUserResponse
getUserInfo
FromToken
()
{
//
从请求上下文中获取当前请求
//
获取当前请求上下文
ServletRequestAttributes
attributes
=
(
ServletRequestAttributes
)
RequestContextHolder
.
getRequestAttributes
();
ServletRequestAttributes
attributes
=
(
ServletRequestAttributes
)
RequestContextHolder
.
getRequestAttributes
();
if
(
attributes
==
null
)
{
if
(
attributes
==
null
)
{
log
.
error
(
"无法获取当前请求上下文"
);
log
.
error
(
"无法获取当前请求上下文"
);
...
@@ -89,63 +92,44 @@ public class ApiSubscribeRecordServiceImpl implements ApiSubscribeRecordService
...
@@ -89,63 +92,44 @@ public class ApiSubscribeRecordServiceImpl implements ApiSubscribeRecordService
throw
new
RuntimeException
(
"未提供认证 Token"
);
throw
new
RuntimeException
(
"未提供认证 Token"
);
}
}
//
----- 通用提取逻辑:取最后一个空格之后的部分,兼容任意前缀(如 "zuihuibi "、"Bearer " 等)-----
//
直接使用原始 authorization 值,不做任何处理,远程接口会自动剥离前缀
String
token
=
authorization
;
String
token
=
authorization
;
int
lastSpaceIndex
=
authorization
.
lastIndexOf
(
" "
);
log
.
info
(
"调用远程解析 Token 接口,原始 authorization: {}"
,
authorization
);
if
(
lastSpaceIndex
!=
-
1
)
{
token
=
authorization
.
substring
(
lastSpaceIndex
+
1
);
log
.
info
(
"认证头包含前缀,已自动提取 Token 部分(原头:{})"
,
authorization
);
}
// ----------------------------------------------------------------------------------------
// 1. 解析 Token 获取用户 ID
String
userIdStr
=
SfpTokenUtil
.
getUserIdFromToken
(
token
);
if
(!
StringUtils
.
hasText
(
userIdStr
))
{
log
.
error
(
"Token 解析失败,未获取到用户 ID"
);
throw
new
RuntimeException
(
"Token 无效"
);
}
Long
sfpUserId
;
try
{
sfpUserId
=
Long
.
valueOf
(
userIdStr
);
}
catch
(
NumberFormatException
e
)
{
log
.
error
(
"用户 ID 格式错误: {}"
,
userIdStr
);
throw
new
RuntimeException
(
"Token 中的用户 ID 格式错误"
);
}
//
2. 根据环境获取 SFP API 基础地址并调用接口
//
根据环境获取 ajb 服务地址
String
sfpApiBaseUrl
=
getSfpApi
BaseUrl
();
String
ajbBaseUrl
=
getAjb
BaseUrl
();
String
url
=
sfpApiBaseUrl
+
"/user/query/sfpUser
"
;
String
parseUrl
=
ajbBaseUrl
+
"/user/parse/token
"
;
HttpHeaders
headers
=
new
HttpHeaders
();
HttpHeaders
headers
=
new
HttpHeaders
();
headers
.
setContentType
(
MediaType
.
APPLICATION_JSON
);
headers
.
setContentType
(
MediaType
.
APPLICATION_JSON
);
String
requestBody
=
String
.
format
(
"{\"sfpUserId\":%d}"
,
sfpUserId
);
Map
<
String
,
String
>
requestBody
=
new
HashMap
<>();
HttpEntity
<
String
>
entity
=
new
HttpEntity
<>(
requestBody
,
headers
);
requestBody
.
put
(
"token"
,
token
);
HttpEntity
<
Map
<
String
,
String
>>
entity
=
new
HttpEntity
<>(
requestBody
,
headers
);
log
.
info
(
"调用 SFP 查询用户信息, url={}, requestBody={}"
,
url
,
requestBody
);
log
.
info
(
"调用远程解析 Token 接口, url={}, token前50字符: {}"
,
parseUrl
,
token
.
substring
(
0
,
Math
.
min
(
50
,
token
.
length
()))
+
"..."
);
try
{
try
{
ResponseEntity
<
JsonResult
>
responseEntity
=
restTemplate
.
postForEntity
(
u
rl
,
entity
,
JsonResult
.
class
);
ResponseEntity
<
JsonResult
>
responseEntity
=
restTemplate
.
postForEntity
(
parseU
rl
,
entity
,
JsonResult
.
class
);
if
(
responseEntity
.
getStatusCode
().
is2xxSuccessful
())
{
if
(
responseEntity
.
getStatusCode
().
is2xxSuccessful
())
{
JsonResult
body
=
responseEntity
.
getBody
();
JsonResult
body
=
responseEntity
.
getBody
();
if
(
body
!=
null
&&
body
.
isSuccess
())
{
if
(
body
!=
null
&&
body
.
isSuccess
())
{
Object
data
=
body
.
getData
();
Object
data
=
body
.
getData
();
if
(
data
!=
null
)
{
if
(
data
!=
null
)
{
QuerySfpUserResponse
userInfo
=
JSON
.
parseObject
(
JSON
.
toJSONString
(
data
),
QuerySfpUserResponse
.
class
);
QuerySfpUserResponse
userInfo
=
JSON
.
parseObject
(
JSON
.
toJSONString
(
data
),
QuerySfpUserResponse
.
class
);
String
wxOpenId
=
userInfo
.
getWxOpenId
();
if
(
userInfo
.
getId
()
==
null
)
{
if
(
StringUtils
.
hasText
(
wxOpenId
))
{
log
.
error
(
"远程解析返回的用户ID为空"
);
log
.
info
(
"获取到用户 openid: {}"
,
wxOpenId
);
throw
new
RuntimeException
(
"用户信息不完整"
);
return
wxOpenId
;
}
else
{
log
.
error
(
"用户信息中 wxOpenId 为空, sfpUserId={}"
,
sfpUserId
);
throw
new
RuntimeException
(
"用户未绑定小程序 openid"
);
}
}
log
.
info
(
"远程解析 Token 成功,用户ID: {}, openid: {}"
,
userInfo
.
getId
(),
userInfo
.
getWxOpenId
());
return
userInfo
;
}
}
}
}
}
}
log
.
error
(
"
调用 SFP 接口
失败, response={}"
,
responseEntity
);
log
.
error
(
"
远程解析 Token
失败, response={}"
,
responseEntity
);
throw
new
RuntimeException
(
"获取用户信息失败"
);
throw
new
RuntimeException
(
"获取用户信息失败"
);
}
catch
(
Exception
e
)
{
}
catch
(
Exception
e
)
{
log
.
error
(
"调用
SFP 查询用户
接口异常"
,
e
);
log
.
error
(
"调用
远程解析 Token
接口异常"
,
e
);
throw
new
RuntimeException
(
"获取用户信息异常: "
+
e
.
getMessage
());
throw
new
RuntimeException
(
"获取用户信息异常: "
+
e
.
getMessage
());
}
}
}
}
...
@@ -159,15 +143,18 @@ public class ApiSubscribeRecordServiceImpl implements ApiSubscribeRecordService
...
@@ -159,15 +143,18 @@ public class ApiSubscribeRecordServiceImpl implements ApiSubscribeRecordService
return
Result
.
fail
(
"订阅记录列表为空"
);
return
Result
.
fail
(
"订阅记录列表为空"
);
}
}
// 从 Token 中获取当前用户的
openid
(所有记录共用同一个用户)
// 从 Token 中获取当前用户的
完整信息
(所有记录共用同一个用户)
String
openid
;
QuerySfpUserResponse
userInfo
;
try
{
try
{
openid
=
getOpenid
FromToken
();
userInfo
=
getUserInfo
FromToken
();
}
catch
(
Exception
e
)
{
}
catch
(
Exception
e
)
{
log
.
error
(
"获取用户
openid
失败"
,
e
);
log
.
error
(
"获取用户
信息
失败"
,
e
);
return
Result
.
fail
(
"获取用户信息失败:"
+
e
.
getMessage
());
return
Result
.
fail
(
"获取用户信息失败:"
+
e
.
getMessage
());
}
}
String
openid
=
userInfo
.
getWxOpenId
();
String
userId
=
userInfo
.
getId
().
toString
();
// Long -> String
List
<
SubscribeRecord
>
records
=
new
ArrayList
<>();
List
<
SubscribeRecord
>
records
=
new
ArrayList
<>();
for
(
SubscribeRecordDTO
dto
:
dtoList
)
{
for
(
SubscribeRecordDTO
dto
:
dtoList
)
{
// 1. 根据 wxTemplateId 查询模板信息
// 1. 根据 wxTemplateId 查询模板信息
...
@@ -188,6 +175,7 @@ public class ApiSubscribeRecordServiceImpl implements ApiSubscribeRecordService
...
@@ -188,6 +175,7 @@ public class ApiSubscribeRecordServiceImpl implements ApiSubscribeRecordService
record
.
setProjectType
(
dto
.
getProjectType
());
record
.
setProjectType
(
dto
.
getProjectType
());
record
.
setWxTemplateId
(
dto
.
getWxTemplateId
());
record
.
setWxTemplateId
(
dto
.
getWxTemplateId
());
record
.
setOpenid
(
openid
);
record
.
setOpenid
(
openid
);
record
.
setUserId
(
userId
);
// 设置用户ID
record
.
setTemplateBizId
(
template
.
getTemplateBizId
());
record
.
setTemplateBizId
(
template
.
getTemplateBizId
());
record
.
setChannelBizId
(
template
.
getChannelBizId
());
record
.
setChannelBizId
(
template
.
getChannelBizId
());
...
@@ -201,7 +189,7 @@ public class ApiSubscribeRecordServiceImpl implements ApiSubscribeRecordService
...
@@ -201,7 +189,7 @@ public class ApiSubscribeRecordServiceImpl implements ApiSubscribeRecordService
boolean
success
=
subscribeRecordService
.
batchSave
(
records
);
boolean
success
=
subscribeRecordService
.
batchSave
(
records
);
if
(
success
)
{
if
(
success
)
{
log
.
info
(
"批量保存订阅记录成功, 数量={}
"
,
records
.
size
()
);
log
.
info
(
"批量保存订阅记录成功, 数量={}
, 用户ID={}"
,
records
.
size
(),
userId
);
return
Result
.
success
();
return
Result
.
success
();
}
else
{
}
else
{
log
.
error
(
"批量保存订阅记录失败"
);
log
.
error
(
"批量保存订阅记录失败"
);
...
@@ -216,7 +204,8 @@ public class ApiSubscribeRecordServiceImpl implements ApiSubscribeRecordService
...
@@ -216,7 +204,8 @@ public class ApiSubscribeRecordServiceImpl implements ApiSubscribeRecordService
// 从 Token 中获取当前用户的 openid
// 从 Token 中获取当前用户的 openid
String
openid
;
String
openid
;
try
{
try
{
openid
=
getOpenidFromToken
();
QuerySfpUserResponse
userInfo
=
getUserInfoFromToken
();
openid
=
userInfo
.
getWxOpenId
();
}
catch
(
Exception
e
)
{
}
catch
(
Exception
e
)
{
log
.
error
(
"获取用户 openid 失败"
,
e
);
log
.
error
(
"获取用户 openid 失败"
,
e
);
return
Result
.
fail
(
"获取用户信息失败:"
+
e
.
getMessage
());
return
Result
.
fail
(
"获取用户信息失败:"
+
e
.
getMessage
());
...
...
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