package com.example.librarysystem.controller;
//
import com.example.librarysystem.entity.BorrowRecord;
import com.example.librarysystem.mapper.BorrowRecordsMapper;
import com.example.librarysystem.service.BorrowRecordService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/api/borrow-records")
public class BorrowRecordController {
    @Autowired
    private BorrowRecordService borrowRecordService;
    @Autowired
    private BorrowRecordsMapper borrowRecordsMapper;

    @PostMapping("/borrow")
    public ResponseEntity<?> borrowBook(@RequestBody BorrowRecord borrowRecord) {
        try {
            BorrowRecord savedRecord = borrowRecordService.borrowBook(borrowRecord);
            return new ResponseEntity<>(savedRecord, HttpStatus.OK);
        } catch (Exception e) {
            return new ResponseEntity<>("借阅图书失败：" + e.getMessage(), HttpStatus.BAD_REQUEST);
        }
    }
    @GetMapping("/user/borrow-history/{userId}")
    public ResponseEntity<List<Map<String, Object>>> getBorrowHistoryByUserId(@PathVariable Long userId) {
        List<Map<String, Object>> records = borrowRecordsMapper.findBorrowHistoryByUserId(userId);
        System.out.println("Borrow history records: " + records);
        return new ResponseEntity<>(records, HttpStatus.OK);
    }
    @GetMapping()
    public ResponseEntity<List<BorrowRecord>> getBorrowRecords() {
        List<BorrowRecord> records = borrowRecordService.getBorrowRecords();
        return new ResponseEntity<>(records, HttpStatus.OK);
    }
    @PostMapping("/return/{id}")
    public ResponseEntity<String> returnBook(@PathVariable Long id) {
        try {
            borrowRecordService.returnBook(id);
            return new ResponseEntity<>("还书成功", HttpStatus.OK); // 直接返回字符串
        } catch (Exception e) {
            return new ResponseEntity<>("还书失败: " + e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }
    @GetMapping("/{id}")
    public ResponseEntity<BorrowRecord> getBorrowRecordById(@PathVariable Long id) {
        BorrowRecord record = borrowRecordService.getBorrowRecordById(id);
        if (record!= null) {
            return new ResponseEntity<>(record, HttpStatus.OK);
        } else {
            return new ResponseEntity<>(HttpStatus.NOT_FOUND);
        }
    }

    @DeleteMapping("/{id}")
    public ResponseEntity<?> deleteBorrowRecord(@PathVariable Long id) {
        borrowRecordService.deleteBorrowRecord(id);
        return new ResponseEntity<>("Borrow record deleted successfully", HttpStatus.OK);
    }

    @PostMapping("/edit")
    public ResponseEntity<?> editBorrowRecord(@RequestBody BorrowRecord borrowRecord) {
        BorrowRecord editedRecord = borrowRecordService.editBorrowRecord(borrowRecord);
        return new ResponseEntity<>(editedRecord, HttpStatus.OK);
    }
}    package com.example.librarysystem.controller;

    import com.baomidou.mybatisplus.core.toolkit.Wrappers;
    import com.example.librarysystem.entity.Books;
    import com.example.librarysystem.mapper.BooksMapper;
    import com.example.librarysystem.service.BookService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.http.HttpStatus;
    import org.springframework.http.ResponseEntity;
    import org.springframework.web.bind.annotation.*;


    import java.util.Collections;
    import java.util.List;
    import java.util.Map;

    @RestController
    @RequestMapping("/api/books")
    public class BookController {
        @Autowired
        private BookService bookService;

        @Autowired
        private BooksMapper booksMapper;

        // 添加图书的接口
        @PostMapping("/add")
        public ResponseEntity<?> addBook(@RequestBody Books book) {
            try {
                // 确保在此处获取有效内容
                if (book.getTitle() == null || book.getTitle().isEmpty()) {
                    return new ResponseEntity<>("书名不能为空", HttpStatus.BAD_REQUEST);
                }
                Books savedBook = bookService.addBook(book);
                return new ResponseEntity<>(savedBook, HttpStatus.OK);
            } catch (Exception e) {
                System.err.println("添加图书时出错: " + e.getMessage()); // 日志错误信息
                return new ResponseEntity<>("添加图书失败：" + e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
            }
        }
        // 根据书名删除图书的新接口
        @PostMapping("/deleteByTitle")
        public ResponseEntity<?> deleteBookByTitle(@RequestBody Map<String, String> map, @RequestHeader(value = "user-type", required = false) String userType) {
            if (!"admin".equals(userType)) {


                return new ResponseEntity<>("权限不足，只有管理员可以删除图书", HttpStatus.FORBIDDEN);
            }
            String title = map.get("title");
            try {
                bookService.deleteBookByTitle(title);
                return new ResponseEntity<>("Book deleted successfully", HttpStatus.OK);
            } catch (Exception e) {
                return new ResponseEntity<>("删除图书失败：" + e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
            }
        }

        @DeleteMapping("/{id}")
        public ResponseEntity<?> deleteBook(@PathVariable Long id, @RequestHeader(value = "user-type", required = false) String userType) {
            if (!"admin".equals(userType)) {
                return new ResponseEntity<>("权限不足，只有管理员可以删除图书", HttpStatus.FORBIDDEN);
            }
            try {
                bookService.deleteBook(id);
                return new ResponseEntity<>("Book deleted successfully", HttpStatus.OK);
            } catch (Exception e) {
                return new ResponseEntity<>("删除图书失败：" + e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
            }
        }
        @GetMapping("/{id}")
        public ResponseEntity<Books> getBookById(@PathVariable Long id) {
            Books book = bookService.getBookById(id);

            if (book == null) {
                return new ResponseEntity<>(HttpStatus.NOT_FOUND);
            }

            return new ResponseEntity<>(book, HttpStatus.OK);
        }
        // 新增根据书名修改图书的接口
        @PostMapping("/editByTitle")
        public ResponseEntity<?> editBookByTitle(@RequestBody Map<String, String> map) {
            String oldTitle = map.get("oldTitle");
            String newTitle = map.get("newTitle");
            String newAuthor = map.get("newAuthor");
            String newYearPublishedStr = map.get("newYearPublished");
            int newYearPublished = 0;
            try {
                if (newYearPublishedStr!= null &&!newYearPublishedStr.isEmpty()) {
                    newYearPublished = Integer.parseInt(newYearPublishedStr);
                }
            } catch (NumberFormatException e) {
                return new ResponseEntity<>("出版年份格式错误", HttpStatus.BAD_REQUEST);
            }
            Books newBookInfo = new Books();
            newBookInfo.setTitle(newTitle);
            newBookInfo.setAuthor(newAuthor);
            newBookInfo.setYearPublished(newYearPublished);
            try {
                bookService.editBookByTitle(oldTitle, newBookInfo);
                return new ResponseEntity<>("Book edited successfully", HttpStatus.OK);
            } catch (Exception e) {
                return new ResponseEntity<>("修改图书失败：" + e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
            }
        }
        @GetMapping("/all")
        public ResponseEntity<List<Books>> getBooks() {
            List<Books> books = bookService.getBooks();
            return new ResponseEntity<>(books, HttpStatus.OK);
        }

        @PostMapping("/edit")
        public ResponseEntity<?> editBook(@RequestBody Books book) {
            Books editedBook = bookService.editBook(book);
            return new ResponseEntity<>(editedBook, HttpStatus.OK);
        }

        @PostMapping("/search")
        public ResponseEntity<List<Books>> searchBooks(@RequestBody Map<String, String> map) {
            String keyword = map.get("keyword"); // 获取搜索关键字
            System.out.println("Searching for keyword: " + keyword); // 打印接收的关键词

            List<Books> booksList = null;
            try {
                if (keyword != null && !keyword.isEmpty()) {
                    booksList = booksMapper.selectList(Wrappers.<Books>lambdaQuery()
                            .like(Books::getTitle, keyword) // 模糊查询书名
                            .or()
                            .like(Books::getAuthor, keyword)); // 或者根据作者模糊查询
                    System.out.println("Total books found: " + booksList.size()); // 打印搜索到的书籍数量
                } else {
                    System.out.println("关键词为空");
                }
            } catch (Exception e) {
                booksList = Collections.emptyList(); // 如果出错，返回空列表
                System.err.println("Error during search: " + e.getMessage());
            }

            return new ResponseEntity<>(booksList, HttpStatus.OK);
        }
    }package com.example.librarysystem.entity;


import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import java.io.Serializable;

import lombok.Getter;
import lombok.Setter;

/**
 * <p>
 * 
 * </p>
 *
 * @author xxx
 * @since 2024-12-23
 */
@Getter
@Setter

public class Books implements Serializable {

    private static final long serialVersionUID = 1L;

    @TableId(value = "id", type = IdType.AUTO)
    private Integer id;

    private String title;

    private String author;

    @TableField(value = "year_published")
    private Integer yearPublished;

    public Integer getYear_published(){
        return yearPublished;
    }


    public void setYear_published(Integer yearPublished){
        this.yearPublished = yearPublished;
    }
}
package com.example.librarysystem.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import java.time.LocalDateTime;

import lombok.Getter;
import lombok.Setter;

/**
 * <p>
 * 
 * </p>
 *
 * @author xxx
 * @since 2024-12-23
 */
@Getter
@Setter
@TableName("borrow_records")

public class BorrowRecord implements Serializable {

    private static final long serialVersionUID = 1L;

    @TableId(value = "id", type = IdType.AUTO)
    private Long id;

    private Integer userId;

    private Integer bookId;

    private LocalDateTime borrowDate;

    private String returnDate;

    private Boolean isReturned;

    private String status;


}
package com.example.librarysystem.mapper;


import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.librarysystem.entity.BorrowRecord;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;

import java.util.List;
import java.util.Map;

/**
 * <p>
 *  Mapper 接口
 * </p>
 *
 * @author xxx
 * @since 2024-12-23
 */
@Mapper
public interface BorrowRecordsMapper extends BaseMapper<BorrowRecord> {
    @Select("SELECT br.id, u.username, b.title, b.author, br.borrow_date, br.return_date, br.is_returned " +
            "FROM borrow_records br " +
            "JOIN books b ON br.book_id = b.id " +
            "JOIN users u ON br.user_id = u.id " +
            "WHERE br.user_id = #{userId}")
    List<Map<String, Object>> findBorrowHistoryByUserId(Long userId);
}
package com.example.librarysystem.service;
//
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.example.librarysystem.entity.BorrowRecord;

import com.example.librarysystem.mapper.BorrowRecordsMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.List;

@Service
public class BorrowRecordService {
    @Autowired
    private BorrowRecordsMapper borrowRecordMapper;

    public BorrowRecord borrowBook(BorrowRecord borrowRecord) {
        if (borrowRecord.getBorrowDate() == null) {
            borrowRecord.setBorrowDate(LocalDateTime.now()); // 设置当前时间为借阅时间
        }
        borrowRecordMapper.insert(borrowRecord);
        return borrowRecord;
    }
    public List<BorrowRecord> getBorrowRecordsByUserId(Long userId) {
        return borrowRecordMapper.selectList(
                Wrappers.<BorrowRecord>lambdaQuery().eq(BorrowRecord::getUserId, userId)
        );
    }
    public void returnBook(Long recordId) {
        BorrowRecord record = borrowRecordMapper.selectById(recordId);
        if (record == null) {
            throw new RuntimeException("未找到借阅记录");
        }

        record.setIsReturned(true);
        record.setReturnDate(LocalDateTime.now().toString()); // 或者可以根据需要设定返回日期格式
        borrowRecordMapper.updateById(record);
    }
    public List<BorrowRecord> getBorrowRecords() {
        return borrowRecordMapper.selectList(null);
    }

    public BorrowRecord getBorrowRecordById(Long id) {
        return borrowRecordMapper.selectById(id);
    }

    public void deleteBorrowRecord(Long id) {
        borrowRecordMapper.deleteById(id);
    }

    public BorrowRecord editBorrowRecord(BorrowRecord borrowRecord) {

        borrowRecordMapper.updateById(borrowRecord);
        return borrowRecord;
    }
}    package com.example.librarysystem.service;

    import com.baomidou.mybatisplus.core.toolkit.Wrappers;
    import com.example.librarysystem.entity.Books;
    import com.example.librarysystem.mapper.BooksMapper;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;

    import java.util.List;

    @Service
    public class BookService {

        @Autowired
        private BooksMapper bookMapper;

        public Books addBook(Books books) {
            try {
                // 可以添加日志打印出版年份的值，便于排查问题
                System.out.println("准备插入图书的出版年份: " + books.getYearPublished());
                bookMapper.insert(books);
                return books;
            } catch (Exception e) {
                throw new RuntimeException("图书插入数据库失败", e);
            }
        }

        public void deleteBook(Long id) {
            int rowsAffected = bookMapper.deleteById(id);
            if (rowsAffected == 0) {
                throw new RuntimeException("删除图书失败，可能该图书不存在或删除操作出现问题");
            }
        }
        public void deleteBookByTitle(String title) {
            Books book = bookMapper.selectOne(Wrappers.<Books>lambdaQuery().eq(Books::getTitle, title));
            if (book == null) {
                throw new RuntimeException("要删除的图书不存在");
            }
            int rowsAffected = bookMapper.deleteById(book.getId());
            if (rowsAffected == 0) {
                throw new RuntimeException("删除图书失败，可能删除操作出现问题");
            }
        }
        public List<Books> getBooks() {
            List<Books> booksList = bookMapper.selectList(null);
            for (Books book : booksList) {
                // 只在出版年份为 null 时设置默认值为 0，避免覆盖正确的出版年份
                if (book.getYearPublished() == null) {
                    book.setYearPublished(0);
                }
            }
            return booksList;
        }
        public Books getBookById(Long id) {
            return bookMapper.selectById(id);
        }
        public Books editBook(Books books) {
            if (books.getId() == null) {
                throw new RuntimeException("要修改的图书 id 不能为空");
            }
            // 检查图书是否存在
            Books existingBook = bookMapper.selectById(books.getId());
            if (existingBook == null) {
                throw new RuntimeException("要修改的图书不存在");
            }
            bookMapper.updateById(books);
            return books;
        }
        // 新增根据书名修改图书的方法
        public void editBookByTitle(String oldTitle, Books newBookInfo) {

            Books existingBook = bookMapper.selectOne(Wrappers.<Books>lambdaQuery().eq(Books::getTitle, oldTitle));
            if (existingBook == null) {
                throw new RuntimeException("要修改的图书不存在");
            }
            // 将找到的图书的信息更新为新的信息
            existingBook.setTitle(newBookInfo.getTitle());
            existingBook.setAuthor(newBookInfo.getAuthor());
            existingBook.setYearPublished(newBookInfo.getYearPublished());
            bookMapper.updateById(existingBook);
        }
    }<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>管理员页面</title>
    <link href="./css/admin.css" rel="stylesheet" type="text/css">
</head>
<style>
    li {
        list-style-type: none;
    }

    table {
        width: 100%;
        border-collapse: collapse;
        margin-top: 20px;
    }

    th,
    td {
        border: 1px solid #ddd;
        padding: 12px;
        text-align: center;
    }

    th {
        background-color: #f2f2f2;
        font-weight: bold;
    }

    .book-list-container {
        margin-top: 20px;
    }

    .book-list-container h2 {
        margin-bottom: 20px;
    }

    input[type="checkbox"] {
        width: 20px;
        height: 20px;
        margin-right: 10px;
    }

    .book-list-header {
        display: flex;
        align-items: center;
        margin-bottom: 10px;
    }

    .book-list-header input[type="checkbox"] {
        margin-right: 10px;
    }

    .book-list-container ul {
        list-style-type: none;
        padding: 0;
    }

    .book-list-container li {
        display: flex;
        align-items: center;
        background-color: #fff;
        padding: 10px;
        border: 1px solid #ddd;
        margin-bottom: 10px;
    }

    .book-item {
        display: flex;
        align-items: center;
        flex-grow: 1;
    }

    .book-actions {
        display: flex;
        align-items: center;
        margin-left: 10px;
    }

    .book-actions button {
        margin-left: 18px;
    }

    .user-list-container ul {
        list-style-type: none;
        padding: 0;
        width: 100%;
    }

    .user-list-container li {
        display: flex;
        justify-content: space-between;
        align-items: center;
        background-color: #fff;
        padding: 10px;
        margin-bottom: 10px;
    }

    .search-results-container {
        display: flex;
        flex-wrap: wrap;
        justify-content: center;
        gap: 20px;
        /* 卡片之间的间隔 */
        margin-top: 20px;
    }

    .book-card {
        background-color: #fff;
        border: 1px solid #ddd;
        border-radius: 8px;
        padding: 20px;
        width: 350px;
        box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
        transition: transform 0.2s;
    }

    .book-card:hover {
        transform: scale(1.05);
    }

    .book-card h3 {
        margin-top: 0;
    }

    .book-card p {
        margin: 5px 0;
    }
</style>

<body>
    <div class="topbar">
        <div id="adminName">管理员：</div>
        <button onclick="logout()">退出</button>
    </div>
    <div class="sidebar">
        <h1>管理员菜单</h1>
        <button onclick="showForm('add')">增加图书</button>
        <button onclick="showForm('delete')">删除图书</button>
        <button onclick="showForm('edit')">修改图书</button>
        <button onclick="showForm('search')">查询图书</button>
        <button onclick="showForm('userManagement')">用户管理</button>
        <button onclick="showForm('dataManagement')">图书管理</button>
        <button onclick="showForm('borrowRecords')">借阅记录</button>
    </div>
    <div class="main-content">
        <div class="welcome-message" id="welcomeMessage">
            <h1 style="text-align: center;">欢迎进入管理系统</h1>
        </div>
        <div class="form-container centered-content" id="formContainer" style="display:none;">

        </div>

    </div>
    <script>
        function logout() {
            alert('已退出登录');
            window.location.href = 'login.html';
        }
        function showForm(type, id = null) {

            const formContainer = document.getElementById('formContainer');
            const welcomeMessage = document.getElementById('welcomeMessage');
            formContainer.innerHTML = '';
            formContainer.style.display = 'block';
            welcomeMessage.style.display = 'none';
            switch (type) {
                case 'add':
                    formContainer.innerHTML = `
                        <h1 style="text-align: center";>增加图书</h1>
                        <input type="text" placeholder="书名">
                        <input type="text" placeholder="作者">
                        <input type="number" placeholder="出版年份">
                        <div style="text-align: center;">
                        <button style="padding: 10px 20px; font-size: 16px;" onclick="addBook()">添加</button>
                    `;
                    break;
                case 'delete':
                    formContainer.innerHTML = `
                        <h1 style="text-align: center";>删除图书</h1>
                        <input type="text" id="bookTitle" placeholder="输入书名" style="width: 96%;" />
                        <div style="text-align: center;">
                        <button style="padding: 10px 20px; font-size: 16px;" onclick="deleteBookByTitle()">删除</button>
                    `;
                    break;
                case 'borrowRecords':
                    formContainer.innerHTML = `
                        <div style="text-align: center;">
                        <h1 style="text-align: center";>借阅记录</h1>
                        <div id="borrowRecordsList"></div>`;
                    loadBorrowRecords();
                    break;
                case 'edit':
                    formContainer.innerHTML = `
        <h1 style="text-align: center";>修改图书</h1>
        <input type="text" placeholder="旧书名" id="oldTitle">
        <input type="text" placeholder="新书名" id="newTitle">
        <input type="text" placeholder="新作者" id="newAuthor">
        <input type="number" placeholder="新出版年份" id="newYearPublished">
        <div style="text-align: center;">
        <button style="padding: 10px 20px; font-size: 16px;" onclick="editBookByTitle()">修改</button>
    `;
                    break;
                case 'search':
                    formContainer.innerHTML = `
                        <div style="text-align: center;">
                        <h1 style="text-align: center";>查询图书</h1>
                        <input type="text" placeholder="搜索关键词" id="searchKeyword">
                        <button style="padding: 10px 20px; font-size: 16px;" onclick="searchBooks()">查询</button>
                    `;
                    break;
                case 'userManagement':
                    loadUsers().then(users => {
                        const userItems = users.map(user => `
            <li style="display: flex; justify-content: space-between; align-items: center; width: 100%;">
                <span style="flex-grow: 1; margin-right: 10px;">${user.username}</span>
                <div class="book-actions">
                    <button onclick="editUserForm('${user.id}')" ${user.role === 'admin' ? 'disabled' : ''}>编辑</button>
                    <button onclick="deleteUser('${user.id}')" ${user.role === 'admin' ? 'disabled' : ''}>删除</button>
                </div>
            </li>`).join("");

                        formContainer.innerHTML = `
            <h1 style="text-align: center;">用户管理</h1>
            <div class="user-list-container" style="display: flex; flex-direction: column; align-items: center;">
                <ul style="list-style-type: none; padding: 0;">
                    ${userItems}
                </ul>
            </div>
        `;
                    });
                    break;
                case 'dataManagement':
                    formContainer.innerHTML = `
                        <h2>数据管理</h2>
                        <!-- 这里可以添加数据管理的相关表单或内容 -->
                    `;
                    loadBooks();
                    break;
                case 'borrowRecords':
                    formContainer.innerHTML = `
                    <h2 style="text-align: center";>借阅记录</h2>
                        <!-- 这里可以添加借阅记录的相关表单或内容 -->
                    `;
                    break;
                case 'editUser':
                    fetch(`http://localhost:8080/api/users/edit${id}`)
                        .then(response => {
                            if (!response.ok) {
                                throw new Error('Failed to fetch user data');
                            }
                            return response.json();
                        })
                        .then(user => {
                            const formContainer = document.getElementById('formContainer');
                            formContainer.innerHTML = `
                <input type="hidden" value="${id}" name="id">
                <input type="text" placeholder="用户名" value="${user.username}" name="username">
                <input type="password" placeholder="密码" name="password">
                <select name="role">
                    <option value="user" ${user.role === 'user' ? 'selected' : ''}>用户</option>
                    <option value="admin" ${user.role === 'admin' ? 'selected' : ''}>管理员</option>
                </select>
                <button onclick="editUser(${id})">保存</button>
            `;
                        })
                        .catch(error => {
                            console.error('获取用户数据出错:', error);
                            alert('获取用户数据失败: ' + error.message);
                        });
                    break;
                case 'deleteUser':
                    if (confirm(`确定要删除用户ID为${id}的用户吗？此操作不可撤销！`)) {
                        deleteUser(id);
                    }
                    break;
                default:
                    formContainer.style.display = 'none';
                    welcomeMessage.style.display = 'block'; // 默认显示欢迎消息
            }
        }

        function deleteBookByTitle() {
            const bookTitle = document.getElementById('bookTitle').value; // 获取书名
            if (!bookTitle) {
                alert('请输入书名以进行删除');
                return;
            }
            fetch('http://localhost:8080/api/books/deleteByTitle', {  // 修改接口路径，对应后端新的删除接口
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                    'user-type': 'admin'
                },
                body: JSON.stringify({ title: bookTitle })
            })
                .then(response => {
                    if (!response.ok) {
                        throw new Error('网络响应不正常');
                    }
                    return response.text();
                })
                .then(data => {
                    alert('图书删除成功');
                    loadBooks();  // 重新加载图书列表
                })
                .catch(error => {
                    alert('删除图书时出错：' + error.message);
                });
        }
        function addBook() {
            const formContainer = document.getElementById('formContainer');
            const title = formContainer.querySelector('input[placeholder="书名"]').value;
            const author = formContainer.querySelector('input[placeholder="作者"]').value;
            const yearPublishedInput = formContainer.querySelector('input[placeholder="出版年份"]');
            const year_published_str = yearPublishedInput.value;

            let year_published;
            if (year_published_str.trim() === '') {
                alert('请输入出版年份');
                return;
            }
            if (!isNaN(Number(year_published_str))) {
                year_published = parseInt(year_published_str);
            } else {
                alert('出版年份输入格式不正确，请输入合法的数字');
                return;
            }

            fetch('http://localhost:8080/api/books/add', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                    'user-type': 'admin' // 确保你有相应的权限
                },
                body: JSON.stringify({ title, author, yearPublished: year_published })
            })
                .then(response => {
                    if (response.ok) {
                        return response.json(); // 响应成功时解析 JSON
                    } else {
                        return response.text().then((text) => {
                            throw new Error(text); // 捕获非 2xx 响应
                        });
                    }
                })
                .then(data => {
                    alert('图书添加成功：' + data.title); // 显示添加成功的书名
                    loadBooks(); // 重新加载书籍
                    formContainer.innerHTML = ''; // 清空表单
                })
                .catch(error => {
                    console.error('Error adding book:', error);
                    alert('添加图书失败：' + error.message); // 提示错误信息
                });
        }
        function searchBooks() {
            const keyword = document.getElementById('searchInput').value;
            if (keyword.trim() === '') {
                alert('请输入搜索关键词');
                return;
            }

            fetch('http://localhost:8080/api/books/search', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify({ keyword: keyword })
            })
                .then(response => {
                    if (!response.ok) {
                        throw new Error('网络响应不正常');
                    }
                    return response.json();
                })
                .then(data => {
                    displaySearchResults(data); // 传递返回的数据
                })
                .catch(error => console.error('Error:', error));
        }

        function displaySearchResults(books) {
            const searchResults = document.getElementById('searchResults');
            searchResults.innerHTML = ''; // 清空之前的结果

            if (books.length === 0) {
                searchResults.innerHTML = '<p>没有找到相关书籍</p>';
            } else {
                books.forEach(book => {
                    const listItem = document.createElement('div');
                    listItem.className = 'search-result-item';
                    listItem.innerHTML = `
                <div>
                    <strong>书名:</strong> ${book.title}<br>
                    <strong>作者:</strong> ${book.author}<br>
                    <strong>出版年份:</strong> ${book.yearPublished || '未知'}
                </div>
                <div class="book-actions">
                    <button onclick="borrowBook(${book.id})">借阅</button>
                    <button onclick="addToFavorites(${book.id})">添加到收藏</button>
                </div>
            `;
                    searchResults.appendChild(listItem);
                });
            }
        }

        function loadBooks() {
            console.log('Starting to load books...');
            return fetch('http://localhost:8080/api/books/all')
                .then(response => {
                    console.log('Received response from get-books:', response);
                    if (!response.ok) {
                        throw new Error('网络响应不正常');
                    }
                    return response.json();
                })
                .then(books => {
                    console.log("获取到的图书列表详细信息:", books);
                    displayBooks(books);
                    return Promise.resolve();
                })
                .catch(error => {
                    console.error('Error loading books:', error);
                    alert('加载图书时出错：' + error.message);
                    return Promise.reject(error);
                });
        }
        function displayBooks(books) {
            const formContainer = document.getElementById('formContainer');
            formContainer.innerHTML = `
        <h2 style="text-align: center;">图书管理</h2>
        <div class="book-list-container">
            <div class="book-list-header">
                <input type="checkbox" id="selectAllBooks"> 全选
                <button onclick="deleteSelectedBooks()">删除选中</button>
            </div>
            <ul id="bookList">
    `;
            books.forEach(book => {
                let yearToShow = book.year_published;
                // 仅在year_published为null或undefined或为负数时设置为'暂无出版年份'
                if (yearToShow === null || yearToShow === undefined || yearToShow < 0) {
                    yearToShow = '暂无出版年份';
                }
                formContainer.innerHTML += `
    <li style="display: flex; align-items: center;">
        <div class="book-item" style="flex-grow: 1; display: flex; align-items: center;">
            <input type="checkbox" class="bookCheckbox" value="${book.id}">
            <strong>书名:</strong> ${book.title} &nbsp;&nbsp;
            <strong>作者:</strong> ${book.author} &nbsp;&nbsp;
            <strong>出版年份:</strong> ${yearToShow}
        </div>
    <div class="book-actions">
        <button onclick="editBookForm('${book.id}')">编辑</button>
        <button onclick="deleteBook('${book.id}')">删除</button> <!-- 直接调用删除 -->
    </div>
    </li>
`;
            });
            formContainer.innerHTML += `
            </ul>
        </div>
    `;

            const selectAllCheckbox = document.getElementById('selectAllBooks');
            selectAllCheckbox.addEventListener('change', function () {
                const checkboxes = document.querySelectorAll('.bookCheckbox');
                checkboxes.forEach(checkbox => {
                    checkbox.checked = this.checked;
                });
            });
            const bookCheckboxes = document.querySelectorAll('.bookCheckbox');
            bookCheckboxes.forEach(checkbox => {
                checkbox.addEventListener('change', function () {
                    const allChecked = Array.from(bookCheckboxes).every(cb => cb.checked);
                    selectAllCheckbox.checked = allChecked;
                });
            });
        }
        function deleteSelectedBooks() {
            const checkboxes = document.querySelectorAll('.bookCheckbox:checked');
            const bookIds = Array.from(checkboxes).map(checkbox => checkbox.value);

            if (bookIds.length === 0) {
                alert('没有选中任何书籍。');
                return;
            }

            if (confirm('确定要删除选中的书籍吗？此操作不可撤销！')) {
                bookIds.forEach(id => {
                    deleteBook(id);
                });
            }
        }


        function loadUsers() {
            return fetch('http://localhost:8080/api/users/all')
                .then(response => {
                    if (!response.ok) {
                        throw new Error('网络响应不正常，状态码：' + response.status);
                    }
                    return response.json();
                })
                .then(users => {
                    displayUsers(users);
                    return users;
                })
                .catch(error => {
                    console.error('Error loading users:', error);
                    alert('加载用户时出错：' + error.message);
                    // 可以考虑添加重试逻辑，比如延迟一段时间后重试
                    setTimeout(() => {
                        loadUsers();
                    }, 2000);
                    return [];
                });
        }

        function displayUsers(users) {
            const formContainer = document.getElementById('formContainer');
            formContainer.innerHTML = `
        <h2 style="text-align: center;">用户管理</h2>
        <div class="user-list-container" style="display: flex; flex-direction: column; align-items: center;">
            <ul style="list-style-type: none; padding: 0;">
                ${users.map(user => `
                    <li style="margin: 10px 0; display: flex; justify-content: space-between; align-items: center;">
                        <span style="flex-grow: 1; margin-right: 10px;">${user.username}</span>
                        <div class="book-actions">
                            <button onclick="editUserForm('${user.id}')" ${user.role === 'admin' ? 'disabled' : ''}>编辑</button>
                            <button onclick="deleteUser('${user.id}', '${user.username}')" ${user.role === 'admin' ? 'disabled' : ''}>删除</button>
                        </div>
                    </li>
                `).join('')}
            </ul>
        </div>
    `;
        }
        function loadBorrowRecords() {
            fetch('http://localhost:8080/api/borrow-records')
                .then(response => {
                    if (!response.ok) {
                        throw new Error('网络响应不正常');
                    }
                    return response.json();
                })
                .then(records => {
                    displayBorrowRecords(records);
                })
                .catch(error => {
                    alert('加载借阅记录时出错：' + error.message);
                });
        }

        function displayBorrowRecords(records) {
    const borrowRecordsList = document.getElementById('borrowRecordsList');
    borrowRecordsList.innerHTML = '';

    if (records.length === 0) {
        borrowRecordsList.innerHTML = '<p>无借阅记录。</p>';
    } else {
        const table = document.createElement('table');
        table.innerHTML = `
            <tr>
                <th>用户名</th>
                <th>书名</th>
                <th>作者</th>
                <th>借阅日期</th>
                <th>还书日期</th>
                <th>状态</th>
                <th>操作</th>
            </tr>
        `;

        records.forEach(record => {
            const borrowDate = new Date(record.borrow_date);
            const returnDate = record.return_date ? new Date(record.return_date) : '未还';
            const formattedBorrowDate = borrowDate.toLocaleDateString('zh-CN');
            const formattedReturnDate = returnDate instanceof Date ? returnDate.toLocaleDateString('zh-CN') : '未还';

            const row = document.createElement('tr');
            row.innerHTML = `
                <td>${record.username || '未知'}</td>
                <td>${record.title || '未知'}</td>
                <td>${record.author || '未知'}</td>
                <td>${formattedBorrowDate}</td>
                <td>${formattedReturnDate}</td>
                <td>${record.is_returned ? '已还' : '未还'}</td>
                <td style="text-align: center;">
                    <button onclick="deleteBorrowRecordConfirm(${record.id})">删除</button>
                </td>
            `;
            table.appendChild(row);
        });

        borrowRecordsList.appendChild(table);
    }
}


        function deleteUser(id) {
            if (confirm(`确定要删除用户ID为${id}的用户吗？此操作不可撤销！`)) {
                fetch(`http://localhost:8080/api/users/${id}`, {
                    method: 'DELETE',
                    headers: { 'Content-Type': 'application/json' }
                })
                    .then(response => {
                        if (response.status === 200) {
                            return response.text();
                        } else if (response.status === 404) {
                            throw new Error('用户不存在，无法删除');
                        } else {
                            throw new Error('删除用户时出现未知错误，状态码：' + response.status);
                        }
                    })
                    .then(data => {
                        alert('用户删除成功');
                        loadUsers(); // 重新加载用户列表
                    })
                    .catch(error => {
                        console.error('Error deleting user:', error);
                        alert('删除用户时出现错误：' + error.message);
                    });
            }
        }
        function editUserForm(id) {
            fetch(`http://localhost:8080/api/users/${id}`)
                .then(response => {
                    if (!response.ok) {
                        throw new Error('获取用户信息失败，状态码：' + response.status);
                    }
                    return response.json();
                })
                .then(user => {
                    console.log('获取到的用户信息:', user);
                    const formContainer = document.getElementById('formContainer');
                    formContainer.innerHTML = `
                    <form id="editUserForm">
                        <input type="hidden" value="${id}" name="id">
                        <input type="text" placeholder="用户名" value="${user.username}" name="username">
                        <input type="password" placeholder="旧密码" name="oldPassword" required>
                        <input type="password" placeholder="新密码" name="newPassword">
                        <select name="role">
                            <option value="user" ${user.role === 'user' ? 'selected' : ''}>用户</option>
                            <option value="admin" ${user.role === 'admin' ? 'selected' : ''}>管理员</option>
                        </select>
                        <button type="button" onclick="editUser(${id})">保存</button>
                        <button type="button" onclick="cancelEditUser()">取消</button>
                    </form>
                `;
                })
                .catch(error => {
                    console.error('编辑用户信息获取出错：', error);
                    alert('获取用户信息失败，请稍后重试：' + error.message);
                });
        }
        function editUser(id) {
            const form = document.querySelector(`#editUserForm`);
            if (!form || !(form instanceof HTMLFormElement)) {
                return;
            }
            const formData = new FormData(form);
            // 处理可能存在格式问题的数据，比如去除密码字段前后空格
            formData.set('username', formData.get('username').trim());
            formData.set('oldPassword', formData.get('oldPassword').trim());
            formData.set('newPassword', formData.get('newPassword').trim());
            const data = Object.fromEntries(formData.entries());

            // 发送POST请求到/api/users/edit
            fetch('http://localhost:8080/api/users/edit', {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify(data)
            })
                .then(response => {
                    if (!response.ok) {
                        // 处理错误响应
                        return response.json().then(err => {
                            alert('编辑用户失败，原因：' + (err.message || '未知错误'));
                        });
                    }
                    return response.json(); // 假设成功响应也是JSON格式
                })
                .then(data => {
                    // 处理成功响应
                    alert(data.message || '用户信息更新成功');
                    loadUsers(); // 重新加载用户列表
                })
                .catch(error => {
                    console.error('Error editing user:', error);
                    alert('编辑用户信息时出错，请稍后重试：' + error.message);
                });
        }
        function editBookForm(bookId) {
            fetch(`http://localhost:8080/api/books/${bookId}`)
                .then(response => {
                    if (!response.ok) {
                        throw new Error('未能获取图书信息');
                    }
                    return response.json();
                })
                .then(book => {
                    const formContainer = document.getElementById('formContainer');
                    formContainer.innerHTML = `
                <h2>修改图书</h2>
                <input type="hidden" value="${book.id}" id="bookId">
                <input type="text" placeholder="书名" id="newTitle" value="${book.title}">
                <input type="text" placeholder="作者" id="newAuthor" value="${book.author}">
                <input type="number" placeholder="出版年份" id="newYearPublished" value="${book.yearPublished}">
                <button onclick="editBook()">保存</button>
                <button onclick="cancelEditBook()">取消</button>
            `;
                })
                .catch(error => {
                    alert('获取图书信息失败，请稍后重试：' + error.message);
                });
        }

        function deleteBook(bookId) {
            if (!bookId) {
                alert('无效的图书ID');
                return;
            }
            fetch(`http://localhost:8080/api/books/${bookId}`, {
                method: 'DELETE',
                headers: {
                    'Content-Type': 'application/json',
                    'user-type': 'admin' // 加上相应头，确认请求权限
                }
            })
                .then(response => {
                    if (!response.ok) {
                        throw new Error('网络响应不正常');
                    }
                    return response.text();
                })
                .then(data => {
                    alert('图书删除成功');
                    loadBooks();  // 重新加载图书列表
                })
                .catch(error => {
                    alert('删除图书时出错：' + error.message);
                });
        }

        function editBook() {
            const bookId = document.getElementById('bookId').value;
            let newTitle = document.getElementById('newTitle').value;
            let newAuthor = document.getElementById('newAuthor').value;
            let newYearPublished = document.getElementById('newYearPublished').value;

            if (newTitle === '' || newAuthor === '' || newYearPublished === '') {
                alert('请填写完整信息');
                return;
            }

            const book = {
                id: parseInt(bookId),
                title: newTitle,
                author: newAuthor,
                year_published: parseInt(newYearPublished) // 确保使用合适的字段名称
            };

            fetch('http://localhost:8080/api/books/edit', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                    'user-type': 'admin' // 请确保权限设置
                },
                body: JSON.stringify(book)
            })
                .then(response => {
                    if (!response.ok) {
                        throw new Error('网络响应不正常');
                    }
                    return response.text();
                })
                .then(data => {
                    alert('图书修改成功');
                    loadBooks(); // 刷新书籍列表
                })
                .catch(error => {
                    alert('修改图书时出错：' + error.message);
                });
        }
        function editBookByTitle() {
            const oldTitle = document.getElementById('oldTitle').value;
            const newTitle = document.getElementById('newTitle').value;
            const newAuthor = document.getElementById('newAuthor').value;
            const newYearPublished = document.getElementById('newYearPublished').value;

            if (!oldTitle || !newTitle || !newAuthor || newYearPublished === '') {
                alert('请填写完整信息');
                return;
            }

            fetch('http://localhost:8080/api/books/editByTitle', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify({
                    oldTitle: oldTitle,
                    newTitle: newTitle,
                    newAuthor: newAuthor,
                    newYearPublished: newYearPublished
                })
            })
                .then(response => {
                    if (!response.ok) {
                        throw new Error('网络响应不正常: ' + response.statusText);
                    }
                    return response.text();
                })
                .then(data => {
                    console.log('Book edited:', data);
                    alert('图书修改成功');
                    showForm('dataManagement');
                })
                .catch(error => {
                    alert('修改图书时出错：' + error.message);
                });
        }
        function deleteBorrowRecordConfirm(recordId) {
            if (confirm(`确定要删除借阅记录ID为${recordId}的记录吗？此操作不可撤销！`)) {
                deleteBorrowRecord(recordId);
            }
        }

        function deleteBorrowRecord(recordId) {
            fetch(`http://localhost:8080/api/borrow-records/${recordId}`, {
                method: 'DELETE',
                headers: {
                    'Content-Type': 'application/json'
                }
            })
                .then(response => {
                    if (!response.ok) {
                        throw new Error('网络响应不正常');
                    }
                    return response.text();
                })
                .then(data => {
                    alert('借阅记录删除成功');
                    loadBorrowRecords(); // 重新加载借阅记录
                })
                .catch(error => {
                    console.error('Error deleting borrow record:', error);
                    alert('删除借阅记录时出错：' + error.message);
                });
        }

        // 获取当前管理员信息
        function fetchCurrentAdmin() {
            fetch('http://localhost:8080/admin/current')
                .then(response => {
                    if (!response.ok) {
                        throw new Error('网络响应不正常');
                    }
                    return response.json();
                })
                .then(data => {
                    console.log(data);

                    document.getElementById('adminName').textContent = `管理员：${data.username}`;
                })
                .catch(error => {
                    console.error('获取管理员名错误:', error);
                    document.getElementById('adminName').textContent = '管理员：未知'; // 出错时处理
                });
        }
    </script>
</body>

</html>package com.example.librarysystem.mapper;


import com.example.librarysystem.entity.Books;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;

/**
 * <p>
 *  Mapper 接口
 * </p>
 *
 * @author xxx
 * @since 2024-12-23
 *
 *
 */

@Mapper
public interface BooksMapper extends BaseMapper<Books> {

}
借阅记录这样显示未知	未知	未知	Invalid Date	未还	未还	         后端控制器显示JDBC Connection [HikariProxyConnection@813146093 wrapping com.mysql.cj.jdbc.ConnectionImpl@7fdcbb60] will not be managed by Spring
==>  Preparing: SELECT id,user_id,book_id,borrow_date,return_date,is_returned,status FROM borrow_records
==> Parameters: 
<==    Columns: id, user_id, book_id, borrow_date, return_date, is_returned, status
<==        Row: 62, 16, 118, 2024-12-25 02:54:16.807000, 2024-12-25T10:54:19.784, 1, null
<==      Total: 1
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@58ae4f7d]