""" 排期 API — 查询未来排播计划 降级逻辑: - schedules 表有数据 → 从 schedules 取未来 limit 条 JOIN episodes - schedules 表无数据 → 从 episodes 表取最近 limit 期待播期次(air_date 升序) """ from fastapi import APIRouter, Depends from sqlmodel import Session, select from app.core.deps import get_current_user from app.db.session import get_session from app.models.user import User from app.models.episode import Episode from app.models.schedule import Schedule router = APIRouter(prefix="/api/schedules", tags=["排期"]) @router.get("/upcoming") def list_upcoming_schedules( limit: int = 6, session: Session = Depends(get_session), current_user: User = Depends(get_current_user), ): """获取未来排播计划(三角色均可读)。 优先从 schedules 表取,schedules 无数据时降级取 episodes 最近待播期次。 """ # 先查 schedules statement = ( select(Schedule, Episode) .join(Episode, Schedule.episode_id == Episode.id, isouter=True) .where(Schedule.planned_air_date >= Episode.air_date) .order_by(Schedule.planned_air_date.asc()) .limit(limit) ) results = session.exec(statement).all() # 降级:从 episodes 直接取(当 schedules 为空或不足时) if not results or len(results) < limit: fallback_stmt = ( select(Episode) .order_by(Episode.air_date.asc()) .limit(limit) ) episodes = session.exec(fallback_stmt).all() return [ { "episode_number": ep.episode_number, "program_name": ep.program_name, "planned_air_date": str(ep.air_date), "editor_name_snapshot": ep.editor_name_snapshot, } for ep in episodes ] # schedules 有数据 output = [] for schedule, episode in results: if episode is None: continue output.append({ "episode_number": episode.episode_number, "program_name": episode.program_name, "planned_air_date": str(schedule.planned_air_date), "editor_name_snapshot": episode.editor_name_snapshot, }) return output