从零构建全栈图书管理系统:Spring Boot + Kotlin 后端 & React + Tauri 跨平台前端
写在前面
一个合格的图书管理系统需要什么?借书还书、库存管理、用户认证——这些是基本盘。但除此之外呢?安全防枚举、等保三级审计日志、跨平台客户端(Web / Linux / Windows / Android)统一代码库——这些”标配”之外的工程实践,才是一个项目从 Demo 走向生产的关键。
最近我用 Kotlin + Spring Boot 写了一套后端,用 React + TypeScript + Tauri 搭了对应的跨平台前端,完整覆盖了从数据库设计到 CI/CD 构建发布的全流程。这篇文章聊聊架构设计和几个有价值的技术决策。
项目地址:
先上几张截图感受一下最终效果:

▲ 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 | controller → service → mapper → entity |
三个关键词:清晰、安全、可审计。分层的意义不在于”规范”,而在于横切关注点的织入位置明确——审计切面环绕在 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 | 公开接口 (无需登录) |
前端: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 端
| 未登录(游客模式) | 普通用户 | 管理员 |
|---|---|---|
![]() |
![]() |
![]() |
移动端
| 登录 | 游客模式 | 普通用户 | 管理员 |
|---|---|---|---|
![]() |
![]() |
![]() |
![]() |
桌面端侧边栏导航 + 移动端底部标签栏自适应,同一套代码根据屏幕宽度自动切换布局。
跨平台架构
1 | src/ |
一套代码库,五种构建产物:
| 平台 | 产物 |
|---|---|
| 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,每个路由声明 requireAuth 和 requiredRole 元信息,守卫组件统一处理。
部署
后端
1 | # 构建 jar |
提供完整的 compose.yaml + .env 示例,支持 Docker Compose 一键部署。日志目录通过 volume 挂载到宿主机,方便日志采集和分析。
前端
1 | # Web 构建 |
前端 Docker 镜像基于 nginx:alpine,多阶段构建(Node 编译 + Nginx 服务),最终镜像仅含静态文件,体积小启动快。
一些工程实践
几个值得一提的点:
零 XML 配置的 MyBatis-Plus。整个项目没有一行 mapper XML 文件,全部通过
BaseMapper<T>+ Lambda QueryWrapper 实现。代码即文档,不需要在 XML 和 Java 之间跳转。协程并发查询。借阅记录查询时,用户信息和图书信息是独立的两条 SQL。用
kotlinx-coroutines的async/await并发发起,减少串行等待时间。前端字段名自动转换。后端返回
snake_case,前端使用camelCase。Axios 拦截器 +transformResponse递归转换,API 层完全无感。收集发布产物脚本。前端项目提供
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 进行许可。



