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/grader_scope.py |   71 +++++++++++++++++++++++++++++++++++
 1 files changed, 71 insertions(+), 0 deletions(-)

diff --git a/backend/app/grader_scope.py b/backend/app/grader_scope.py
new file mode 100644
index 0000000..a46686b
--- /dev/null
+++ b/backend/app/grader_scope.py
@@ -0,0 +1,71 @@
+from fastapi import HTTPException
+from sqlalchemy import false, select
+from sqlalchemy.orm import Session
+
+from app.models import GraderSubject, ImportBatch, User
+
+
+def list_all_subject_names(db: Session) -> list[str]:
+    return list(db.scalars(select(ImportBatch.subject_name).distinct().order_by(ImportBatch.subject_name)))
+
+
+def get_grader_subjects(db: Session, user_id: int) -> list[str]:
+    return list(
+        db.scalars(
+            select(GraderSubject.subject_name)
+            .where(GraderSubject.user_id == user_id)
+            .order_by(GraderSubject.subject_name)
+        )
+    )
+
+
+def validate_subject_names(db: Session, names: list[str]) -> list[str]:
+    cleaned = []
+    seen = set()
+    for n in names:
+        s = (n or "").strip()
+        if not s or s in seen:
+            continue
+        seen.add(s)
+        cleaned.append(s)
+    if not cleaned:
+        raise HTTPException(400, detail="璇疯嚦灏戦�夋嫨涓�涓鐩�")
+    known = set(list_all_subject_names(db))
+    unknown = [s for s in cleaned if s not in known]
+    if unknown:
+        raise HTTPException(400, detail=f"鏈煡绉戠洰锛歿', '.join(unknown)}")
+    return cleaned
+
+
+def set_grader_subjects(db: Session, user_id: int, names: list[str]) -> None:
+    validated = validate_subject_names(db, names)
+    db.query(GraderSubject).filter(GraderSubject.user_id == user_id).delete()
+    for name in validated:
+        db.add(GraderSubject(user_id=user_id, subject_name=name))
+
+
+def allowed_subjects_for_user(db: Session, user: User) -> list[str] | None:
+    """None = 涓嶉檺鍒讹紙绠$悊鍛橈級锛涘垪琛� = 鑰冭瘎鍛樺彲瑙佺鐩��"""
+    if user.role == "admin":
+        return None
+    if user.role == "grader":
+        return get_grader_subjects(db, user.id)
+    return []
+
+
+def assert_subject_allowed(db: Session, user: User, subject_name: str | None) -> None:
+    if not subject_name:
+        raise HTTPException(404, detail="璁板綍涓嶅瓨鍦�")
+    allowed = allowed_subjects_for_user(db, user)
+    if allowed is None:
+        return
+    if subject_name not in allowed:
+        raise HTTPException(403, detail="鏃犳潈鏌ョ湅璇ョ鐩暟鎹�")
+
+
+def apply_subject_scope(q, subject_column, allowed: list[str] | None):
+    if allowed is None:
+        return q
+    if not allowed:
+        return q.where(false())
+    return q.where(subject_column.in_(allowed))

--
Gitblit v1.8.0