From e429c291995f3f20184079e480031533ae5c03e6 Mon Sep 17 00:00:00 2001
From: zjk <852185829@qq.com>
Date: 星期五, 18 九月 2026 17:24:28 +0800
Subject: [PATCH] refactor(全项目): 综合优化全端业务与修复各类问题
---
tcm-training-admin-backend/src/main/java/com/tcm/training/admin/live/service/LiveSessionStatusSyncService.java | 65 +++++++++++++++++++++++++++++++-
1 files changed, 63 insertions(+), 2 deletions(-)
diff --git a/tcm-training-admin-backend/src/main/java/com/tcm/training/admin/live/service/LiveSessionStatusSyncService.java b/tcm-training-admin-backend/src/main/java/com/tcm/training/admin/live/service/LiveSessionStatusSyncService.java
index 67a38ee..86e8ea7 100644
--- a/tcm-training-admin-backend/src/main/java/com/tcm/training/admin/live/service/LiveSessionStatusSyncService.java
+++ b/tcm-training-admin-backend/src/main/java/com/tcm/training/admin/live/service/LiveSessionStatusSyncService.java
@@ -10,8 +10,10 @@
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
+import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
+import java.util.Map;
import java.util.Set;
@Service
@@ -46,7 +48,8 @@
.orderByAsc(LiveSession::getId));
int startedCount = 0;
if (dueSessions != null && !dueSessions.isEmpty()) {
- for (LiveSession dueSession : dueSessions) {
+ List<LiveSession> effectiveDueSessions = pickEffectiveDueSessions(dueSessions);
+ for (LiveSession dueSession : effectiveDueSessions) {
// 定时任务与人工开播共用同一套状态迁移逻辑,避免状态口径分叉。
LiveSessionStatusVO statusVO = liveSessionAppService.autoStart(dueSession.getId(), now);
if (statusVO == null) {
@@ -58,7 +61,8 @@
}
if (startedCount > 0) {
- log.info("live session auto start finished, scanned={}, started={}", dueSessions.size(), startedCount);
+ log.info("live session auto start finished, scanned={}, effective={}, started={}",
+ dueSessions.size(), effectiveDueSessions.size(), startedCount);
}
}
@@ -66,6 +70,63 @@
}
/**
+ * 同一课程只挑一条最应被自动开播的场次,避免历史过期开播记录被批量拉起后又互相收敛。
+ */
+ private List<LiveSession> pickEffectiveDueSessions(List<LiveSession> dueSessions) {
+ if (dueSessions == null || dueSessions.isEmpty()) {
+ return dueSessions;
+ }
+ Map<Long, LiveSession> effectiveSessionMap = new LinkedHashMap<Long, LiveSession>();
+ for (LiveSession dueSession : dueSessions) {
+ if (dueSession == null || dueSession.getLiveCourseId() == null) {
+ continue;
+ }
+ LiveSession current = effectiveSessionMap.get(dueSession.getLiveCourseId());
+ if (current == null || compareDueSession(current, dueSession) < 0) {
+ effectiveSessionMap.put(dueSession.getLiveCourseId(), dueSession);
+ }
+ }
+ return new java.util.ArrayList<LiveSession>(effectiveSessionMap.values());
+ }
+
+ /**
+ * 自动开播候选按计划开播时间排序,时间更晚者优先;同时间取 ID 更大的最新记录。
+ */
+ private int compareDueSession(LiveSession left, LiveSession right) {
+ LocalDateTime leftTime = left == null ? null : left.getStartTime();
+ LocalDateTime rightTime = right == null ? null : right.getStartTime();
+ if (leftTime == null && rightTime == null) {
+ return compareSessionId(left, right);
+ }
+ if (leftTime == null) {
+ return -1;
+ }
+ if (rightTime == null) {
+ return 1;
+ }
+ int timeCompare = leftTime.compareTo(rightTime);
+ if (timeCompare != 0) {
+ return timeCompare;
+ }
+ return compareSessionId(left, right);
+ }
+
+ private int compareSessionId(LiveSession left, LiveSession right) {
+ Long leftId = left == null ? null : left.getId();
+ Long rightId = right == null ? null : right.getId();
+ if (leftId == null && rightId == null) {
+ return 0;
+ }
+ if (leftId == null) {
+ return -1;
+ }
+ if (rightId == null) {
+ return 1;
+ }
+ return leftId.compareTo(rightId);
+ }
+
+ /**
* 定时收敛历史残留的直播中场次,避免同课程出现多条或过期直播中状态。
*/
private void reconcileLivingCourses(LocalDateTime now) {
--
Gitblit v1.7.1