Files
drl_2/xuexiao/routes/class_.py
user9994793890 ee860ce0ae Initial commit
2026-05-29 10:28:07 +08:00

181 lines
8.5 KiB
Python

"""班级管理和考勤路由"""
from datetime import date
from flask import render_template, request, redirect, url_for, flash, session
from models import (db, Class_, Course, Teacher, Student, ClassStudent,
StudentAccount, AttendanceRecord)
from utils import (
login_required, log_operation, permission_required, export_excel,
filter_classes_query, filter_students_query, teacher_can_access_class,
)
def register_routes(app):
@app.route('/classes', endpoint='class_list')
@login_required
@permission_required('class_view')
def class_list():
keyword = request.args.get('keyword', '')
query = filter_classes_query(Class_.query)
if keyword:
query = query.filter(Class_.name.contains(keyword))
classes = query.order_by(Class_.id.desc()).all()
courses = {c.id: c.name for c in Course.query.all()}
teachers = {t.id: t.name for t in Teacher.query.all()}
return render_template('class_list.html', classes=classes,
courses=courses, teachers=teachers, keyword=keyword)
@app.route('/classes/add', methods=['GET', 'POST'], endpoint='class_add')
@login_required
@permission_required('class_add')
def class_add():
if request.method == 'POST':
cls = Class_(
name=request.form.get('name'),
course_id=int(request.form.get('course_id')),
teacher_id=int(request.form.get('teacher_id')),
max_students=int(request.form.get('max_students', 20)),
status=int(request.form.get('status', 1)),
remark=request.form.get('remark', '')
)
db.session.add(cls)
db.session.commit()
log_operation('创建班级', f'班级:{cls.name}')
flash('班级创建成功', 'success')
return redirect(url_for('class_list'))
courses = Course.query.filter_by(status=1).all()
teachers = Teacher.query.filter_by(status=1).all()
return render_template('class_form.html', class_=None,
courses=courses, teachers=teachers)
@app.route('/classes/edit/<int:id>', methods=['GET', 'POST'], endpoint='class_edit')
@login_required
@permission_required('class_edit')
def class_edit(id):
cls = db.session.get(Class_, id)
if request.method == 'POST':
cls.name = request.form.get('name')
cls.course_id = int(request.form.get('course_id'))
cls.teacher_id = int(request.form.get('teacher_id'))
cls.max_students = int(request.form.get('max_students', 20))
cls.status = int(request.form.get('status', 1))
cls.remark = request.form.get('remark', '')
db.session.commit()
log_operation('编辑班级', f'班级ID:{id}')
flash('班级更新成功', 'success')
return redirect(url_for('class_list'))
courses = Course.query.filter_by(status=1).all()
teachers = Teacher.query.filter_by(status=1).all()
return render_template('class_form.html', class_=cls,
courses=courses, teachers=teachers)
@app.route('/classes/detail/<int:id>', endpoint='class_detail')
@login_required
@permission_required('class_view')
def class_detail(id):
cls = db.session.get(Class_, id)
if not cls:
flash('班级不存在', 'danger')
return redirect(url_for('class_list'))
course = db.session.get(Course, cls.course_id) if cls else None
teacher = db.session.get(Teacher, cls.teacher_id) if cls else None
class_students = ClassStudent.query.filter_by(class_id=id, status=1).all()
attendance_records = (
AttendanceRecord.query.filter_by(class_id=id)
.order_by(AttendanceRecord.date.desc(), AttendanceRecord.id.desc())
.limit(20)
.all()
)
student_ids = [cs.student_id for cs in class_students]
students = {s.id: s for s in Student.query.filter(Student.id.in_(student_ids)).all()} if student_ids else {}
# 计算可用学生(未在该班级的)
enrolled_ids = set(student_ids)
base = filter_students_query(Student.query.filter_by(status=1))
available_students = base.filter(~Student.id.in_(enrolled_ids)).all() if enrolled_ids else base.all()
return render_template('class_detail.html', class_=cls, course=course,
teacher=teacher, class_students=class_students,
students=students, available_students=available_students,
attendance_records=attendance_records)
@app.route('/classes/<int:class_id>/add_student', methods=['POST'], endpoint='class_add_student')
@login_required
@permission_required('class_edit')
def class_add_student(class_id):
student_id = int(request.form.get('student_id'))
existing = ClassStudent.query.filter_by(class_id=class_id,
student_id=student_id, status=1).first()
if existing:
flash('该学员已在班级中', 'warning')
else:
cs = ClassStudent(class_id=class_id, student_id=student_id,
join_date=date.today(), status=1)
db.session.add(cs)
db.session.commit()
log_operation('添加班级学员', f'班级ID:{class_id} 学员ID:{student_id}')
flash('学员添加成功', 'success')
return redirect(url_for('class_detail', id=class_id))
@app.route('/classes/<int:class_id>/remove_student/<int:student_id>', endpoint='class_remove_student')
@login_required
@permission_required('class_edit')
def class_remove_student(class_id, student_id):
cs = ClassStudent.query.filter_by(class_id=class_id,
student_id=student_id, status=1).first()
if cs:
cs.status = 0
db.session.commit()
log_operation('移除班级学员', f'班级ID:{class_id} 学员ID:{student_id}')
flash('学员已移除', 'success')
return redirect(url_for('class_detail', id=class_id))
@app.route('/classes/<int:class_id>/attendance', methods=['GET', 'POST'], endpoint='class_attendance')
@login_required
@permission_required('attendance_add')
def class_attendance(class_id):
cls = db.session.get(Class_, class_id)
if not cls:
flash('班级不存在', 'danger')
return redirect(url_for('class_list'))
class_students = ClassStudent.query.filter_by(class_id=class_id, status=1).all()
student_ids = [cs.student_id for cs in class_students]
students = {s.id: s for s in Student.query.filter(Student.id.in_(student_ids)).all()} if student_ids else {}
if request.method == 'POST':
att_date_str = request.form.get('att_date') or date.today().isoformat()
att_date = __import__('datetime').datetime.strptime(att_date_str, '%Y-%m-%d').date()
for cs in class_students:
status = request.form.get(f'status_{cs.student_id}', 'present')
remark = request.form.get(f'remark_{cs.student_id}', '')
record = AttendanceRecord(
class_id=class_id, student_id=cs.student_id,
date=att_date, status=status, remark=remark
)
db.session.add(record)
db.session.commit()
log_operation('考勤录入', f'班级ID:{class_id} 日期:{att_date_str}')
flash('考勤录入成功', 'success')
return redirect(url_for('class_detail', id=class_id))
return render_template('attendance_form.html', class_=cls,
class_students=class_students, students=students,
today=date.today().isoformat())
@app.route('/attendance', endpoint='attendance_select')
@login_required
@permission_required('attendance_view')
def attendance_select():
"""考勤入口:选择班级"""
classes = filter_classes_query(Class_.query.filter_by(status=1)).all()
courses = {c.id: c.name for c in Course.query.all()}
return render_template('attendance_select.html', classes=classes, courses=courses)
@app.route('/classes/export', endpoint='class_export')
@login_required
@permission_required('class_export')
def class_export():
from utils import export_classes as do_export
return do_export()