fix_bug_login_and_user

This commit is contained in:
superlishunqin 2025-05-01 22:34:54 +08:00
parent 4f06468ec9
commit 5f46d87528
10 changed files with 131 additions and 13 deletions

View File

@ -1,4 +1,4 @@
from flask import Flask, render_template, session, g, Markup
from flask import Flask, render_template, session, g, Markup, redirect, url_for
from flask_login import LoginManager
from app.models.user import db, User
from app.controllers.user import user_bp
@ -118,7 +118,7 @@ def create_app(config=None):
@app.route('/')
def index():
if not current_user.is_authenticated:
return render_template('login.html')
return redirect(url_for('user.login'))
return render_template('index.html') # 无需传递current_userFlask-Login自动提供
@app.errorhandler(404)

View File

@ -2,6 +2,7 @@ from flask import Blueprint, render_template, request, redirect, url_for, flash,
from app.models.book import Book, Category
from app.models.user import db
from app.utils.auth import login_required, admin_required
from flask_login import current_user, login_required
import os
from werkzeug.utils import secure_filename
import datetime
@ -14,6 +15,7 @@ book_bp = Blueprint('book', __name__)
@login_required
@admin_required
def admin_book_list():
print(f"DEBUG: admin_book_list 函数被调用,用户={current_user.username},认证状态={current_user.is_authenticated}")
page = request.args.get('page', 1, type=int)
per_page = request.args.get('per_page', 10, type=int)
# 只显示状态为1的图书未下架的图书
@ -128,7 +130,6 @@ def book_detail(book_id):
)
# 添加图书页面
# 添加图书页面
@book_bp.route('/add', methods=['GET', 'POST'])
@login_required
@ -193,7 +194,7 @@ def add_book():
ext = '.jpg' # 默认扩展名
filename = f"{uuid.uuid4()}{ext}"
upload_folder = os.path.join(current_app.static_folder, 'uploads', 'covers')
upload_folder = os.path.join(current_app.static_folder, 'covers')
# 确保上传目录存在
if not os.path.exists(upload_folder):
@ -201,7 +202,7 @@ def add_book():
file_path = os.path.join(upload_folder, filename)
cover_file.save(file_path)
cover_url = f'/static/uploads/covers/{filename}'
cover_url = f'/static/covers/{filename}'
except Exception as e:
current_app.logger.error(f"封面上传失败: {str(e)}")
flash(f"封面上传失败: {str(e)}", 'warning')
@ -322,7 +323,7 @@ def edit_book(book_id):
cover_file = request.files['cover']
if cover_file and cover_file.filename != '':
filename = secure_filename(f"{uuid.uuid4()}_{cover_file.filename}")
upload_folder = os.path.join(current_app.static_folder, 'uploads/covers')
upload_folder = os.path.join(current_app.static_folder, 'covers')
# 确保上传目录存在
if not os.path.exists(upload_folder):
@ -606,3 +607,18 @@ def export_books():
# 提供下载链接
return redirect(url_for('static', filename=f'temp/{filename}'))
@book_bp.route('/test-permissions')
def test_permissions():
"""测试当前用户权限"""
if not current_user.is_authenticated:
return "未登录"
return f"""
<h1>用户权限信息</h1>
<p>用户名: {current_user.username}</p>
<p>角色ID: {current_user.role_id}</p>
<p>是否管理员: {'' if current_user.role_id == 1 else ''}</p>
<p><a href="/book/admin/list">尝试访问管理页面</a></p>
"""

View File

