|
|
"""
|
|
|
点名相关API路由
|
|
|
"""
|
|
|
from fastapi import APIRouter, Depends, HTTPException
|
|
|
from sqlalchemy.orm import Session
|
|
|
from datetime import datetime
|
|
|
from backend.database import get_db
|
|
|
from backend.models import Student, RollCallRecord, ScoreRecord
|
|
|
from backend.schemas import (
|
|
|
RollCallRequest, RollCallResult, RollCallRecordCreate,
|
|
|
RollCallRecordResponse
|
|
|
)
|
|
|
from backend.utils.probability import get_random_student, get_next_order_student
|
|
|
from backend.utils.events import trigger_random_event
|
|
|
from typing import Optional, List
|
|
|
|
|
|
router = APIRouter(prefix="/api/rollcall", tags=["rollcall"])
|
|
|
|
|
|
# 存储当前顺序点名的学生ID(简单实现,生产环境应使用Redis等)
|
|
|
current_order_student_id: Optional[int] = None
|
|
|
|
|
|
@router.post("/start", response_model=RollCallResult)
|
|
|
def start_rollcall(request: RollCallRequest, db: Session = Depends(get_db)):
|
|
|
"""开始点名"""
|
|
|
global current_order_student_id
|
|
|
|
|
|
try:
|
|
|
if request.rollcall_type == "random":
|
|
|
# 随机点名
|
|
|
student = get_random_student(db)
|
|
|
student.random_rollcall_count += 1
|
|
|
elif request.rollcall_type == "order":
|
|
|
# 顺序点名
|
|
|
student = get_next_order_student(db, current_order_student_id)
|
|
|
current_order_student_id = student.id
|
|
|
student.order_rollcall_count += 1
|
|
|
else:
|
|
|
raise HTTPException(status_code=400, detail="无效的点名类型")
|
|
|
|
|
|
db.commit()
|
|
|
|
|
|
return RollCallResult(
|
|
|
student_id=student.id,
|
|
|
student_code=student.student_id,
|
|
|
name=student.name,
|
|
|
major=student.major,
|
|
|
total_score=student.total_score,
|
|
|
random_rollcall_count=student.random_rollcall_count
|
|
|
)
|
|
|
|
|
|
except ValueError as e:
|
|
|
raise HTTPException(status_code=400, detail=str(e))
|
|
|
except Exception as e:
|
|
|
db.rollback()
|
|
|
raise HTTPException(status_code=500, detail=f"点名失败: {str(e)}")
|
|
|
|
|
|
@router.post("/record", response_model=RollCallRecordResponse)
|
|
|
def record_rollcall(record: RollCallRecordCreate, db: Session = Depends(get_db)):
|
|
|
"""记录点名结果并更新积分"""
|
|
|
student = db.query(Student).filter(Student.id == record.student_id).first()
|
|
|
if not student:
|
|
|
raise HTTPException(status_code=404, detail="学生不存在")
|
|
|
|
|
|
# 触发随机事件
|
|
|
event = trigger_random_event()
|
|
|
event_multiplier = event["multiplier"]
|
|
|
|
|
|
# 计算积分变化
|
|
|
attendance_score = 1.0 if record.is_present else 0.0
|
|
|
question_repeat_score = record.question_repeat_score # -1, 0, 0.5
|
|
|
answer_score: float = record.answer_score # 0-3
|
|
|
|
|
|
# 应用事件倍数
|
|
|
total_score_change = (
|
|
|
(attendance_score + question_repeat_score + answer_score) * event_multiplier
|
|
|
)
|
|
|
|
|
|
# 更新学生积分
|
|
|
student.total_score += total_score_change
|
|
|
# 检查转移权(被点名两次后获得一次转移权)
|
|
|
total_rollcall_count = student.random_rollcall_count + student.order_rollcall_count
|
|
|
if total_rollcall_count % 2 == 0 and total_rollcall_count > 0:
|
|
|
student.transfer_right_count += 1
|
|
|
|
|
|
# 创建点名记录
|
|
|
rollcall_record = RollCallRecord(
|
|
|
student_id=record.student_id,
|
|
|
rollcall_type=record.rollcall_type,
|
|
|
is_present=record.is_present,
|
|
|
question_repeat_score=question_repeat_score,
|
|
|
answer_score=answer_score,
|
|
|
attendance_score=attendance_score,
|
|
|
total_score_change=total_score_change,
|
|
|
event_type=event["type"]
|
|
|
)
|
|
|
db.add(rollcall_record)
|
|
|
|
|
|
# 创建积分记录
|
|
|
score_record = ScoreRecord(
|
|
|
student_id=record.student_id,
|
|
|
score_change=total_score_change,
|
|
|
reason=f"点名记录: {event['name']}"
|
|
|
)
|
|
|
db.add(score_record)
|
|
|
|
|
|
db.commit()
|
|
|
db.refresh(rollcall_record)
|
|
|
tmp = RollCallRecordResponse(
|
|
|
id=rollcall_record.id,
|
|
|
student_id=student.id,
|
|
|
student_code=student.student_id,
|
|
|
student_name=student.name,
|
|
|
rollcall_type=rollcall_record.rollcall_type,
|
|
|
is_present=rollcall_record.is_present,
|
|
|
total_score_change=rollcall_record.total_score_change,
|
|
|
created_at=rollcall_record.created_at
|
|
|
)
|
|
|
print(tmp.model_dump_json())
|
|
|
return RollCallRecordResponse(
|
|
|
id=rollcall_record.id,
|
|
|
student_id=student.id,
|
|
|
student_code=student.student_id,
|
|
|
student_name=student.name,
|
|
|
rollcall_type=rollcall_record.rollcall_type,
|
|
|
is_present=rollcall_record.is_present,
|
|
|
total_score_change=rollcall_record.total_score_change,
|
|
|
created_at=rollcall_record.created_at
|
|
|
)
|
|
|
|
|
|
@router.get("/records", response_model=List[RollCallRecordResponse])
|
|
|
def get_rollcall_records(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
|
|
|
"""获取点名记录列表"""
|
|
|
records = (
|
|
|
db.query(RollCallRecord)
|
|
|
.join(Student)
|
|
|
.offset(skip)
|
|
|
.limit(limit)
|
|
|
.order_by(RollCallRecord.created_at.desc())
|
|
|
.all()
|
|
|
)
|
|
|
|
|
|
result = []
|
|
|
for record in records:
|
|
|
result.append(RollCallRecordResponse(
|
|
|
id=record.id,
|
|
|
student_id=record.student_id,
|
|
|
student_code=record.student.student_id,
|
|
|
student_name=record.student.name,
|
|
|
rollcall_type=record.rollcall_type,
|
|
|
is_present=record.is_present,
|
|
|
total_score_change=record.total_score_change,
|
|
|
created_at=record.created_at
|
|
|
))
|
|
|
|
|
|
return result
|
|
|
|
|
|
@router.post("/transfer")
|
|
|
def transfer_rollcall(request_data: dict, db: Session = Depends(get_db)):
|
|
|
"""转移点名(使用转移权)"""
|
|
|
from_student_id = request_data.get("from_student_id")
|
|
|
to_student_id = request_data.get("to_student_id")
|
|
|
|
|
|
if not from_student_id or not to_student_id:
|
|
|
raise HTTPException(status_code=400, detail="缺少必要参数")
|
|
|
|
|
|
from_student = db.query(Student).filter(Student.id == from_student_id).first()
|
|
|
to_student = db.query(Student).filter(Student.id == to_student_id).first()
|
|
|
|
|
|
if not from_student or not to_student:
|
|
|
raise HTTPException(status_code=404, detail="学生不存在")
|
|
|
|
|
|
if from_student.transfer_right_count <= 0:
|
|
|
raise HTTPException(status_code=400, detail="没有可用的转移权")
|
|
|
|
|
|
# 使用转移权
|
|
|
from_student.transfer_right_count -= 1
|
|
|
|
|
|
db.commit()
|
|
|
|
|
|
return {
|
|
|
"message": "转移成功",
|
|
|
"from_student": from_student.name,
|
|
|
"to_student": to_student.name,
|
|
|
"remaining_transfer_rights": from_student.transfer_right_count
|
|
|
}
|
|
|
|