You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

100 lines
3.2 KiB

"""
积分和排名相关API路由
"""
from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.orm import Session
from typing import List, Optional
from backend.database import get_db
from backend.models import Student
from backend.schemas import RankingResponse, RankingItem
from backend.utils.excel import export_scores_to_excel
import os
import tempfile
router = APIRouter(prefix="/api/scores", tags=["scores"])
@router.get("/ranking", response_model=RankingResponse)
def get_ranking(top_n: int = 10, db: Session = Depends(get_db)):
"""获取积分排名"""
students = (db.query(Student).order_by(Student.total_score.desc()).limit(top_n).all())
rankings = []
for rank, student in enumerate(students, 1):
rankings.append(
RankingItem(rank=rank,
student_id=student.student_id,
name=student.name,
major=student.major,
total_score=student.total_score,
random_rollcall_count=student.random_rollcall_count))
total = db.query(Student).count()
return RankingResponse(rankings=rankings, total=total)
@router.get("/export")
def export_scores(db: Session = Depends(get_db)):
"""导出积分详单"""
students = db.query(Student).all()
# 准备数据
students_data = []
for student in students:
students_data.append({
'学号': student.student_id,
'姓名': student.name,
'专业': student.major or '',
'随机点名次数': student.random_rollcall_count,
'总积分': student.total_score
})
# 创建临时文件
with tempfile.NamedTemporaryFile(delete=False, suffix=".xlsx") as tmp_file:
tmp_path = tmp_file.name
try:
# 导出到Excel
export_scores_to_excel(students_data, tmp_path)
# 读取文件内容
with open(tmp_path, 'rb') as f:
file_content = f.read()
# 删除临时文件
os.remove(tmp_path)
from fastapi.responses import Response
return Response(content=file_content,
media_type="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
headers={"Content-Disposition": "attachment; filename=scores.xlsx"})
except Exception as e:
if os.path.exists(tmp_path):
os.remove(tmp_path)
raise HTTPException(status_code=500, detail=f"导出失败: {str(e)}")
from sqlalchemy import func
@router.get("/statistics")
def get_statistics(db: Session = Depends(get_db)):
"""获取统计信息"""
total_students = db.query(Student).count()
total_rollcall_count = db.query(
func.sum(Student.random_rollcall_count + Student.order_rollcall_count)).scalar() or 0
avg_score = db.query(func.avg(Student.total_score)).scalar() or 0.0
max_score = db.query(func.max(Student.total_score)).scalar() or 0.0
min_score = db.query(func.min(Student.total_score)).scalar() or 0.0
return {
"total_students": total_students,
"total_rollcall_count": total_rollcall_count,
"avg_score": round(float(avg_score), 2),
"max_score": float(max_score),
"min_score": float(min_score),
}