| | from flask import Flask, jsonify, render_template, request |
| | import pandas as pd |
| | import re |
| | from datetime import datetime, timedelta |
| |
|
| | app = Flask(__name__) |
| |
|
| | |
| | grade_files = { |
| | "22级": r"./数据表/22级.xlsx", |
| | "23级": r"./数据表/23级.xlsx", |
| | "24级": r"./数据表/24级.xlsx", |
| | } |
| | |
| | student_file_path = r"./数据表/区队-学号-姓名-1.xlsx" |
| | student_data = pd.read_excel(student_file_path) |
| | |
| | teacher_files = { |
| | "2024-2025学年第一学期": r"./数据表/教学安排表20241125112641.xlsx", |
| | } |
| |
|
| | |
| | grade_dataframes = {} |
| | for grade, file_path in grade_files.items(): |
| | df = pd.read_excel(file_path) |
| | df["grade"] = grade |
| | grade_dataframes[grade] = df |
| |
|
| | grade_data = pd.concat(grade_dataframes.values(), ignore_index=True) |
| |
|
| | |
| | teacher_dataframes = {} |
| | for semester, file_path in teacher_files.items(): |
| | df = pd.read_excel(file_path) |
| | df["学年学期"] = semester |
| | teacher_dataframes[semester] = df |
| |
|
| | teacher_data = pd.concat(teacher_dataframes.values(), ignore_index=True) |
| |
|
| | |
| | first_week_start_date = datetime(2024, 9, 2) |
| |
|
| |
|
| |
|
| | def parse_weeks(weeks_str): |
| | if not weeks_str or pd.isna(weeks_str): |
| | return set() |
| | weeks = set() |
| | for part in weeks_str.split(","): |
| | try: |
| | if "-" in part: |
| | start, end = map(int, part.split("-")) |
| | weeks.update(range(start, end + 1)) |
| | else: |
| | weeks.add(int(part)) |
| | except ValueError: |
| | print(f"跳过无效周次: {part}") |
| | continue |
| | return weeks |
| |
|
| |
|
| | |
| | |
| | def parse_day_and_period(period_str): |
| | if not period_str or pd.isna(period_str): |
| | return None |
| | try: |
| | day_match = re.search(r"[一二三四五六日]", period_str) |
| | period_match = re.search(r"\[(\d+)-(\d+)节\]", period_str) |
| |
|
| | if day_match and period_match: |
| | day = "一二三四五六日".index(day_match.group()) + 1 |
| | start, end = map(int, period_match.groups()) |
| | periods = list(range(start, end + 1)) |
| | return day, periods |
| | except Exception as e: |
| | print(f"解析失败: {period_str}, 错误: {e}") |
| | return None |
| |
|
| | |
| | def calculate_date(week, day): |
| | days_from_start = (week - 1) * 7 + (day - 1) |
| | return first_week_start_date + timedelta(days=days_from_start) |
| |
|
| | @app.route("/") |
| | def index(): |
| | return render_template("index.html") |
| | @app.route("/teachers") |
| | def teacher_page(): |
| | return render_template("teacher.html") |
| | |
| | @app.route("/api/student_courses") |
| | def get_student_courses(): |
| | week = request.args.get("week", 1) |
| | grade = request.args.get("grade", None) |
| | admin_class = request.args.get("admin_class", None) |
| |
|
| | |
| | filtered_data = grade_data |
| | if grade: |
| | filtered_data = filtered_data[filtered_data["grade"] == grade] |
| | if admin_class: |
| | filtered_data = filtered_data[filtered_data["行政班级"].str.contains(admin_class, na=False)] |
| |
|
| | |
| | filtered_data = filtered_data[filtered_data["课程类别"].str.contains("必修课", na=False)] |
| |
|
| | if week: |
| | week = int(week) |
| | filtered_data = filtered_data[ |
| | filtered_data["周次"].apply(lambda x: week in parse_weeks(x) if pd.notna(x) else False) |
| | ] |
| |
|
| | |
| | results = [] |
| | for _, row in filtered_data.iterrows(): |
| | day_and_period = parse_day_and_period(row["节次"]) |
| | if day_and_period: |
| | day, periods = day_and_period |
| | course_date = calculate_date(week, day) |
| | results.append({ |
| | "课程": row["课程"].split("]")[1] if "]" in row["课程"] else row["课程"], |
| | "教师": row["教师"], |
| | "地点": row["地点"].split("(")[0] if "(" in row["地点"] else row["地点"], |
| | "星期": day, |
| | "日期": course_date.strftime("%Y-%m-%d"), |
| | "节次": periods, |
| | "节次范围": f"第{periods[0]}-{periods[-1]}节", |
| | "周次": row["周次"] |
| | }) |
| |
|
| | |
| | results = sorted(results, key=lambda x: (x["星期"], x["节次"][0])) |
| | return jsonify(results) |
| |
|
| | @app.route("/api/classes") |
| | def get_classes(): |
| | classes = grade_data["行政班级"].dropna().unique().tolist() |
| | return jsonify(sorted(classes)) |
| |
|
| | |
| | @app.route("/api/teachers") |
| | def get_teachers(): |
| | teachers = teacher_data["教师"].dropna().unique().tolist() |
| | return jsonify(sorted(teachers)) |
| |
|
| | @app.route("/api/teacher_courses") |
| | def get_courses_by_teacher(): |
| | week = request.args.get("week", 1) |
| | teacher = request.args.get("teacher", None) |
| |
|
| | |
| | filtered_data = teacher_data |
| | if teacher: |
| | filtered_data = filtered_data[filtered_data["教师"] == teacher] |
| | if week: |
| | week = int(week) |
| | filtered_data = filtered_data[filtered_data["周次"].apply(lambda x: week in parse_weeks(x) if pd.notna(x) else False)] |
| |
|
| | |
| | results = [] |
| | for _, row in filtered_data.iterrows(): |
| | day_and_period = parse_day_and_period(row["节次"]) |
| | if day_and_period: |
| | day, periods = day_and_period |
| | course_date = calculate_date(week, day) |
| | results.append({ |
| | "课程": row["课程"].split("]")[1] if "]" in row["课程"] else row["课程"], |
| | "教师": row["教师"], |
| | "地点": row["地点"].split("(")[0] if "(" in row["地点"] else row["地点"], |
| | "星期": day, |
| | "日期": course_date.strftime("%Y-%m-%d"), |
| | "节次": periods, |
| | "节次范围": f"第{periods[0]}-{periods[-1]}节", |
| | "周次": row["周次"] |
| | }) |
| |
|
| | |
| | results = sorted(results, key=lambda x: (x["星期"], x["节次"][0])) |
| | return jsonify(results) |
| |
|
| | |
| | @app.route("/students") |
| | def student_page(): |
| | return render_template("student.html") |
| |
|
| | @app.route("/api/students") |
| | def get_students(): |
| | students = student_data["姓名"].dropna().unique().tolist() |
| | return jsonify(sorted(students)) |
| |
|
| | @app.route("/api/student_courses_v2") |
| | def get_student_courses_v2(): |
| | week = request.args.get("week", 1) |
| | student_name = request.args.get("student_name", "").strip() |
| |
|
| | if not student_name: |
| | return jsonify({"error": "缺少学生姓名参数"}), 400 |
| |
|
| | |
| | student_data_copy = student_data.copy() |
| | student_data_copy["区队"] = student_data_copy["区队"].str.extract(r"\](.*)$")[0].str.strip() |
| |
|
| | |
| | matching_students = student_data_copy[student_data_copy["姓名"].str.contains(student_name, na=False)] |
| | if matching_students.empty: |
| | return jsonify({"error": "未找到匹配的学生信息"}), 404 |
| |
|
| | |
| | admin_classes = matching_students["区队"].unique() |
| |
|
| | |
| | filtered_data = grade_data[grade_data["行政班级"].isin(admin_classes)] |
| |
|
| | |
| | filtered_data = filtered_data[filtered_data["课程类别"].str.contains("必修课", na=False)] |
| |
|
| | |
| | if week: |
| | week = int(week) |
| | filtered_data = filtered_data[ |
| | filtered_data["周次"].apply(lambda x: week in parse_weeks(x) if pd.notna(x) else False) |
| | ] |
| | |
| | if filtered_data.empty: |
| | return jsonify({"error": "未找到匹配的课程表"}), 404 |
| |
|
| | |
| | results = [] |
| | for _, row in filtered_data.iterrows(): |
| | day_and_period = parse_day_and_period(row["节次"]) |
| | if day_and_period: |
| | day, periods = day_and_period |
| | course_date = calculate_date(week, day) |
| | results.append({ |
| | "课程": row["课程"].split("]")[1] if "]" in row["课程"] else row["课程"], |
| | "教师": row["教师"], |
| | "地点": row["地点"].split("(")[0] if "(" in row["地点"] else row["地点"], |
| | "星期": day, |
| | "日期": course_date.strftime("%Y-%m-%d"), |
| | "节次": periods, |
| | "节次范围": f"第{periods[0]}-{periods[-1]}节", |
| | "周次": row["周次"] |
| | }) |
| |
|
| | |
| | results = sorted(results, key=lambda x: (x["星期"], x["节次"][0])) |
| | return jsonify(results) |
| |
|
| |
|
| |
|
| |
|
| | if __name__ == "__main__": |
| | app.run(host="0.0.0.0", port=7860) |
| |
|
| |
|