引言
图书馆传统的借阅流程往往繁琐,查书、借书、还书常需线下排队。为了优化这一体验,我们设计并实现了一个轻量级的在线图书借阅平台。该系统支持学生和管理员双角色,涵盖图书查询、借阅、续借、归还及超期提醒等核心功能。作为课程设计项目,重点在于利用现代技术栈快速构建规范化的系统架构。
环境准备
开发环境基于 Windows,使用 IntelliJ IDEA 社区版。后端采用 Spring Boot 3.x + MyBatis-Plus + MySQL 8.0,前端使用 Thymeleaf + Bootstrap 实现响应式布局。
1. 基础配置
安装 JDK 并配置环境变量,确保 Maven 能正常拉取依赖。数据库方面,初始化 MySQL 8.0 实例,创建对应的库表结构。
2. 插件辅助
在 IDE 中集成 AI 编程助手,通过自然语言描述需求,快速生成实体类、Mapper 接口及基础业务逻辑,显著提升开发效率。
模块设计与编码
系统遵循分层架构设计,包含 Entity(实体)、DTO(数据传输对象)、VO(视图对象)、Service(业务逻辑)及 Controller(控制层)。
1. 实体层设计
用户实体区分学生与管理员角色,图书实体记录馆藏状态,借阅记录关联双方并计算到期时间。
package com.student.library.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.time.LocalDateTime;
@Data
@NoArgsConstructor
@AllArgsConstructor
@TableName("user")
public class User {
@TableId(type = IdType.AUTO)
private Long id;
private String account;
private String password;
private String name;
private Integer role; // 0=学生,1=管理员
private String className;
private String email;
private LocalDateTime createTime;
}
图书实体需维护库存数量,确保并发下的数据一致性。
package com.student.library.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.time.LocalDateTime;
@Data
@NoArgsConstructor
@AllArgsConstructor
@TableName("book")
public class Book {
@TableId(type = IdType.AUTO)
private Long bookNo;
private String bookName;
private String author;
private Long categoryId;
private String publisher;
private LocalDateTime publishDate;
private Integer totalCount;
private Integer availableCount;
private String description;
}
2. 数据传输对象 (DTO)
DTO 用于接收前端请求参数,并配合校验注解保证数据合法性。
package com.student.library.dto;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
@Data
public class BorrowBookDTO {
@NotNull(message = "学生 ID 不能为空")
private Long studentId;
@NotNull(message = "图书编号不能为空")
private Long bookNo;
@NotNull(message = "借阅天数不能为空")
private Integer borrowDays = 30;
}
3. 业务逻辑实现
借阅服务是核心,涉及事务控制、库存校验及超期判断。
package com.student.library.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.student.library.dto.BorrowBookDTO;
import com.student.library.entity.Book;
import com.student.library.entity.BorrowRecord;
import com.student.library.entity.User;
import com.student.library.mapper.BookMapper;
import com.student.library.mapper.BorrowRecordMapper;
import com.student.library.mapper.UserMapper;
import com.student.library.service.BorrowService;
import com.student.library.vo.BorrowRecordVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDate;
import java.time.temporal.ChronoUnit;
import java.util.List;
import java.util.stream.Collectors;
@Slf4j
@Service
@RequiredArgsConstructor
public class BorrowServiceImpl extends ServiceImpl<BorrowRecordMapper, BorrowRecord> implements BorrowService {
private final BorrowRecordMapper borrowRecordMapper;
private final BookMapper bookMapper;
private final UserMapper userMapper;
@Override
@Transactional
public BorrowRecord borrowBook(BorrowBookDTO borrowBookDTO) {
log.info("学生借阅图书:学生 ID={},图书编号={}", borrowBookDTO.getStudentId(), borrowBookDTO.getBookNo());
// 1. 校验学生身份
User student = userMapper.selectById(borrowBookDTO.getStudentId());
if (student == null || student.getRole() != 0) {
throw new RuntimeException("无效的学生账号");
}
// 2. 校验图书库存
Book book = bookMapper.selectById(borrowBookDTO.getBookNo());
if (book == null || book.getAvailableCount() <= 0) {
throw new RuntimeException("该图书不存在或无库存");
}
// 3. 更新库存并保存记录
book.setAvailableCount(book.getAvailableCount() - 1);
bookMapper.updateById(book);
BorrowRecord record = new BorrowRecord();
record.setStudentId(borrowBookDTO.getStudentId());
record.setBookNo(borrowBookDTO.getBookNo());
record.setBorrowDate(LocalDate.now());
record.setDueDate(LocalDate.now().plusDays(borrowBookDTO.getBorrowDays()));
record.setReturnStatus(0);
save(record);
return record;
}
// ... 其他方法如续借、查询省略,逻辑类似
}
前端展示
前端采用 Bootstrap 5 构建响应式界面,适配 PC 端图书馆终端。
1. 图书查询页
顶部导航栏包含搜索框与分类筛选。列表以卡片形式展示图书封面、书名及剩余可借数量。若库存为 0,显示红色标签提示。
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>图书查询</title>
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<nav class="navbar navbar-dark bg-primary mb-4">
<div class="container">
<a class="navbar-brand" href="#">校园图书馆</a>
</div>
</nav>
<div class="container">
<h3 class="mb-4">图书查询</h3>
<!-- 搜索与列表区域 -->
<div class="row">
<div class="col-md-3">
<div class="list-group">
<a href="#" class="list-group-item active">全部图书</a>
<a href="#" class="list-group-item">计算机类</a>
<a href="#" class="list-group-item">文学类</a>
</div>
</div>
<div class="col-md-9">
<div class="row">
<!-- 图书卡片示例 -->
<div class="col-md-4 mb-4">
<div class="card">
<div class="card-body">
<h5 class="card-title">Java 编程思想</h5>
<p class="card-text">剩余可借:<span class="text-success">5</span>/10</p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>
2. 借阅记录页
表格展示当前借阅状态,临近到期时高亮显示。提供续借与归还预约入口。
优化与调试
1. 安全加固
密码存储采用 BCrypt 加密,避免明文泄露。登录校验时比对哈希值而非原始密码。
2. 业务逻辑完善
- 超期提醒:在查询借阅记录时计算剩余天数,小于 3 天标记预警。
- 库存扣减:借阅操作必须包裹在事务中,确保库存扣减与记录生成原子性一致。
- 分类管理:补充了图书分类的动态管理功能,支持管理员灵活调整。
总结
本项目完整实现了图书借阅的核心业务流程。通过引入 AI 辅助编码,大幅减少了样板代码的编写时间,使开发者能更专注于业务逻辑的实现与系统性能优化。后续可进一步扩展预约功能或与图书馆实际系统对接。

