import csv import io import uuid from fastapi import APIRouter, Depends from fastapi.responses import StreamingResponse 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.services.student_access import get_student_for_user router = APIRouter(tags=["export"]) @router.get("/students/{student_id}/scores/export") def export_scores_csv( student_id: uuid.UUID, db: Session = Depends(get_db), current_user: User = Depends(get_current_user), ): student = get_student_for_user(db, student_id, current_user.id) exams = ( db.query(ExamRecord) .options(joinedload(ExamRecord.scores).joinedload(SubjectScore.subject)) .filter(ExamRecord.student_id == student_id) .order_by(ExamRecord.exam_date.asc()) .all() ) output = io.StringIO() writer = csv.writer(output) writer.writerow(["考试日期", "考试类型", "标题", "科目", "总分", "得分", "占比"]) type_map = {"weekly": "周考", "monthly": "月考", "final": "期末"} for exam in exams: for score in exam.scores: writer.writerow([ exam.exam_date.isoformat(), type_map.get(exam.exam_type.value, exam.exam_type.value), exam.title or "", score.subject.name if score.subject else "", float(score.total_score), float(score.obtained_score), f"{float(score.ratio) * 100:.2f}%", ]) output.seek(0) filename = f"{student.name}_scores.csv" return StreamingResponse( iter([output.getvalue().encode("utf-8-sig")]), media_type="text/csv", headers={"Content-Disposition": f'attachment; filename="{filename}"'}, )