superlishunqin e7fa4bc030 first commit
2025-06-11 19:56:34 +08:00

180 lines
7.0 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from flask import Blueprint, render_template, request, redirect, url_for, flash, session
from flask_login import login_user, logout_user, login_required, current_user
from werkzeug.security import check_password_hash, generate_password_hash
from app.models import db, User, Student
from app.utils.database import safe_commit
from datetime import datetime
import re
auth_bp = Blueprint('auth', __name__)
@auth_bp.route('/login', methods=['GET', 'POST'])
def login():
if current_user.is_authenticated:
if current_user.is_admin():
return redirect(url_for('admin.dashboard'))
else:
return redirect(url_for('student.dashboard'))
if request.method == 'POST':
student_number = request.form.get('student_number', '').strip()
password = request.form.get('password', '')
remember = request.form.get('remember', False)
if not student_number or not password:
flash('请输入学号和密码', 'error')
return render_template('auth/login.html')
# 查找用户
user = User.query.filter_by(student_number=student_number).first()
if user and user.check_password(password):
if not user.is_active:
flash('账户已被禁用,请联系管理员', 'error')
return render_template('auth/login.html')
# 更新最后登录时间
user.last_login = datetime.utcnow()
success, error = safe_commit()
if not success:
flash('系统错误,请稍后重试', 'error')
return render_template('auth/login.html')
login_user(user, remember=remember)
# 获取重定向地址
next_page = request.args.get('next')
if next_page:
return redirect(next_page)
# 根据用户角色重定向
if user.is_admin():
flash(f'欢迎回来,管理员!', 'success')
return redirect(url_for('admin.dashboard'))
else:
# 获取学生姓名
student = Student.query.filter_by(student_number=student_number).first()
name = student.name if student else student_number
flash(f'欢迎回来,{name}', 'success')
return redirect(url_for('student.dashboard'))
else:
flash('学号或密码错误', 'error')
return render_template('auth/login.html')
@auth_bp.route('/logout')
@login_required
def logout():
logout_user()
flash('您已成功退出登录', 'info')
return redirect(url_for('auth.login'))
@auth_bp.route('/change_password', methods=['GET', 'POST'])
@login_required
def change_password():
if request.method == 'POST':
current_password = request.form.get('current_password', '')
new_password = request.form.get('new_password', '')
confirm_password = request.form.get('confirm_password', '')
# 验证输入
if not all([current_password, new_password, confirm_password]):
flash('请填写所有密码字段', 'error')
return render_template('auth/change_password.html')
# 验证当前密码
if not current_user.check_password(current_password):
flash('当前密码不正确', 'error')
return render_template('auth/change_password.html')
# 验证新密码与确认密码是否一致
if new_password != confirm_password:
flash('新密码与确认密码不匹配', 'error')
return render_template('auth/change_password.html')
# 密码长度验证
if len(new_password) < 6:
flash('新密码长度至少6位', 'error')
return render_template('auth/change_password.html')
# 密码复杂度验证(可选)
if not re.search(r'^(?=.*[a-zA-Z])(?=.*\d).+$', new_password):
flash('新密码必须包含字母和数字', 'error')
return render_template('auth/change_password.html')
# 检查新密码是否与当前密码相同
if current_user.check_password(new_password):
flash('新密码不能与当前密码相同', 'error')
return render_template('auth/change_password.html')
try:
# 更新密码
current_user.set_password(new_password)
success, error = safe_commit()
if success:
flash('密码修改成功', 'success')
# 根据用户角色重定向
if current_user.is_admin():
return redirect(url_for('auth.profile'))
else:
return redirect(url_for('auth.profile'))
else:
flash(f'密码修改失败: {error}', 'error')
except Exception as e:
flash(f'密码修改失败: {str(e)}', 'error')
return render_template('auth/change_password.html')
@auth_bp.route('/profile')
@login_required
def profile():
"""用户个人信息页面"""
try:
if current_user.is_admin():
# 管理员信息页面
user_info = {
'user_id': current_user.user_id,
'student_number': current_user.student_number,
'role': current_user.role,
'is_active': current_user.is_active,
'last_login': current_user.last_login,
'created_at': current_user.created_at
}
return render_template('auth/admin_profile.html', user_info=user_info)
else:
# 学生信息页面
student = Student.query.filter_by(student_number=current_user.student_number).first()
user_info = {
'user_id': current_user.user_id,
'student_number': current_user.student_number,
'role': current_user.role,
'is_active': current_user.is_active,
'last_login': current_user.last_login,
'created_at': current_user.created_at,
# 学生特有信息
'name': student.name if student else None,
'gender': student.gender if student else None,
'grade': student.grade if student else None,
'phone': student.phone if student else None,
'supervisor': student.supervisor if student else None,
'college': student.college if student else None,
'major': student.major if student else None,
'degree_type': student.degree_type if student else None,
'status': student.status if student else None,
'enrollment_date': student.enrollment_date if student else None
}
return render_template('auth/student_profile.html', user_info=user_info, student=student)
except Exception as e:
flash(f'获取个人信息失败: {str(e)}', 'error')
if current_user.is_admin():
return redirect(url_for('admin.dashboard'))
else:
return redirect(url_for('student.dashboard'))