218 lines
8.9 KiB
Python
218 lines
8.9 KiB
Python
"""系统管理路由:用户、角色、操作日志、课程安排"""
|
|
from datetime import datetime, date
|
|
from flask import render_template, request, redirect, url_for, flash, session
|
|
from models import (db, User, Role, OperationLog, Course, Teacher, Class_, Schedule)
|
|
from utils import login_required, log_operation, permission_required, export_excel, PERMISSIONS, PERMISSION_GROUPS
|
|
|
|
|
|
def _build_permissions_dict():
|
|
"""构建模板所需的嵌套权限字典结构"""
|
|
result = {}
|
|
for i, (module_name, perm_keys) in enumerate(PERMISSION_GROUPS):
|
|
module_key = f'module_{i}'
|
|
result[module_key] = {
|
|
'label': module_name,
|
|
'permissions': {k: PERMISSIONS[k] for k in perm_keys if k in PERMISSIONS}
|
|
}
|
|
return result
|
|
|
|
|
|
def register_routes(app):
|
|
|
|
# ==================== 用户管理 ====================
|
|
|
|
@app.route('/users', endpoint='user_list')
|
|
@login_required
|
|
@permission_required('user_view')
|
|
def user_list():
|
|
users = User.query.order_by(User.id).all()
|
|
roles = {r.id: r.name for r in Role.query.all()}
|
|
return render_template('user_list.html', users=users, roles=roles)
|
|
|
|
@app.route('/users/add', methods=['GET', 'POST'], endpoint='user_add')
|
|
@login_required
|
|
@permission_required('user_add')
|
|
def user_add():
|
|
if request.method == 'POST':
|
|
username = request.form.get('username')
|
|
password = request.form.get('password')
|
|
real_name = request.form.get('real_name')
|
|
role_id = request.form.get('role_id')
|
|
remark = request.form.get('remark', '')
|
|
|
|
if User.query.filter_by(username=username).first():
|
|
flash('用户名已存在', 'danger')
|
|
return redirect(url_for('user_add'))
|
|
|
|
user = User(username=username, real_name=real_name,
|
|
role_id=role_id, status=1, remark=remark)
|
|
user.set_password(password)
|
|
db.session.add(user)
|
|
db.session.commit()
|
|
log_operation('创建用户', f'用户名:{username}')
|
|
flash('用户创建成功', 'success')
|
|
return redirect(url_for('user_list'))
|
|
|
|
roles = Role.query.all()
|
|
return render_template('user_form.html', roles=roles, user=None)
|
|
|
|
@app.route('/users/edit/<int:user_id>', methods=['GET', 'POST'], endpoint='user_edit')
|
|
@login_required
|
|
@permission_required('user_edit')
|
|
def user_edit(user_id):
|
|
user = db.session.get(User, user_id)
|
|
if request.method == 'POST':
|
|
user.real_name = request.form.get('real_name')
|
|
user.role_id = request.form.get('role_id')
|
|
user.status = int(request.form.get('status', 1))
|
|
user.remark = request.form.get('remark', '')
|
|
password = request.form.get('password')
|
|
if password:
|
|
user.set_password(password)
|
|
db.session.commit()
|
|
log_operation('编辑用户', f'用户ID:{user_id}')
|
|
flash('用户更新成功', 'success')
|
|
return redirect(url_for('user_list'))
|
|
|
|
roles = Role.query.all()
|
|
return render_template('user_form.html', roles=roles, user=user)
|
|
|
|
# ==================== 角色管理 ====================
|
|
|
|
@app.route('/roles', endpoint='role_list')
|
|
@login_required
|
|
@permission_required('role_view')
|
|
def role_list():
|
|
roles = Role.query.order_by(Role.id).all()
|
|
return render_template('role_list.html', roles=roles)
|
|
|
|
@app.route('/roles/add', methods=['GET', 'POST'], endpoint='role_add')
|
|
@login_required
|
|
@permission_required('role_add')
|
|
def role_add():
|
|
if request.method == 'POST':
|
|
name = request.form.get('name')
|
|
permissions_list = request.form.getlist('permissions')
|
|
permissions = ','.join(permissions_list)
|
|
remark = request.form.get('remark', '')
|
|
role = Role(name=name, permissions=permissions, remark=remark)
|
|
db.session.add(role)
|
|
db.session.commit()
|
|
log_operation('创建角色', f'角色:{name}')
|
|
flash('角色创建成功', 'success')
|
|
return redirect(url_for('role_list'))
|
|
|
|
return render_template('role_form.html', role=None, PERMISSIONS=_build_permissions_dict())
|
|
|
|
@app.route('/roles/edit/<int:role_id>', methods=['GET', 'POST'], endpoint='role_edit')
|
|
@login_required
|
|
@permission_required('role_edit')
|
|
def role_edit(role_id):
|
|
role = db.session.get(Role, role_id)
|
|
if request.method == 'POST':
|
|
role.name = request.form.get('name')
|
|
permissions_list = request.form.getlist('permissions')
|
|
role.permissions = ','.join(permissions_list)
|
|
role.remark = request.form.get('remark', '')
|
|
db.session.commit()
|
|
log_operation('编辑角色', f'角色ID:{role_id}')
|
|
flash('角色更新成功', 'success')
|
|
return redirect(url_for('role_list'))
|
|
|
|
return render_template('role_form.html', role=role, PERMISSIONS=_build_permissions_dict())
|
|
|
|
@app.route('/roles/delete/<int:role_id>', methods=['POST'], endpoint='role_delete')
|
|
@login_required
|
|
@permission_required('role_delete')
|
|
def role_delete(role_id):
|
|
role = db.session.get(Role, role_id)
|
|
if not role:
|
|
flash('角色不存在', 'danger')
|
|
return redirect(url_for('role_list'))
|
|
if role.name == '超级管理员':
|
|
flash('不能删除超级管理员角色', 'danger')
|
|
return redirect(url_for('role_list'))
|
|
if User.query.filter_by(role_id=role_id).first():
|
|
flash('该角色下仍有用户,无法删除', 'danger')
|
|
return redirect(url_for('role_list'))
|
|
db.session.delete(role)
|
|
db.session.commit()
|
|
log_operation('删除角色', f'角色:{role.name}')
|
|
flash('角色已删除', 'success')
|
|
return redirect(url_for('role_list'))
|
|
|
|
# ==================== 操作日志 ====================
|
|
|
|
@app.route('/operation_logs', endpoint='log_list')
|
|
@login_required
|
|
@permission_required('log_view')
|
|
def log_list():
|
|
keyword = request.args.get('keyword', '')
|
|
page = request.args.get('page', 1, type=int)
|
|
per_page = 20
|
|
query = OperationLog.query
|
|
if keyword:
|
|
query = query.filter(
|
|
db.or_(
|
|
OperationLog.operation_type.contains(keyword),
|
|
OperationLog.operation_detail.contains(keyword),
|
|
)
|
|
)
|
|
total = query.count()
|
|
logs = query.order_by(OperationLog.created_at.desc()).offset((page - 1) * per_page).limit(per_page).all()
|
|
return render_template('log_list.html', logs=logs, keyword=keyword,
|
|
total=total, page=page, per_page=per_page)
|
|
|
|
# ==================== 课程安排 ====================
|
|
|
|
@app.route('/schedules', endpoint='schedule_list')
|
|
@login_required
|
|
@permission_required('schedule_view')
|
|
def schedule_list():
|
|
schedules = Schedule.query.order_by(Schedule.date.desc()).all()
|
|
return render_template('schedule_list.html', schedules=schedules)
|
|
|
|
@app.route('/schedules/add', methods=['GET', 'POST'], endpoint='schedule_add')
|
|
@login_required
|
|
@permission_required('schedule_add')
|
|
def schedule_add():
|
|
if request.method == 'POST':
|
|
class_id = request.form.get('class_id')
|
|
teacher_id = request.form.get('teacher_id')
|
|
schedule_date = request.form.get('date')
|
|
start_time = request.form.get('start_time')
|
|
end_time = request.form.get('end_time')
|
|
topic = request.form.get('topic', '')
|
|
remark = request.form.get('remark', '')
|
|
|
|
schedule = Schedule(
|
|
class_id=class_id, teacher_id=teacher_id,
|
|
date=datetime.strptime(schedule_date, '%Y-%m-%d').date() if schedule_date else date.today(),
|
|
start_time=start_time, end_time=end_time,
|
|
topic=topic or remark,
|
|
)
|
|
db.session.add(schedule)
|
|
db.session.commit()
|
|
log_operation('创建课程安排', f'班级ID:{class_id} 日期:{schedule_date}')
|
|
flash('课程安排创建成功', 'success')
|
|
return redirect(url_for('schedule_list'))
|
|
|
|
classes = Class_.query.filter_by(status=1).all()
|
|
teachers = Teacher.query.filter_by(status=1).all()
|
|
return render_template('schedule_form.html', classes=classes, teachers=teachers)
|
|
|
|
|
|
@app.route('/schedules/export', endpoint='schedule_export')
|
|
@login_required
|
|
@permission_required('schedule_export')
|
|
def schedule_export():
|
|
from utils import export_schedules as do_export
|
|
return do_export()
|
|
|
|
@app.route('/operation_logs/export', endpoint='log_export')
|
|
@login_required
|
|
@permission_required('log_export')
|
|
def operation_log_export():
|
|
from utils import export_operation_logs as do_export
|
|
return do_export()
|