Przeglądaj źródła

1、调整定时任务限制

yys 6 dni temu
rodzic
commit
c26004f431

+ 30 - 0
fs-live-app/src/main/java/com/fs/live/task/LiveCompletionPointsTask.java

@@ -172,6 +172,18 @@ public class LiveCompletionPointsTask {
     }
 
     private LiveConsoleOpLog dispatchCompletionCouponNotify(Long liveId, Long userId, Long watchDuration, boolean forcePush) {
+        // 直播已结束:不再推送完课优惠券弹窗,避免结束后仍可领取
+        Live live = liveService.selectLiveDbByLiveId(liveId);
+        if (live == null) {
+            live = liveService.selectLiveByLiveId(liveId);
+        }
+        if (LiveCompletionConfigUtils.isLiveEndedForRewardPush(live)) {
+            log.info("[完课优惠券] 直播已结束,跳过 WebSocket 推送, liveId={}, userId={}, status={}, finishTime={}",
+                    liveId, userId,
+                    live != null ? live.getStatus() : null,
+                    live != null ? live.getFinishTime() : null);
+            return null;
+        }
         LiveCompletionCouponNotifyResult notifyResult =
                 completionCouponService.prepareCompletionCouponNotify(liveId, userId, watchDuration, forcePush);
         if (notifyResult == null || !notifyResult.isShouldNotify()) {
@@ -226,6 +238,14 @@ public class LiveCompletionPointsTask {
 
     private boolean pushCompletionCouponQuestion(Long liveId, Long userId, LiveCompletionCouponNotifyResult notifyResult,
                                                  LiveConsoleOpLog opLog) {
+        Live live = liveService.selectLiveDbByLiveId(liveId);
+        if (live == null) {
+            live = liveService.selectLiveByLiveId(liveId);
+        }
+        if (LiveCompletionConfigUtils.isLiveEndedForRewardPush(live)) {
+            log.info("[完课优惠券] 推送前检测到直播已结束,取消 WebSocket, liveId={}, userId={}", liveId, userId);
+            return false;
+        }
         SendMsgVo sendMsgVo = new SendMsgVo();
         sendMsgVo.setLiveId(liveId);
         sendMsgVo.setUserId(userId);
@@ -244,6 +264,16 @@ public class LiveCompletionPointsTask {
         for (Live live : activeLives) {
             try {
                 Long liveId = live.getLiveId();
+                // 以 DB 最新状态为准:已结束或结束时间已过则不再处理完课奖励/推送
+                Live latestLive = liveService.selectLiveDbByLiveId(liveId);
+                if (latestLive == null) {
+                    latestLive = live;
+                }
+                if (LiveCompletionConfigUtils.isLiveEndedForRewardPush(latestLive)) {
+                    log.info("[完课定时] 直播已结束,跳过完课奖励与 WebSocket 推送, liveId={}, status={}, finishTime={}",
+                            liveId, latestLive.getStatus(), latestLive.getFinishTime());
+                    continue;
+                }
                 LiveWatchUser queryUser = new LiveWatchUser();
                 queryUser.setLiveId(liveId);
                 List<LiveWatchUser> watchUsers = liveWatchUserService.selectAllWatchUser(queryUser);

+ 27 - 0
fs-live-app/src/main/java/com/fs/live/task/Task.java

@@ -536,6 +536,12 @@ public class Task {
                         LOG_PREFIX, live.getLiveId(), live.getStartTime());
                 continue;
             }
+            // 直播已结束(或结束时间已过):不再发放/推送看课奖励,避免结束后仍可领取
+            if (LiveCompletionConfigUtils.isLiveEndedForRewardPush(live)) {
+                log.info("{} autoUpdateWatchReward 直播已结束,跳过看课奖励推送: liveId={}, status={}, finishTime={}",
+                        LOG_PREFIX, live.getLiveId(), live.getStatus(), live.getFinishTime());
+                continue;
+            }
             if (config.getWatchDuration() == null || config.getWatchDuration() <= 0) {
                 log.info("{} autoUpdateWatchReward 未配置观看时长: liveId={}", LOG_PREFIX, live.getLiveId());
                 continue;
@@ -604,6 +610,12 @@ public class Task {
             if (live.getStartTime() != null && live.getStartTime().isAfter(LocalDateTime.now())) {
                 return;
             }
+            // 直播已结束(或结束时间已过):心跳不再发放/推送看课奖励
+            if (LiveCompletionConfigUtils.isLiveEndedForRewardPush(live)) {
+                log.info("{} tryGrantWatchRewardOnHeartbeat 直播已结束,跳过: liveId={}, userId={}, status={}, finishTime={}",
+                        LOG_PREFIX, liveId, userId, live.getStatus(), live.getFinishTime());
+                return;
+            }
             long requiredWatchSeconds = config.getWatchDuration() * 60L;
             Long watchSeconds = liveWatchUserService.getUserLiveWatchDurationSeconds(liveId, userId);
             if (watchSeconds == null || watchSeconds < requiredWatchSeconds) {
@@ -631,6 +643,12 @@ public class Task {
         if (live == null || config == null || userIds == null || userIds.isEmpty()) {
             return 0;
         }
+        // 统一兜底:已结束直播不再发放看课奖励、不推 WebSocket
+        if (LiveCompletionConfigUtils.isLiveEndedForRewardPush(live)) {
+            log.info("{} grantWatchRewardToUsers 直播已结束,跳过发放与推送: liveId={}, status={}, finishTime={}",
+                    LOG_PREFIX, live.getLiveId(), live.getStatus(), live.getFinishTime());
+            return 0;
+        }
         List<Long> actions = config.resolveActions();
         if (actions.isEmpty()) {
             return 0;
@@ -958,6 +976,15 @@ public class Task {
 
     private void sendCouponRewardMessage(Long liveId, Long userId, LiveCoupon coupon, LiveConsoleOpLog opLog) {
         try {
+            Live live = liveService.selectLiveDbByLiveId(liveId);
+            if (live == null) {
+                live = liveService.selectLiveByLiveId(liveId);
+            }
+            if (LiveCompletionConfigUtils.isLiveEndedForRewardPush(live)) {
+                log.info("{} sendCouponRewardMessage 直播已结束,跳过 WebSocket: liveId={}, userId={}",
+                        LOG_PREFIX, liveId, userId);
+                return;
+            }
             SendMsgVo sendMsgVo = new SendMsgVo();
             sendMsgVo.setLiveId(liveId);
             sendMsgVo.setUserId(userId);

+ 29 - 1
fs-live-app/src/main/java/com/fs/live/websocket/service/WebSocketServer.java

@@ -1099,6 +1099,11 @@ public class WebSocketServer {
     }
 
     public void sendIntegralMessage(Long liveId, Long userId, Long scoreAmount, LiveConsoleOpLog opLog) {
+        Live live = liveService.selectLiveByLiveId(liveId);
+        if (com.fs.live.utils.LiveCompletionConfigUtils.isLiveEndedForRewardPush(live)) {
+            log.info("[看课奖励] 直播已结束,跳过积分 WebSocket 推送, liveId={}, userId={}", liveId, userId);
+            return;
+        }
         ConcurrentHashMap<Long, Session> room = getRoom(liveId);
         Session session = room.get(userId);
         if (session == null || !session.isOpen()) {
@@ -1121,6 +1126,11 @@ public class WebSocketServer {
      * 发送完课积分弹窗通知给特定用户
      */
     public void sendCompletionPointsMessage(Long liveId, Long userId, SendMsgVo sendMsgVo) {
+        Live live = liveService.selectLiveByLiveId(liveId);
+        if (com.fs.live.utils.LiveCompletionConfigUtils.isLiveEndedForRewardPush(live)) {
+            log.info("[完课积分] 直播已结束,跳过 WebSocket 推送, liveId={}, userId={}", liveId, userId);
+            return;
+        }
         ConcurrentHashMap<Long, Session> room = getRoom(liveId);
         Session session = room.get(userId);
         if (session == null || !session.isOpen()) {
@@ -1138,6 +1148,11 @@ public class WebSocketServer {
      * @return 是否推送成功(用户在线且发送成功)
      */
     public boolean sendCompletionCouponQuestionMessage(Long liveId, Long userId, SendMsgVo sendMsgVo) {
+        Live live = liveService.selectLiveByLiveId(liveId);
+        if (com.fs.live.utils.LiveCompletionConfigUtils.isLiveEndedForRewardPush(live)) {
+            log.info("[完课优惠券] 直播已结束,跳过 WebSocket 推送, liveId={}, userId={}", liveId, userId);
+            return false;
+        }
         ConcurrentHashMap<Long, Session> room = getRoom(liveId);
         Session session = room.get(userId);
         if (session == null || !session.isOpen()) {
@@ -1882,11 +1897,19 @@ public class WebSocketServer {
             return;
         }
         try {
+            Live live = liveService.selectLiveByLiveId(liveId);
+            // 直播已结束:心跳不再推送完课奖励 WebSocket,避免结束后仍可领取
+            if (com.fs.live.utils.LiveCompletionConfigUtils.isLiveEndedForRewardPush(live)) {
+                log.info("[完课心跳检查] 直播已结束,跳过推送, liveId={}, userId={}, status={}, finishTime={}",
+                        liveId, userId,
+                        live != null ? live.getStatus() : null,
+                        live != null ? live.getFinishTime() : null);
+                return;
+            }
             Long duration = liveWatchUserService.getUserWatchDuration(liveId, userId);
             if (duration == null || duration <= 0) {
                 return;
             }
-            Live live = liveService.selectLiveByLiveId(liveId);
             String configJson = live != null ? live.getConfigJson() : null;
             // 完课积分:独立判定,写完课积分留存
             if (com.fs.live.utils.LiveCompletionConfigUtils.isCompletionPointsMode(configJson)) {
@@ -1911,6 +1934,11 @@ public class WebSocketServer {
      */
     private void checkAndSendCompletionPointsInRealTime(long liveId, long userId, Long duration) {
         try {
+            Live live = liveService.selectLiveByLiveId(liveId);
+            if (com.fs.live.utils.LiveCompletionConfigUtils.isLiveEndedForRewardPush(live)) {
+                log.info("[实时完课推送] 直播已结束,跳过 WebSocket, liveId={}, userId={}", liveId, userId);
+                return;
+            }
             log.debug("[实时完课检查] liveId={}, userId={}, duration={}秒", liveId, userId, duration);
 
             // 1. 调用完课记录服务检查并创建完课记录

+ 20 - 0
fs-service/src/main/java/com/fs/live/utils/LiveCompletionConfigUtils.java

@@ -4,8 +4,10 @@ import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import com.fs.common.utils.StringUtils;
+import com.fs.live.domain.Live;
 import com.fs.live.vo.LiveRewardCouponItem;
 
+import java.time.LocalDateTime;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.LinkedHashMap;
@@ -39,6 +41,24 @@ public final class LiveCompletionConfigUtils {
     private LiveCompletionConfigUtils() {
     }
 
+    /**
+     * 直播已结束且结束时间不晚于当前时间时,看课/完课奖励不再向 App 推送 WebSocket,避免结束后仍可领取。
+     * <p>
+     * 判定:status=3(已结束);或 finishTime 已过(状态尚未及时刷成 3 的竞态兜底)。
+     * </p>
+     */
+    public static boolean isLiveEndedForRewardPush(Live live) {
+        if (live == null) {
+            return true;
+        }
+        Integer status = live.getStatus();
+        if (status != null && status == 3) {
+            return true;
+        }
+        LocalDateTime finishTime = live.getFinishTime();
+        return finishTime != null && !finishTime.isAfter(LocalDateTime.now());
+    }
+
     public static JSONObject parseConfig(String configJson) {
         if (StringUtils.isEmpty(configJson)) {
             return null;