Skip to content

Repository files navigation

SpringBootApp

A Spring Boot 4.1.0 backend project with RBAC permission management, built with MyBatis-Plus, Sa-Token, and Redis.

Tech Stack

Layer Technology
Framework Spring Boot 4.1.0 / Spring Framework 7.0.8
ORM MyBatis-Plus 3.5.9
Auth Sa-Token 1.45.0 + Redis session storage
Database MySQL 8.4
Cache Redis (Lettuce + connection pool)
API Docs SpringDoc OpenAPI 2.8.5 (Swagger UI)
Logging Logback (SLF4J)
Build Maven 3.9.16 (wrapper)
Java JDK 17

Prerequisites

  • JDK 17
  • MySQL 8.4+
  • Redis 6+
  • Maven 3.9+ (or use the included wrapper mvnw.cmd)

Quick Start

1. Clone & Configure

git clone "https://github.com/Gin4ever688/SpringBootApp"
cd SpringBootApp

2. Database Setup

Execute the SQL files in order to create the database and seed data.

3. Configure application-dev.yaml

Update the datasource and Redis credentials in src/main/resources/application-dev.yaml to match your local environment:

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/test
    username: root
    password: your_password
  data:
    redis:
      host: localhost
      port: 6379
      password: your_redis_password

4. Run

# Using Maven wrapper
mvnw spring-boot:run

# Or open in IDEA and run SpringBootAppApplication

5. Access

URL Description
http://localhost:8000/login.html Login page (static)
http://localhost:8000/index.html Dashboard (static, after login)
http://localhost:8000/swagger-ui.html Swagger API docs
http://localhost:8000/v3/api-docs OpenAPI JSON

Project Structure

src/main/java/com/example/springbootapp/
├── aspect/               # AOP logging (request log aspect)
├── common/               # Common classes
│   ├── ErrorCode.java    # Error code enum
│   └── Result.java       # Unified response body
├── config/               # Configuration classes
│   ├── CorsConfig.java           # CORS
│   ├── MyBatisPlusConfig.java    # MyBatis-Plus
│   ├── OpenApiConfig.java        # Swagger security scheme
│   ├── RedisConfig.java          # Redis template
│   ├── SaTokenConfigure.java     # Sa-Token interceptor
│   └── StpInterfaceImpl.java     # Permission/role loader
├── controller/           # REST controllers
│   ├── AuthController.java       # login / register / password / deactivate
│   ├── MenuController.java       # menu CRUD + nav
│   ├── RoleController.java       # role CRUD
│   └── UserController.java       # user CRUD
├── dto/                  # DTOs
│   ├── req/              # Request DTOs
│   └── resp/             # Response DTOs (PageResp, AuthInfoResp)
├── entity/               # MyBatis-Plus entities
├── filter/               # Servlet filters (TraceFilter with MDC)
├── handler/              # Exception handlers + MetaObjectHandler
├── mapper/               # MyBatis-Plus mappers
├── service/              # Service interfaces + implementations
└── util/                 # Utilities (PasswordUtil)

RBAC Permission Model

User → UserRole → Role → RolePermission → Permission

Tables

Table Description
system_user Users (with password, salt, logic delete)
system_role Roles (code: admin, user, etc.)
system_permission Permission codes (system:user:query, system:menu:create, etc.)
system_user_role User-role mapping
system_role_permission Role-permission mapping
system_menu Navigation menu tree (for frontend sidebar)

Super Admin

Users with role admin automatically get all permissions from system_permission table, regardless of role-permission mappings. Adding a new permission to system_permission is immediately available to all admin users — zero maintenance.

API Reference

