from __future__ import annotations from fastapi import APIRouter, Depends, HTTPException, Query, Request from ..api_utils import file_meta, load_accounts, payload_to_account, read_register_payload from ..auth import verify_accounts_auth, verify_admin_auth from ..config import ACCOUNTS_PATH, CLASSNOTES_PATH, write_lock from ..data import ( ACCOUNT_STATUSES, DuplicateRecordError, account_summary, account_to_dict, create_account, filter_accounts, register_class_record_lines, register_payment_lines, update_account, ) from ..schemas import AccountPayload router = APIRouter() @router.post("/api/register/class-records") async def register_class_records(request: Request, _user: str = Depends(verify_admin_auth)): try: payload = await read_register_payload(request) with write_lock: result = register_class_record_lines( CLASSNOTES_PATH, ACCOUNTS_PATH, lines=payload.lines, line=payload.line, ) except DuplicateRecordError as exc: raise HTTPException(status_code=409, detail=str(exc)) from exc except ValueError as exc: raise HTTPException(status_code=400, detail=str(exc)) from exc return {"ok": True, **result} @router.post("/api/register/payments") async def register_payments(request: Request, _user: str = Depends(verify_admin_auth)): try: payload = await read_register_payload(request) with write_lock: result = register_payment_lines(ACCOUNTS_PATH, lines=payload.lines, line=payload.line) except ValueError as exc: raise HTTPException(status_code=400, detail=str(exc)) from exc return {"ok": True, **result} @router.get("/api/account-health") def account_health(_user: str = Depends(verify_accounts_auth)): accounts = load_accounts() return { "ok": True, "accounts": file_meta(ACCOUNTS_PATH), "accounts_count": len(accounts), "account_summary": account_summary(accounts), } @router.get("/api/accounts") def accounts( q: str = Query("", description="学生姓名或学生ID"), status_filter: str = Query("", alias="status", description="账户状态"), _user: str = Depends(verify_accounts_auth), ): all_accounts = load_accounts() rows = filter_accounts(all_accounts, keyword=q, status=status_filter) return { "summary": account_summary(all_accounts), "count": len(rows), "accounts": [account_to_dict(account) for account in rows], } @router.get("/api/accounts/{student}") def account_detail(student: str, _user: str = Depends(verify_accounts_auth)): for account in load_accounts(): if account.student == student or account.student_id == student: return account_to_dict(account) raise HTTPException(status_code=404, detail=f"未找到学生账户: {student}") @router.get("/api/admin/statuses") def admin_statuses(_user: str = Depends(verify_admin_auth)): return {"account_statuses": sorted(ACCOUNT_STATUSES)} @router.post("/api/admin/accounts") def admin_create_account(payload: AccountPayload, _user: str = Depends(verify_admin_auth)): try: with write_lock: result = create_account(ACCOUNTS_PATH, payload_to_account(payload)) except ValueError as exc: raise HTTPException(status_code=400, detail=str(exc)) from exc return {"ok": True, **result} @router.put("/api/admin/accounts/{student_id}") def admin_update_account(student_id: str, payload: AccountPayload, _user: str = Depends(verify_admin_auth)): try: with write_lock: result = update_account(ACCOUNTS_PATH, student_id, payload_to_account(payload)) except ValueError as exc: raise HTTPException(status_code=400, detail=str(exc)) from exc return {"ok": True, **result}