| | |
| | | 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)) { |
| | |
| | | } |
| | | |
| | | /** |
| | | * 获取直播结束时间,优先使用实际结束时间。 |
| | | * 获取直播结束时间,优先使用实际结束时间,其次按计划开播时间和配置时长计算。 |
| | | */ |
| | | public LocalDateTime resolveEndedAt(LiveSession session) { |
| | | if (session == null) { |
| | |
| | | } |
| | | 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(); |
| | | } |
| | |
| | | /** |
| | | * 将时间线上最近一场已开始场次解析为当前直播场次。 |
| | | */ |
| | | private LiveSession resolveCurrentSession(LiveSession latestStartedSession) { |
| | | private LiveSession resolveCurrentSession(LiveSession latestStartedSession, LocalDateTime now) { |
| | | if (latestStartedSession == null) { |
| | | return null; |
| | | } |
| | | if (defaultNumber(latestStartedSession.getLiveStatus()) != SESSION_STATUS_LIVING) { |
| | | 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; |
| | | } |
| | | 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) { |
| | |
| | | } |
| | | |
| | | /** |
| | | * 判断场次在 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) { |