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
5946471a
Commit
5946471a
authored
Jun 23, 2026
by
zhangxingmin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
push
parent
a5c1a711
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
33 additions
and
7 deletions
+33
-7
yd-notice-api/src/main/java/com/yd/notice/api/service/impl/ApiNotificationTaskServiceImpl.java
+2
-0
yd-notice-service/src/main/java/com/yd/notice/service/send/MiniprogramMessageSender.java
+12
-2
yd-notice-service/src/main/java/com/yd/notice/service/service/impl/NotificationTaskServiceImpl.java
+19
-5
No files found.
yd-notice-api/src/main/java/com/yd/notice/api/service/impl/ApiNotificationTaskServiceImpl.java
View file @
5946471a
package
com
.
yd
.
notice
.
api
.
service
.
impl
;
package
com
.
yd
.
notice
.
api
.
service
.
impl
;
import
com.alibaba.fastjson.JSON
;
import
com.yd.common.result.Result
;
import
com.yd.common.result.Result
;
import
com.yd.notice.api.service.ApiNotificationTaskService
;
import
com.yd.notice.api.service.ApiNotificationTaskService
;
import
com.yd.notice.feign.request.ApiSendRequest
;
import
com.yd.notice.feign.request.ApiSendRequest
;
...
@@ -23,6 +24,7 @@ public class ApiNotificationTaskServiceImpl implements ApiNotificationTaskServic
...
@@ -23,6 +24,7 @@ public class ApiNotificationTaskServiceImpl implements ApiNotificationTaskServic
*/
*/
@Override
@Override
public
Result
<
ApiSendResponse
>
send
(
ApiSendRequest
request
)
{
public
Result
<
ApiSendResponse
>
send
(
ApiSendRequest
request
)
{
log
.
info
(
"通用发送接口=>入参ApiSendRequest:{}"
,
JSON
.
toJSONString
(
request
));
String
taskBizId
=
iNotificationTaskService
.
createAndSendTask
(
String
taskBizId
=
iNotificationTaskService
.
createAndSendTask
(
request
.
getChannelBizId
(),
request
.
getChannelBizId
(),
request
.
getTemplateBizId
(),
request
.
getTemplateBizId
(),
...
...
yd-notice-service/src/main/java/com/yd/notice/service/send/MiniprogramMessageSender.java
View file @
5946471a
...
@@ -4,6 +4,7 @@ import cn.binarywang.wx.miniapp.bean.WxMaSubscribeMessage;
...
@@ -4,6 +4,7 @@ import cn.binarywang.wx.miniapp.bean.WxMaSubscribeMessage;
import
cn.binarywang.wx.miniapp.api.WxMaService
;
import
cn.binarywang.wx.miniapp.api.WxMaService
;
import
cn.binarywang.wx.miniapp.api.impl.WxMaServiceImpl
;
import
cn.binarywang.wx.miniapp.api.impl.WxMaServiceImpl
;
import
cn.binarywang.wx.miniapp.config.impl.WxMaDefaultConfigImpl
;
import
cn.binarywang.wx.miniapp.config.impl.WxMaDefaultConfigImpl
;
import
com.alibaba.fastjson.JSON
;
import
com.alibaba.fastjson.JSONObject
;
import
com.alibaba.fastjson.JSONObject
;
import
com.yd.notice.service.model.ChannelConfig
;
import
com.yd.notice.service.model.ChannelConfig
;
import
com.yd.notice.service.model.NotificationTask
;
import
com.yd.notice.service.model.NotificationTask
;
...
@@ -34,18 +35,22 @@ public class MiniprogramMessageSender implements MessageSender {
...
@@ -34,18 +35,22 @@ public class MiniprogramMessageSender implements MessageSender {
@Override
@Override
public
SendResult
send
(
NotificationTask
task
)
{
public
SendResult
send
(
NotificationTask
task
)
{
try
{
try
{
log
.
info
(
"进入小程序消息发送器=>入参:{}"
,
JSON
.
toJSONString
(
task
));
// 1. 查询渠道配置(获取 AppId 和 Secret)
// 1. 查询渠道配置(获取 AppId 和 Secret)
ChannelConfig
config
=
channelConfigService
.
getByChannelBizId
(
task
.
getChannelBizId
());
ChannelConfig
config
=
channelConfigService
.
getByChannelBizId
(
task
.
getChannelBizId
());
log
.
info
(
"进入小程序消息发送器=>渠道:{}"
,
JSON
.
toJSONString
(
config
));
if
(
config
==
null
||
config
.
getStatus
()
!=
1
)
{
if
(
config
==
null
||
config
.
getStatus
()
!=
1
)
{
return
SendResult
.
failNonRetryable
(
"CONFIG_NOT_EXIST"
,
"渠道配置不存在或已禁用"
);
return
SendResult
.
failNonRetryable
(
"CONFIG_NOT_EXIST"
,
"渠道配置不存在或已禁用"
);
}
}
JSONObject
wxConfig
=
JSONObject
.
parseObject
(
config
.
getConfigValue
());
JSONObject
wxConfig
=
JSONObject
.
parseObject
(
config
.
getConfigValue
());
log
.
info
(
"进入小程序消息发送器=>渠道配置值JSON:{}"
,
JSON
.
toJSONString
(
wxConfig
));
String
appid
=
wxConfig
.
getString
(
"appid"
);
String
appid
=
wxConfig
.
getString
(
"appid"
);
String
secret
=
wxConfig
.
getString
(
"secret"
);
String
secret
=
wxConfig
.
getString
(
"secret"
);
// 2. 查询模板配置(获取微信侧 templateId 和 content 模板)
// 2. 查询模板配置(获取微信侧 templateId 和 content 模板)
NotificationTemplate
template
=
templateService
.
getById
(
task
.
getTemplateBizId
());
NotificationTemplate
template
=
templateService
.
getById
(
task
.
getTemplateBizId
());
log
.
info
(
"进入小程序消息发送器=>消息模板:{}"
,
JSON
.
toJSONString
(
template
));
if
(
template
==
null
)
{
if
(
template
==
null
)
{
return
SendResult
.
failNonRetryable
(
"TEMPLATE_NOT_EXIST"
,
"模板不存在"
);
return
SendResult
.
failNonRetryable
(
"TEMPLATE_NOT_EXIST"
,
"模板不存在"
);
}
}
...
@@ -59,10 +64,13 @@ public class MiniprogramMessageSender implements MessageSender {
...
@@ -59,10 +64,13 @@ public class MiniprogramMessageSender implements MessageSender {
// 但为了标准化,我们在这里再次解析,顺便提取 page 跳转路径
// 但为了标准化,我们在这里再次解析,顺便提取 page 跳转路径
String
renderedContent
=
task
.
getContent
();
String
renderedContent
=
task
.
getContent
();
JSONObject
contentJson
=
JSONObject
.
parseObject
(
renderedContent
);
JSONObject
contentJson
=
JSONObject
.
parseObject
(
renderedContent
);
log
.
info
(
"进入小程序消息发送器=>消息内容JSON:{}"
,
JSON
.
toJSONString
(
contentJson
));
// 提取 page(跳转路径),并从 data 中移除
// 提取 page(跳转路径),并从 data 中移除
String
page
=
contentJson
.
getString
(
"page"
);
String
page
=
contentJson
.
getString
(
"page"
);
log
.
info
(
"进入小程序消息发送器=>page:{}"
,
page
);
contentJson
.
remove
(
"page"
);
contentJson
.
remove
(
"page"
);
log
.
info
(
"进入小程序消息发送器=>移除page:{}"
,
JSON
.
toJSONString
(
contentJson
));
// 4. 构建微信订阅消息数据结构(新版本使用 List<MsgData>)
// 4. 构建微信订阅消息数据结构(新版本使用 List<MsgData>)
List
<
WxMaSubscribeMessage
.
MsgData
>
dataList
=
new
ArrayList
<>();
List
<
WxMaSubscribeMessage
.
MsgData
>
dataList
=
new
ArrayList
<>();
...
@@ -71,6 +79,7 @@ public class MiniprogramMessageSender implements MessageSender {
...
@@ -71,6 +79,7 @@ public class MiniprogramMessageSender implements MessageSender {
String
value
=
entry
.
getValue
()
!=
null
?
entry
.
getValue
().
toString
()
:
""
;
String
value
=
entry
.
getValue
()
!=
null
?
entry
.
getValue
().
toString
()
:
""
;
dataList
.
add
(
new
WxMaSubscribeMessage
.
MsgData
(
key
,
value
));
dataList
.
add
(
new
WxMaSubscribeMessage
.
MsgData
(
key
,
value
));
}
}
log
.
info
(
"进入小程序消息发送器=>构建微信订阅消息数据结构List<MsgData>:{}"
,
JSON
.
toJSONString
(
dataList
));
// 5. 构建消息体
// 5. 构建消息体
WxMaSubscribeMessage
message
=
new
WxMaSubscribeMessage
();
WxMaSubscribeMessage
message
=
new
WxMaSubscribeMessage
();
...
@@ -80,6 +89,7 @@ public class MiniprogramMessageSender implements MessageSender {
...
@@ -80,6 +89,7 @@ public class MiniprogramMessageSender implements MessageSender {
if
(
StringUtils
.
hasText
(
page
))
{
if
(
StringUtils
.
hasText
(
page
))
{
message
.
setPage
(
page
);
message
.
setPage
(
page
);
}
}
log
.
info
(
"进入小程序消息发送器=>构建消息体WxMaSubscribeMessage:{}"
,
JSON
.
toJSONString
(
message
));
// 6. 调用微信 SDK 发送
// 6. 调用微信 SDK 发送
WxMaService
wxMaService
=
buildWxMaService
(
appid
,
secret
);
WxMaService
wxMaService
=
buildWxMaService
(
appid
,
secret
);
...
@@ -93,7 +103,7 @@ public class MiniprogramMessageSender implements MessageSender {
...
@@ -93,7 +103,7 @@ public class MiniprogramMessageSender implements MessageSender {
Integer
errorCode
=
e
.
getError
().
getErrorCode
();
// 正确获取错误码
Integer
errorCode
=
e
.
getError
().
getErrorCode
();
// 正确获取错误码
String
errCode
=
errorCode
!=
null
?
errorCode
.
toString
()
:
"UNKNOWN"
;
String
errCode
=
errorCode
!=
null
?
errorCode
.
toString
()
:
"UNKNOWN"
;
String
errMsg
=
e
.
getMessage
();
String
errMsg
=
e
.
getMessage
();
log
.
error
(
"微信小程序发送失败, taskBizId={}, errCode={}, errMsg={}"
,
task
.
getTaskBizId
(),
errCode
,
errMsg
);
log
.
info
(
"微信小程序发送失败, taskBizId={}, errCode={}, errMsg={}"
,
task
.
getTaskBizId
(),
errCode
,
errMsg
);
// 处理不可重试错误
// 处理不可重试错误
if
(
USER_REFUSE_ERROR
.
equals
(
errCode
)
||
TEMPLATE_INVALID
.
equals
(
errCode
))
{
if
(
USER_REFUSE_ERROR
.
equals
(
errCode
)
||
TEMPLATE_INVALID
.
equals
(
errCode
))
{
...
@@ -102,7 +112,7 @@ public class MiniprogramMessageSender implements MessageSender {
...
@@ -102,7 +112,7 @@ public class MiniprogramMessageSender implements MessageSender {
return
SendResult
.
failRetryable
(
errCode
,
errMsg
);
return
SendResult
.
failRetryable
(
errCode
,
errMsg
);
}
catch
(
Exception
e
)
{
}
catch
(
Exception
e
)
{
log
.
error
(
"微信小程序发送异常, taskBizId={}"
,
task
.
getTaskBizId
(),
e
);
log
.
info
(
"微信小程序发送异常, taskBizId={}"
,
task
.
getTaskBizId
(),
e
);
return
SendResult
.
failRetryable
(
"SEND_EXCEPTION"
,
e
.
getMessage
());
return
SendResult
.
failRetryable
(
"SEND_EXCEPTION"
,
e
.
getMessage
());
}
}
}
}
...
...
yd-notice-service/src/main/java/com/yd/notice/service/service/impl/NotificationTaskServiceImpl.java
View file @
5946471a
package
com
.
yd
.
notice
.
service
.
service
.
impl
;
package
com
.
yd
.
notice
.
service
.
service
.
impl
;
import
cn.hutool.core.date.LocalDateTimeUtil
;
import
cn.hutool.core.date.LocalDateTimeUtil
;
import
com.alibaba.fastjson.JSON
;
import
com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper
;
import
com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper
;
import
com.baomidou.mybatisplus.extension.service.impl.ServiceImpl
;
import
com.baomidou.mybatisplus.extension.service.impl.ServiceImpl
;
import
com.yd.common.exception.BusinessException
;
import
com.yd.common.exception.BusinessException
;
...
@@ -58,6 +59,7 @@ public class NotificationTaskServiceImpl extends ServiceImpl<NotificationTaskMap
...
@@ -58,6 +59,7 @@ public class NotificationTaskServiceImpl extends ServiceImpl<NotificationTaskMap
.
eq
(
NotificationTemplate:
:
getTemplateBizId
,
templateBizId
)
.
eq
(
NotificationTemplate:
:
getTemplateBizId
,
templateBizId
)
.
eq
(
NotificationTemplate:
:
getStatus
,
1
)
.
eq
(
NotificationTemplate:
:
getStatus
,
1
)
);
);
log
.
info
(
"查询模板=>出参NotificationTemplate:{}"
,
JSON
.
toJSONString
(
template
));
if
(
template
==
null
)
{
if
(
template
==
null
)
{
throw
new
BusinessException
(
"模板不存在或已禁用"
);
throw
new
BusinessException
(
"模板不存在或已禁用"
);
}
}
...
@@ -65,6 +67,8 @@ public class NotificationTaskServiceImpl extends ServiceImpl<NotificationTaskMap
...
@@ -65,6 +67,8 @@ public class NotificationTaskServiceImpl extends ServiceImpl<NotificationTaskMap
// 2. 渲染标题和内容
// 2. 渲染标题和内容
String
title
=
templateRenderUtil
.
render
(
template
.
getTitleTemplate
(),
params
);
String
title
=
templateRenderUtil
.
render
(
template
.
getTitleTemplate
(),
params
);
String
content
=
templateRenderUtil
.
render
(
template
.
getContentTemplate
(),
params
);
String
content
=
templateRenderUtil
.
render
(
template
.
getContentTemplate
(),
params
);
log
.
info
(
"渲染标题=>出参title:{}"
,
title
);
log
.
info
(
"渲染内容=>出参content:{}"
,
content
);
// 3. 创建任务
// 3. 创建任务
NotificationTask
task
=
new
NotificationTask
();
NotificationTask
task
=
new
NotificationTask
();
...
@@ -83,6 +87,7 @@ public class NotificationTaskServiceImpl extends ServiceImpl<NotificationTaskMap
...
@@ -83,6 +87,7 @@ public class NotificationTaskServiceImpl extends ServiceImpl<NotificationTaskMap
task
.
setCreateTime
(
LocalDateTime
.
now
());
task
.
setCreateTime
(
LocalDateTime
.
now
());
task
.
setUpdateTime
(
LocalDateTime
.
now
());
task
.
setUpdateTime
(
LocalDateTime
.
now
());
save
(
task
);
save
(
task
);
log
.
info
(
"创建任务=>出参NotificationTask:{}"
,
JSON
.
toJSONString
(
task
));
log
.
info
(
"创建消息任务成功,taskBizId: {},准备异步发送"
,
taskBizId
);
log
.
info
(
"创建消息任务成功,taskBizId: {},准备异步发送"
,
taskBizId
);
...
@@ -92,11 +97,12 @@ public class NotificationTaskServiceImpl extends ServiceImpl<NotificationTaskMap
...
@@ -92,11 +97,12 @@ public class NotificationTaskServiceImpl extends ServiceImpl<NotificationTaskMap
}
}
private
void
doSendTask
(
NotificationTask
task
)
{
private
void
doSendTask
(
NotificationTask
task
)
{
log
.
info
(
"异步发送doSendTask=>入参NotificationTask:{}"
,
JSON
.
toJSONString
(
task
));
String
taskBizId
=
task
.
getTaskBizId
();
String
taskBizId
=
task
.
getTaskBizId
();
// 防止并发重复发送
// 防止并发重复发送
if
(
task
.
getStatus
()
!=
0
)
{
if
(
task
.
getStatus
()
!=
0
)
{
log
.
warn
(
"任务状态不是待发送,跳过执行: {}"
,
taskBizId
);
log
.
info
(
"任务状态不是待发送,跳过执行: {}"
,
taskBizId
);
return
;
return
;
}
}
...
@@ -115,27 +121,33 @@ public class NotificationTaskServiceImpl extends ServiceImpl<NotificationTaskMap
...
@@ -115,27 +121,33 @@ public class NotificationTaskServiceImpl extends ServiceImpl<NotificationTaskMap
if
(
success
)
{
if
(
success
)
{
log
.
info
(
"消息发送成功,taskBizId: {}"
,
taskBizId
);
log
.
info
(
"消息发送成功,taskBizId: {}"
,
taskBizId
);
}
else
{
}
else
{
log
.
error
(
"消息发送最终失败,taskBizId: {}"
,
taskBizId
);
log
.
info
(
"消息发送最终失败,taskBizId: {}"
,
taskBizId
);
}
}
}
}
private
boolean
sendWithRetryAndRecord
(
NotificationTask
task
)
{
private
boolean
sendWithRetryAndRecord
(
NotificationTask
task
)
{
log
.
info
(
"带重试的发送sendWithRetryAndRecord=>入参NotificationTask:{}"
,
JSON
.
toJSONString
(
task
));
int
maxRetry
=
task
.
getMaxRetry
();
int
maxRetry
=
task
.
getMaxRetry
();
int
currentRetry
=
0
;
int
currentRetry
=
0
;
long
waitMillis
=
1000
;
long
waitMillis
=
1000
;
// 获取渠道类型
// 获取渠道类型
ChannelConfig
channelConfig
=
channelConfigService
.
getByChannelBizId
(
task
.
getChannelBizId
());
ChannelConfig
channelConfig
=
channelConfigService
.
getByChannelBizId
(
task
.
getChannelBizId
());
log
.
info
(
"获取渠道类型=>出参ChannelConfig:{}"
,
JSON
.
toJSONString
(
channelConfig
));
if
(
channelConfig
==
null
)
{
if
(
channelConfig
==
null
)
{
log
.
error
(
"渠道配置不存在,taskBizId: {}, channelBizId: {}"
,
task
.
getTaskBizId
(),
task
.
getChannelBizId
());
log
.
error
(
"渠道配置不存在,taskBizId: {}, channelBizId: {}"
,
task
.
getTaskBizId
(),
task
.
getChannelBizId
());
return
false
;
return
false
;
}
}
String
channelType
=
channelConfig
.
getChannelType
();
String
channelType
=
channelConfig
.
getChannelType
();
MessageSender
sender
=
senderRouter
.
getSender
(
channelType
);
MessageSender
sender
=
senderRouter
.
getSender
(
channelType
);
log
.
info
(
"获取发送类=>出参MessageSender:{}"
,
JSON
.
toJSONString
(
sender
));
log
.
info
(
"sendWithRetryAndRecord=>参数currentRetry:{}"
,
currentRetry
);
log
.
info
(
"sendWithRetryAndRecord=>参数maxRetry:{}"
,
maxRetry
);
while
(
currentRetry
<=
maxRetry
)
{
while
(
currentRetry
<=
maxRetry
)
{
// 创建发送记录(待发送)
// 创建发送记录(待发送)
NotificationRecord
record
=
buildInitialRecord
(
task
,
currentRetry
);
NotificationRecord
record
=
buildInitialRecord
(
task
,
currentRetry
);
log
.
info
(
"进入while循环=>创建发送记录(待发送):{}"
,
JSON
.
toJSONString
(
record
));
recordService
.
save
(
record
);
recordService
.
save
(
record
);
LocalDateTime
startTime
=
LocalDateTime
.
now
();
LocalDateTime
startTime
=
LocalDateTime
.
now
();
...
@@ -149,11 +161,13 @@ public class NotificationTaskServiceImpl extends ServiceImpl<NotificationTaskMap
...
@@ -149,11 +161,13 @@ public class NotificationTaskServiceImpl extends ServiceImpl<NotificationTaskMap
recordService
.
updateById
(
record
);
recordService
.
updateById
(
record
);
// 调用具体发送器
// 调用具体发送器
log
.
info
(
"进入while循环=>调用具体发送器:{}"
,
JSON
.
toJSONString
(
task
));
result
=
sender
.
send
(
task
);
result
=
sender
.
send
(
task
);
log
.
info
(
"进入while循环=>调用具体发送器出参返回:{}"
,
JSON
.
toJSONString
(
result
));
costTime
=
(
int
)
(
LocalDateTimeUtil
.
between
(
startTime
,
LocalDateTime
.
now
()).
toMillis
());
costTime
=
(
int
)
(
LocalDateTimeUtil
.
between
(
startTime
,
LocalDateTime
.
now
()).
toMillis
());
}
catch
(
Exception
e
)
{
}
catch
(
Exception
e
)
{
log
.
error
(
"发送异常,taskBizId: {}, retry: {}"
,
task
.
getTaskBizId
(),
currentRetry
,
e
);
log
.
info
(
"发送异常,taskBizId: {}, retry: {}"
,
task
.
getTaskBizId
(),
currentRetry
,
e
);
result
=
SendResult
.
failRetryable
(
"UNKNOWN_ERROR"
,
e
.
getMessage
());
result
=
SendResult
.
failRetryable
(
"UNKNOWN_ERROR"
,
e
.
getMessage
());
costTime
=
(
int
)
(
LocalDateTimeUtil
.
between
(
startTime
,
LocalDateTime
.
now
()).
toMillis
());
costTime
=
(
int
)
(
LocalDateTimeUtil
.
between
(
startTime
,
LocalDateTime
.
now
()).
toMillis
());
}
}
...
@@ -179,10 +193,10 @@ public class NotificationTaskServiceImpl extends ServiceImpl<NotificationTaskMap
...
@@ -179,10 +193,10 @@ public class NotificationTaskServiceImpl extends ServiceImpl<NotificationTaskMap
if
(
currentRetry
<=
maxRetry
)
{
if
(
currentRetry
<=
maxRetry
)
{
if
(!
result
.
isRetryable
())
{
if
(!
result
.
isRetryable
())
{
log
.
warn
(
"检测到不可重试错误,放弃重试,taskBizId: {}, errorCode: {}"
,
task
.
getTaskBizId
(),
result
.
getErrorCode
());
log
.
info
(
"检测到不可重试错误,放弃重试,taskBizId: {}, errorCode: {}"
,
task
.
getTaskBizId
(),
result
.
getErrorCode
());
break
;
break
;
}
}
log
.
warn
(
"发送失败,{}秒后进行第{}次重试,taskBizId: {}"
,
waitMillis
/
1000
,
currentRetry
,
task
.
getTaskBizId
());
log
.
info
(
"发送失败,{}秒后进行第{}次重试,taskBizId: {}"
,
waitMillis
/
1000
,
currentRetry
,
task
.
getTaskBizId
());
try
{
try
{
Thread
.
sleep
(
waitMillis
);
Thread
.
sleep
(
waitMillis
);
waitMillis
=
Math
.
min
(
waitMillis
*
2
,
30000
);
waitMillis
=
Math
.
min
(
waitMillis
*
2
,
30000
);
...
...
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