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'))