This repository has been archived on 2024-09-30. You can view files and clone it, but cannot push or open issues/pull-requests.
SmartRollCall/app/views.py

401 lines
12 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

import os
import logging
# 第三方库
import openpyxl
from flask import Flask, redirect, url_for, render_template, session, jsonify, request, send_file
from datetime import datetime
# 应用内部模块
from utils.time_utils import check_now_time
from utils.allowed_files import allowed_excel
from db.connection import MySQLPool
from db.database_manager import DatabaseManager
from models.Student import Student
from models.Teacher import Teacher
from models.User import User
from config import SECRET_KEY, LOGGING_CONFIG, 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():
student_number = session.get('number')
db_manager = DatabaseManager()
if check_identity(student_number) == "student":
course_data = db_manager.get_class_courses(student_number)
return jsonify(course_data)
else:
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)
print(all_course_data)
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():
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})
# 获取今天是星期几
now = datetime.now()
day_of_week = now.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, period_id)
print(data)
# 返回课程信息
return jsonify({
'msg': 'ok',
'data': data
})
@app.route('/api/student-sign-in', methods=['POST'])
def student_sign_in():
number = session.get("number")
course_name = request.form.get('course_name')
course_id = request.form.get('course_id')
now = datetime.now()
date = now.strftime("%Y年%m月%d%H:%M")
status = "出勤"
print(f"number: {number},course_name: {course_name},course_id: {course_id}")
db_manager = DatabaseManager()
result = db_manager.update_sign_in_info(number, course_id, course_name, date, status)
if result == 1:
return jsonify({"msg": "ok", "data": "签到成功!"})
else:
return jsonify({"msg": "fail", "data": "签到失败!"})
@app.route('/api/get-today-courses')
def student_get_today_courses():
number = session.get('number')
if not number:
return jsonify({"msg": "用户未登录或编号不可用", "data": None})
# 获取今天是星期几
now = datetime.now() # 获取当前时间
day_of_week = now.weekday() + 1
# 如果是周末
if not (1 <= day_of_week <= 5):
return jsonify({"msg": "周末没有课程", "data": None})
db_manager = DatabaseManager()
data = db_manager.student_get_today_courses(number, day_of_week)
# 返回课程信息
return jsonify({
'msg': 'ok',
'data': data
})
@app.route('/api/teacher-sign-in', methods=['POST'])
def teacher_sign_in():
course_id = request.form['course_id']
course_name = request.form['course_name']
class_name = request.form['class_name']
major_id = request.form['major_id']
now = datetime.now()
date = now.strftime("%Y年%m月%d%H:%M")
status = "出勤"
print(f"course_id: {course_id},course_name: {course_name},class_name: {class_name},major_id: {major_id}")
db_manager = DatabaseManager()
data = db_manager.teacher_sign_in(course_id, course_name, class_name, major_id,date,status)
return data
if __name__ == '__main__':
app.run(debug=True)