ADD file via upload

结对
fzu102301139 5 months ago
parent c429af6d34
commit 2e8bfdc470

271
app.py

@ -0,0 +1,271 @@
from flask import Flask, render_template, request, redirect, flash, session
import random
import atexit
import os
import sys
import database
import file_handler
# 添加当前目录到 Python 路径(必要)
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
# 初始化管理器(必要)
db_manager = database.DatabaseManager()
file_handler = file_handler.FileHandler()
app = Flask(__name__)
app.secret_key = 'dev'
def init_database():
"""应用启动时初始化数据库连接"""
print("应用启动:初始化数据库连接")
if db_manager.connect():
print("数据库连接初始化成功")
return True
else:
print("数据库连接初始化失败")
return False
def close_database():
"""应用关闭时清理数据库连接"""
print("应用关闭:清理数据库连接")
db_manager.disconnect()
atexit.register(close_database)
@app.route('/')
def page1():
"""主页面"""
return render_template('page.html', student=None)
@app.route('/upload', methods=['POST'])
def upload_file():
"""上传学生名单文件"""
if 'file' not in request.files:
flash('没有选择文件')
return redirect('/')
file = request.files['file']
if file.filename == '':
flash('没有选择文件')
return redirect('/')
if file and file_handler.allowed_file(file.filename):
try:
if not db_manager.connection or not db_manager.connection.is_connected():
db_manager.connect()
processed_data = file_handler.process_for_database(file)
# 处理文件上传
success = db_manager.process_file_upload(processed_data)
if success:
flash('文件上传成功,新数据已添加到现有数据中')
else:
flash('数据导入失败')
return redirect('/')
except Exception as e:
flash(f'文件处理失败: {str(e)}')
return redirect('/')
else:
flash('不允许的文件类型')
return redirect('/')
@app.route('/sequential_roll_call')
def sequential_roll_call():
"""顺序点名 - 简单循环"""
try:
if not db_manager.connection or not db_manager.connection.is_connected():
db_manager.connect()
students = db_manager.get_all_students()
if not students:
flash('没有学生数据,请先上传文件')
return redirect('/')
# 按学号排序
sorted_students = sorted(students, key=lambda x: x['id'])
# 获取上次点名的学生ID
last_student_id = session.get('last_student_id')
if last_student_id:
# 找到上次学生的位置
current_index = next((i for i, s in enumerate(sorted_students)
if s['id'] == last_student_id), -1)
# 点下一个学生
next_index = (current_index + 1) % len(sorted_students)
else:
# 第一次点名,点第一个学生
next_index = 0
current_student = sorted_students[next_index]
session['last_student_id'] = current_student['id']
flash(f'顺序点到: {current_student["name"]} (第{next_index + 1}个)')
return render_template('page.html', student=current_student)
except Exception as e:
flash(f'点名失败: {str(e)}')
return redirect('/')
@app.route('/random_roll_call')
def random_roll_call():
"""随机点名(积分越低被点概率越高)"""
try:
if not db_manager.connection or not db_manager.connection.is_connected():
db_manager.connect()
students = db_manager.get_all_students()
if not students:
flash('没有学生数据,请先上传文件')
return redirect('/')
# 计算权重:分数越低,权重越高
weights = []
for student in students:
weight = 10 + (100 - student['score']) * 0.5
weights.append(max(weight, 1))
selected_student = random.choices(students, weights=weights, k=1)[0]
# 记录随机点名次数
db_manager.increment_random_call_count(selected_student['id'])
flash(f'随机点到: {selected_student["name"]}')
# 渲染页面并传递学生信息
return render_template('page.html', student=selected_student)
except Exception as e:
flash(f'随机点名失败: {str(e)}')
return redirect('/')
@app.route('/update_score', methods=['POST'])
def update_score():
"""更新学生分数"""
try:
if not db_manager.connection or not db_manager.connection.is_connected():
db_manager.connect()
student_id = request.form.get('student_id')
action = request.form.get('action')
performance = request.form.get('performance', 1)
student = db_manager.get_student_by_id(student_id)
if not student:
flash('学生不存在')
return redirect('/')
score_change = 0
message = ""
if action == 'attend':
score_change = 1
message = f"{student['name']} 到达课堂,+1分"
elif action == 'repeat_question_success':
score_change = 0.5
message = f"{student['name']} 准确重复问题,+0.5分"
elif action == 'repeat_question_fail':
score_change = -1
message = f"{student['name']} 未能重复问题,-1分"
elif action == 'answer_question':
try:
performance_score = float(performance)
score_change = min(max(performance_score, 0.5), 3)
message = f"{student['name']} 回答问题,+{score_change}"
except:
flash('请输入有效的分数')
return redirect('/')
success = db_manager.update_student_score(student_id, score_change)
if success:
flash(message)
# 获取更新后的学生信息并传递到页面
updated_student = db_manager.get_student_by_id(student_id)
return render_template('page.html', student=updated_student)
else:
flash('更新分数失败')
return redirect('/')
except Exception as e:
flash(f'更新分数失败: {str(e)}')
return redirect('/')
@app.route('/export_students')
def export_students():
"""导出学生数据到Excel"""
try:
if not db_manager.connection or not db_manager.connection.is_connected():
db_manager.connect()
students = db_manager.get_all_students()
if students:
exported_file = file_handler.export_to_excel(students)
if exported_file:
flash(f'导出成功: {exported_file}')
else:
flash('导出失败')
else:
flash('导出失败,没有学生数据')
return redirect('/')
except Exception as e:
flash(f'导出失败: {str(e)}')
return redirect('/')
@app.route('/show_chart')
def show_chart():
"""直接显示积分图表页面"""
try:
if not db_manager.connection or not db_manager.connection.is_connected():
db_manager.connect()
students = db_manager.get_all_students()
if students:
chart_data = file_handler.generate_simple_score_chart(students, top_n=10)
if chart_data:
# 直接渲染包含图表的页面
return render_template('chart.html', chart_data=chart_data)
# 如果没有数据,返回错误信息
return render_template('chart.html', error='没有学生数据或生成图表失败')
except Exception as e:
return render_template('chart.html', error=f'生成图表失败: {str(e)}')
@app.route('/clear_data', methods=['POST'])
def clear_data():
"""清空学生数据"""
try:
if not db_manager.connection or not db_manager.connection.is_connected():
db_manager.connect()
success = db_manager.clear_student_data()
if success:
flash('数据清空成功')
else:
flash('数据清空失败')
return redirect('/')
except Exception as e:
flash(f'清空数据失败: {str(e)}')
return redirect('/')
if __name__ == '__main__':
if init_database():
app.run(debug=True, host='0.0.0.0', port=5000)
else:
print("应用启动失败:数据库连接初始化失败")
Loading…
Cancel
Save