Auth (/auth/**)

Method Path Auth Description
POST /auth/login - Login, returns token
POST /auth/register - Register new user (auto-assigns role_id=4)
PUT /auth/password Token Change password (clears token, forces re-login)
POST /auth/deactivateAccount Token Deactivate account (logical delete + logout)
GET /auth/logout - Logout (clear token)
GET /auth/info Token Get user info + permissions + roles
GET /auth/me Token Get current user ID
GET /auth/tokenInfo Token Get token metadata
GET /auth/isLogin - Check login status

Menu (/menu/**)

Method Path Permission Description
GET /menu/nav Login only Navigation sidebar (filtered by user permissions)
GET /menu system:menu:query Paged query
GET /menu/{id} system:menu:query Get by ID
GET /menu/all system:menu:query List all
POST /menu system:menu:create Create
PUT /menu/{id} system:menu:update Update
DELETE /menu/{id} system:menu:delete Delete

Role (/role/**)

Method Path Permission Description
GET /role system:role:query Paged query
GET /role/{id} system:role:query Get by ID
POST /role system:role:create Create
PUT /role/{id} system:role:update Update
DELETE /role/{id} system:role:delete Delete

User (/user/**)

Method Path Permission Description
GET /user system:user:query Paged query
GET /user/{id} system:user:query Get by ID
POST /user system:user:create Create
PUT /user/{id} system:user:update Update
DELETE /user/{id} system:user:delete Delete

Testing

# Login as admin
curl -X POST http://localhost:8000/auth/login \
  -H "Content-Type: application/json" \
  -d '{"username":"admin","password":"admin123"}'
# Response: {"code":200,"data":"xxxx-xxxx-xxx","msg":"success"}

# Get user info + permissions
curl http://localhost:8000/auth/info \
  -H "token: xxxx-xxxx-xxx"

# Query menus (requires system:menu:query)
curl http://localhost:8000/menu?page=1&size=10 \
  -H "token: xxxx-xxxx-xxx"

# Navigation menu (no permission required)
curl http://localhost:8000/menu/nav \
  -H "token: xxxx-xxxx-xxx"

Profiles

The project supports multiple environments through Spring Boot profiles:

Profile Config File Usage
dev (default) application-dev.yaml Development
prod application-prod.yaml Production

Switch profiles via:

# JVM argument
-Dspring.profiles.active=prod

# Environment variable
SPRING_PROFILES_ACTIVE=prod

Global Exception Handling

Exception HTTP Code Response
NotLoginException 401 {code:401, errorCode:"UNAUTHORIZED", msg:"not logged in"}
NotPermissionException 403 {code:403, msg:"no permission: xxx"}
NotRoleException 403 {code:403, msg:"no role: xxx"}
MethodArgumentNotValidException 400 {code:400, errorCode:"PARAM_INVALID", msg:"..."}
DataIntegrityViolationException 400 {code:400, errorCode:"DATA_CONFLICT", msg:"..."}
RuntimeException 400 {code:400, msg:"..."}
Other 500 {code:500, errorCode:"INTERNAL_ERROR"}

Logging

  • Console: colored output with traceId from MDC
  • File: logs/app.log (daily rolling, 100MB max, 30 days retention, GZip compressed)
  • Request logs captured at both Filter layer (all HTTP) and AOP layer (controller methods)

Docker Deployment

Prerequisites

  • Docker Desktop installed and running
  • MySQL (localhost:3307) and Redis (localhost:6380) running on host machine
  • Project JAR built locally

Quick Start

# 1. Build JAR locally
.\mvnw.cmd package -DskipTests

# 2. Build Docker image & start container
docker compose up -d

# 3. Check logs
docker compose logs -f

Update & Redeploy After Code Changes

# Step 1: Rebuild the JAR with latest code
.\mvnw.cmd package -DskipTests

# Step 2: Rebuild Docker image (uses cached layers, fast)
docker compose build

# Step 3: Restart container with new image
docker compose up -d

Or in one line:

.\mvnw.cmd package -DskipTests && docker compose build && docker compose up -d

Other Commands

# View logs
docker compose logs -f

# Stop container (data preserved)
docker compose stop

# Stop & remove container
docker compose down

# Clean rebuild (ignore cache)
docker compose build --no-cache

Notes

  • The container connects to MySQL and Redis on your host machine via host.docker.internal
  • If Docker Hub is unreachable (common in China), configure a registry mirror in Docker Desktop: Settings → Docker Engine → add registry-mirrors, then Apply & Restart

About

A Spring Boot 4.1.0 backend project with RBAC permission management, built with MyBatis-Plus, Sa-Token, and Redis.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages