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.

160 lines
6.3 KiB

from fastapi import FastAPI, File, UploadFile, HTTPException, Body
from fastapi.responses import HTMLResponse
from starlette.middleware.cors import CORSMiddleware
from starlette.staticfiles import StaticFiles
from typing import Union, Dict, List
from io import BytesIO
import pandas as pd
import random
app = FastAPI()
# 假设你的静态文件存放在名为 'static' 的文件夹中
app.mount("/static", StaticFiles(directory="static"), name="static")
data: List[Dict[str, Union[str, int]]] = []
students_scores = {}
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
@app.get("/", response_class=HTMLResponse)
async def read_root():
# 返回 stu_roll.html 页面
with open("stu_roll.html", "r", encoding="utf-8") as f:
return f.read()
@app.post("/upload")
async def list_upload(file: UploadFile = File(...)):
global data, students_scores
if file.content_type != "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet":
return {"message": "错误的文件格式,请重新上传!"}
file_content = await file.read()
# 使用 openpyxl 作为引擎读取 .xlsx 文件
df = pd.read_excel(BytesIO(file_content), engine='openpyxl')
if "学号" not in df.columns or "姓名" not in df.columns:
return {"message": "文件中缺少学号或姓名列!"}
data = [{"学号": str(row["学号"]).strip(), "姓名": row["姓名"], "积分": 0, "被点名次数": 0} for row in
df.to_dict(orient='records')]
students_scores = {student["学号"]: 0 for student in data}
print(f"Uploaded students: {students_scores}")
return {"message": "名单上传成功!", "students": data} # 返回学生数据
@app.get("/roll")
def list_roll(enable_random_events: bool = False):
if not data:
return {"message": "还未上传学生名单,暂无任何数据!"}
total_score = sum(students_scores.values()) # 计算所有学生的总积分
# 如果总积分为零,给所有学生相同的权重
if total_score <= 0:
weights = [1] * len(data) # 所有学生的权重相同
else:
# 计算权重
weights = [total_score - students_scores[student["学号"]] for student in data]
# 使用权重进行随机选择
chosen_student = random.choices(data, weights=weights, k=1)[0]
# 更新被点名次数
chosen_student["被点名次数"] += 1
print(f"Chosen student: {chosen_student['姓名']} - 被点名次数: {chosen_student['被点名次数']}")
# 打印调试信息
print(f"Chosen student: {chosen_student}")
# 检查是否有转移权
if chosen_student["被点名次数"] >= 3:
chosen_student["被点名次数"] = 0
return {"学号": chosen_student["学号"], "姓名": chosen_student["姓名"], "转移权": True}
# 处理随机事件
if enable_random_events:
random_event_result = handle_random_events(chosen_student)
return {"学号": chosen_student["学号"], "姓名": chosen_student["姓名"], "转移权": False,
"随机事件": random_event_result}
return {"学号": chosen_student["学号"], "姓名": chosen_student["姓名"], "转移权": False}
@app.get("/rank")
def list_rank():
if not data:
return {"message": "请先上传学生名单!"}
sorted_data = sorted(data, key=lambda x: x["积分"], reverse=True)
return sorted_data
@app.post("/evaluate-answer")
async def evaluate_answer(
student_id: str = Body(...),
is_come: bool = Body(...),
can_repeat: bool = Body(...),
answer_correct: str = Body(...)
):
global students_scores, data
score_delta = 0
print(
f"Received student_id: {student_id}, is_come: {is_come}, can_repeat: {can_repeat}, answer_correct: {answer_correct}")
# 检查学生 ID 是否存在
if student_id not in students_scores:
print(f"Student ID {student_id} not found in scores.")
raise HTTPException(status_code=404, detail="Student not found.")
# 根据回答情况计算积分变化
if is_come:
score_delta += 1
if can_repeat:
score_delta += 0.5
else:
score_delta -= 0.5
if answer_correct == "完全正确":
score_delta += 3
elif answer_correct == "部分正确":
score_delta += 1.5
else:
score_delta -= 1
# 更新 students_scores 字典
students_scores[student_id] += score_delta
# 更新 data 列表中的积分
for student in data:
if student["学号"] == student_id:
student["积分"] += score_delta
break
print(f"Score updated for student_id: {student_id}, new score: {students_scores[student_id]}")
return {"success": True}
def handle_random_events(chosen_student):
event = random.choice(["mdfucker", "士多啤梨", "吖食啦嘞", "abandon", "疯狂星期四V你50"])
event_description = ""
if event == "surprise mdfucker":
print(f"{chosen_student['姓名']} surprise mdfucker")
students_scores[chosen_student["学号"]] += 2
chosen_student["积分"] += 2
event_description = "surprise mdfucker"
elif event == "士多啤梨":
print(f"{chosen_student['姓名']} 士多啤梨!")
students_scores[chosen_student["学号"]] += 1
chosen_student["积分"] += 1
event_description = "士多啤梨"
if event == "吖食啦嘞":
print(f"{chosen_student['姓名']} 吖食啦嘞!")
students_scores[chosen_student["学号"]] -= 2
chosen_student["积分"] -= 2
event_description = "吖食啦嘞"
if event == "abandon":
print(f"{chosen_student['姓名']} abandon")
students_scores[chosen_student["学号"]] -= 1
chosen_student["积分"] -= 1
event_description = "abandon"
elif event == "疯狂星期四V你50":
if chosen_student["积分"] % 50 == 0: # 积分是50的因数
print(f"{chosen_student['姓名']} 疯狂星期四V你50")
students_scores[chosen_student["学号"]] += 1.5
chosen_student["积分"] += 1.5
event_description = "疯狂星期四V你50"
return event_description