“mitao”
2026-04-24 b620af46945757c8c578a9f8d3ef472e40544d70
tcm-training-admin-backend/src/main/java/com/tcm/training/admin/app/live/support/AppLiveCourseDisplaySupport.java
@@ -36,14 +36,14 @@
        CourseDisplaySnapshot snapshot = new CourseDisplaySnapshot();
        LiveSession latestStartedSession = findLatestStartedSession(safeSessions, now);
        snapshot.setLatestStartedSession(latestStartedSession);
        LiveSession currentSession = resolveCurrentSession(latestStartedSession);
        LiveSession currentSession = resolveCurrentSession(latestStartedSession, now);
        snapshot.setCurrentSession(currentSession);
        if (currentSession != null) {
            snapshot.setDisplayStatus(DISPLAY_STATUS_LIVING);
            return snapshot;
        }
        LiveSession latestEndedSession = resolveLatestEndedSession(safeSessions, latestStartedSession);
        LiveSession latestEndedSession = resolveLatestEndedSession(safeSessions, latestStartedSession, now);
        snapshot.setLatestEndedSession(latestEndedSession);
        snapshot.setLatestEndedAt(resolveEndedAt(latestEndedSession));
        if (isInEndedCooldown(latestEndedSession, now, endedCooldownMinutes)) {
@@ -115,7 +115,7 @@
    }
    /**
     * 获取直播结束时间,优先使用实际结束时间。
     * 获取直播结束时间,优先使用实际结束时间,其次按计划开播时间和配置时长计算。
     */
    public LocalDateTime resolveEndedAt(LiveSession session) {
        if (session == null) {
@@ -123,6 +123,9 @@
        }
        if (session.getActualEndTime() != null) {
            return session.getActualEndTime();
        }
        if (session.getStartTime() != null && defaultNumber(session.getDurationSeconds()) > 0) {
            return session.getStartTime().plusSeconds(defaultNumber(session.getDurationSeconds()));
        }
        return session.getStartTime();
    }
@@ -206,26 +209,44 @@
    /**
     * 将时间线上最近一场已开始场次解析为当前直播场次。
     */
    private LiveSession resolveCurrentSession(LiveSession latestStartedSession) {
    private LiveSession resolveCurrentSession(LiveSession latestStartedSession, LocalDateTime now) {
        if (latestStartedSession == null) {
            return null;
        }
        if (defaultNumber(latestStartedSession.getLiveStatus()) != SESSION_STATUS_LIVING) {
            return null;
        if (defaultNumber(latestStartedSession.getLiveStatus()) == SESSION_STATUS_LIVING) {
            if (defaultNumber(latestStartedSession.getDurationSeconds()) > 0) {
                LocalDateTime endedAt = resolveEndedAt(latestStartedSession);
                if (endedAt != null && !endedAt.isAfter(now)) {
                    return null;
                }
            }
            return latestStartedSession;
        }
        return latestStartedSession;
        if (defaultNumber(latestStartedSession.getLiveStatus()) == SESSION_STATUS_NOT_STARTED) {
            if (defaultNumber(latestStartedSession.getDurationSeconds()) <= 0) {
                return latestStartedSession;
            }
            LocalDateTime endedAt = resolveEndedAt(latestStartedSession);
            // APP 展示态按计划时间实时计算,避免低频定时任务导致到点后仍显示未开始。
            if (endedAt == null || endedAt.isAfter(now)) {
                return latestStartedSession;
            }
        }
        return null;
    }
    /**
     * 解析最近一场已结束场次,优先使用时间线上的最新已开始场次。
     */
    private LiveSession resolveLatestEndedSession(List<LiveSession> sessions, LiveSession latestStartedSession) {
        if (latestStartedSession != null && defaultNumber(latestStartedSession.getLiveStatus()) == SESSION_STATUS_ENDED) {
    private LiveSession resolveLatestEndedSession(List<LiveSession> sessions,
                                                  LiveSession latestStartedSession,
                                                  LocalDateTime now) {
        if (isEndedForDisplay(latestStartedSession, now)) {
            return latestStartedSession;
        }
        LiveSession result = null;
        for (LiveSession session : sessions) {
            if (defaultNumber(session.getLiveStatus()) != SESSION_STATUS_ENDED) {
            if (!isEndedForDisplay(session, now)) {
                continue;
            }
            if (result == null || compareEndedSession(result, session) < 0) {
@@ -236,6 +257,27 @@
    }
    /**
     * 判断场次在 APP 当前展示口径下是否已经结束。
     */
    private boolean isEndedForDisplay(LiveSession session, LocalDateTime now) {
        if (session == null) {
            return false;
        }
        if (defaultNumber(session.getLiveStatus()) == SESSION_STATUS_ENDED) {
            return true;
        }
        int status = defaultNumber(session.getLiveStatus());
        if (status != SESSION_STATUS_NOT_STARTED && status != SESSION_STATUS_LIVING) {
            return false;
        }
        if (defaultNumber(session.getDurationSeconds()) <= 0) {
            return false;
        }
        LocalDateTime endedAt = resolveEndedAt(session);
        return session.getStartTime() != null && endedAt != null && !endedAt.isAfter(now);
    }
    /**
     * 选择下一场待开播的场次。
     */
    private LiveSession findNextSession(List<LiveSession> sessions, LocalDateTime now) {