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
93
94
95
96
97
98
99
100
from collections import defaultdict
 
from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy import select
from sqlalchemy.orm import Session
 
from app.auth import get_current_user
from app.database import get_db
from app.grader_scope import assert_subject_allowed
from app.models import (
    ExamPaperMap,
    ExaminationExamExaminee,
    ExaminationExaminee,
    ExaminationExamineeExamAnswerItem,
    ExaminationPaperItem,
    ExaminationPaperSource,
    ImportBatch,
    User,
)
from app.schemas import AttemptDetail, PartGroup, QuestionDetail
 
router = APIRouter(prefix="/api", tags=["attempts"])
 
 
@router.get("/attempts/{attempt_id}", response_model=AttemptDetail)
def get_attempt(
    attempt_id: str,
    db: Session = Depends(get_db),
    user: User = Depends(get_current_user),
):
    try:
        attempt_pk = int(attempt_id)
    except ValueError:
        raise HTTPException(404, detail="记录不存在")
    attempt = db.get(ExaminationExamExaminee, attempt_pk)
    if not attempt:
        raise HTTPException(404, detail="记录不存在")
    examinee = db.get(ExaminationExaminee, attempt.examinee_id)
    batch = db.get(ImportBatch, attempt.import_batch_id)
    assert_subject_allowed(db, user, batch.subject_name if batch else None)
    pmap = db.scalar(
        select(ExamPaperMap).where(ExamPaperMap.exam_id == attempt.exam_id)
    )
    paper_id = pmap.paper_source_id if pmap else (batch.paper_source_id if batch else None)
    paper = db.get(ExaminationPaperSource, paper_id) if paper_id else None
 
    items = list(
        db.scalars(
            select(ExaminationPaperItem)
            .where(ExaminationPaperItem.paper_source_id == paper_id)
            .order_by(ExaminationPaperItem.part_ref, ExaminationPaperItem.item_order)
        )
    ) if paper else []
 
    answer_items = {
        ai.external_item_id: ai
        for ai in db.scalars(
            select(ExaminationExamineeExamAnswerItem).where(
                ExaminationExamineeExamAnswerItem.exam_examinee_id == attempt_pk
            )
        )
    }
 
    groups: dict[str, list[QuestionDetail]] = defaultdict(list)
    part_order: list[str] = []
    for it in items:
        pn = it.part_name or "题目"
        if pn not in part_order:
            part_order.append(pn)
        ai = answer_items.get(it.external_item_id)
        groups[pn].append(
            QuestionDetail(
                external_item_id=it.external_item_id,
                part_name=it.part_name,
                item_type=it.item_type,
                item_order=it.item_order,
                title_html=it.title_html,
                detail_json=it.detail_json,
                max_score=it.max_score,
                reference_answer=it.reference_answer,
                user_answer=ai.answer_raw if ai else None,
                is_correct=ai.is_correct if ai else False,
                score=ai.score if ai else 0,
            )
        )
 
    return AttemptDetail(
        attempt_id=str(attempt.id),
        examinee_name=examinee.nickname if examinee else None,
        id_card=examinee.id_card if examinee else None,
        score=attempt.score,
        paper_total_score=paper.total_score if paper else None,
        paper_name=paper.paper_name if paper else None,
        subject_name=batch.subject_name if batch else None,
        room_id=attempt.room_id,
        seat_number=attempt.seat_number,
        start_time=attempt.start_time,
        end_time=attempt.end_time,
        parts=[PartGroup(part_name=p, questions=groups[p]) for p in part_order],
    )