yearning
12 小时以前 3f96c9c6502243b06efd4bb34a189e72e3a5557c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
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))