feat(sms): 为短信发送增加3秒间隔保护机制

- 在SmsBirthdayServiceImpl和SmsTaskServiceImpl中增加3秒发送间隔
- 添加详细的发送进度日志,显示当前发送第几位专家
- 实现线程中断处理,确保间隔等待可被正确中断
- 优化短信发送流程,最后一位专家发送后不等待间隔
- 增强日志记录,包含发送开始、进度、等待和完成状态
- 保护短信接口避免因频繁调用导致的压力和限流问题

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
master
李一帆 2025-09-25 14:51:21 +08:00
parent e550137ebf
commit f9450c9ffc
2 changed files with 44 additions and 9 deletions

View File

@ -86,10 +86,14 @@ public class SmsBirthdayServiceImpl extends ServiceImpl<SmsBirthdayMapper, SmsBi
}
// 逐个发送个性化短信
for (Specialist specialist : specialists) {
int totalSpecialists = specialists.size();
log.info("开始向{}位专家发送生日短信", totalSpecialists);
for (int i = 0; i < specialists.size(); i++) {
Specialist specialist = specialists.get(i);
String content = template.replace("{姓名}", specialist.getName());
try {
// 替换模板中的占位符
log.info("正在发送第{}/{}位专家{}的生日短信", i + 1, totalSpecialists, specialist.getName());
// 创建短信日志记录
SmsLog smsLog = new SmsLog();
@ -114,6 +118,18 @@ public class SmsBirthdayServiceImpl extends ServiceImpl<SmsBirthdayMapper, SmsBi
// 保存短信日志记录
smsLogMapper.insert(smsLog);
// 如果不是最后一位专家等待3秒再发送下一条
if (i < specialists.size() - 1) {
try {
log.info("等待3秒后发送下一条短信...");
Thread.sleep(3000); // 3秒间隔
} catch (InterruptedException ie) {
Thread.currentThread().interrupt();
log.warn("生日短信发送间隔被中断");
break;
}
}
} catch (Exception e) {
log.error("向专家{}发送生日短信时发生异常: {}", specialist.getName(), e.getMessage(), e);
@ -131,6 +147,8 @@ public class SmsBirthdayServiceImpl extends ServiceImpl<SmsBirthdayMapper, SmsBi
}
}
}
log.info("生日短信批量发送任务完成");
}
/**

View File

@ -138,11 +138,16 @@ public class SmsTaskServiceImpl extends ServiceImpl<SmsTaskMapper, SmsTask> impl
}
// 逐个发送个性化短信
for (Specialist specialist : specialists) {
int totalSpecialists = specialists.size();
log.info("开始向{}位专家发送主题日短信[{}]", totalSpecialists, smsTask.getSubjectName());
for (int i = 0; i < specialists.size(); i++) {
Specialist specialist = specialists.get(i);
// 替换模板中的占位符
String content = template.replace("{姓名}", specialist.getName())
.replace("{主题}", smsTask.getSubjectName());
try {
// 替换模板中的占位符
String content = template.replace("{姓名}", specialist.getName())
.replace("{主题}", smsTask.getSubjectName());
log.info("正在发送第{}/{}位专家{}的主题日短信", i + 1, totalSpecialists, specialist.getName());
// 创建短信日志记录
SmsLog smsLog = new SmsLog();
@ -167,6 +172,18 @@ public class SmsTaskServiceImpl extends ServiceImpl<SmsTaskMapper, SmsTask> impl
// 保存短信日志记录
smsLogMapper.insert(smsLog);
// 如果不是最后一位专家等待3秒再发送下一条
if (i < specialists.size() - 1) {
try {
log.info("等待3秒后发送下一条短信...");
Thread.sleep(3000); // 3秒间隔
} catch (InterruptedException ie) {
Thread.currentThread().interrupt();
log.warn("短信发送间隔被中断");
break;
}
}
} catch (Exception e) {
log.error("向专家{}发送主题日短信[{}]时发生异常: {}", specialist.getName(), smsTask.getSubjectName(), e.getMessage(), e);
@ -175,9 +192,7 @@ public class SmsTaskServiceImpl extends ServiceImpl<SmsTaskMapper, SmsTask> impl
SmsLog failedSmsLog = new SmsLog();
failedSmsLog.setName(specialist.getName())
.setPhone(specialist.getPhone())
.setContent(template.replace("{姓名}", specialist.getName())
.replace("{称呼}", specialist.getAddress() != null ? specialist.getAddress() : "")
.replace("{主题}", smsTask.getSubjectName()))
.setContent(content)
.setRemark("主题日短信-" + smsTask.getSubjectName() + "-发送异常: " + e.getMessage())
.setSendTm(new java.util.Date());
smsLogMapper.insert(failedSmsLog);
@ -187,6 +202,8 @@ public class SmsTaskServiceImpl extends ServiceImpl<SmsTaskMapper, SmsTask> impl
}
}
log.info("主题日短信任务[{}]发送完成", smsTask.getSubjectName());
// 标记任务今日已发送
AtomicBoolean sentFlag = taskSmsSentToday.computeIfAbsent(smsTask.getId(), k -> new AtomicBoolean(false));
sentFlag.set(true);