Files
gsfdc/server/app/api/site/discipline.py
T

73 lines
2.4 KiB
Python

from fastapi import APIRouter, Depends, File, Form, HTTPException, UploadFile, status
from sqlalchemy.orm import Session
from app.db import get_db
from app.models.content import read_upload_limit
from app.models.discipline import create_complaint, public_complaint_status, public_notice
router = APIRouter()
def _content_type(value: str | None) -> str:
raw = (value or "").split(";", 1)[0].strip().lower()
return raw.replace("\r", "").replace("\n", "")[:128]
def _read_limited(upload: UploadFile, limit: int) -> bytes:
chunks = bytearray()
while True:
piece = upload.file.read(65536)
if not piece:
break
if len(chunks) + len(piece) > limit:
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="文件超过大小上限")
chunks.extend(piece)
return bytes(chunks)
@router.get("/discipline/notice")
def read_notice(db: Session = Depends(get_db)) -> dict:
return public_notice(db)
@router.post("/discipline/complaints")
def submit_complaint(
title: str = Form(""),
subject: str = Form(""),
body: str = Form(""),
contactName: str = Form(""),
mobile: str = Form(""),
email: str = Form(""),
evidence: list[UploadFile] | None = File(default=None),
db: Session = Depends(get_db),
):
limit = read_upload_limit(db)
if limit is None:
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="未配置上传大小上限")
files: list[tuple[str, str, bytes]] = []
for upload in evidence or []:
if upload is None or not getattr(upload, "filename", None):
continue
files.append((upload.filename, _content_type(upload.content_type), _read_limited(upload, limit)))
try:
return create_complaint(
db,
title=title,
subject=subject,
body=body,
contact_name=contactName,
mobile=mobile,
email=email,
files=files,
)
except ValueError as exc:
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(exc)) from exc
@router.get("/discipline/complaints/{code}")
def read_complaint_status(code: str, db: Session = Depends(get_db)) -> dict:
body = public_complaint_status(db, code)
if body is None:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="未找到该查询码")
return body