import os import openpyxl as openpyxl from flask import Flask, redirect, url_for, render_template, session, jsonify, request, send_file 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 if __name__ == '__main__': app.run(debug=True)