345 lines
11 KiB
Python
345 lines
11 KiB
Python
import datetime
|
||
import os
|
||
|
||
import openpyxl as openpyxl
|
||
from flask import Flask, redirect, url_for, render_template, session, jsonify, request, send_file
|
||
from utils.time_utils import check_now_time
|
||
from utils.allowed_files import allowed_excel
|
||
from db.connection import MySQLPool
|
||
from config import SECRET_KEY
|
||
from db.database_manager import DatabaseManager
|
||
from models.Student import Student
|
||
from models.Teacher import Teacher
|
||
from models.User import User
|
||
import logging
|
||
from config import LOGGING_CONFIG
|
||
from config import FILE_PATH
|
||
|
||
app = Flask(__name__, static_folder='static')
|
||
app.secret_key = SECRET_KEY # 从配置文件设置
|
||
logging.basicConfig(**LOGGING_CONFIG)
|
||
|
||
# 一个全局MySQLPool对象,用于管理数据库连接
|
||
mysql_pool = MySQLPool()
|
||
# 配置文件路径,例如指向一个 'files' 目录
|
||
app.config['FILE_PATH'] = FILE_PATH
|
||
|
||
|
||
@app.route('/')
|
||
def index():
|
||
# 如果用户已登录,则重定向到主页;否则,重定向到登录页面
|
||
if 'number' in session:
|
||
return redirect(url_for('home'))
|
||
else:
|
||
return render_template('login.html')
|
||
|
||
|
||
@app.route('/register', methods=['GET', 'POST'])
|
||
def register():
|
||
if request.method == 'POST':
|
||
data = request.get_json()
|
||
print(data)
|
||
user = User(
|
||
name=data.get('name'),
|
||
number=data.get('number'),
|
||
password=data.get('password'), # 确保密码安全处理
|
||
status=True
|
||
)
|
||
identity = check_identity(user.number)
|
||
db_manager = DatabaseManager()
|
||
if not db_manager.user_exists(user.number):
|
||
db_manager.insert_user(user)
|
||
user_id = db_manager.query_user_id(user.number)
|
||
if identity == "teacher":
|
||
teacher = Teacher(name=user.name, teacher_number=user.number, user_id=user_id)
|
||
db_manager.insert_teacher(teacher)
|
||
else: # assumed student
|
||
class_name = user.number[1:5] + "级" + user.number[5:7] + "班"
|
||
major_id = user.number[7:10]
|
||
student = Student(student_name=user.name, student_number=user.number, user_id=user_id,
|
||
major_id=major_id,
|
||
class_name=class_name)
|
||
db_manager.insert_student(student)
|
||
return jsonify({"success": True, "message": "注册成功"})
|
||
else:
|
||
return jsonify({"success": False, "message": "用户已存在"})
|
||
else:
|
||
return render_template('register.html')
|
||
|
||
|
||
def check_identity(number):
|
||
identity = None
|
||
if number[0] == 'G':
|
||
identity = "teacher"
|
||
return identity
|
||
else:
|
||
identity = "student"
|
||
return identity
|
||
|
||
|
||
@app.route('/login', methods=['GET', 'POST'])
|
||
def login():
|
||
if request.method == 'GET':
|
||
return render_template('login.html')
|
||
else:
|
||
number = request.form['number']
|
||
password = request.form['password']
|
||
db_manager = DatabaseManager()
|
||
|
||
result = db_manager.valid_login(number, password) # 获取验证结果
|
||
|
||
# 确保用户已验证且活跃(未被禁用)
|
||
if result['valid'] and result['status'] == 1:
|
||
# 登录成功
|
||
session['number'] = number
|
||
session['role'] = check_identity(number)
|
||
session['name'] = result['name']
|
||
return jsonify(success=True, message="登录成功")
|
||
elif not result['status']:
|
||
# 用户被禁用的情况
|
||
return jsonify(success=False, message="账户已被禁用")
|
||
else:
|
||
# 其他登录失败情况
|
||
return jsonify(success=False, message="无效的用户名或密码")
|
||
|
||
|
||
@app.route('/forget', methods=['GET', 'POST'])
|
||
def forget_page():
|
||
return render_template('forget.html')
|
||
|
||
|
||
@app.route('/home')
|
||
def home():
|
||
if 'number' in session:
|
||
return render_template('home.html')
|
||
else:
|
||
return redirect("login")
|
||
|
||
|
||
@app.route('/logout')
|
||
def logout():
|
||
# 清除session中的所有信息
|
||
session.clear()
|
||
# 返回一个响应,或者重定向到登录页面
|
||
return redirect('/login')
|
||
|
||
|
||
@app.route('/api/menu')
|
||
def get_menu():
|
||
db_manager = DatabaseManager()
|
||
|
||
# 从session中获取用户角色
|
||
if 'role' in session:
|
||
role = session['role']
|
||
menu_items = db_manager.get_menu(role)
|
||
|
||
# 转换菜单项为期望的格式并返回
|
||
formatted_menu_items = [
|
||
{"name": item['menu_name'], "path": item['path']} for item in menu_items
|
||
]
|
||
return jsonify(formatted_menu_items)
|
||
|
||
# 如果没有角色信息,可能用户未登录或session过期
|
||
return jsonify([]), 401 # 未授权状态码
|
||
|
||
|
||
@app.route('/home/profile', methods=['GET', 'POST'])
|
||
def profile():
|
||
if request.method == 'POST':
|
||
# 从表单获取数据
|
||
nickname = request.form['nickname']
|
||
avatar = request.files['avatar']
|
||
|
||
# 处理头像和昵称更新逻辑
|
||
# ...
|
||
|
||
return "资料更新成功" # 或者重定向到其他页面
|
||
|
||
# 如果是GET请求,显示表单页面
|
||
return render_template('profile.html') # 确保这里渲染的是包含上面表单的HTML页面
|
||
|
||
|
||
@app.route('/course-info', methods=['GET', 'POST'])
|
||
def course_info():
|
||
if request.method == "GET":
|
||
return render_template('course-info.html')
|
||
|
||
|
||
@app.route('/api/get-course-info', methods=['GET'])
|
||
def get_course_info():
|
||
db_manager = DatabaseManager()
|
||
course_data = db_manager.get_all_courses()
|
||
return jsonify(course_data)
|
||
|
||
|
||
@app.route('/api/get-course-type', methods=['GET'])
|
||
def get_course_type():
|
||
db_manager = DatabaseManager()
|
||
course_data = db_manager.get_course_type()
|
||
# 创建存储必修和选修课程名称的字典
|
||
course_info = {"必修": [], "选修": []}
|
||
for course in course_data:
|
||
if course['course_type'] == '必修':
|
||
course_info["必修"].append(course['course_name'])
|
||
elif course['course_type'] == '选修':
|
||
course_info["选修"].append(course['course_name'])
|
||
|
||
return jsonify(course_info)
|
||
|
||
|
||
@app.route('/api/get-announcement-info', methods=['GET'])
|
||
def get_announcement_info():
|
||
db_manager = DatabaseManager()
|
||
announcement_info = db_manager.get_announcement_info()
|
||
|
||
return jsonify(course_info)
|
||
|
||
|
||
@app.route('/attendance', methods=['GET', 'POST'])
|
||
def course_checkin():
|
||
return render_template('attendance.html')
|
||
|
||
|
||
@app.route('/announcement', methods=['GET', 'POST'])
|
||
def announcement():
|
||
return render_template('announcement.html')
|
||
|
||
|
||
@app.route('/attendance-teacher', methods=['GET', 'POST'])
|
||
def announcement_teacher():
|
||
return render_template('attendance-teacher.html')
|
||
|
||
|
||
@app.route('/attendance-reminder', methods=['GET', 'POST'])
|
||
def attendance_reminder():
|
||
return render_template('attendance-reminder.html')
|
||
|
||
|
||
@app.route('/course-category', methods=['GET', 'POST'])
|
||
def course_category():
|
||
return render_template('course-category.html')
|
||
|
||
|
||
@app.route('/attendance-teacher/import-class', methods=['GET'])
|
||
def import_class():
|
||
return render_template('import-class.html')
|
||
|
||
|
||
@app.route('/attendance-teacher/attendance', methods=['GET'])
|
||
def teacher_attendance():
|
||
return render_template('attendance-teacher.html')
|
||
|
||
|
||
@app.route('/api/get-teacher-attendance-table', methods=['GET'])
|
||
def get_current_teacher_courses():
|
||
number = session.get('number')
|
||
# 获取分页参数
|
||
page = request.args.get('page', 1, type=int) # 如果没有提供,默认为第一页
|
||
limit = request.args.get('limit', 10, type=int) # 如果没有提供,默认每页10条
|
||
|
||
# 获取所有课程数据
|
||
db_manager = DatabaseManager()
|
||
all_course_data = db_manager.get_current_teacher_courses(number)
|
||
logging.info(f"all_course_data: {all_course_data}")
|
||
# 计算分页的起始和结束索引
|
||
start = (page - 1) * limit
|
||
end = start + limit
|
||
|
||
# 获取当前页的数据
|
||
current_page_data = all_course_data[start:end]
|
||
|
||
# 构建响应字典
|
||
response = {
|
||
'msg': 'ok' if current_page_data else 'no_data',
|
||
'count': len(all_course_data), # 数据的总数
|
||
'data': current_page_data # 当前页的课程信息列表
|
||
}
|
||
|
||
# 将查询结果转换为JSON格式并返回
|
||
return jsonify(response)
|
||
|
||
|
||
@app.route('/files/template.xlsx')
|
||
def download_template():
|
||
# 确保这个路径是你的文件实际所在的服务器路径
|
||
path = os.path.join(app.config['FILE_PATH'], "template.xlsx")
|
||
return send_file(path, as_attachment=True)
|
||
|
||
|
||
@app.route('/api/receive-excel', methods=['POST'])
|
||
def receive_excel():
|
||
# 检查是否有文件在请求中
|
||
if 'file' not in request.files:
|
||
return jsonify({"error": "No file part"}), 400
|
||
|
||
file = request.files['file']
|
||
|
||
# 如果用户没有选择文件,浏览器也会提交一个空的文件名
|
||
if file.filename == '':
|
||
return jsonify({"error": "No selected file"}), 400
|
||
|
||
# 检查文件是不是 Excel 文件
|
||
if file and allowed_excel(file.filename):
|
||
try:
|
||
# 使用 openpyxl 读取文件内容
|
||
workbook = openpyxl.load_workbook(file)
|
||
# TODO: 在这里处理你的Excel文件,例如读取数据
|
||
print(workbook)
|
||
return jsonify({"message": "File successfully processed"}), 200
|
||
except Exception as e:
|
||
return jsonify({"error": str(e)}), 500
|
||
else:
|
||
return jsonify({"error": "Invalid file type"}), 400
|
||
|
||
|
||
@app.route('/api/get-course-name', methods=['GET'])
|
||
def get_course_name():
|
||
data = {'course_name': "信息技术"}
|
||
return jsonify({
|
||
'msg': 'ok',
|
||
'data': data
|
||
})
|
||
period_id, period_name = check_now_time() # 获取当前时间段信息
|
||
print(f"period_id: {period_id}, period_name: {period_name}")
|
||
|
||
# 如果当前不在任何时间段内
|
||
if period_id is None:
|
||
return jsonify({
|
||
'msg': period_name, # 返回不在课程时间段内的消息
|
||
'data': None
|
||
})
|
||
|
||
# 获取当前用户编号
|
||
number = session.get('number')
|
||
if not number:
|
||
return jsonify({"msg": "用户未登录或编号不可用", "data": None})
|
||
|
||
# 获取今天是星期几
|
||
day_of_week = datetime.date.today().weekday() + 1
|
||
|
||
# 如果是周末
|
||
if not (1 <= day_of_week <= 5):
|
||
return jsonify({"msg": "周末没有课程", "data": None})
|
||
|
||
# 如果是工作日,获取课程信息
|
||
print(f"day of week: {day_of_week}")
|
||
db_manager = DatabaseManager()
|
||
data = db_manager.get_course_name(number, day_of_week)
|
||
print(data)
|
||
|
||
# 返回课程信息
|
||
return jsonify({
|
||
'msg': 'ok',
|
||
'data': data
|
||
})
|
||
|
||
|
||
@app.route('/api/student-sign-in', methods=['POST'])
|
||
def student_sign_in():
|
||
number = session.get("number")
|
||
print(number)
|
||
return "aaa"
|
||
|
||
if __name__ == '__main__':
|
||
app.run(debug=True)
|