Update app.py
Browse files
app.py
CHANGED
|
@@ -5,26 +5,43 @@ from datetime import datetime, timedelta
|
|
| 5 |
|
| 6 |
app = Flask(__name__)
|
| 7 |
|
| 8 |
-
# 加载 Excel 数据
|
| 9 |
grade_files = {
|
| 10 |
-
"22级": r"
|
| 11 |
-
"23级": r"
|
| 12 |
-
"24级": r"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 13 |
}
|
| 14 |
|
| 15 |
# 预加载所有年级数据
|
| 16 |
-
|
| 17 |
for grade, file_path in grade_files.items():
|
| 18 |
df = pd.read_excel(file_path)
|
| 19 |
df["grade"] = grade # 添加年级字段
|
| 20 |
-
|
|
|
|
|
|
|
| 21 |
|
| 22 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 23 |
|
| 24 |
# 第一周的开始日期
|
| 25 |
first_week_start_date = datetime(2024, 9, 2) # 第一周星期一的日期
|
| 26 |
|
| 27 |
-
|
|
|
|
| 28 |
def parse_weeks(weeks_str):
|
| 29 |
if not weeks_str or pd.isna(weeks_str):
|
| 30 |
return set()
|
|
@@ -42,6 +59,7 @@ def parse_weeks(weeks_str):
|
|
| 42 |
return weeks
|
| 43 |
|
| 44 |
|
|
|
|
| 45 |
# 星期与节次解析函数
|
| 46 |
def parse_day_and_period(period_str):
|
| 47 |
if not period_str or pd.isna(period_str):
|
|
@@ -67,16 +85,18 @@ def calculate_date(week, day):
|
|
| 67 |
@app.route("/")
|
| 68 |
def index():
|
| 69 |
return render_template("index.html")
|
| 70 |
-
|
| 71 |
-
|
| 72 |
-
|
| 73 |
-
|
|
|
|
|
|
|
| 74 |
week = request.args.get("week", 1)
|
| 75 |
grade = request.args.get("grade", None)
|
| 76 |
admin_class = request.args.get("admin_class", None)
|
| 77 |
|
| 78 |
# 筛选数据
|
| 79 |
-
filtered_data =
|
| 80 |
if grade:
|
| 81 |
filtered_data = filtered_data[filtered_data["grade"] == grade]
|
| 82 |
if admin_class:
|
|
@@ -99,9 +119,9 @@ def get_courses():
|
|
| 99 |
day, periods = day_and_period
|
| 100 |
course_date = calculate_date(week, day) # 计算课程日期
|
| 101 |
results.append({
|
| 102 |
-
|
| 103 |
"教师": row["教师"],
|
| 104 |
-
"地点": row["地点"]
|
| 105 |
"星期": day,
|
| 106 |
"日期": course_date.strftime("%Y-%m-%d"), # 格式化为字符串
|
| 107 |
"节次": periods,
|
|
@@ -113,12 +133,117 @@ def get_courses():
|
|
| 113 |
results = sorted(results, key=lambda x: (x["星期"], x["节次"][0]))
|
| 114 |
return jsonify(results)
|
| 115 |
|
| 116 |
-
|
| 117 |
@app.route("/api/classes")
|
| 118 |
def get_classes():
|
| 119 |
-
classes =
|
| 120 |
return jsonify(sorted(classes))
|
| 121 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 122 |
|
| 123 |
if __name__ == "__main__":
|
| 124 |
app.run(host="0.0.0.0", port=7860)
|
|
|
|
| 5 |
|
| 6 |
app = Flask(__name__)
|
| 7 |
|
| 8 |
+
# 加载 Excel 数据 - 学生年级数据
|
| 9 |
grade_files = {
|
| 10 |
+
"22级": r"./数据表\22级.xlsx",
|
| 11 |
+
"23级": r"./数据表\23级.xlsx",
|
| 12 |
+
"24级": r"./数据表\24级.xlsx",
|
| 13 |
+
}
|
| 14 |
+
# 加载学生数据表
|
| 15 |
+
student_file_path = r"./数据表/区队-学号-姓名-1.xlsx"
|
| 16 |
+
student_data = pd.read_excel(student_file_path)
|
| 17 |
+
# 加载 Excel 数据 - 教师课程数据
|
| 18 |
+
teacher_files = {
|
| 19 |
+
"2024-2025学年第一学期": r"./数据表\信息学院教师.xlsx",
|
| 20 |
}
|
| 21 |
|
| 22 |
# 预加载所有年级数据
|
| 23 |
+
grade_dataframes = {}
|
| 24 |
for grade, file_path in grade_files.items():
|
| 25 |
df = pd.read_excel(file_path)
|
| 26 |
df["grade"] = grade # 添加年级字段
|
| 27 |
+
grade_dataframes[grade] = df
|
| 28 |
+
|
| 29 |
+
grade_data = pd.concat(grade_dataframes.values(), ignore_index=True)
|
| 30 |
|
| 31 |
+
# 预加载教师课程数据
|
| 32 |
+
teacher_dataframes = {}
|
| 33 |
+
for semester, file_path in teacher_files.items():
|
| 34 |
+
df = pd.read_excel(file_path)
|
| 35 |
+
df["学年学期"] = semester # 添加学年学期字段
|
| 36 |
+
teacher_dataframes[semester] = df
|
| 37 |
+
|
| 38 |
+
teacher_data = pd.concat(teacher_dataframes.values(), ignore_index=True)
|
| 39 |
|
| 40 |
# 第一周的开始日期
|
| 41 |
first_week_start_date = datetime(2024, 9, 2) # 第一周星期一的日期
|
| 42 |
|
| 43 |
+
|
| 44 |
+
|
| 45 |
def parse_weeks(weeks_str):
|
| 46 |
if not weeks_str or pd.isna(weeks_str):
|
| 47 |
return set()
|
|
|
|
| 59 |
return weeks
|
| 60 |
|
| 61 |
|
| 62 |
+
# print(parse_weeks("1-2,4,7-9"))
|
| 63 |
# 星期与节次解析函数
|
| 64 |
def parse_day_and_period(period_str):
|
| 65 |
if not period_str or pd.isna(period_str):
|
|
|
|
| 85 |
@app.route("/")
|
| 86 |
def index():
|
| 87 |
return render_template("index.html")
|
| 88 |
+
@app.route("/teachers")
|
| 89 |
+
def teacher_page():
|
| 90 |
+
return render_template("teacher.html")
|
| 91 |
+
# 学生课程相关 API
|
| 92 |
+
@app.route("/api/student_courses")
|
| 93 |
+
def get_student_courses():
|
| 94 |
week = request.args.get("week", 1)
|
| 95 |
grade = request.args.get("grade", None)
|
| 96 |
admin_class = request.args.get("admin_class", None)
|
| 97 |
|
| 98 |
# 筛选数据
|
| 99 |
+
filtered_data = grade_data
|
| 100 |
if grade:
|
| 101 |
filtered_data = filtered_data[filtered_data["grade"] == grade]
|
| 102 |
if admin_class:
|
|
|
|
| 119 |
day, periods = day_and_period
|
| 120 |
course_date = calculate_date(week, day) # 计算课程日期
|
| 121 |
results.append({
|
| 122 |
+
"课程": row["课程"],#.split("]")[1],
|
| 123 |
"教师": row["教师"],
|
| 124 |
+
"地点": row["地点"],#.split("(")[0],
|
| 125 |
"星期": day,
|
| 126 |
"日期": course_date.strftime("%Y-%m-%d"), # 格式化为字符串
|
| 127 |
"节次": periods,
|
|
|
|
| 133 |
results = sorted(results, key=lambda x: (x["星期"], x["节次"][0]))
|
| 134 |
return jsonify(results)
|
| 135 |
|
|
|
|
| 136 |
@app.route("/api/classes")
|
| 137 |
def get_classes():
|
| 138 |
+
classes = grade_data["行政班级"].dropna().unique().tolist()
|
| 139 |
return jsonify(sorted(classes))
|
| 140 |
|
| 141 |
+
# 教师课程相关 API
|
| 142 |
+
@app.route("/api/teachers")
|
| 143 |
+
def get_teachers():
|
| 144 |
+
teachers = teacher_data["教师"].dropna().unique().tolist()
|
| 145 |
+
return jsonify(sorted(teachers))
|
| 146 |
+
|
| 147 |
+
@app.route("/api/teacher_courses")
|
| 148 |
+
def get_courses_by_teacher():
|
| 149 |
+
week = request.args.get("week", 1)
|
| 150 |
+
teacher = request.args.get("teacher", None)
|
| 151 |
+
|
| 152 |
+
# 筛选数据
|
| 153 |
+
filtered_data = teacher_data
|
| 154 |
+
if teacher:
|
| 155 |
+
filtered_data = filtered_data[filtered_data["教师"] == teacher]
|
| 156 |
+
if week:
|
| 157 |
+
week = int(week)
|
| 158 |
+
filtered_data = filtered_data[filtered_data["周次"].apply(lambda x: week in parse_weeks(x) if pd.notna(x) else False)]
|
| 159 |
+
|
| 160 |
+
# 解析课程信息
|
| 161 |
+
results = []
|
| 162 |
+
for _, row in filtered_data.iterrows():
|
| 163 |
+
day_and_period = parse_day_and_period(row["节次"])
|
| 164 |
+
if day_and_period:
|
| 165 |
+
day, periods = day_and_period
|
| 166 |
+
course_date = calculate_date(week, day) # 计算课程日期
|
| 167 |
+
results.append({
|
| 168 |
+
"课程": row["课程"].split("]")[1],
|
| 169 |
+
"教师": row["教师"],
|
| 170 |
+
"地点": row["地点"].split("(")[0],
|
| 171 |
+
"星期": day,
|
| 172 |
+
"日期": course_date.strftime("%Y-%m-%d"), # 格式化为字符串
|
| 173 |
+
"节次": periods,
|
| 174 |
+
"节次范围": f"第{periods[0]}-{periods[-1]}节",
|
| 175 |
+
"周次": row["周次"]
|
| 176 |
+
})
|
| 177 |
+
|
| 178 |
+
# 按星期和节次排序
|
| 179 |
+
results = sorted(results, key=lambda x: (x["星期"], x["节次"][0]))
|
| 180 |
+
return jsonify(results)
|
| 181 |
+
|
| 182 |
+
# 路由��学生查询页面
|
| 183 |
+
@app.route("/students")
|
| 184 |
+
def student_page():
|
| 185 |
+
return render_template("student.html")
|
| 186 |
+
|
| 187 |
+
@app.route("/api/student_courses_v2")
|
| 188 |
+
def get_student_courses_v2():
|
| 189 |
+
week = request.args.get("week", 1)
|
| 190 |
+
student_name = request.args.get("student_name", "").strip()
|
| 191 |
+
|
| 192 |
+
if not student_name:
|
| 193 |
+
return jsonify({"error": "缺少学生姓名参数"}), 400
|
| 194 |
+
|
| 195 |
+
# 使用拷贝的数据,避免修改原始 student_data
|
| 196 |
+
student_data_copy = student_data.copy()
|
| 197 |
+
student_data_copy["区队"] = student_data_copy["区队"].str.extract(r"\](.*)$")[0].str.strip()
|
| 198 |
+
|
| 199 |
+
# 查找匹配的学生信息
|
| 200 |
+
matching_students = student_data_copy[student_data_copy["姓名"].str.contains(student_name, na=False)]
|
| 201 |
+
if matching_students.empty:
|
| 202 |
+
return jsonify({"error": "未找到匹配的学生信息"}), 404
|
| 203 |
+
|
| 204 |
+
# 获取学生所在班级
|
| 205 |
+
admin_classes = matching_students["区队"].unique()
|
| 206 |
+
|
| 207 |
+
# 筛选课程数据
|
| 208 |
+
filtered_data = grade_data[grade_data["行政班级"].isin(admin_classes)]
|
| 209 |
+
|
| 210 |
+
# 按课程类型筛选
|
| 211 |
+
filtered_data = filtered_data[filtered_data["课程类别"].str.contains("必修课", na=False)]
|
| 212 |
+
|
| 213 |
+
# 按周次筛选
|
| 214 |
+
if week:
|
| 215 |
+
week = int(week)
|
| 216 |
+
filtered_data = filtered_data[
|
| 217 |
+
filtered_data["周次"].apply(lambda x: week in parse_weeks(x) if pd.notna(x) else False)
|
| 218 |
+
]
|
| 219 |
+
# 如果没有找到课程数据
|
| 220 |
+
if filtered_data.empty:
|
| 221 |
+
return jsonify({"error": "未找到匹配的课程表"}), 404
|
| 222 |
+
|
| 223 |
+
# 解析课程信息
|
| 224 |
+
results = []
|
| 225 |
+
for _, row in filtered_data.iterrows():
|
| 226 |
+
day_and_period = parse_day_and_period(row["节次"])
|
| 227 |
+
if day_and_period:
|
| 228 |
+
day, periods = day_and_period
|
| 229 |
+
course_date = calculate_date(week, day) # 计算课程日期
|
| 230 |
+
results.append({
|
| 231 |
+
"课程": row["课程"],
|
| 232 |
+
"教师": row["教师"],
|
| 233 |
+
"地点": row["地点"],
|
| 234 |
+
"星期": day,
|
| 235 |
+
"日期": course_date.strftime("%Y-%m-%d"), # 格式化为字符串
|
| 236 |
+
"节次": periods,
|
| 237 |
+
"节次范围": f"第{periods[0]}-{periods[-1]}节",
|
| 238 |
+
"周次": row["周次"]
|
| 239 |
+
})
|
| 240 |
+
|
| 241 |
+
# 按星期和节次排序
|
| 242 |
+
results = sorted(results, key=lambda x: (x["星期"], x["节次"][0]))
|
| 243 |
+
return jsonify(results)
|
| 244 |
+
|
| 245 |
+
|
| 246 |
+
|
| 247 |
|
| 248 |
if __name__ == "__main__":
|
| 249 |
app.run(host="0.0.0.0", port=7860)
|