Files
gsfdc/server/app/api/admin/home.py
T

324 lines
9.3 KiB
Python

from fastapi import APIRouter, Depends, HTTPException, status
from pydantic import BaseModel, Field
from sqlalchemy.orm import Session
from app.core.deps import require_staff
from app.db import get_db
from app.models.home import (
admin_home_view,
create_article,
create_slide,
delete_article,
delete_slide,
update_slide,
save_audiences,
save_compliance,
save_contact,
save_home,
save_honors,
save_hot_links,
save_members,
save_menu,
save_related_links,
set_article_display,
update_article,
)
router = APIRouter(dependencies=[Depends(require_staff)])
class TemplateWrite(BaseModel):
name: str
slogan: str = ""
valueProposition: str = ""
class HomeWrite(BaseModel):
activeTemplate: str
templates: list[TemplateWrite] = Field(min_length=2, max_length=2)
class ArticleDisplayWrite(BaseModel):
news: int | None = None
notices: int | None = None
policies: int | None = None
dashboard: int | None = None
class ArticleWrite(BaseModel):
category: str
title: str = ""
publishedAt: str | None = None
published: bool = False
bodyHtml: str = ""
imageFileId: int | None = None
attachmentFileIds: list[int] = Field(default_factory=list)
kind: str | None = None
class AudienceLinkWrite(BaseModel):
label: str
url: str = ""
visible: bool = True
sortOrder: int = 0
class AudienceCategoryWrite(BaseModel):
name: str
links: list[AudienceLinkWrite] = Field(default_factory=list)
class AudienceWrite(BaseModel):
categories: list[AudienceCategoryWrite] = Field(min_length=3, max_length=3)
class HotLinkWrite(BaseModel):
key: str
label: str
url: str = ""
visible: bool = True
sortOrder: int = 0
class HotLinksWrite(BaseModel):
links: list[HotLinkWrite] = Field(default_factory=list)
class ContactWrite(BaseModel):
name: str
address: str = ""
phone: str = ""
email: str = ""
latitude: float | None = None
longitude: float | None = None
class ContactBatchWrite(BaseModel):
templates: list[ContactWrite] = Field(min_length=2, max_length=2)
class RelatedLinkWrite(BaseModel):
label: str
url: str = ""
visible: bool = True
sortOrder: int = 0
class RelatedCategoryWrite(BaseModel):
name: str
links: list[RelatedLinkWrite] = Field(default_factory=list)
class RelatedLinksWrite(BaseModel):
templateName: str
categories: list[RelatedCategoryWrite] = Field(min_length=3, max_length=3)
class ComplianceWrite(BaseModel):
templateName: str
links: list[RelatedLinkWrite] = Field(default_factory=list)
class HonorItemWrite(BaseModel):
imageFileId: int
sortOrder: int = 0
class HonorWrite(BaseModel):
intervalSeconds: int = Field(gt=0)
items: list[HonorItemWrite] = Field(default_factory=list)
class MemberItemWrite(BaseModel):
name: str
url: str = ""
imageFileId: int
sortOrder: int = 0
class MemberWrite(BaseModel):
intervalSeconds: int = Field(gt=0)
items: list[MemberItemWrite] = Field(default_factory=list)
class MenuItemWrite(BaseModel):
key: str
label: str
url: str = ""
visible: bool = False
sortOrder: int = 0
class MenuWrite(BaseModel):
items: list[MenuItemWrite] = Field(default_factory=list)
class SlideWrite(BaseModel):
title: str = ""
imageFileId: int
sortOrder: int = 0
enabled: bool = True
intervalSeconds: int = Field(gt=0)
published: bool = False
bodyHtml: str = ""
attachmentFileIds: list[int] = Field(default_factory=list)
@router.get("/home")
def read_home(db: Session = Depends(get_db)) -> dict:
return admin_home_view(db)
@router.put("/home")
def write_home(body: HomeWrite, db: Session = Depends(get_db)) -> dict:
try:
save_home(
db,
body.activeTemplate,
[item.model_dump() for item in body.templates],
)
except ValueError as exc:
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(exc)) from exc
return {"ok": True}
@router.put("/home/audiences")
def write_audiences(body: AudienceWrite, db: Session = Depends(get_db)) -> dict:
try:
save_audiences(db, [item.model_dump() for item in body.categories])
except ValueError as exc:
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(exc)) from exc
return {"ok": True}
@router.put("/home/hot-links")
def write_hot_links(body: HotLinksWrite, db: Session = Depends(get_db)) -> dict:
try:
save_hot_links(db, [item.model_dump() for item in body.links])
except ValueError as exc:
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(exc)) from exc
return {"ok": True}
@router.put("/home/contact")
def write_contact(body: ContactBatchWrite, db: Session = Depends(get_db)) -> dict:
try:
save_contact(db, [item.model_dump() for item in body.templates])
except ValueError as exc:
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(exc)) from exc
return {"ok": True}
@router.put("/home/related-links")
def write_related_links(body: RelatedLinksWrite, db: Session = Depends(get_db)) -> dict:
try:
save_related_links(
db,
body.templateName,
[item.model_dump() for item in body.categories],
)
except ValueError as exc:
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(exc)) from exc
return {"ok": True}
@router.put("/home/compliance")
def write_compliance(body: ComplianceWrite, db: Session = Depends(get_db)) -> dict:
try:
save_compliance(db, body.templateName, [item.model_dump() for item in body.links])
except ValueError as exc:
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(exc)) from exc
return {"ok": True}
@router.put("/home/honors")
def write_honors(body: HonorWrite, db: Session = Depends(get_db)) -> dict:
try:
save_honors(db, body.intervalSeconds, [item.model_dump() for item in body.items])
except ValueError as exc:
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(exc)) from exc
return {"ok": True}
@router.put("/home/members")
def write_members(body: MemberWrite, db: Session = Depends(get_db)) -> dict:
try:
save_members(db, body.intervalSeconds, [item.model_dump() for item in body.items])
except ValueError as exc:
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(exc)) from exc
return {"ok": True}
@router.put("/home/menu")
def write_menu(body: MenuWrite, db: Session = Depends(get_db)) -> dict:
try:
save_menu(db, [item.model_dump() for item in body.items])
except ValueError as exc:
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(exc)) from exc
return {"ok": True}
@router.put("/home/articles/display")
def write_article_display(body: ArticleDisplayWrite, db: Session = Depends(get_db)) -> dict:
try:
set_article_display(db, body.model_dump(exclude_unset=True))
except ValueError as exc:
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(exc)) from exc
return {"ok": True}
@router.post("/home/articles")
def write_article(body: ArticleWrite, db: Session = Depends(get_db)) -> dict:
try:
article_id = create_article(db, body.model_dump())
except ValueError as exc:
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(exc)) from exc
return {"id": article_id}
@router.put("/home/articles/{article_id}")
def revise_article(article_id: int, body: ArticleWrite, db: Session = Depends(get_db)) -> dict:
try:
update_article(db, article_id, body.model_dump())
except ValueError as exc:
code = status.HTTP_404_NOT_FOUND if str(exc) == "文章不存在" else status.HTTP_400_BAD_REQUEST
raise HTTPException(status_code=code, detail=str(exc)) from exc
return {"ok": True}
@router.delete("/home/articles/{article_id}")
def remove_article(article_id: int, db: Session = Depends(get_db)) -> dict:
try:
delete_article(db, article_id)
except ValueError as exc:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(exc)) from exc
return {"ok": True}
@router.post("/home/slides")
def write_slide(body: SlideWrite, db: Session = Depends(get_db)) -> dict:
try:
slide_id = create_slide(db, body.model_dump())
except ValueError as exc:
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(exc)) from exc
return {"id": slide_id}
@router.put("/home/slides/{slide_id}")
def revise_slide(slide_id: int, body: SlideWrite, db: Session = Depends(get_db)) -> dict:
try:
update_slide(db, slide_id, body.model_dump())
except ValueError as exc:
code = status.HTTP_404_NOT_FOUND if str(exc) == "轮播不存在" else status.HTTP_400_BAD_REQUEST
raise HTTPException(status_code=code, detail=str(exc)) from exc
return {"ok": True}
@router.delete("/home/slides/{slide_id}")
def remove_slide(slide_id: int, db: Session = Depends(get_db)) -> dict:
try:
delete_slide(db, slide_id)
except ValueError as exc:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(exc)) from exc
return {"ok": True}