""" Seasonal products router: serves both autumn (游牧的森林) and winter (嗨冰雪). Mounted twice at /api/autumn-products and /api/winter-products. """ from __future__ import annotations from fastapi import APIRouter, Depends, HTTPException from sqlalchemy.orm import Session from app.database import get_db from app.auth import get_current_user from app.models.seasonal_product import ( SeasonalProductConfig, SeasonalProductVersion, SeasonalProductHighlight, SeasonalProductTimeline, ) from app.schemas.seasonal_product import ( SeasonalConfigSchema, SeasonalVersionSchema, SeasonalVersionResponse, SeasonalHighlightSchema, SeasonalHighlightResponse, SeasonalTimelineSchema, SeasonalTimelineResponse, ) def create_seasonal_router(season: str, label: str) -> APIRouter: router = APIRouter(prefix=f"/api/{season}-products", tags=[f"{label}产品"], dependencies=[Depends(get_current_user)]) def _get_config(db: Session) -> SeasonalProductConfig: config = db.query(SeasonalProductConfig).filter_by(season=season).first() if not config: config = SeasonalProductConfig(season=season) db.add(config) db.flush() return config @router.get("/config", response_model=SeasonalConfigSchema) def get_config(db: Session = Depends(get_db)): c = _get_config(db) return SeasonalConfigSchema( narrative=c.narrative, style=c.style, brand_name=c.brand_name, version_label=c.version_label, season_label=c.season_label, ) @router.put("/config") def update_config(req: SeasonalConfigSchema, db: Session = Depends(get_db)): c = _get_config(db) c.narrative = req.narrative c.style = req.style c.brand_name = req.brand_name c.version_label = req.version_label c.season_label = req.season_label db.commit() return {"message": "更新成功"} # --- Versions --- @router.get("/versions", response_model=list[SeasonalVersionResponse]) def list_versions(db: Session = Depends(get_db)): rows = db.query(SeasonalProductVersion).filter_by(season=season).order_by(SeasonalProductVersion.sort_order).all() return [ SeasonalVersionResponse( id=v.id, version_id=v.version_id, name=v.name, days=v.days, nights=v.nights, tag=v.tag, line=v.line, route=v.route, audience=v.audience, description=v.description, highlights=v.highlights or [], itinerary=v.itinerary or [], sort_order=v.sort_order, ) for v in rows ] @router.post("/versions", response_model=SeasonalVersionResponse, status_code=201) def create_version(req: SeasonalVersionSchema, db: Session = Depends(get_db)): v = SeasonalProductVersion( season=season, version_id=req.version_id, name=req.name, days=req.days, nights=req.nights, tag=req.tag, line=req.line, route=req.route, audience=req.audience, description=req.description, highlights=req.highlights, itinerary=req.itinerary, ) db.add(v) db.commit() db.refresh(v) return SeasonalVersionResponse( id=v.id, version_id=v.version_id, name=v.name, days=v.days, nights=v.nights, tag=v.tag, line=v.line, route=v.route, audience=v.audience, description=v.description, highlights=v.highlights or [], itinerary=v.itinerary or [], sort_order=v.sort_order, ) @router.put("/versions/{v_id}") def update_version(v_id: int, req: SeasonalVersionSchema, db: Session = Depends(get_db)): v = db.query(SeasonalProductVersion).get(v_id) if not v or v.season != season: raise HTTPException(status_code=404, detail="版本不存在") v.version_id = req.version_id v.name = req.name v.days = req.days v.nights = req.nights v.tag = req.tag v.line = req.line v.route = req.route v.audience = req.audience v.description = req.description v.highlights = req.highlights v.itinerary = req.itinerary db.commit() return {"message": "更新成功"} @router.delete("/versions/{v_id}") def delete_version(v_id: int, db: Session = Depends(get_db)): v = db.query(SeasonalProductVersion).get(v_id) if not v or v.season != season: raise HTTPException(status_code=404, detail="版本不存在") db.delete(v) db.commit() return {"message": "删除成功"} # --- Highlights --- @router.get("/highlights", response_model=list[SeasonalHighlightResponse]) def list_highlights(category: str = None, db: Session = Depends(get_db)): q = db.query(SeasonalProductHighlight).filter_by(season=season) if category: q = q.filter_by(category=category) return [ SeasonalHighlightResponse(id=h.id, category=h.category, title=h.title, description=h.description, sort_order=h.sort_order) for h in q.order_by(SeasonalProductHighlight.sort_order).all() ] @router.put("/highlights") def update_highlights(items: list[SeasonalHighlightSchema], db: Session = Depends(get_db)): db.query(SeasonalProductHighlight).filter_by(season=season).delete() for i, h in enumerate(items): db.add(SeasonalProductHighlight(season=season, category=h.category, title=h.title, description=h.description, sort_order=i)) db.commit() return {"message": "亮点更新成功"} # --- Timeline --- @router.get("/timeline", response_model=list[SeasonalTimelineResponse]) def list_timeline(db: Session = Depends(get_db)): rows = db.query(SeasonalProductTimeline).filter_by(season=season).order_by(SeasonalProductTimeline.sort_order).all() return [ SeasonalTimelineResponse(id=t.id, version=t.version, date=t.date, title=t.title, changes=t.changes or [], reason=t.reason, sort_order=t.sort_order) for t in rows ] @router.post("/timeline", response_model=SeasonalTimelineResponse, status_code=201) def create_timeline(req: SeasonalTimelineSchema, db: Session = Depends(get_db)): t = SeasonalProductTimeline(season=season, version=req.version, date=req.date, title=req.title, changes=req.changes, reason=req.reason) db.add(t) db.commit() db.refresh(t) return SeasonalTimelineResponse(id=t.id, version=t.version, date=t.date, title=t.title, changes=t.changes or [], reason=t.reason, sort_order=t.sort_order) @router.put("/timeline/{t_id}") def update_timeline(t_id: int, req: SeasonalTimelineSchema, db: Session = Depends(get_db)): t = db.query(SeasonalProductTimeline).get(t_id) if not t or t.season != season: raise HTTPException(status_code=404, detail="时间线不存在") t.version = req.version t.date = req.date t.title = req.title t.changes = req.changes t.reason = req.reason db.commit() return {"message": "更新成功"} @router.delete("/timeline/{t_id}") def delete_timeline(t_id: int, db: Session = Depends(get_db)): t = db.query(SeasonalProductTimeline).get(t_id) if not t or t.season != season: raise HTTPException(status_code=404, detail="时间线不存在") db.delete(t) db.commit() return {"message": "删除成功"} return router autumn_router = create_seasonal_router("autumn", "秋季") winter_router = create_seasonal_router("winter", "冬季")