yearning
11 小时以前 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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
from fastapi import APIRouter, Depends, HTTPException, Query
from sqlalchemy import func, select
from sqlalchemy.orm import Session
 
from app.auth import get_current_user
from app.database import get_db
from app.grader_scope import allowed_subjects_for_user, apply_subject_scope
from app.models import (
    ExamPaperMap,
    ExaminationExamExaminee,
    ExaminationExaminee,
    ExaminationPaperSource,
    ImportBatch,
    User,
)
from app.schemas import ScoreRow, ScoresResponse
 
router = APIRouter(prefix="/api", tags=["scores"])
 
 
@router.get("/subjects")
def list_subjects(db: Session = Depends(get_db), user: User = Depends(get_current_user)):
    q = select(ImportBatch.subject_name).distinct().order_by(ImportBatch.subject_name)
    allowed = allowed_subjects_for_user(db, user)
    if allowed is not None:
        if not allowed:
            return {"items": []}
        q = q.where(ImportBatch.subject_name.in_(allowed))
    rows = db.scalars(q)
    return {"items": list(rows)}
 
 
@router.get("/scores", response_model=ScoresResponse)
def list_scores(
    page: int = Query(1, ge=1),
    page_size: int = Query(20, ge=1, le=100),
    name: str | None = None,
    id_card: str | None = None,
    subject: str | None = None,
    db: Session = Depends(get_db),
    user: User = Depends(get_current_user),
):
    allowed = allowed_subjects_for_user(db, user)
    if subject and allowed is not None and subject not in allowed:
        raise HTTPException(403, detail="无权查看该科目")
    q = (
        select(
            ExaminationExamExaminee,
            ExaminationExaminee,
            ImportBatch.subject_name,
            ExaminationPaperSource.paper_name,
        )
        .join(ExaminationExaminee, ExaminationExaminee.id == ExaminationExamExaminee.examinee_id)
        .join(ImportBatch, ImportBatch.id == ExaminationExamExaminee.import_batch_id)
        .outerjoin(ExamPaperMap, ExamPaperMap.exam_id == ExaminationExamExaminee.exam_id)
        .outerjoin(
            ExaminationPaperSource,
            ExaminationPaperSource.id == ExamPaperMap.paper_source_id,
        )
    )
    if name:
        q = q.where(ExaminationExaminee.nickname.contains(name))
    if id_card:
        q = q.where(ExaminationExaminee.id_card.contains(id_card))
    if subject:
        q = q.where(ImportBatch.subject_name == subject)
    q = apply_subject_scope(q, ImportBatch.subject_name, allowed)
 
    count_q = select(func.count()).select_from(q.subquery())
    total = db.scalar(count_q) or 0
    rows = db.execute(
        q.order_by(ExaminationExamExaminee.id.desc())
        .offset((page - 1) * page_size)
        .limit(page_size)
    ).all()
 
    items = [
        ScoreRow(
            examinee_id=str(ex.examinee_id),
            name=ee.nickname,
            id_card=ee.id_card,
            subject_name=sn,
            score=ex.score,
            attempt_id=str(ex.id),
            room_id=ex.room_id,
            paper_name=pn,
            start_time=ex.start_time,
            end_time=ex.end_time,
        )
        for ex, ee, sn, pn in rows
    ]
    return ScoresResponse(total=total, page=page, page_size=page_size, items=items)