“mitao”
2026-04-17 d699da385dda6257677ee93bef47388c0635f64e
tcm-training-admin-backend/src/main/java/com/tcm/training/admin/live/service/LiveSessionStatusSyncService.java
@@ -78,6 +78,18 @@
            return;
        }
        int endedCount = autoEndExpiredLivingSessions(livingSessions, now);
        if (endedCount > 0) {
            livingSessions = liveSessionMapper.selectList(new LambdaQueryWrapper<LiveSession>()
                    .eq(LiveSession::getDeleted, 0)
                    .eq(LiveSession::getLiveStatus, 1)
                    .orderByAsc(LiveSession::getLiveCourseId)
                    .orderByAsc(LiveSession::getId));
            if (livingSessions == null || livingSessions.isEmpty()) {
                return;
            }
        }
        Set<Long> courseIds = new LinkedHashSet<Long>();
        for (LiveSession livingSession : livingSessions) {
            if (livingSession == null || livingSession.getLiveCourseId() == null) {
@@ -94,4 +106,66 @@
            log.info("live session reconcile finished, livingCourses={}, repaired={}", courseIds.size(), repairedCount);
        }
    }
    /**
     * 自动结束已超过配置时长的直播中场次。
     */
    private int autoEndExpiredLivingSessions(List<LiveSession> livingSessions, LocalDateTime now) {
        if (livingSessions == null || livingSessions.isEmpty()) {
            return 0;
        }
        int endedCount = 0;
        int skippedCount = 0;
        for (LiveSession livingSession : livingSessions) {
            if (!shouldAutoEnd(livingSession, now)) {
                if (livingSession == null
                        || livingSession.getDurationSeconds() == null
                        || livingSession.getDurationSeconds().intValue() <= 0
                        || resolveSessionStartTime(livingSession) == null) {
                    skippedCount++;
                }
                continue;
            }
            LiveSessionStatusVO statusVO = liveSessionAppService.autoEnd(livingSession.getId(), now);
            if (statusVO != null) {
                endedCount++;
            }
        }
        if (endedCount > 0 || skippedCount > 0) {
            log.info("live session auto end finished, scanned={}, ended={}, skipped={}",
                    livingSessions.size(), endedCount, skippedCount);
        }
        return endedCount;
    }
    /**
     * 判断直播中场次是否已到自动结束时间。
     */
    private boolean shouldAutoEnd(LiveSession session, LocalDateTime now) {
        if (session == null) {
            return false;
        }
        Integer durationSeconds = session.getDurationSeconds();
        if (durationSeconds == null || durationSeconds.intValue() <= 0) {
            return false;
        }
        LocalDateTime startTime = resolveSessionStartTime(session);
        if (startTime == null) {
            return false;
        }
        return !startTime.plusSeconds(durationSeconds.longValue()).isAfter(now);
    }
    /**
     * 优先使用实际开播时间,没有时回退到计划开播时间。
     */
    private LocalDateTime resolveSessionStartTime(LiveSession session) {
        if (session == null) {
            return null;
        }
        if (session.getActualStartTime() != null) {
            return session.getActualStartTime();
        }
        return session.getStartTime();
    }
}