刘涛 8c0a5f489d Initial commit: hulai admin API backend
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-22 22:01:23 +08:00

188 行
6.8 KiB
Python

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.product import (
ProductConfig, ProductVersion, ProductVersionHighlight,
SummerCamp, SummerCampPrinciple, SummerCampActivity, SummerCampItinerary, SummerCampFaq,
SelectionGuide,
)
from app.schemas.product import (
ProductConfigSchema, ProductVersionSchema, ProductVersionResponse,
SummerCampSchema, SelectionGuideSchema,
)
router = APIRouter(prefix="/api/products", tags=["产品管理"], dependencies=[Depends(get_current_user)])
def _get_config(db: Session) -> ProductConfig:
config = db.query(ProductConfig).first()
if not config:
config = ProductConfig()
db.add(config)
db.flush()
return config
@router.get("/config", response_model=ProductConfigSchema)
def get_config(db: Session = Depends(get_db)):
config = _get_config(db)
return ProductConfigSchema(narrative=config.narrative, pricing_philosophy=config.pricing_philosophy)
@router.put("/config")
def update_config(req: ProductConfigSchema, db: Session = Depends(get_db)):
config = _get_config(db)
config.narrative = req.narrative
config.pricing_philosophy = req.pricing_philosophy
db.commit()
return {"message": "更新成功"}
@router.get("/versions", response_model=list[ProductVersionResponse])
def list_versions(db: Session = Depends(get_db)):
config = _get_config(db)
versions = db.query(ProductVersion).filter_by(config_id=config.id).order_by(ProductVersion.sort_order).all()
result = []
for v in versions:
resp = ProductVersionResponse(
id=v.id, version_id=v.version_id, name=v.name, days=v.days, nights=v.nights,
audience=v.audience, description=v.description, tag=v.tag, sort_order=v.sort_order,
highlights=[h.text for h in v.highlights],
)
result.append(resp)
return result
@router.post("/versions", response_model=ProductVersionResponse, status_code=201)
def create_version(req: ProductVersionSchema, db: Session = Depends(get_db)):
config = _get_config(db)
v = ProductVersion(
config_id=config.id, version_id=req.version_id, name=req.name,
days=req.days, nights=req.nights, audience=req.audience,
description=req.description, tag=req.tag,
)
db.add(v)
db.flush()
for i, h in enumerate(req.highlights):
db.add(ProductVersionHighlight(version_id=v.id, text=h, sort_order=i))
db.commit()
db.refresh(v)
return ProductVersionResponse(
id=v.id, version_id=v.version_id, name=v.name, days=v.days, nights=v.nights,
audience=v.audience, description=v.description, tag=v.tag, sort_order=v.sort_order,
highlights=[h.text for h in v.highlights],
)
@router.put("/versions/{v_id}")
def update_version(v_id: int, req: ProductVersionSchema, db: Session = Depends(get_db)):
v = db.query(ProductVersion).get(v_id)
if not v:
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.audience = req.audience
v.description = req.description
v.tag = req.tag
# Replace highlights
db.query(ProductVersionHighlight).filter_by(version_id=v.id).delete()
for i, h in enumerate(req.highlights):
db.add(ProductVersionHighlight(version_id=v.id, text=h, sort_order=i))
db.commit()
return {"message": "更新成功"}
@router.delete("/versions/{v_id}")
def delete_version(v_id: int, db: Session = Depends(get_db)):
v = db.query(ProductVersion).get(v_id)
if not v:
raise HTTPException(status_code=404, detail="版本不存在")
db.delete(v)
db.commit()
return {"message": "删除成功"}
@router.get("/summer-camp", response_model=SummerCampSchema)
def get_summer_camp(db: Session = Depends(get_db)):
config = _get_config(db)
camp = db.query(SummerCamp).filter_by(config_id=config.id).first()
if not camp:
return SummerCampSchema()
return SummerCampSchema(
name=camp.name, positioning=camp.positioning, days=camp.days, nights=camp.nights,
sessions=camp.sessions_json, difference_from_v9=camp.difference_from_v9,
principles=[p.text for p in camp.principles],
activities=[a.text for a in camp.activities],
itinerary=[it.text for it in camp.itinerary],
faq=[{"question": f.question, "answer": f.answer} for f in camp.faq],
)
@router.put("/summer-camp")
def update_summer_camp(req: SummerCampSchema, db: Session = Depends(get_db)):
config = _get_config(db)
camp = db.query(SummerCamp).filter_by(config_id=config.id).first()
if not camp:
camp = SummerCamp(config_id=config.id)
db.add(camp)
db.flush()
camp.name = req.name
camp.positioning = req.positioning
camp.days = req.days
camp.nights = req.nights
camp.sessions_json = req.sessions
camp.difference_from_v9 = req.difference_from_v9
# Replace sub-collections
db.query(SummerCampPrinciple).filter_by(camp_id=camp.id).delete()
for i, p in enumerate(req.principles):
db.add(SummerCampPrinciple(camp_id=camp.id, text=p, sort_order=i))
db.query(SummerCampActivity).filter_by(camp_id=camp.id).delete()
for i, a in enumerate(req.activities):
db.add(SummerCampActivity(camp_id=camp.id, text=a, sort_order=i))
db.query(SummerCampItinerary).filter_by(camp_id=camp.id).delete()
for i, it in enumerate(req.itinerary):
db.add(SummerCampItinerary(camp_id=camp.id, text=it, sort_order=i))
db.query(SummerCampFaq).filter_by(camp_id=camp.id).delete()
for i, f in enumerate(req.faq):
db.add(SummerCampFaq(camp_id=camp.id, question=f.question, answer=f.answer, sort_order=i))
db.commit()
return {"message": "夏令营更新成功"}
@router.get("/selection-guide", response_model=SelectionGuideSchema)
def get_selection_guide(db: Session = Depends(get_db)):
config = _get_config(db)
guide = db.query(SelectionGuide).filter_by(config_id=config.id).first()
if not guide:
return SelectionGuideSchema()
return SelectionGuideSchema(
by_vacation_length=guide.by_vacation_length or [],
by_child_age=guide.by_child_age or [],
by_preference=guide.by_preference or [],
)
@router.put("/selection-guide")
def update_selection_guide(req: SelectionGuideSchema, db: Session = Depends(get_db)):
config = _get_config(db)
guide = db.query(SelectionGuide).filter_by(config_id=config.id).first()
if not guide:
guide = SelectionGuide(config_id=config.id)
db.add(guide)
guide.by_vacation_length = req.by_vacation_length
guide.by_child_age = req.by_child_age
guide.by_preference = req.by_preference
db.commit()
return {"message": "选品指南更新成功"}