feat: add student/class statistics page with Chart.js visualizations
This commit is contained in:
@@ -16,6 +16,7 @@ from app.models import (
|
||||
db,
|
||||
Student,
|
||||
Class,
|
||||
StudentProblem,
|
||||
PracticePlan,
|
||||
PROBLEM_LIST,
|
||||
SEVERITY_LEVELS,
|
||||
@@ -67,6 +68,14 @@ def students_page():
|
||||
)
|
||||
|
||||
|
||||
@main_bp.route("/statistics")
|
||||
def statistics_page():
|
||||
"""数据统计页"""
|
||||
if not check_login():
|
||||
return redirect("/login")
|
||||
return render_template("statistics.html", active_nav="statistics")
|
||||
|
||||
|
||||
@main_bp.route("/api/students", methods=["GET"])
|
||||
@login_required_json
|
||||
def get_students():
|
||||
@@ -366,3 +375,69 @@ def import_students():
|
||||
|
||||
except Exception as e:
|
||||
return jsonify({"error": f"导入失败: {str(e)}"}), 500
|
||||
|
||||
|
||||
@main_bp.route("/api/statistics/students")
|
||||
def get_student_statistics():
|
||||
"""获取学员统计数据"""
|
||||
# 全体学员数量
|
||||
total_students = Student.query.count()
|
||||
|
||||
# 全体问题记录
|
||||
problems = StudentProblem.query.all()
|
||||
|
||||
# 问题级别分布(来自 StudentProblem.level)
|
||||
levels = ["启蒙", "入门", "进阶", "熟练", "精通"]
|
||||
level_dist = {lv: 0 for lv in levels}
|
||||
for p in problems:
|
||||
if p.level in level_dist:
|
||||
level_dist[p.level] += 1
|
||||
|
||||
# 问题严重程度分布
|
||||
severity_dist = {"轻微": 0, "中等": 0, "严重": 0}
|
||||
for p in problems:
|
||||
if p.severity in severity_dist:
|
||||
severity_dist[p.severity] += 1
|
||||
|
||||
# 各班级学员数量
|
||||
classes = Class.query.filter_by(active=True).all()
|
||||
class_student_count = []
|
||||
for c in classes:
|
||||
class_student_count.append({
|
||||
"class_id": c.id,
|
||||
"class_name": c.name,
|
||||
"level": c.level,
|
||||
"student_count": len(c.students)
|
||||
})
|
||||
|
||||
# 问题×级别矩阵(严重程度 × 学员级别)
|
||||
severities = ["轻微", "中等", "严重"]
|
||||
matrix = {}
|
||||
for sev in severities:
|
||||
matrix[sev] = {}
|
||||
for lv in levels:
|
||||
matrix[sev][lv] = 0
|
||||
|
||||
for p in problems:
|
||||
if p.level in levels and p.severity in severities:
|
||||
matrix[p.severity][p.level] += 1
|
||||
|
||||
# 各班级问题数量
|
||||
class_problem_count = []
|
||||
for c in classes:
|
||||
class_problems = [p for p in problems if p.student.class_id == c.id]
|
||||
class_problem_count.append({
|
||||
"class_id": c.id,
|
||||
"class_name": c.name,
|
||||
"problem_count": len(class_problems)
|
||||
})
|
||||
|
||||
return jsonify({
|
||||
"total_students": total_students,
|
||||
"total_problems": len(problems),
|
||||
"level_distribution": level_dist,
|
||||
"severity_distribution": severity_dist,
|
||||
"class_student_count": class_student_count,
|
||||
"class_problem_count": class_problem_count,
|
||||
"problem_level_matrix": matrix,
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user