从零构建全栈图书管理系统:Spring Boot + Kotlin 后端 & React + Tauri 跨平台前端

御坂スバル Lv1

写在前面

一个合格的图书管理系统需要什么?借书还书、库存管理、用户认证——这些是基本盘。但除此之外呢?安全防枚举、等保三级审计日志、跨平台客户端(Web / Linux / Windows / Android)统一代码库——这些”标配”之外的工程实践,才是一个项目从 Demo 走向生产的关键。

最近我用 Kotlin + Spring Boot 写了一套后端,用 React + TypeScript + Tauri 搭了对应的跨平台前端,完整覆盖了从数据库设计到 CI/CD 构建发布的全流程。这篇文章聊聊架构设计和几个有价值的技术决策。

项目地址:

先上几张截图感受一下最终效果:

Web 端登录

▲ Web 端登录页

Web 端管理员界面

▲ Web 端管理后台 — 图书管理

移动端首页

▲ 移动端首页(未登录)

移动端管理后台

▲ 移动端管理后台

后端:Kotlin + Spring Boot

技术栈

组件 选型 理由
语言 Kotlin 2.2 简洁的语法糖、空安全、协程支持
框架 Spring Boot 4.0 生态成熟,AOP 切面编程天然适合横切关注点
ORM MyBatis-Plus 3.5 零 XML 配置,BaseMapper 通用 CRUD 开箱即用
数据库 MySQL 8.0 InnoDB,utf8mb4
认证 jjwt + Argon2 无状态 JWT + 抗 GPU/ASIC 暴力破解的密码哈希
文档 SpringDoc OpenAPI 3 Swagger UI 自动生成,支持在线调试
日志 Logback + kotlin-logging Janino 条件表达式,按天滚动压缩归档

架构分层

1
2
3
4
controller  →  service  →  mapper  →  entity
↑ ↑
@RequireRole AOP 切面
(角色校验) (审计 + 日志)

三个关键词:清晰安全可审计。分层的意义不在于”规范”,而在于横切关注点的织入位置明确——审计切面环绕在 Service 层,权限切面拦截在 Controller 层,各自职责边界清晰。

统一响应模板

所有接口返回 ApiResult<T> 统一格式,业务码自动映射 HTTP 状态码。这个设计的意义在于:前端只需要处理一种数据结构,错误分支由业务码驱动而非 HTTP 状态码的字符串解析。

安全设计(几个有意思的点)

防用户枚举攻击。登录失败时不返回”用户不存在”或”密码错误”的区分信息,并且无论用户名是否存在,都对输入密码执行 Argon2 哈希比对(dummy hash 策略),消除基于响应时间的枚举攻击面。

审计日志字段级掩码。敏感参数(password、token、secret、authorization)在审计日志中自动替换为 ***,不需要开发者在每个 Controller 里手动处理。实现方式是通过 AOP 切面在参数序列化阶段做 key 匹配和值替换。

AOP 角色权限校验。自定义 @RequireRole 注解,声明式地挂在 Controller 方法上,切面自动从 JWT 中提取角色信息并校验。新增接口时,加一个注解比在方法体内写 if-else 更不容易漏。

等保三级审计日志

审计日志不是事后打印几行 log 就完事的。项目按 GB/T 22239-2019 8.1.4.3 的要求,结构化记录以下字段:

  • 事件类型(CTRL / SVC)
  • 用户标识(用户名 + ID + 角色)
  • 来源 IP + User-Agent
  • HTTP 方法 + 请求路径
  • 操作参数(敏感字段自动掩码)
  • 返回状态码 + 操作对象 ID
  • 执行耗时(毫秒)

持久化策略:按天滚动 + 单文件 100MB 上限 + 保留 365 天 + 总量上限 20GB,超出自动清理。通过环境变量 LOG_PATH 控制落盘路径,不配置则仅输出到控制台。

API 设计

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
公开接口 (无需登录)
POST /api/auth/login 登录
POST /api/auth/logout 登出
GET /api/books/search 搜索图书
GET /api/books/getone 图书详情
GET /api/books/getall 所有图书 (分页)

