Files
bookMgr/README.MD
T
msksbr 87e31efa85 docs(readme): fix heading levels in deployment config section
Demote subheadings from h3 to h4 to reflect correct document
structure hierarchy.
2026-05-24 13:49:37 +08:00

12 KiB
Raw Permalink Blame History

图书管理系统

version Kotlin Spring Boot MySQL Java 21 license

一个基于 Spring Boot + Kotlin + MyBatis-Plus 的后端图书管理系统,提供图书管理、用户认证、借阅归还等核心功能。项目注重安全性、可审计性,等保三级审计日志开箱即用。

功能

  • 认证与授权 — JWT 无状态登录,Argon2 密码哈希,基于 AOP 的角色权限校验(admin / user),防用户枚举攻击
  • 图书管理 — 搜索(书名 / 作者)、查看详情、新增 / 修改 / 删除 / 调整库存(管理员),书名 + 作者判重
  • 借阅管理 — 借书 / 还书(自动扣减 / 恢复库存)、个人借阅记录、管理员可查看全部借阅及手动操作
  • 审计日志 — 等保三级(GB/T 22239-2019 8.1.4.3),结构化审计日志,含用户标识、来源 IP、操作参数、结果摘要,支持持久化到文件
  • 统一响应 — 所有接口返回 ApiResult<T> 统一格式,业务码自动映射 HTTP 状态码
  • OpenAPI 文档 — SpringDoc 自动生成,支持在线调试

技术栈

类别 技术 版本 说明
语言 Kotlin 2.2.21 JVM 目标
框架 Spring Boot 4.0.6
ORM MyBatis-Plus 3.5.15 零 XML 配置,BaseMapper 通用 CRUD
数据库 MySQL 8.0 InnoDButf8mb4
认证 jjwt (JSON Web Token) 0.13.0 HMAC-SHA256 签名
密码 Argon2 (Spring Security Crypto) 5.3+ 抗 GPU/ASIC 暴力破解
协程 kotlinx-coroutines 1.10.2 并发查询用户 + 图书信息
文档 SpringDoc OpenAPI 3.0.3 Swagger UI
AOP AspectJ Weaver 日志 / 审计 / 权限三切面
日志 Logback + kotlin-logging 7.0.0 Janino 条件表达式,按天滚动

快速开始

1. 准备数据库

MySQL 8.0 中新建一个数据库(如 bookmgr),然后运行建表脚本:

mysql -u root -p bookmgr < bookmgr.schema.sql

脚本只建表,不插数据。默认用户由应用首次启动时自动创建。

2. 配置环境变量

生产环境通过环境变量注入配置:

