成绩复盘与 PC 端上传优化:各科考试状态多选及树状统计。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-06-28 16:33:21 +08:00
parent acfe002fbf
commit ff4e0b1d37
14 changed files with 956 additions and 556 deletions
+28 -1
View File
@@ -1,3 +1,4 @@
import json
import uuid
from fastapi import APIRouter, Depends, HTTPException, Query, status
@@ -6,13 +7,37 @@ from sqlalchemy.orm import Session, joinedload
from app.core.database import get_db
from app.core.deps import get_current_user
from app.models.user import ExamRecord, SubjectScore, User
from app.schemas import ExamCreate, ExamOut, ExamUpdate, ScoreOut, TrendResponse
from app.schemas import ExamCreate, ExamOut, ExamUpdate, ReviewStatusEnum, ScoreOut, TrendResponse
from app.services.score_trend import build_trend
from app.services.student_access import get_student_for_user
router = APIRouter(tags=["exams"])
def _parse_review_statuses(raw: str | None) -> list[ReviewStatusEnum]:
if not raw:
return []
try:
data = json.loads(raw)
except json.JSONDecodeError:
return []
if not isinstance(data, list):
return []
result: list[ReviewStatusEnum] = []
for item in data:
try:
result.append(ReviewStatusEnum(str(item)))
except ValueError:
continue
return result
def _serialize_review_statuses(statuses: list[ReviewStatusEnum] | None) -> str | None:
if not statuses:
return None
return json.dumps([s.value for s in statuses], ensure_ascii=False)
def _score_to_out(score: SubjectScore) -> ScoreOut:
return ScoreOut(
id=score.id,
@@ -21,6 +46,7 @@ def _score_to_out(score: SubjectScore) -> ScoreOut:
total_score=float(score.total_score),
obtained_score=float(score.obtained_score),
ratio=float(score.ratio),
review_statuses=_parse_review_statuses(score.review_statuses_json),
)
@@ -45,6 +71,7 @@ def _apply_scores(db: Session, exam: ExamRecord, scores_data):
total_score=item.total_score,
obtained_score=item.obtained_score,
ratio=ratio,
review_statuses_json=_serialize_review_statuses(item.review_statuses),
)
)