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