普通用户 (需 JWT + user 角色)
POST /api/borrows/borrowbook 借书
POST /api/borrows/returnbook 还书
GET /api/borrows/* 我的借阅记录

管理员 (需 JWT + admin 角色)
POST /api/admin/books/* 图书 CRUD + 库存调整
GET /api/admin/borrows/* 全局借阅管理

前端:React + Tauri 跨平台

技术选型

组件 选型 说明
框架 React 19 + TypeScript 5.8 最新稳定版
构建 Vite 7.3 ESM 原生 HMR,毫秒级热更新
CSS Tailwind CSS 4.3 原子化,设计令牌一致
UI 组件 shadcn/ui + Radix 无头组件,完全可控的样式和行为
数据请求 TanStack Query 5 缓存策略、自动 refetch、乐观更新
HTTP Axios 拦截器自动注入 JWT、snake→camel 字段转换
状态管理 Zustand 5 轻量,auth / theme 两个 store 各自独立
路由 React Router 7 嵌套布局路由 + 路由守卫
桌面端 Tauri 2.11 Rust 后端 + WebView 前端,包体积远小于 Electron
Toast Sonner 零配置,支持 rich colors

界面展示

Web 端

未登录(游客模式) 普通用户 管理员
guest-web user-web admin-web

移动端

登录 游客模式 普通用户 管理员
login-mobie guest-mobie user-mobie admin-mobie

桌面端侧边栏导航 + 移动端底部标签栏自适应,同一套代码根据屏幕宽度自动切换布局。

跨平台架构

1
2
3
4
5
6
7
src/
├── api/ # axios 请求函数,snake→camel 自动转换
├── features/ # 页面模块:auth / books / borrows / admin
├── components/ # shadcn/ui 组件 + 布局组件
├── router/ # React Router + 路由守卫
├── store/ # Zustand:auth + theme
└── hooks/ # useIsMobile / usePlatform

一套代码库,五种构建产物:

平台 产物
Web .tar.gz .zip(SPA 静态文件)
Linux .AppImage .deb .rpm .pkg.tar.zst
Windows .msi .exe
macOS .dmg
Android .apk(arm64 / x86_64 / universal)

响应式布局

桌面端使用侧边栏导航,移动端自动切换为底部标签栏。useIsMobile hook 通过媒体查询判断断点,布局组件根据结果渲染不同的导航组件。不是两套代码,而是同一套组件树 + 条件渲染。

深色模式

跟随系统主题 / 手动切换 / localStorage 持久化,三种模式无缝切换。Tailwind 的 dark: 变体配合 CSS 变量驱动,主题切换瞬间生效无闪烁。

路由守卫

未登录用户访问需要认证的页面会自动重定向到登录页;普通用户访问管理后台会被拦截。守卫逻辑集中在 router/guards.tsx,每个路由声明 requireAuthrequiredRole 元信息,守卫组件统一处理。

部署

后端

1
2
3
4
5
6
7
8
9
# 构建 jar
./gradlew bootJar
java -jar build/libs/bookMgr-0.1.jar

# 或 Docker
docker pull git.msksbr.com/msksbr/bookmgr:latest
docker run -d --name bookmgr -p 8080:8080 \
-e DB_URL=... -e DB_PASSWORD=... -e JWT_SECRET=... \
git.msksbr.com/msksbr/bookmgr:latest

提供完整的 compose.yaml + .env 示例,支持 Docker Compose 一键部署。日志目录通过 volume 挂载到宿主机,方便日志采集和分析。

前端

1
2
3
4
5
6
7
8
9
10
# Web 构建
pnpm build
# 产物在 dist/,丢进 Nginx 即可

# 桌面端
pnpm tauri build

# Docker
docker pull git.msksbr.com/msksbr/bookmgr-client:latest
docker run -d -p 80:80 git.msksbr.com/msksbr/bookmgr-client:latest

前端 Docker 镜像基于 nginx:alpine,多阶段构建(Node 编译 + Nginx 服务),最终镜像仅含静态文件,体积小启动快。

一些工程实践

几个值得一提的点:

  1. 零 XML 配置的 MyBatis-Plus。整个项目没有一行 mapper XML 文件,全部通过 BaseMapper<T> + Lambda QueryWrapper 实现。代码即文档,不需要在 XML 和 Java 之间跳转。

  2. 协程并发查询。借阅记录查询时,用户信息和图书信息是独立的两条 SQL。用 kotlinx-coroutinesasync/await 并发发起,减少串行等待时间。

  3. 前端字段名自动转换。后端返回 snake_case,前端使用 camelCase。Axios 拦截器 + transformResponse 递归转换,API 层完全无感。

  4. 收集发布产物脚本。前端项目提供 collect-artifacts.sh / collect-artifacts.cmd,自动将各平台构建产物汇总到 releases/<version>/ 目录并规范命名。CI/CD 流程可以直接调用,不需要手动整理。

结语

这个项目从数据库 schema 到前端 UI 组件,从安全审计到跨平台打包,覆盖了一条完整的技术链路。如果你正在学 Kotlin/Spring Boot,或者想了解 Tauri 跨平台开发的实践,可以参考一下项目结构和实现细节。

两个项目均以 MIT 协议开源,欢迎 Star 和 PR。

  • 标题: 从零构建全栈图书管理系统:Spring Boot + Kotlin 后端 & React + Tauri 跨平台前端
  • 作者: 御坂スバル
  • 创建于 : 2026-05-26 18:45:00
  • 更新于 : 2026-05-31 11:23:44
  • 链接: https://msksbr.com/2026/05/26/bookMgr-system/
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。
评论