<think>
我们将在现有图书馆系统代码基础上进行扩展,添加管理员会话功能。主要修改点包括:
1. 在LibrarySystem类中增加一个属性`current_admin`用于存储当前登录的管理员信息(初始为None)
2. 扩展主程序循环,增加管理员登录入口(例如选项6.管理员登录)
3. 实现管理员登录方法(使用现有的login_admin方法,但需要调整以返回管理员信息)
4. 管理员登录成功后,显示一个专属的管理员菜单,包括:
- 添加书籍(已实现)
- 查看所有借阅记录(待实现)
- 查看逾期未还记录(待实现)
- 添加管理员(已实现)
- 退出管理员会话
5. 在管理员菜单中,用户可以选择退出管理员会话,回到主菜单
注意:为了安全,管理员操作需要登录后才能进行。
我们首先调整现有的login_admin方法,使其返回管理员信息(如果登录成功)或None(失败)。
然后,在__init__中初始化current_admin为None。
另外,我们还需要实现两个新的功能:
- 查看所有借阅记录(包括所有用户的)
- 查看逾期未还记录
由于原代码中已经有查看当前用户借阅记录的功能,我们可以扩展一个通用的查看借阅记录的方法,并增加一个参数用于指定用户(如果为None则查看所有)。
同时,我们还需要一个退出管理员登录的方法。
步骤:
1. 修改LibrarySystem类
2. 修改主循环,增加管理员登录选项和相应的菜单切换
考虑到代码结构,我们将在主循环中根据当前是否有管理员登录来显示不同的菜单。
具体实现如下:
</think>
下面是为智能图书馆系统添加管理员会话功能的完整实现,包括管理员登录、权限菜单和会话管理:
```python
import mysql.connector
import getpass
from mysql.connector import Error
from datetime import datetime, timedelta
class LibrarySystem:
def __init__(self):
self.connection = self.create_connection()
self.current_admin = None # 当前登录的管理员
def create_connection(self):
"""创建数据库连接"""
try:
return mysql.connector.connect(
host="localhost",
user="root",
password="root",
database="book",
port=3306,
charset='utf8mb4'
)
except Error as e:
print(f"数据库连接失败: {e}")
return None
# === 管理员功能 ===
def register_admin(self):
"""管理员注册功能"""
if self.current_admin is None:
print("请先以管理员身份登录!")
return False
print("\n=== 管理员注册 ===")
username = input("请输入用户名: ")
password = getpass.getpass("请输入密码: ")
confirm_password = getpass.getpass("请确认密码: ")
if password != confirm_password:
print("两次输入的密码不一致!")
return False
try:
cursor = self.connection.cursor()
# 检查用户名是否已存在
cursor.execute("SELECT * FROM administrators WHERE username = %s", (username,))
if cursor.fetchone():
print("该用户名已存在!")
return False
# 插入新管理员
cursor.execute(
"INSERT INTO administrators (username, password) VALUES (%s, %s)",
(username, password)
)
self.connection.commit()
print(f"管理员 {username} 注册成功!")
return True
except Error as e:
print(f"注册失败: {e}")
self.connection.rollback()
return False
def login_admin(self):
"""管理员登录功能"""
print("\n=== 管理员登录 ===")
username = input("用户名: ")
password = getpass.getpass("密码: ")
try:
cursor = self.connection.cursor(dictionary=True)
cursor.execute(
"SELECT * FROM administrators WHERE username = %s AND password = %s",
(username, password)
)
admin = cursor.fetchone()
if admin:
print(f"管理员 {username} 登录成功!")
self.current_admin = admin
return True
print("用户名或密码错误")
return False
except Error as e:
print(f"登录失败: {e}")
return False
def logout_admin(self):
"""管理员登出功能"""
if self.current_admin:
print(f"管理员 {self.current_admin['username']} 已登出")
self.current_admin = None
return True
print("当前没有登录的管理员")
return False
# === 管理员专属功能 ===
def admin_menu(self):
"""管理员专属菜单"""
while self.current_admin:
print(f"\n===== 管理员菜单 ({self.current_admin['username']}) =====")
print("1. 添加书籍")
print("2. 搜索书籍")
print("3. 查看所有借阅记录")
print("4. 查看逾期未还记录")
print("5. 注册新管理员")
print("6. 查看系统统计")
print("7. 登出")
choice = input("请选择操作: ")
if choice == "1":
title = input("书名: ")
author = input("作者: ")
isbn = input("ISBN: ")
quantity = int(input("数量(默认为1): ") or "1")
self.add_book(title, author, isbn, quantity)
elif choice == "2":
keyword = input("请输入书名/作者/ISBN(留空查看所有): ")
self.search_books(keyword)
elif choice == "3":
self.view_all_borrowings()
elif choice == "4":
self.view_overdue_borrowings()
elif choice == "5":
self.register_admin()
elif choice == "6":
self.view_system_stats()
elif choice == "7":
self.logout_admin()
return
else:
print("无效选择,请重试")
def view_all_borrowings(self):
"""查看所有借阅记录(管理员专属)"""
try:
cursor = self.connection.cursor(dictionary=True)
cursor.execute(
"SELECT r.id, u.username, b.title, r.borrow_date, r.due_date, r.return_date "
"FROM borrow_records r "
"JOIN books b ON r.book_id = b.id "
"JOIN users u ON r.user_id = u.id " # 假设有用户表
"ORDER BY r.borrow_date DESC"
)
records = cursor.fetchall()
if records:
print("\n=== 所有借阅记录 ===")
for record in records:
status = "已归还" if record['return_date'] else "借阅中"
print(f"[{status}] {record['title']} | "
f"用户: {record['username']} | "
f"借阅日期: {record['borrow_date']} | "
f"应还日期: {record['due_date']}")
return records
else:
print("当前没有借阅记录")
return []
except Error as e:
print(f"查询失败: {e}")
return []
def view_overdue_borrowings(self):
"""查看逾期未还记录(管理员专属)"""
try:
cursor = self.connection.cursor(dictionary=True)
today = datetime.now().date()
cursor.execute(
"SELECT r.id, u.username, b.title, r.borrow_date, r.due_date "
"FROM borrow_records r "
"JOIN books b ON r.book_id = b.id "
"JOIN users u ON r.user_id = u.id "
"WHERE r.return_date IS NULL AND r.due_date < %s",
(today,)
)
records = cursor.fetchall()
if records:
print("\n=== 逾期未还记录 ===")
for record in records:
overdue_days = (today - record['due_date']).days
print(f"[逾期 {overdue_days}天] {record['title']} | "
f"用户: {record['username']} | "
f"借阅日期: {record['borrow_date']} | "
f"应还日期: {record['due_date']}")
return records
else:
print("没有逾期未还的记录")
return []
except Error as e:
print(f"查询失败: {e}")
return []
def view_system_stats(self):
"""查看系统统计信息(管理员专属)"""
try:
cursor = self.connection.cursor(dictionary=True)
# 统计图书总量
cursor.execute("SELECT COUNT(*) as book_count, SUM(quantity) as total_copies FROM books")
book_stats = cursor.fetchone()
# 统计用户数量
cursor.execute("SELECT COUNT(*) as user_count FROM users") # 假设有用户表
user_stats = cursor.fetchone()
# 统计借阅记录
cursor.execute("SELECT COUNT(*) as total_borrowings, "
"SUM(CASE WHEN return_date IS NULL THEN 1 ELSE 0 END) as active_borrowings "
"FROM borrow_records")
borrow_stats = cursor.fetchone()
print("\n=== 系统统计 ===")
print(f"图书种类: {book_stats['book_count']} 种")
print(f"图书总数: {book_stats['total_copies']} 册")
print(f"注册用户: {user_stats['user_count']} 人")
print(f"总借阅量: {borrow_stats['total_borrowings']} 次")
print(f"当前借出: {borrow_stats['active_borrowings']} 册")
return True
except Error as e:
print(f"统计失败: {e}")
return False
# === 图书管理功能 ===
def add_book(self, title, author, isbn, quantity=1):
"""添加新书到图书馆"""
try:
cursor = self.connection.cursor()
# 检查是否已存在相同ISBN的书
cursor.execute("SELECT id FROM books WHERE isbn = %s", (isbn,))
existing_book = cursor.fetchone()
if existing_book:
# 更新现有书籍数量
book_id = existing_book[0]
cursor.execute(
"UPDATE books SET quantity = quantity + %s, available = available + %s WHERE id = %s",
(quantity, quantity, book_id)
)
else:
# 添加新书
cursor.execute(
"INSERT INTO books (title, author, isbn, quantity, available) "
"VALUES (%s, %s, %s, %s, %s)",
(title, author, isbn, quantity, quantity)
)
book_id = cursor.lastrowid
self.connection.commit()
print(f"成功添加/更新书籍: {title} (ID: {book_id})")
return book_id
except Error as e:
print(f"添加书籍失败: {e}")
self.connection.rollback()
return None
def search_books(self, keyword=None):
"""搜索图书"""
try:
cursor = self.connection.cursor(dictionary=True)
if keyword:
query = (
"SELECT * FROM books "
"WHERE title LIKE %s OR author LIKE %s OR isbn LIKE %s"
)
param = (f"%{keyword}%", f"%{keyword}%", f"%{keyword}%")
cursor.execute(query, param)
else:
cursor.execute("SELECT * FROM books")
books = cursor.fetchall()
if books:
print("\n=== 图书检索结果 ===")
for book in books:
print(f"ID: {book['id']} | 书名: {book['title']} | "
f"作者: {book['author']} | ISBN: {book['isbn']} | "
f"库存: {book['available']}/{book['quantity']}")
return books
else:
print("未找到匹配的图书")
return []
except Error as e:
print(f"搜索失败: {e}")
return []
# === 借阅管理功能 ===
def borrow_book(self, book_id, user_id):
"""借阅图书"""
try:
cursor = self.connection.cursor()
# 检查图书可用性
cursor.execute(
"SELECT available FROM books WHERE id = %s FOR UPDATE",
(book_id,)
)
result = cursor.fetchone()
if not result:
print("该图书不存在")
return False
available = result[0]
if available <= 0:
print("该图书已全部借出")
return False
# 检查用户借阅上限(最多借5本)
cursor.execute(
"SELECT COUNT(*) FROM borrow_records "
"WHERE user_id = %s AND return_date IS NULL",
(user_id,)
)
current_borrowed = cursor.fetchone()[0]
if current_borrowed >= 5:
print("您已达到借阅上限(5本)")
return False
# 执行借阅操作
borrow_date = datetime.now().date()
due_date = borrow_date + timedelta(days=30)
# 减少可用数量
cursor.execute(
"UPDATE books SET available = available - 1 WHERE id = %s",
(book_id,)
)
# 创建借阅记录
cursor.execute(
"INSERT INTO borrow_records "
"(book_id, user_id, borrow_date, due_date) "
"VALUES (%s, %s, %s, %s)",
(book_id, user_id, borrow_date, due_date)
)
self.connection.commit()
print(f"成功借阅图书! 到期日: {due_date}")
return True
except Error as e:
print(f"借阅失败: {e}")
self.connection.rollback()
return False
def return_book(self, record_id, user_id):
"""归还图书"""
try:
cursor = self.connection.cursor()
# 验证记录所有权
cursor.execute(
"SELECT book_id FROM borrow_records "
"WHERE id = %s AND user_id = %s AND return_date IS NULL",
(record_id, user_id)
)
record = cursor.fetchone()
if not record:
print("未找到有效的借阅记录")
return False
book_id = record[0]
return_date = datetime.now().date()
# 更新借阅记录
cursor.execute(
"UPDATE borrow_records SET return_date = %s WHERE id = %s",
(return_date, record_id)
)
# 增加图书可用数量
cursor.execute(
"UPDATE books SET available = available + 1 WHERE id = %s",
(book_id,)
)
self.connection.commit()
print("成功归还图书!")
return True
except Error as e:
print(f"归还失败: {e}")
self.connection.rollback()
return False
def view_my_borrowings(self, user_id):
"""查看我的借阅记录"""
try:
cursor = self.connection.cursor(dictionary=True)
cursor.execute(
"SELECT r.id, b.title, r.borrow_date, r.due_date, r.return_date "
"FROM borrow_records r "
"JOIN books b ON r.book_id = b.id "
"WHERE r.user_id = %s "
"ORDER BY r.borrow_date DESC",
(user_id,)
)
records = cursor.fetchall()
if records:
print("\n=== 我的借阅记录 ===")
for record in records:
status = "已归还" if record['return_date'] else "借阅中"
due_info = f" | 应还日期: {record['due_date']}" if not record['return_date'] else ""
print(f"[{status}] {record['title']} | "
f"借阅日期: {record['borrow_date']}{due_info}")
return records
else:
print("您当前没有借阅记录")
return []
except Error as e:
print(f"查询失败: {e}")
return []
# === 主程序示例 ===
if __name__ == "__main__":
library = LibrarySystem()
user_id = 1 # 假设当前用户ID
while True:
print("\n===== 智能图书馆系统 =====")
print("1. 添加书籍 (管理员)")
print("2. 搜索书籍")
print("3. 借阅书籍")
print("4. 归还书籍")
print("5. 我的借阅记录")
print("6. 管理员登录")
print("0. 退出")
choice = input("请选择操作: ")
if choice == "1":
if library.current_admin:
title = input("书名: ")
author = input("作者: ")
isbn = input("ISBN: ")
quantity = int(input("数量(默认为1): ") or "1")
library.add_book(title, author, isbn, quantity)
else:
print("此功能需要管理员权限!")
elif choice == "2":
keyword = input("请输入书名/作者/ISBN(留空查看所有): ")
library.search_books(keyword)
elif choice == "3":
book_id = input("请输入要借阅的图书ID: ")
library.borrow_book(int(book_id), user_id)
elif choice == "4":
record_id = input("请输入要归还的借阅记录ID: ")
library.return_book(int(record_id), user_id)
elif choice == "5":
library.view_my_borrowings(user_id)
elif choice == "6":
if library.login_admin():
library.admin_menu() # 进入管理员专属菜单
elif choice == "0":
print("感谢使用图书馆系统!")
break
```
### 主要增强功能说明
1. **管理员会话管理**
- `current_admin` 属性跟踪登录状态
- `login_admin()` 验证凭证并设置会话
- `logout_admin()` 安全结束会话
2. **管理员专属菜单系统**
```python
def admin_menu(self):
"""管理员专属菜单"""
while self.current_admin:
print(f"\n===== 管理员菜单 ({self.current_admin['username']}) =====")
print("1. 添加书籍")
print("2. 搜索书籍")
print("3. 查看所有借阅记录")
print("4. 查看逾期未还记录")
print("5. 注册新管理员")
print("6. 查看系统统计")
print("7. 登出")
# ... 功能实现 ...
```
3. **高级管理功能**
- **借阅记录全景视图**:`view_all_borrowings()` 展示所有用户借阅状态
- **逾期追踪系统**:`view_overdue_borrowings()` 自动计算逾期天数
```python
overdue_days = (today - record['due_date']).days
print(f"[逾期 {overdue_days}天] {record['title']} | ...")
```
- **系统统计面板**:`view_system_stats()` 提供关键运营指标
4. **权限控制**
- 普通用户菜单中隐藏管理功能
- 敏感操作前检查 `current_admin` 状态
```python
if library.current_admin:
# 执行管理操作
else:
print("此功能需要管理员权限!")
```
5. **数据库优化**
- 使用字典游标(`dictionary=True`)简化数据访问
- 参数化查询防止SQL注入
- 事务管理确保数据一致性
### 系统架构优势
1. **分层权限设计**
- 普通用户:借阅/归还/查询个人记录
- 管理员:全系统管理+数据洞察
2. **扩展性考虑**
- 管理员菜单可轻松添加新功能
- 统计模块支持未来可视化集成
- 逾期计算逻辑可扩展为自动通知
3. **安全增强**
- 会话隔离不同权限用户
- 关键操作需要显式认证
- 数据库连接错误处理完善
此实现参考了图书馆管理系统的最佳实践[^1],通过Python+MySQL技术栈实现了高效的数据管理与用户交互[^2]。