fix(task): 避免重复发送下载和过期通知
All checks were successful
ZhenTu-BE/pipeline/head This commit looks good

- 在发送下载通知前检查用户是否已接收通知
- 在发送过期通知前检查用户是否已接收通知- 在发送额外下载通知前检查用户是否已接收通知
- 使用ConcurrentHashMap.newKeySet()确保线程安全- 添加调试日志以追踪重复通知的跳过情况- 优化通知逻辑以提升定时任务执行效率
This commit is contained in:
2025-10-14 20:31:45 +08:00
parent 29f4bbf2d8
commit aa7330000f

View File

@@ -29,8 +29,11 @@ import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
@Component
@EnableScheduling
@@ -51,11 +54,20 @@ public class DownloadNotificationTasker {
@Scheduled(cron = "0 0 21 * * *")
public void sendDownloadNotification() {
log.info("开始执行定时任务");
// 用于记录已发送通知的用户ID,避免重复发送
Set<Long> sentMemberIds = ConcurrentHashMap.newKeySet();
videoMapper.listRelationByCreateTime(new Date(System.currentTimeMillis() - 24 * 60 * 60 * 1000), new Date())
.forEach(item -> {
if (item.getIsBuy() == 1) {
return;
}
// 检查该用户是否已经发送过通知,避免重复发送
if (sentMemberIds.contains(item.getMemberId())) {
log.debug("用户[memberId={}]已发送过下载通知,跳过", item.getMemberId());
return;
}
sentMemberIds.add(item.getMemberId());
MemberRespVO member = memberMapper.getById(item.getMemberId());
MpConfigEntity scenicMp = scenicRepository.getScenicMpConfig(member.getScenicId());
// 发送模板消息
@@ -110,11 +122,20 @@ public class DownloadNotificationTasker {
@Scheduled(cron = "0 0 20 * * *")
public void sendExpireNotification() {
log.info("开始执行定时任务");
// 用于记录已发送通知的用户ID,避免重复发送
Set<Long> sentMemberIds = ConcurrentHashMap.newKeySet();
videoMapper.listRelationByCreateTime(new Date(System.currentTimeMillis() - 2 * 24 * 60 * 60 * 1000), new Date(System.currentTimeMillis() - 24 * 60 * 60 * 1000))
.forEach(item -> {
if (item.getIsBuy() == 1) {
return;
}
// 检查该用户是否已经发送过通知,避免重复发送
if (sentMemberIds.contains(item.getMemberId())) {
log.debug("用户[memberId={}]已发送过过期提醒通知,跳过", item.getMemberId());
return;
}
sentMemberIds.add(item.getMemberId());
MemberRespVO member = memberMapper.getById(item.getMemberId());
MpConfigEntity scenicMp = scenicRepository.getScenicMpConfig(member.getScenicId());
ScenicConfigEntity scenicConfig = scenicRepository.getScenicConfig(item.getScenicId());
@@ -202,12 +223,20 @@ public class DownloadNotificationTasker {
}
log.info("当前景区{},配置了{}", scenic.getName(), scenicConfig.getString("extra_notification_time"));
// 使用线程安全的Set记录已发送通知的用户ID,避免重复发送
Set<Long> sentMemberIds = ConcurrentHashMap.newKeySet();
videoMapper.listRelationByCreateTime(DateUtil.beginOfDay(new Date()), new Date())
.stream()
.filter(item -> item.getIsBuy() == 0)
.filter(item -> item.getScenicId().equals(scenicId))
.parallel()
.forEach(item -> {
// 检查该用户是否已经发送过通知,避免重复发送
if (!sentMemberIds.add(item.getMemberId())) {
log.debug("用户[memberId={}]已发送过额外下载通知,跳过", item.getMemberId());
return;
}
MemberRespVO member = memberMapper.getById(item.getMemberId());
MpConfigEntity scenicMp = scenicRepository.getScenicMpConfig(member.getScenicId());
// 发送模板消息