2025-07-04 19:07:35 +08:00

142 lines
4.8 KiB
Python
Raw Permalink 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, 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'))