from flask import Blueprint, render_template, request, redirect, url_for, flash, session, jsonify from app.forms import LoginForm, RegisterForm from app.models.user import User from app.models.verification import EmailVerification from app.utils.email_service import send_verification_email from config.database import db auth_bp = Blueprint('auth', __name__, url_prefix='/auth') @auth_bp.route('/login', methods=['GET', 'POST']) def login(): """用户登录""" if 'user_id' in session: return redirect(url_for('main.index')) form = LoginForm() if form.validate_on_submit(): username = form.username.data password = form.password.data # 支持用户名、手机号、邮箱登录 user = User.query.filter( (User.username == username) | (User.phone == username) | (User.email == username) ).first() if user and user.check_password(password): if user.status == 0: flash('账户已被禁用,请联系管理员', 'error') return render_template('user/login.html', form=form) # 登录成功,设置session session['user_id'] = user.id session['username'] = user.username session['nickname'] = user.nickname or user.username session.permanent = form.remember_me.data flash(f'欢迎回来,{user.nickname or user.username}!', 'success') # 获取登录前的页面 next_page = request.args.get('next') if next_page: return redirect(next_page) return redirect(url_for('main.index')) else: flash('用户名或密码错误', 'error') return render_template('user/login.html', form=form) @auth_bp.route('/send_email_code', methods=['POST']) def send_email_code(): """发送邮箱验证码""" try: data = request.get_json() email = data.get('email') code_type = data.get('type', 1) # 默认为注册类型 if not email: return jsonify({'success': False, 'message': '邮箱地址不能为空'}) # 检查邮箱格式 import re email_pattern = r'^[^\s@]+@[^\s@]+\.[^\s@]+$' if not re.match(email_pattern, email): return jsonify({'success': False, 'message': '邮箱格式不正确'}) # 如果是注册,检查邮箱是否已被注册 if code_type == 1: existing_user = User.query.filter_by(email=email).first() if existing_user: return jsonify({'success': False, 'message': '该邮箱已被注册'}) # 检查是否频繁发送(1分钟内只能发送一次) from datetime import datetime, timedelta recent_code = EmailVerification.query.filter_by( email=email, type=code_type ).filter( EmailVerification.created_at > datetime.utcnow() - timedelta(minutes=1) ).first() if recent_code: return jsonify({'success': False, 'message': '发送过于频繁,请稍后再试'}) # 创建验证码 verification = EmailVerification.create_verification(email, code_type) # 发送邮件 send_verification_email(email, verification.code, code_type) return jsonify({'success': True, 'message': '验证码已发送'}) except Exception as e: print(f"发送邮箱验证码错误: {e}") return jsonify({'success': False, 'message': '发送失败,请重试'}) @auth_bp.route('/register', methods=['GET', 'POST']) def register(): """用户注册""" if 'user_id' in session: return redirect(url_for('main.index')) form = RegisterForm() if form.validate_on_submit(): try: # 验证邮箱验证码 if not EmailVerification.verify_code(form.email.data, form.email_code.data, 1): flash('邮箱验证码错误或已过期', 'error') return render_template('user/register.html', form=form) user = User( username=form.username.data, email=form.email.data, phone=form.phone.data, nickname=form.username.data ) user.set_password(form.password.data) db.session.add(user) db.session.commit() flash('注册成功!请登录', 'success') return redirect(url_for('auth.login')) except Exception as e: db.session.rollback() flash('注册失败,请重试', 'error') print(f"注册错误: {e}") return render_template('user/register.html', form=form) @auth_bp.route('/logout') def logout(): """用户登出""" session.clear() flash('您已成功登出', 'info') return redirect(url_for('main.index'))