diff --git a/app/__init__.py b/app/__init__.py index 6408655..c84812c 100644 --- a/app/__init__.py +++ b/app/__init__.py @@ -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_user,Flask-Login自动提供 @app.errorhandler(404) diff --git a/app/controllers/book.py b/app/controllers/book.py index d6f9570..19ec822 100644 --- a/app/controllers/book.py +++ b/app/controllers/book.py @@ -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""" +

用户权限信息

+

用户名: {current_user.username}

+

角色ID: {current_user.role_id}

+

是否管理员: {'是' if current_user.role_id == 1 else '否'}

+

尝试访问管理页面

+ """ diff --git a/app/controllers/borrow.py b/app/controllers/borrow.py index c5362a0..f68acb1 100644 --- a/app/controllers/borrow.py +++ b/app/controllers/borrow.py @@ -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/', 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)}' + }) diff --git a/app/controllers/user.py b/app/controllers/user.py index bdecc6f..85a9bd9 100644 --- a/app/controllers/user.py +++ b/app/controllers/user.py @@ -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//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 \ No newline at end of file + }), 500 diff --git a/app/models/user.py b/app/models/user.py index 4dbfa1c..ba7fa6c 100644 --- a/app/models/user.py +++ b/app/models/user.py @@ -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 diff --git a/app/static/uploads/covers/69a1f7af-2b9c-4354-9af9-f3bb909acad4_.jpg b/app/static/covers/0c78e7aa-df33-49c6-b921-5a82d723964f.jpg similarity index 100% rename from app/static/uploads/covers/69a1f7af-2b9c-4354-9af9-f3bb909acad4_.jpg rename to app/static/covers/0c78e7aa-df33-49c6-b921-5a82d723964f.jpg diff --git a/app/static/covers/69a1f7af-2b9c-4354-9af9-f3bb909acad4_.jpg b/app/static/covers/69a1f7af-2b9c-4354-9af9-f3bb909acad4_.jpg new file mode 100644 index 0000000..72cbaec Binary files /dev/null and b/app/static/covers/69a1f7af-2b9c-4354-9af9-f3bb909acad4_.jpg differ diff --git a/app/static/covers/jieyou.jpg b/app/static/covers/jieyou.jpg new file mode 100644 index 0000000..2098825 Binary files /dev/null and b/app/static/covers/jieyou.jpg differ diff --git a/app/static/covers/santi.jpg b/app/static/covers/santi.jpg new file mode 100644 index 0000000..e21adaa Binary files /dev/null and b/app/static/covers/santi.jpg differ diff --git a/app/templates/book/list.html b/app/templates/book/list.html index a20dfbe..a8bb77d 100644 --- a/app/templates/book/list.html +++ b/app/templates/book/list.html @@ -8,8 +8,6 @@ {% block content %}
- -