@ -1,4 +1,5 @@
from flask import Blueprint, request, redirect, url_for, flash, g
from flask import Blueprint, request, redirect, url_for, flash, g, jsonify
from flask_login import current_user, login_required
from app.models.book import Book
from app.models.borrow import BorrowRecord
from app.models.inventory import InventoryLog
@ -80,3 +81,80 @@ def borrow_book():
flash(f'借阅失败: {str(e)}', 'danger')
return redirect(url_for('book.book_detail', book_id=book_id))
@borrow_bp.route('/add/<int:book_id>', methods=['POST'])
@login_required
def add_borrow(book_id):
# 验证图书存在
book = Book.query.get_or_404(book_id)
# 默认借阅天数
borrow_days = 14
# 检查库存
if book.stock <= 0:
return jsonify({
'success': False,
'message': f'{book.title}》当前无库存,无法借阅'
})
# 检查是否已借阅
existing_borrow = BorrowRecord.query.filter_by(
user_id=current_user.id, # 使用current_user
book_id=book_id,
status=1 # 1表示借阅中
).first()
if existing_borrow:
return jsonify({
'success': False,
'message': f'您已借阅《{book.title}》,请勿重复借阅'
})
try:
# 创建借阅记录
now = datetime.datetime.now()
due_date = now + datetime.timedelta(days=borrow_days)
borrow_record = BorrowRecord(
user_id=current_user.id, # 使用current_user
book_id=book_id,
borrow_date=now,
due_date=due_date,
status=1, # 1表示借阅中
created_at=now,
updated_at=now
)
# 更新图书库存
book.stock -= 1
book.updated_at = now
db.session.add(borrow_record)
db.session.commit()
# 添加库存变更日志
inventory_log = InventoryLog(
book_id=book_id,
change_type='借出',
change_amount=-1,
after_stock=book.stock,
operator_id=current_user.id, # 使用current_user
remark='用户借书',
changed_at=now
)
db.session.add(inventory_log)
db.session.commit()
return jsonify({
'success': True,
'message': f'成功借阅《{book.title}》,请在 {due_date.strftime("%Y-%m-%d")} 前归还'
})
except Exception as e:
db.session.rollback()
return jsonify({
'success': False,
'message': f'借阅失败: {str(e)}'
})

View File

@ -53,9 +53,19 @@ verification_codes = VerificationStore()
def admin_required(f):
@wraps(f)
def decorated_function(*args, **kwargs):
if not current_user.is_authenticated or current_user.role_id != 1:
flash('您没有管理员权限', 'error')
print(
f"DEBUG: admin_required检查用户认证={current_user.is_authenticated}角色ID={current_user.role_id if current_user.is_authenticated else 'None'}")
if not current_user.is_authenticated:
print("DEBUG: 用户未登录,重定向到登录页面")
return redirect(url_for('user.login', next=request.url))
if current_user.role_id != 1:
print(f"DEBUG: 用户{current_user.username}不是管理员角色ID={current_user.role_id}")
flash('您没有管理员权限访问此页面', 'error')
return redirect(url_for('index'))
print(f"DEBUG: 用户{current_user.username}是管理员,允许访问")
return f(*args, **kwargs)
return decorated_function
@ -63,8 +73,21 @@ def admin_required(f):
@user_bp.route('/login', methods=['GET', 'POST'])
def login():
# 如果用户已经登录,直接重定向到首页
print(f"DEBUG: 登录函数被调用,认证状态={current_user.is_authenticated}")
print(f"DEBUG: 请求方法={request.method}next参数={request.args.get('next')}")
# 获取next参数
next_page = request.args.get('next')
# 如果用户已经登录,处理重定向
if current_user.is_authenticated:
if next_page:
from urllib.parse import urlparse
parsed = urlparse(next_page)
path = parsed.path
print(f"DEBUG: 提取的路径={path}")
# 删除特殊处理直接重定向到path
return redirect(path)
return redirect(url_for('index'))
if request.method == 'POST':
@ -363,6 +386,8 @@ def get_role_user_count(role_id):
count = User.query.filter_by(role_id=role_id).count()
return jsonify({'count': count})
"""
@user_bp.route('/user/role/<int:role_id>/count', methods=['GET'])
@login_required
@admin_required
@ -379,4 +404,4 @@ def get_role_user_count(role_id):
'success': False,
'message': f"查询失败: {str(e)}",
'count': 0
}), 500
}), 500

View File

@ -27,6 +27,7 @@ class User(db.Model, UserMixin):
self.nickname = nickname
self.role_id = role_id
@property
def is_active(self):
return self.status == 1

View File

Before

Width:  |  Height:  |  Size: 761 KiB

After

Width:  |  Height:  |  Size: 761 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 761 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

BIN
app/static/covers/santi.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 404 KiB

View File

@ -8,8 +8,6 @@
{% block content %}
<div class="book-list-container">
<!-- 添加泡泡动画元素 -->
<!-- 这些泡泡会通过 JS 动态创建 -->
<div class="page-header">
<h1>图书管理</h1>