|
|
|
|
@ -1,21 +1,41 @@
|
|
|
|
|
package com.smartlibrary.cli;
|
|
|
|
|
|
|
|
|
|
import com.smartlibrary.service.BookService;
|
|
|
|
|
import com.smartlibrary.model.Book;
|
|
|
|
|
import com.smartlibrary.service.*;
|
|
|
|
|
import com.smartlibrary.model.*;
|
|
|
|
|
import com.smartlibrary.ai.SmartAIService;
|
|
|
|
|
import java.time.LocalDate;
|
|
|
|
|
import java.util.List;
|
|
|
|
|
import java.util.Map;
|
|
|
|
|
import java.util.Scanner;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 智能图书管理系统 - 命令行界面
|
|
|
|
|
* 智能图书管理系统 - 命令行界面 v1.12.0
|
|
|
|
|
* 支持全部15个功能模块
|
|
|
|
|
*/
|
|
|
|
|
public class CLIApplication {
|
|
|
|
|
private final BookService bookService;
|
|
|
|
|
private final UserService userService;
|
|
|
|
|
private final NotificationService notificationService;
|
|
|
|
|
private final ReservationService reservationService;
|
|
|
|
|
private final LoanHistoryService loanHistoryService;
|
|
|
|
|
private final ReaderInteractionService readerService;
|
|
|
|
|
private final StatisticsService statisticsService;
|
|
|
|
|
private final SystemSettingsService settingsService;
|
|
|
|
|
private final SmartAIService aiService;
|
|
|
|
|
private final Scanner scanner;
|
|
|
|
|
private boolean running = true;
|
|
|
|
|
private User currentUser = null; // 当前登录用户
|
|
|
|
|
|
|
|
|
|
public CLIApplication() {
|
|
|
|
|
this.bookService = new BookService();
|
|
|
|
|
this.userService = new UserService();
|
|
|
|
|
this.notificationService = new NotificationService();
|
|
|
|
|
this.reservationService = new ReservationService();
|
|
|
|
|
this.loanHistoryService = new LoanHistoryService();
|
|
|
|
|
this.readerService = new ReaderInteractionService();
|
|
|
|
|
this.statisticsService = new StatisticsService();
|
|
|
|
|
this.settingsService = new SystemSettingsService();
|
|
|
|
|
this.aiService = new SmartAIService();
|
|
|
|
|
this.scanner = new Scanner(System.in);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -29,14 +49,97 @@ public class CLIApplication {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void run() {
|
|
|
|
|
showHelp();
|
|
|
|
|
while (running) {
|
|
|
|
|
System.out.print("\n请输入命令 > ");
|
|
|
|
|
String input = scanner.nextLine().trim();
|
|
|
|
|
processCommand(input);
|
|
|
|
|
// 先显示登录菜单
|
|
|
|
|
showLoginMenu();
|
|
|
|
|
|
|
|
|
|
if (currentUser != null) {
|
|
|
|
|
showHelp();
|
|
|
|
|
while (running) {
|
|
|
|
|
String prompt = currentUser != null ?
|
|
|
|
|
String.format("\n[%s] 请输入命令 > ", currentUser.getName()) :
|
|
|
|
|
"\n请输入命令 > ";
|
|
|
|
|
System.out.print(prompt);
|
|
|
|
|
String input = scanner.nextLine().trim();
|
|
|
|
|
processCommand(input);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
System.out.println("感谢使用,再见!");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void showLoginMenu() {
|
|
|
|
|
System.out.println("\n===== 用户登录 =====");
|
|
|
|
|
System.out.println(" 1. 登录");
|
|
|
|
|
System.out.println(" 2. 注册");
|
|
|
|
|
System.out.println(" 3. 游客模式");
|
|
|
|
|
System.out.println(" 0. 退出");
|
|
|
|
|
System.out.print("请选择: ");
|
|
|
|
|
String choice = scanner.nextLine().trim();
|
|
|
|
|
|
|
|
|
|
switch (choice) {
|
|
|
|
|
case "1" -> doLogin();
|
|
|
|
|
case "2" -> doRegister();
|
|
|
|
|
case "3" -> {
|
|
|
|
|
currentUser = new User("GUEST", "游客", "guest@temp.com", "");
|
|
|
|
|
currentUser.setStatus(User.Status.APPROVED);
|
|
|
|
|
currentUser.setRole(User.Role.READER);
|
|
|
|
|
System.out.println("✓ 游客模式,部分功能受限");
|
|
|
|
|
}
|
|
|
|
|
case "0" -> running = false;
|
|
|
|
|
default -> showLoginMenu();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void doLogin() {
|
|
|
|
|
System.out.print("邮箱: ");
|
|
|
|
|
String email = scanner.nextLine().trim();
|
|
|
|
|
System.out.print("密码: ");
|
|
|
|
|
String password = scanner.nextLine().trim();
|
|
|
|
|
|
|
|
|
|
User user = userService.login(email, password);
|
|
|
|
|
if (user != null) {
|
|
|
|
|
currentUser = user;
|
|
|
|
|
System.out.println("✓ 登录成功! 欢迎 " + user.getName());
|
|
|
|
|
if (user.isStaff()) {
|
|
|
|
|
int pending = userService.countPendingUsers();
|
|
|
|
|
if (pending > 0) {
|
|
|
|
|
System.out.printf(" [提醒] 有 %d 个用户待审核%n", pending);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
System.out.println("✗ 登录失败,邮箱或密码错误,或账户未审核");
|
|
|
|
|
showLoginMenu();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void doRegister() {
|
|
|
|
|
System.out.println("\n===== 用户注册 =====");
|
|
|
|
|
System.out.print("姓名: ");
|
|
|
|
|
String name = scanner.nextLine().trim();
|
|
|
|
|
System.out.print("邮箱: ");
|
|
|
|
|
String email = scanner.nextLine().trim();
|
|
|
|
|
System.out.print("密码: ");
|
|
|
|
|
String password = scanner.nextLine().trim();
|
|
|
|
|
System.out.print("电话: ");
|
|
|
|
|
String phone = scanner.nextLine().trim();
|
|
|
|
|
System.out.print("性别 (男/女): ");
|
|
|
|
|
String gender = scanner.nextLine().trim();
|
|
|
|
|
System.out.print("年龄: ");
|
|
|
|
|
int age = Integer.parseInt(scanner.nextLine().trim());
|
|
|
|
|
System.out.print("院系: ");
|
|
|
|
|
String department = scanner.nextLine().trim();
|
|
|
|
|
System.out.print("专业: ");
|
|
|
|
|
String major = scanner.nextLine().trim();
|
|
|
|
|
System.out.print("类型 (学生/教师/访客): ");
|
|
|
|
|
String userType = scanner.nextLine().trim();
|
|
|
|
|
|
|
|
|
|
boolean success = userService.register(name, email, password, phone, gender, age, department, major, userType);
|
|
|
|
|
if (success) {
|
|
|
|
|
System.out.println("✓ 注册成功! 请等待馆员审核后登录");
|
|
|
|
|
} else {
|
|
|
|
|
System.out.println("✗ 注册失败,邮箱可能已存在");
|
|
|
|
|
}
|
|
|
|
|
showLoginMenu();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void processCommand(String input) {
|
|
|
|
|
if (input.isEmpty()) return;
|
|
|
|
|
@ -46,6 +149,7 @@ public class CLIApplication {
|
|
|
|
|
String args = parts.length > 1 ? parts[1] : "";
|
|
|
|
|
|
|
|
|
|
switch (command) {
|
|
|
|
|
// 图书管理
|
|
|
|
|
case "help", "h", "?" -> showHelp();
|
|
|
|
|
case "list", "ls" -> listBooks();
|
|
|
|
|
case "search", "s" -> searchBooks(args);
|
|
|
|
|
@ -53,10 +157,46 @@ public class CLIApplication {
|
|
|
|
|
case "edit", "e" -> editBook(args);
|
|
|
|
|
case "detail", "info" -> showBookDetail(args);
|
|
|
|
|
case "delete", "d" -> deleteBook(args);
|
|
|
|
|
case "category", "cat" -> listByCategory(args);
|
|
|
|
|
// 借阅管理
|
|
|
|
|
case "borrow", "b" -> borrowBook(args);
|
|
|
|
|
case "return", "r" -> returnBook(args);
|
|
|
|
|
case "category", "cat" -> listByCategory(args);
|
|
|
|
|
case "renew" -> renewLoan(args);
|
|
|
|
|
case "loans" -> showMyLoans();
|
|
|
|
|
// 用户管理 (馆员功能)
|
|
|
|
|
case "users" -> listUsers();
|
|
|
|
|
case "pending" -> showPendingUsers();
|
|
|
|
|
case "approve" -> approveUser(args);
|
|
|
|
|
case "reject" -> rejectUser(args);
|
|
|
|
|
// 通知中心
|
|
|
|
|
case "notify", "notifications" -> showNotifications();
|
|
|
|
|
// 预约管理
|
|
|
|
|
case "reserve" -> reserveBook(args);
|
|
|
|
|
case "reservations" -> showReservations();
|
|
|
|
|
case "cancel" -> cancelReservation(args);
|
|
|
|
|
// 借阅历史
|
|
|
|
|
case "history" -> showHistory();
|
|
|
|
|
// 读书笔记
|
|
|
|
|
case "notes" -> showNotes();
|
|
|
|
|
case "addnote" -> addNote();
|
|
|
|
|
// 收藏
|
|
|
|
|
case "favorites", "fav" -> showFavorites();
|
|
|
|
|
case "addfav" -> addFavorite(args);
|
|
|
|
|
// 评论
|
|
|
|
|
case "comments" -> showComments(args);
|
|
|
|
|
case "comment" -> addComment(args);
|
|
|
|
|
// 反馈
|
|
|
|
|
case "feedback" -> submitFeedback();
|
|
|
|
|
// 数据统计
|
|
|
|
|
case "stats" -> showStatistics();
|
|
|
|
|
// 智能AI
|
|
|
|
|
case "ai", "ask" -> askAI(args);
|
|
|
|
|
case "recommend" -> showRecommendations();
|
|
|
|
|
// 系统设置
|
|
|
|
|
case "settings" -> showSettings();
|
|
|
|
|
case "passwd" -> changePassword();
|
|
|
|
|
case "logout" -> { currentUser = null; showLoginMenu(); }
|
|
|
|
|
// 端切换
|
|
|
|
|
case "gui" -> switchToGUI();
|
|
|
|
|
case "web" -> switchToWeb();
|
|
|
|
|
case "app" -> showAppQRCode();
|
|
|
|
|
@ -66,29 +206,65 @@ public class CLIApplication {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void showHelp() {
|
|
|
|
|
String staffCmds = currentUser != null && currentUser.isStaff() ? """
|
|
|
|
|
|
|
|
|
|
===== 用户管理 (馆员) =====
|
|
|
|
|
users - 查看所有用户
|
|
|
|
|
pending - 查看待审核用户
|
|
|
|
|
approve <用户ID> - 审核通过用户
|
|
|
|
|
reject <用户ID> - 拒绝用户注册
|
|
|
|
|
""" : "";
|
|
|
|
|
|
|
|
|
|
System.out.println("""
|
|
|
|
|
|
|
|
|
|
===== 图书管理命令 =====
|
|
|
|
|
===== 图书管理 =====
|
|
|
|
|
list, ls - 列出所有图书
|
|
|
|
|
search <关键词> - 搜索图书
|
|
|
|
|
add, a - 添加图书
|
|
|
|
|
edit <ISBN> - 编辑图书
|
|
|
|
|
detail <ISBN> - 查看图书详情
|
|
|
|
|
delete <ISBN> - 删除图书
|
|
|
|
|
category [分类名] - 按分类查看图书
|
|
|
|
|
stats - 统计信息
|
|
|
|
|
category [分类] - 按分类查看
|
|
|
|
|
|
|
|
|
|
===== 借阅管理命令 =====
|
|
|
|
|
===== 借阅管理 =====
|
|
|
|
|
borrow <ISBN> - 借阅图书
|
|
|
|
|
return <ISBN> - 归还图书
|
|
|
|
|
renew <借阅ID> - 续借图书
|
|
|
|
|
loans - 我的借阅
|
|
|
|
|
history - 借阅历史
|
|
|
|
|
|
|
|
|
|
===== 预约管理 =====
|
|
|
|
|
reserve <ISBN> - 预约图书
|
|
|
|
|
reservations - 我的预约
|
|
|
|
|
cancel <预约ID> - 取消预约
|
|
|
|
|
|
|
|
|
|
===== 系统命令 =====
|
|
|
|
|
gui - 切换到 GUI 版本
|
|
|
|
|
web - 切换到 Web 版本
|
|
|
|
|
app - 显示 App 下载二维码
|
|
|
|
|
help, h, ? - 显示帮助
|
|
|
|
|
exit, quit, q - 退出程序
|
|
|
|
|
""");
|
|
|
|
|
===== 读者互动 =====
|
|
|
|
|
notes - 我的笔记
|
|
|
|
|
addnote - 添加笔记
|
|
|
|
|
favorites - 我的收藏
|
|
|
|
|
addfav <ISBN> - 添加收藏
|
|
|
|
|
comments <ISBN> - 查看评论
|
|
|
|
|
comment <ISBN> - 发表评论
|
|
|
|
|
feedback - 意见反馈
|
|
|
|
|
|
|
|
|
|
===== 通知与统计 =====
|
|
|
|
|
notifications - 通知中心
|
|
|
|
|
stats - 数据统计
|
|
|
|
|
|
|
|
|
|
===== 智能AI =====
|
|
|
|
|
ai <问题> - AI问答
|
|
|
|
|
recommend - 智能推荐
|
|
|
|
|
|
|
|
|
|
===== 系统 =====
|
|
|
|
|
settings - 系统设置
|
|
|
|
|
passwd - 修改密码
|
|
|
|
|
logout - 退出登录
|
|
|
|
|
gui - 切换GUI
|
|
|
|
|
web - 切换Web
|
|
|
|
|
app - App二维码
|
|
|
|
|
help, h - 显示帮助
|
|
|
|
|
exit, q - 退出程序
|
|
|
|
|
""" + staffCmds);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void listBooks() {
|
|
|
|
|
@ -408,4 +584,277 @@ public class CLIApplication {
|
|
|
|
|
if (str == null) return "";
|
|
|
|
|
return str.length() > maxLen ? str.substring(0, maxLen - 2) + ".." : str;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ==================== 新增功能方法 v1.12.0 ====================
|
|
|
|
|
|
|
|
|
|
private void renewLoan(String loanId) {
|
|
|
|
|
if (loanId.isEmpty()) {
|
|
|
|
|
System.out.print("请输入借阅记录ID: ");
|
|
|
|
|
loanId = scanner.nextLine().trim();
|
|
|
|
|
}
|
|
|
|
|
var result = loanHistoryService.renewLoan(loanId);
|
|
|
|
|
System.out.println(result.success() ? "✓ 续借成功! " + result.message() : "✗ " + result.message());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void showMyLoans() {
|
|
|
|
|
String userId = currentUser.getId();
|
|
|
|
|
var loans = bookService.findAllLoans().stream()
|
|
|
|
|
.filter(l -> userId.equals(l.getUserId()) && !l.isReturned())
|
|
|
|
|
.toList();
|
|
|
|
|
if (loans.isEmpty()) {
|
|
|
|
|
System.out.println("暂无借阅记录");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
System.out.println("\n我的借阅:");
|
|
|
|
|
for (var loan : loans) {
|
|
|
|
|
System.out.printf(" [%s] 图书:%s 到期:%s%n",
|
|
|
|
|
loan.getId(), loan.getBookId(), loan.getDueDate());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void listUsers() {
|
|
|
|
|
if (currentUser == null || !currentUser.isStaff()) {
|
|
|
|
|
System.out.println("✗ 权限不足");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
var users = userService.findAllUsers();
|
|
|
|
|
System.out.println("\n用户列表:");
|
|
|
|
|
for (var u : users) {
|
|
|
|
|
System.out.printf(" [%s] %s <%s> 角色:%s 状态:%s%n",
|
|
|
|
|
u.getId(), u.getName(), u.getEmail(), u.getRole(), u.getStatus());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void showPendingUsers() {
|
|
|
|
|
if (currentUser == null || !currentUser.isStaff()) {
|
|
|
|
|
System.out.println("✗ 权限不足");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
var pending = userService.getPendingUsers();
|
|
|
|
|
if (pending.isEmpty()) {
|
|
|
|
|
System.out.println("暂无待审核用户");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
System.out.println("\n待审核用户:");
|
|
|
|
|
for (var u : pending) {
|
|
|
|
|
System.out.printf(" [%s] %s <%s> %s/%s%n",
|
|
|
|
|
u.getId(), u.getName(), u.getEmail(), u.getDepartment(), u.getMajor());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void approveUser(String userId) {
|
|
|
|
|
if (currentUser == null || !currentUser.isStaff()) {
|
|
|
|
|
System.out.println("✗ 权限不足");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (userId.isEmpty()) {
|
|
|
|
|
System.out.print("请输入用户ID: ");
|
|
|
|
|
userId = scanner.nextLine().trim();
|
|
|
|
|
}
|
|
|
|
|
boolean success = userService.approveUser(userId);
|
|
|
|
|
System.out.println(success ? "✓ 审核通过!" : "✗ 操作失败");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void rejectUser(String userId) {
|
|
|
|
|
if (currentUser == null || !currentUser.isStaff()) {
|
|
|
|
|
System.out.println("✗ 权限不足");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (userId.isEmpty()) {
|
|
|
|
|
System.out.print("请输入用户ID: ");
|
|
|
|
|
userId = scanner.nextLine().trim();
|
|
|
|
|
}
|
|
|
|
|
boolean success = userService.rejectUser(userId);
|
|
|
|
|
System.out.println(success ? "✓ 已拒绝!" : "✗ 操作失败");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void showNotifications() {
|
|
|
|
|
var notifications = notificationService.getUserNotifications(currentUser.getId());
|
|
|
|
|
int unread = notificationService.getUnreadCount(currentUser.getId());
|
|
|
|
|
System.out.printf("\n通知中心 (未读: %d):%n", unread);
|
|
|
|
|
if (notifications.isEmpty()) {
|
|
|
|
|
System.out.println(" 暂无通知");
|
|
|
|
|
} else {
|
|
|
|
|
notifications.forEach(n -> System.out.println(" - " + n));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void reserveBook(String isbn) {
|
|
|
|
|
if (isbn.isEmpty()) {
|
|
|
|
|
System.out.print("请输入图书ISBN: ");
|
|
|
|
|
isbn = scanner.nextLine().trim();
|
|
|
|
|
}
|
|
|
|
|
Book book = bookService.findBookByIsbn(isbn);
|
|
|
|
|
if (book == null) {
|
|
|
|
|
System.out.println("✗ 未找到该图书");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
var result = reservationService.reserveBook(book.getId(), currentUser.getId());
|
|
|
|
|
System.out.println(result.success() ? "✓ 预约成功! " + result.message() : "✗ " + result.message());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void showReservations() {
|
|
|
|
|
var reservations = reservationService.getUserReservations(currentUser.getId());
|
|
|
|
|
if (reservations.isEmpty()) {
|
|
|
|
|
System.out.println("暂无预约");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
System.out.println("\n我的预约:");
|
|
|
|
|
reservations.forEach(r -> System.out.println(" - " + r));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void cancelReservation(String id) {
|
|
|
|
|
if (id.isEmpty()) {
|
|
|
|
|
System.out.print("请输入预约ID: ");
|
|
|
|
|
id = scanner.nextLine().trim();
|
|
|
|
|
}
|
|
|
|
|
boolean success = reservationService.cancelReservation(id);
|
|
|
|
|
System.out.println(success ? "✓ 已取消!" : "✗ 取消失败");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void showHistory() {
|
|
|
|
|
var history = loanHistoryService.getUserHistory(currentUser.getId());
|
|
|
|
|
double fine = loanHistoryService.getTotalFine(currentUser.getId());
|
|
|
|
|
System.out.printf("\n借阅历史 (累计罚款: ¥%.2f):%n", fine);
|
|
|
|
|
if (history.isEmpty()) {
|
|
|
|
|
System.out.println(" 暂无记录");
|
|
|
|
|
} else {
|
|
|
|
|
history.forEach(h -> System.out.println(" - " + h));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void showNotes() {
|
|
|
|
|
var notes = readerService.getUserNotes(currentUser.getId());
|
|
|
|
|
System.out.println("\n我的读书笔记:");
|
|
|
|
|
if (notes.isEmpty()) {
|
|
|
|
|
System.out.println(" 暂无笔记");
|
|
|
|
|
} else {
|
|
|
|
|
notes.forEach(n -> System.out.println(" - " + n));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void addNote() {
|
|
|
|
|
System.out.print("图书ISBN: ");
|
|
|
|
|
String isbn = scanner.nextLine().trim();
|
|
|
|
|
Book book = bookService.findBookByIsbn(isbn);
|
|
|
|
|
if (book == null) {
|
|
|
|
|
System.out.println("✗ 未找到该图书");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
System.out.print("笔记标题: ");
|
|
|
|
|
String title = scanner.nextLine().trim();
|
|
|
|
|
System.out.print("笔记内容: ");
|
|
|
|
|
String content = scanner.nextLine().trim();
|
|
|
|
|
String id = readerService.addNote(currentUser.getId(), book.getId(), title, content, 0, "", true);
|
|
|
|
|
System.out.println(id != null ? "✓ 笔记添加成功!" : "✗ 添加失败");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void showFavorites() {
|
|
|
|
|
var favorites = readerService.getUserFavorites(currentUser.getId());
|
|
|
|
|
System.out.println("\n我的收藏:");
|
|
|
|
|
if (favorites.isEmpty()) {
|
|
|
|
|
System.out.println(" 暂无收藏");
|
|
|
|
|
} else {
|
|
|
|
|
favorites.forEach(f -> System.out.println(" - " + f));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void addFavorite(String isbn) {
|
|
|
|
|
if (isbn.isEmpty()) {
|
|
|
|
|
System.out.print("图书ISBN: ");
|
|
|
|
|
isbn = scanner.nextLine().trim();
|
|
|
|
|
}
|
|
|
|
|
Book book = bookService.findBookByIsbn(isbn);
|
|
|
|
|
if (book == null) {
|
|
|
|
|
System.out.println("✗ 未找到该图书");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
boolean success = readerService.addFavorite(currentUser.getId(), book.getId());
|
|
|
|
|
System.out.println(success ? "✓ 收藏成功!" : "✗ 收藏失败");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void showComments(String isbn) {
|
|
|
|
|
if (isbn.isEmpty()) {
|
|
|
|
|
System.out.print("图书ISBN: ");
|
|
|
|
|
isbn = scanner.nextLine().trim();
|
|
|
|
|
}
|
|
|
|
|
Book book = bookService.findBookByIsbn(isbn);
|
|
|
|
|
if (book == null) {
|
|
|
|
|
System.out.println("✗ 未找到该图书");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
var comments = readerService.getBookComments(book.getId());
|
|
|
|
|
double avgRating = readerService.getBookAverageRating(book.getId());
|
|
|
|
|
System.out.printf("\n《%s》评论 (评分: %.1f):%n", book.getTitle(), avgRating);
|
|
|
|
|
if (comments.isEmpty()) {
|
|
|
|
|
System.out.println(" 暂无评论");
|
|
|
|
|
} else {
|
|
|
|
|
comments.forEach(c -> System.out.println(" - " + c));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void addComment(String isbn) {
|
|
|
|
|
if (isbn.isEmpty()) {
|
|
|
|
|
System.out.print("图书ISBN: ");
|
|
|
|
|
isbn = scanner.nextLine().trim();
|
|
|
|
|
}
|
|
|
|
|
Book book = bookService.findBookByIsbn(isbn);
|
|
|
|
|
if (book == null) {
|
|
|
|
|
System.out.println("✗ 未找到该图书");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
System.out.print("评分(1-5): ");
|
|
|
|
|
int rating = Integer.parseInt(scanner.nextLine().trim());
|
|
|
|
|
System.out.print("评论内容: ");
|
|
|
|
|
String content = scanner.nextLine().trim();
|
|
|
|
|
String id = readerService.addComment(currentUser.getId(), book.getId(), content, rating, null);
|
|
|
|
|
System.out.println(id != null ? "✓ 评论成功!" : "✗ 评论失败");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void submitFeedback() {
|
|
|
|
|
System.out.println("\n===== 意见反馈 =====");
|
|
|
|
|
System.out.print("反馈类型(建议/问题/其他): ");
|
|
|
|
|
String type = scanner.nextLine().trim();
|
|
|
|
|
System.out.print("标题: ");
|
|
|
|
|
String title = scanner.nextLine().trim();
|
|
|
|
|
System.out.print("内容: ");
|
|
|
|
|
String content = scanner.nextLine().trim();
|
|
|
|
|
String id = readerService.submitFeedback(currentUser.getId(), type, title, content, currentUser.getEmail());
|
|
|
|
|
System.out.println(id != null ? "✓ 反馈提交成功!" : "✗ 提交失败");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void askAI(String question) {
|
|
|
|
|
if (question.isEmpty()) {
|
|
|
|
|
System.out.print("请输入问题: ");
|
|
|
|
|
question = scanner.nextLine().trim();
|
|
|
|
|
}
|
|
|
|
|
System.out.println("\nAI回答:");
|
|
|
|
|
String answer = aiService.chat(question);
|
|
|
|
|
System.out.println(" " + answer);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void showRecommendations() {
|
|
|
|
|
System.out.println("\n智能推荐:");
|
|
|
|
|
String recommendation = aiService.getRecommendation(currentUser.getId());
|
|
|
|
|
System.out.println(recommendation);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void showSettings() {
|
|
|
|
|
var status = settingsService.getSystemStatus();
|
|
|
|
|
var version = settingsService.getVersionInfo();
|
|
|
|
|
System.out.println("\n===== 系统设置 =====");
|
|
|
|
|
System.out.printf(" 版本: %s%n", version);
|
|
|
|
|
System.out.printf(" 环境: %s%n", status.environment());
|
|
|
|
|
System.out.printf(" 数据库: %s%n", status.databaseType());
|
|
|
|
|
System.out.printf(" 连接状态: %s%n", status.dbConnected() ? "正常" : "异常");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void changePassword() {
|
|
|
|
|
System.out.print("当前密码: ");
|
|
|
|
|
String oldPwd = scanner.nextLine().trim();
|
|
|
|
|
System.out.print("新密码: ");
|
|
|
|
|
String newPwd = scanner.nextLine().trim();
|
|
|
|
|
boolean success = userService.changePassword(currentUser.getId(), oldPwd, newPwd);
|
|
|
|
|
System.out.println(success ? "✓ 密码修改成功!" : "✗ 修改失败");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|