106 lines
3.6 KiB
Python
106 lines
3.6 KiB
Python
# 创建Web蓝图
|
||
from flask import Blueprint, render_template, request, redirect, url_for, session, flash, jsonify
|
||
from flask_login import login_user, logout_user, login_required, current_user
|
||
from app.models.admin import Admin
|
||
from app import db
|
||
|
||
web_bp = Blueprint('web', __name__)
|
||
user_bp = Blueprint('user', __name__, url_prefix='/index')
|
||
|
||
@web_bp.route('/')
|
||
def index():
|
||
"""首页 - 重定向到前端主页"""
|
||
return redirect(url_for('user.user_index'))
|
||
|
||
@web_bp.route('/login', methods=['GET', 'POST'])
|
||
def login():
|
||
"""登录页面"""
|
||
if request.method == 'POST':
|
||
# 检查CSRF令牌
|
||
if not request.form.get('csrf_token'):
|
||
if request.headers.get('X-Requested-With') == 'XMLHttpRequest':
|
||
return jsonify({
|
||
'success': False,
|
||
'message': '缺少CSRF令牌'
|
||
}), 400
|
||
flash('缺少CSRF令牌', 'error')
|
||
return render_template('login.html')
|
||
|
||
username = request.form.get('username', '').strip()
|
||
password = request.form.get('password', '')
|
||
|
||
if not username or not password:
|
||
# 对于AJAX请求,返回JSON错误
|
||
if request.headers.get('X-Requested-With') == 'XMLHttpRequest':
|
||
return jsonify({
|
||
'success': False,
|
||
'message': '请输入用户名和密码'
|
||
}), 400
|
||
# 对于普通表单提交,使用flash消息
|
||
flash('请输入用户名和密码', 'error')
|
||
return render_template('login.html')
|
||
|
||
# 查找用户
|
||
admin = Admin.query.filter_by(username=username).first()
|
||
if admin and admin.check_password(password) and admin.is_active:
|
||
# 登录成功
|
||
login_user(admin, remember=True)
|
||
|
||
# 更新最后登录信息
|
||
admin.update_last_login(request.remote_addr)
|
||
|
||
# 生成简单的token(实际项目中应使用JWT)
|
||
import secrets
|
||
token = secrets.token_urlsafe(32)
|
||
|
||
# 如果是AJAX请求,返回JSON
|
||
if request.headers.get('X-Requested-With') == 'XMLHttpRequest':
|
||
return jsonify({
|
||
'success': True,
|
||
'token': token,
|
||
'user': {
|
||
'username': admin.username,
|
||
'role': admin.role,
|
||
'is_super_admin': admin.is_super_admin()
|
||
},
|
||
'redirect': url_for('web.dashboard')
|
||
})
|
||
|
||
# 获取next参数
|
||
next_page = request.args.get('next')
|
||
if next_page:
|
||
return redirect(next_page)
|
||
return redirect(url_for('web.dashboard'))
|
||
else:
|
||
# 登录失败
|
||
if request.headers.get('X-Requested-With') == 'XMLHttpRequest':
|
||
return jsonify({
|
||
'success': False,
|
||
'message': '用户名或密码错误'
|
||
}), 401
|
||
flash('用户名或密码错误', 'error')
|
||
|
||
return render_template('login.html')
|
||
|
||
@web_bp.route('/logout')
|
||
@login_required
|
||
def logout():
|
||
"""退出登录"""
|
||
logout_user()
|
||
flash('已退出登录', 'info')
|
||
return redirect(url_for('web.login'))
|
||
|
||
@web_bp.route('/dashboard')
|
||
@login_required
|
||
def dashboard():
|
||
"""仪表板"""
|
||
return render_template('dashboard.html')
|
||
|
||
@web_bp.route('/favicon.ico')
|
||
def favicon():
|
||
"""Favicon 处理 - 返回空响应避免404错误"""
|
||
from flask import Response
|
||
return Response(status=204) # No Content
|
||
|
||
# 导入视图函数
|
||
from . import views, user_views |