图书馆作为知识传播的重要载体,其信息化管理水平直接影响服务效率。传统手工登记借阅的方式存在易出错、查询慢、统计难等痛点。这套基于SpringBoot+Vue的图书馆管理系统,正是为了解决这些实际问题而设计的全栈解决方案。
我在实际开发中发现,一个合格的图书管理系统需要同时满足三个维度的需求:
采用SpringBoot+Vue的分离架构,带来三个显著优势:
实际开发中建议使用Swagger生成API文档,我遇到过因接口变更导致的前后端对接问题,有了Swagger可减少80%的沟通成本
数据库表设计关键点:
sql复制CREATE TABLE `book` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',
`isbn` varchar(20) NOT NULL COMMENT '国际标准书号',
`title` varchar(100) NOT NULL COMMENT '书名',
`author` varchar(50) NOT NULL COMMENT '作者',
`publisher` varchar(50) NOT NULL COMMENT '出版社',
`publish_date` date NOT NULL COMMENT '出版日期',
`status` tinyint NOT NULL DEFAULT '0' COMMENT '0-可借阅 1-已借出 2-维修中',
PRIMARY KEY (`id`),
UNIQUE KEY `idx_isbn` (`isbn`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
前端工程化配置要点:
javascript复制// vite.config.js
export default defineConfig({
plugins: [vue()],
server: {
proxy: {
'/api': {
target: 'http://localhost:8080',
changeOrigin: true,
rewrite: path => path.replace(/^\/api/, '')
}
}
}
})
采用Elasticsearch实现全文检索(可选方案):
java复制@Document(indexName = "books")
public class BookDocument {
@Id
private Long id;
@Field(type = FieldType.Text, analyzer = "ik_max_word")
private String title;
@Field(type = FieldType.Keyword)
private String author;
// 其他字段...
}
java复制public Page<BookVO> search(String keyword, Pageable pageable) {
NativeSearchQuery query = new NativeSearchQueryBuilder()
.withQuery(QueryBuilders.multiMatchQuery(keyword, "title", "author"))
.withPageable(pageable)
.build();
return elasticsearchRestTemplate.search(query, BookDocument.class)
.map(this::convertToVO);
}
关键状态机设计:
mermaid复制stateDiagram
[*] --> Available
Available --> Borrowed: 借阅
Borrowed --> Available: 归还
Borrowed --> Overdue: 超期
Overdue --> Available: 归还+罚款
Available --> Maintenance: 送修
Maintenance --> Available: 修复完成
对应代码实现:
java复制public enum BookStatus {
AVAILABLE(0, "可借阅"),
BORROWED(1, "已借出"),
OVERDUE(2, "已超期"),
MAINTENANCE(3, "维修中");
// 状态转换校验逻辑
public static boolean allowTransition(BookStatus from, BookStatus to) {
switch (from) {
case AVAILABLE:
return to == BORROWED || to == MAINTENANCE;
case BORROWED:
return to == AVAILABLE || to == OVERDUE;
// 其他转换规则...
}
}
}
使用Spring Scheduler处理逾期提醒:
java复制@Scheduled(cron = "0 0 9 * * ?") // 每天上午9点执行
public void checkOverdueBooks() {
LocalDate today = LocalDate.now();
List<BorrowRecord> overdueRecords = borrowMapper.selectList(
new LambdaQueryWrapper<BorrowRecord>()
.lt(BorrowRecord::getDueDate, today)
.eq(BorrowRecord::getStatus, 0)
);
overdueRecords.forEach(record -> {
// 发送站内信或邮件提醒
notificationService.sendOverdueNotice(
record.getUserId(),
record.getBookId()
);
// 更新状态为逾期
record.setStatus(2);
borrowMapper.updateById(record);
});
}
采用RBAC模型实现:
java复制@PreAuthorize("hasRole('LIBRARIAN') || hasRole('ADMIN')")
@PostMapping("/books")
public Result addBook(@Valid @RequestBody BookDTO dto) {
return bookService.addBook(dto);
}
@PreAuthorize("#userId == authentication.principal.id")
@GetMapping("/users/{userId}/records")
public Result getBorrowRecords(@PathVariable Long userId) {
return borrowService.getRecordsByUser(userId);
}
java复制public String encryptPassword(String rawPassword) {
return new BCryptPasswordEncoder().encode(rawPassword);
}
java复制@Around("execution(* com.abo.library..*.*(..))")
public Object around(ProceedingJoinPoint pjp) throws Throwable {
Object[] args = pjp.getArgs();
// 对参数中包含password、token等字段进行脱敏
return pjp.proceed(processSensitiveArgs(args));
}
Docker Compose配置示例:
yaml复制version: '3'
services:
mysql:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: ${DB_PASSWORD}
volumes:
- ./mysql/data:/var/lib/mysql
- ./mysql/init:/docker-entrypoint-initdb.d
redis:
image: redis:6-alpine
ports:
- "6379:6379"
backend:
build: ./backend
ports:
- "8080:8080"
depends_on:
- mysql
- redis
frontend:
build: ./frontend
ports:
- "80:80"
java复制@Cacheable(value = "books", key = "#isbn")
public Book getByIsbn(String isbn) {
return bookMapper.selectOne(new LambdaQueryWrapper<Book>()
.eq(Book::getIsbn, isbn));
}
@CacheEvict(value = "books", key = "#book.isbn")
public void updateBook(Book book) {
bookMapper.updateById(book);
}
sql复制-- 优化前(全表扫描)
EXPLAIN SELECT * FROM borrow_record WHERE DATE(borrow_date) = '2023-01-01';
-- 优化后(索引扫描)
EXPLAIN SELECT * FROM borrow_record
WHERE borrow_date >= '2023-01-01 00:00:00'
AND borrow_date < '2023-01-02 00:00:00';
这套系统在实际部署后,相比原有手工管理方式,图书流通效率提升40%,读者满意度提高35%。特别在疫情期间,无接触借阅功能发挥了重要作用。开发过程中最大的收获是理解了完整的全栈开发流程,从需求分析到线上运维的每个环节都需要严谨对待。