export DB_DRIVER=com.mysql.cj.jdbc.Driver
export DB_TYPE=mysql
export DB_URL=localhost
export DB_PORT=3306
export DB_NAME=bookmgr
export DB_USER=root
export DB_PASSWORD=your-password
export JWT_SECRET=your-secret-at-least-32-chars
export JWT_EXPIRATION_TIME=86400000   # 可选,默认 24 小时,单位毫秒
export LOG_PATH=/var/log/bookmgr      # 可选,不设置则不写日志文件
export LOG_EXPORT_AUDIT=true          # 可选,审计日志持久化,默认开启
export LOG_EXPORT_RUNTIME=false       # 可选,运行日志持久化,默认关闭
export LOG_LEVEL=INFO                 # 可选,包级别日志级别,默认 INFO
变量 必填 说明
DB_DRIVER 驱动类名
DB_TYPE 数据库类型(mysql
DB_URL 数据库地址
DB_PORT 数据库端口
DB_NAME 数据库名
DB_USER 数据库用户
DB_PASSWORD 数据库密码
JWT_SECRET 强烈建议 不设置则每次启动随机生成,已签发 token 全部失效
JWT_EXPIRATION_TIME token 有效期(毫秒),默认 86400000(24 小时)

3. 运行

./gradlew bootRun

4. 默认用户

应用首次启动时自动创建以下用户(幂等,已存在则跳过):

用户名 密码 角色
admin admin 管理员
user01 user01 普通用户
user02 user02 普通用户

注意:预置用户当前硬编码在 InitUserRunner 中。未来计划分三步演进:硬编码 → 配置文件 → 前端初始化向导。生产部署后请第一时间修改密码。

开发指南

IDEA 运行配置

  1. 复制 src/main/resources/application.yamlapplication-dev.yaml,修改数据库连接等本地配置
  2. IDEA → Run Configuration → Active profiles 填写 dev

  1. 启动即可

示例 application-dev.yaml

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/bookmgr
    username: root
    password: your-password
  jackson:
    date-format: yyyy-MM-dd HH:mm:ss
    time-zone: GMT+8
mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.commons.JakartaCommonsLoggingImpl
logging:
  level:
    com.msksbr.bookmgr: DEBUG
  export:
    path: ./log
    runtime-enabled: true
jwt:
  expiration: 86400000
springdoc:
  swagger-ui:
    enabled: true
  api-docs:
    enabled: true

Swagger 文档

开发环境启动后访问:http://localhost:8080/swagger-ui/index.html

生产环境默认关闭,防止 API 文档暴露。

API 概览

公开接口:
  POST   /api/auth/login          — 登录
  POST   /api/auth/logout         — 登出
  GET    /api/books/search         — 搜索图书
  GET    /api/books/getone         — 图书详情
  GET    /api/books/getall         — 所有图书

普通用户(需 JWT + user 角色):
  GET    /api/borrows/getall       — 我的借阅
  GET    /api/borrows/search       — 搜索我的借阅
  GET    /api/borrows/getone       — 借阅详情
  POST   /api/borrows/borrowbook   — 借书
  POST   /api/borrows/returnbook   — 还书

管理员(需 JWT + admin 角色):
  POST   /api/admin/books/add       — 新增图书
  POST   /api/admin/books/update    — 修改图书
  POST   /api/admin/books/delete    — 删除图书
  POST   /api/admin/books/update-stock — 调整库存
  GET    /api/admin/borrows/search  — 搜索借阅
  GET    /api/admin/borrows/getone  — 借阅详情
  GET    /api/admin/borrows/getall  — 全部借阅
  POST   /api/admin/borrows/borrowbook — 手动借书
  POST   /api/admin/borrows/returnbook — 手动还书

请求示例:

# 登录获取 token
curl -X POST http://localhost:8080/api/auth/login \
  -H "Content-Type: application/json" \
  -d '{"username":"admin","password":"admin"}'

# 搜索图书
curl "http://localhost:8080/api/books/search?query=西游记"

# 借书
curl -X POST "http://localhost:8080/api/borrows/borrowbook?bookId=1" \
  -H "Authorization: Bearer <token>"

项目结构

src/main/kotlin/com/msksbr/bookmgr/
├── controller/          # 控制器 — 接口入口
├── service/             # 服务接口
│   └── impl/            # 服务实现 — 业务逻辑
├── mapper/              # MyBatis-Plus 映射器 — 数据访问
├── entity/              # 实体 — 表映射
├── dto/                 # 请求体 DTO
├── vo/                  # 响应 VO
│   └── borrow/          # 借阅相关 VO
├── config/              # 配置 — JWT / 密码 / AOP 切面 / 异常处理 / OpenAPI
├── annotation/          # 自定义注解 — @RequireRole
├── runner/              # 启动任务 — InitUserRunner
├── script/              # 扩展 — log / audit Logger 快捷获取
└── template/            # ApiResult<T> 统一响应模板

部署

Java 直接运行

./gradlew bootJar
java -jar build/libs/bookMgr-0.1.jar

bootJar 会自动排除 application-dev.yaml

Docker

镜像基于 bellsoft/liberica-runtime-container:jre-21-slim-muslJVM 参数 -Xmx512m -Dfile.encoding=UTF-8,暴露 8080 端口。

# 拉取镜像
docker pull git.msksbr.com/msksbr/bookmgr:v0.1

# 运行
docker run -d \
  --name bookmgr \
  -p 8080:8080 \
  -e DB_DRIVER=com.mysql.cj.jdbc.Driver \
  -e DB_TYPE=mysql \
  -e DB_URL=your-db-host \
  -e DB_PORT=3306 \
  -e DB_NAME=bookmgr \
  -e DB_USER=root \
  -e DB_PASSWORD=your-password \
  -e JWT_SECRET=your-secret \
  -e LOG_PATH=/var/log/bookmgr \
  git.msksbr.com/msksbr/bookmgr:v0.1

镜像托管于私有 Gitea 仓库:git.msksbr.com/msksbr/bookMgr

Docker Compose

部署配置文件说明

项目提供标准化 compose\.yaml 部署文件,支持一键启动、环境隔离、日志持久化,适配本地开发与测试环境,默认采用手动管控模式,服务器重启后不会自动拉起服务,需手动执行启动命令。

compose.yaml 配置

services:
  bookmgr:
    image: git.msksbr.com/msksbr/bookmgr:latest
    container_name: bookmgr
    restart: unless-stopped  # 官方标准策略:异常自动重启、默认开机自启,仅手动stop后重启机器不会自启

    # 加载本地环境变量配置文件
    env_file:
      - .env

    # 端口映射:主机8080映射容器8080端口
    ports:
      - "8080:8080"

    # 日志目录持久化挂载,容器日志落地至宿主机
    volumes:
      - ./log:/var/log/bookmgr

    # 本地MySQL专用网络穿透(宿主机数据库开启注释使用)
    # extra_hosts:
    #   - host.docker.internal:host-gateway

.env 环境变量配置示例

统一管理数据库、日志等核心配置,无需修改 compose 文件,开箱即用:

# ====================== 数据库核心配置 ======================
# MySQL驱动类
DB_DRIVER=com.mysql.cj.jdbc.Driver
# 数据库类型
DB_TYPE=mysql
# 数据库连接地址
# Docker容器访问本地MySQL请改为:host.docker.internal
DB_URL=localhost
# MySQL端口号
DB_PORT=3306
# 业务数据库名称
DB_NAME=bookmgr
# 数据库登录用户名
DB_USER=root
# 数据库登录密码
DB_PASSWORD=password

# ====================== 日志配置 ======================
# 容器内日志存储路径
LOG_PATH=/var/log/bookmgr
# 开启运行时日志导出,便于问题排查(推荐开启)
LOG_EXPORT_RUNTIME=true

关键使用说明

  • 网络适配:若 MySQL 部署在宿主机,需取消 extra\_hosts 注释,并将 DB\_URL 修改为 host\.docker\.internal,解决容器无法访问宿主机数据库问题。

  • 运行模式restart: no 为手动测试专用模式,服务完全手动管控,关机/重启不会自启,适配黑盒测试场景。

  • 日志持久化:自动将容器运行日志挂载到宿主机 \./log 目录,永久留存,方便日志排查与数据分析。

  • 版本更新:搭配自研镜像构建脚本,latest 标签会自动同步最新构建版本,支持一键更新部署。

审计日志

满足等保三级要求的结构化审计日志,默认输出到控制台。配置 LOG_PATH 后自动持久化到文件:

$LOG_PATH/
├── audit/
│   ├── audit.log              # 当天审计日志
│   └── audit.2026-05-23.0.gz  # 历史归档(滚动策略:按天 + 100MB,保留 365 天,上限 20GB
└── runtime/
    ├── runtime.log            # 当天运行日志(需 LOG_EXPORT_RUNTIME=true
    └── runtime.2026-05-23.0.gz

审计日志记录字段:事件类型(CTRL / SVC)、用户名、用户 ID、角色、来源 IP、User-Agent、HTTP 方法 + 路径、操作参数(敏感字段自动掩码)、返回状态码、操作对象 ID、耗时。

安全特性

  • 密码使用 Argon2 哈希存储,即使数据库泄露也无法还原
  • 登录失败时对齐响应时间(dummy hash),防止基于延时的用户枚举
  • 敏感参数(password / token / secret / authorization)在审计日志中自动掩码为 ***
  • JWT 密钥支持环境变量注入,不配置则每次启动随机生成
  • 全局异常捕获,不向客户端泄露堆栈信息
  • 生产环境默认关闭 Swagger 文档

声明

本项目基于 MIT 协议开源。本软件无任何销售渠道,不收取费用。请遵守开源协议合法使用。

作者