From aa7330000feda07e00e3b71d4296ceb449289f1b Mon Sep 17 00:00:00 2001 From: Jerry Yan <792602257@qq.com> Date: Tue, 14 Oct 2025 20:31:45 +0800 Subject: [PATCH] =?UTF-8?q?fix(task):=20=E9=81=BF=E5=85=8D=E9=87=8D?= =?UTF-8?q?=E5=A4=8D=E5=8F=91=E9=80=81=E4=B8=8B=E8=BD=BD=E5=92=8C=E8=BF=87?= =?UTF-8?q?=E6=9C=9F=E9=80=9A=E7=9F=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在发送下载通知前检查用户是否已接收通知 - 在发送过期通知前检查用户是否已接收通知- 在发送额外下载通知前检查用户是否已接收通知 - 使用ConcurrentHashMap.newKeySet()确保线程安全- 添加调试日志以追踪重复通知的跳过情况- 优化通知逻辑以提升定时任务执行效率 --- .../task/DownloadNotificationTasker.java | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/src/main/java/com/ycwl/basic/task/DownloadNotificationTasker.java b/src/main/java/com/ycwl/basic/task/DownloadNotificationTasker.java index f653acf9..b0219f1d 100644 --- a/src/main/java/com/ycwl/basic/task/DownloadNotificationTasker.java +++ b/src/main/java/com/ycwl/basic/task/DownloadNotificationTasker.java @@ -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 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 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 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()); // 发送模板消息