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

diff --git a/backend/app/routers/attempts_router.py b/backend/app/routers/attempts_router.py
new file mode 100644
index 0000000..c5aad61
--- /dev/null
+++ b/backend/app/routers/attempts_router.py
@@ -0,0 +1,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],
+    )

--
Gitblit v1.8.0