324 lines
9.3 KiB
Python
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}
|