This commit is contained in:
root
2026-10-16 13:51:00 +08:00
parent 6bf949949c
commit 8fc899d0a9
3830 changed files with 11228 additions and 188377 deletions
+88
View File
@@ -115,3 +115,91 @@ async def report_complete(video_id: int, req: WatchCompleteReq, db: AsyncSession
redis: aioredis.Redis = Depends(get_redis),
identity: Identity = Depends(get_identity)):
return ok(await video_service.report_complete(db, redis, identity, video_id, req.watch_duration))
# ---------- 系列(Series)----------
@router.get("/series/{series_id}")
async def get_series(series_id: int, db: AsyncSession = Depends(get_db)):
"""系列详情 + 全部集数列表(按 episode_no 排序)"""
from app.models.video import Series, Video
from sqlalchemy import select
series = await db.get(Series, series_id)
if not series or series.status != 1:
raise BizException(errors.NOT_FOUND, "系列不存在或已隐藏")
# 关联视频(已发布)
stmt = select(Video).where(
Video.series_id == series_id, Video.status == 2
).order_by(Video.episode_no.asc(), Video.id.asc())
eps = (await db.execute(stmt)).scalars().all()
return ok({
"series": {
"id": series.id,
"title": series.title,
"cover_url": series.cover_url,
"description": series.description,
"total_episodes": len(eps),
},
"episodes": [
{
"video_id": v.id,
"episode_no": v.episode_no,
"title": v.title,
"cover_url": v.cover_url,
"duration": v.duration,
"video_url": v.video_url,
}
for v in eps
],
})
@router.get("/{video_id}/series")
async def get_video_series(video_id: int, db: AsyncSession = Depends(get_db)):
"""当前视频所属系列 + 上下集(用于 PlayerScreen 抽屉入口)"""
from app.models.video import Series, Video
from sqlalchemy import select
video = await db.get(Video, video_id)
if not video or not video.series_id or video.status != 2:
return ok({"has_series": False})
series = await db.get(Series, video.series_id)
if not series or series.status != 1:
return ok({"has_series": False})
stmt = select(Video).where(
Video.series_id == series.id, Video.status == 2
).order_by(Video.episode_no.asc(), Video.id.asc())
all_eps = (await db.execute(stmt)).scalars().all()
# 找当前集索引
current_idx = next((i for i, v in enumerate(all_eps) if v.id == video_id), -1)
prev_ep = all_eps[current_idx - 1] if current_idx > 0 else None
next_ep = all_eps[current_idx + 1] if 0 <= current_idx < len(all_eps) - 1 else None
return ok({
"has_series": True,
"current_episode_no": video.episode_no,
"series": {
"id": series.id,
"title": series.title,
"cover_url": series.cover_url,
"total_episodes": len(all_eps),
},
"episodes": [
{
"video_id": v.id,
"episode_no": v.episode_no,
"title": v.title,
"cover_url": v.cover_url,
"duration": v.duration,
}
for v in all_eps
],
"prev_video_id": prev_ep.id if prev_ep else None,
"next_video_id": next_ep.id if next_ep else None,
})