import random from fastapi import APIRouter, Depends, HTTPException, Query from sqlalchemy import func from sqlalchemy.orm import Session from app.database import get_db from app.models.joke import Joke from app.schemas.joke import JokeResponse, PaginatedJokeResponse router = APIRouter(prefix="/jokes", tags=["笑话"]) def joke_to_response(joke: Joke) -> JokeResponse: """Convert Joke model to JokeResponse schema.""" return JokeResponse( id=joke.id, title=joke.title, content=joke.content, type_id=joke.type_id, crowd_id=joke.crowd_id, status=joke.status, view_count=joke.view_count, like_count=joke.like_count, created_at=joke.created_at, updated_at=joke.updated_at, type_name=joke.type.name if joke.type else None, crowd_name=joke.crowd.name if joke.crowd else None, ) @router.get("/", response_model=PaginatedJokeResponse) def list_jokes( page: int = 1, page_size: int = 20, type_id: int | None = None, crowd_id: int | None = None, db: Session = Depends(get_db), ): """获取笑话列表(仅返回已审核通过的笑话)""" query = db.query(Joke).filter(Joke.status == "approved") if type_id is not None: query = query.filter(Joke.type_id == type_id) if crowd_id is not None: query = query.filter(Joke.crowd_id == crowd_id) total = query.count() offset = (page - 1) * page_size jokes = query.order_by(Joke.created_at.desc()).offset(offset).limit(page_size).all() return PaginatedJokeResponse( items=[joke_to_response(j) for j in jokes], total=total, page=page, page_size=page_size, ) @router.get("/{joke_id}", response_model=JokeResponse) def get_joke(joke_id: int, db: Session = Depends(get_db)): """获取单条笑话详情""" joke = db.query(Joke).filter(Joke.id == joke_id).first() if not joke: raise HTTPException(status_code=404, detail="笑话不存在") # 增加浏览次数 joke.view_count += 1 db.commit() return joke_to_response(joke) @router.get("/random", response_model=JokeResponse) def get_random_joke(db: Session = Depends(get_db)): """随机获取一条已审核通过的笑话""" joke = db.query(Joke).filter(Joke.status == "approved").order_by(func.random()).first() if not joke: raise HTTPException(status_code=404, detail="暂无笑话") return joke_to_response(joke)