From 3f96c9c6502243b06efd4bb34a189e72e3a5557c Mon Sep 17 00:00:00 2001
From: yearning <10538594+wangweifeng1999@user.noreply.gitee.com>
Date: 星期一, 28 九月 2026 19:24:55 +0800
Subject: [PATCH] 复制项目

---
 backend/app/routers/admin_graders_router.py |  105 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 105 insertions(+), 0 deletions(-)

diff --git a/backend/app/routers/admin_graders_router.py b/backend/app/routers/admin_graders_router.py
new file mode 100644
index 0000000..75002e5
--- /dev/null
+++ b/backend/app/routers/admin_graders_router.py
@@ -0,0 +1,105 @@
+from fastapi import APIRouter, Depends, HTTPException
+from sqlalchemy import select
+from sqlalchemy.orm import Session
+
+from app.auth import hash_password, require_admin
+from app.database import get_db
+from app.grader_scope import get_grader_subjects, set_grader_subjects, validate_subject_names
+from app.models import User
+from app.schemas import GraderCreate, GraderOut, GraderUpdate, GradersResponse
+
+router = APIRouter(prefix="/api/admin/graders", tags=["admin-graders"])
+
+
+def _get_grader(db: Session, grader_id: int) -> User:
+    user = db.get(User, grader_id)
+    if not user or user.role != "grader":
+        raise HTTPException(404, detail="鑰冭瘎鍛樹笉瀛樺湪")
+    return user
+
+
+def _to_out(db: Session, u: User) -> GraderOut:
+    return GraderOut(
+        id=u.id,
+        username=u.username,
+        display_name=u.display_name or "",
+        is_active=u.is_active,
+        created_at=u.created_at.isoformat() if u.created_at else "",
+        subjects=get_grader_subjects(db, u.id),
+    )
+
+
+@router.get("", response_model=GradersResponse)
+def list_graders(
+    db: Session = Depends(get_db),
+    _: User = Depends(require_admin),
+):
+    rows = db.scalars(select(User).where(User.role == "grader").order_by(User.id)).all()
+    return GradersResponse(items=[_to_out(db, u) for u in rows])
+
+
+@router.post("", response_model=GraderOut, status_code=201)
+def create_grader(
+    body: GraderCreate,
+    db: Session = Depends(get_db),
+    _: User = Depends(require_admin),
+):
+    username = body.username.strip()
+    if db.query(User).filter(User.username == username).first():
+        raise HTTPException(409, detail="鐢ㄦ埛鍚嶅凡瀛樺湪")
+    validate_subject_names(db, body.subjects)
+    user = User(
+        username=username,
+        password_hash=hash_password(body.password),
+        display_name=body.display_name.strip(),
+        role="grader",
+        is_active=True,
+    )
+    db.add(user)
+    db.flush()
+    set_grader_subjects(db, user.id, body.subjects)
+    db.commit()
+    db.refresh(user)
+    return _to_out(db, user)
+
+
+@router.put("/{grader_id}", response_model=GraderOut)
+def update_grader(
+    grader_id: int,
+    body: GraderUpdate,
+    db: Session = Depends(get_db),
+    _: User = Depends(require_admin),
+):
+    user = _get_grader(db, grader_id)
+    if body.username is not None:
+        username = body.username.strip()
+        if not username:
+            raise HTTPException(400, detail="鐢ㄦ埛鍚嶄笉鑳戒负绌�")
+        other = db.query(User).filter(User.username == username, User.id != grader_id).first()
+        if other:
+            raise HTTPException(409, detail="鐢ㄦ埛鍚嶅凡瀛樺湪")
+        user.username = username
+    if body.display_name is not None:
+        user.display_name = body.display_name.strip()
+    if body.password is not None:
+        user.password_hash = hash_password(body.password)
+    if body.is_active is not None:
+        user.is_active = body.is_active
+    if body.subjects is not None:
+        set_grader_subjects(db, user.id, body.subjects)
+    db.commit()
+    db.refresh(user)
+    return _to_out(db, user)
+
+
+@router.delete("/{grader_id}", status_code=204)
+def delete_grader(
+    grader_id: int,
+    db: Session = Depends(get_db),
+    admin: User = Depends(require_admin),
+):
+    if grader_id == admin.id:
+        raise HTTPException(400, detail="涓嶈兘鍒犻櫎褰撳墠鐧诲綍璐﹀彿")
+    user = _get_grader(db, grader_id)
+    db.delete(user)
+    db.commit()

--
Gitblit v1.8.0