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()
|