基于PRD需求,本架构设计提供一个完整的shadcn管理后台全栈启动模板,专注于用户管理功能,采用现代化的技术栈和最佳实践。
graph TB
subgraph "前端应用层"
A[Admin管理后台 - React 19]
B[Web端 - React 19]
C[小程序 - Taro 4]
end
subgraph "后端服务层"
D[Hono API服务器]
E[认证服务]
F[用户管理服务]
end
subgraph "数据存储层"
G[MySQL数据库]
H[Redis缓存]
I[MinIO文件存储]
end
subgraph "基础设施层"
J[Docker容器]
K[CI/CD流水线]
L[监控日志]
end
A --> D
B --> D
C --> D
D --> E
D --> F
E --> G
F --> G
D --> H
D --> I
J --> A&B&C&D
shadcn-admin-template/
├── packages/
│ ├── client/ # 前端管理后台
│ │ ├── src/
│ │ │ ├── components/ # 通用组件
│ │ │ ├── pages/ # 页面组件
│ │ │ │ ├── auth/ # 认证相关页面
│ │ │ │ ├── users/ # 用户管理页面
│ │ │ │ └── dashboard/ # 仪表板页面
│ │ │ ├── hooks/ # 自定义Hooks
│ │ │ ├── lib/ # 工具库
│ │ │ ├── types/ # TypeScript类型定义
│ │ │ └── styles/ # 样式文件
│ │ ├── public/ # 静态资源
│ │ └── vite.config.ts # Vite配置
│ ├── server/ # 后端API服务
│ │ ├── src/
│ │ │ ├── api/ # API路由
│ │ │ │ ├── auth/ # 认证路由
│ │ │ │ ├── users/ # 用户路由
│ │ │ │ └── health/ # 健康检查
│ │ │ ├── modules/ # 业务模块
│ │ │ │ ├── auth/ # 认证模块
│ │ │ │ ├── users/ # 用户模块
│ │ │ │ └── database/ # 数据库模块
│ │ │ ├── middleware/ # 中间件
│ │ │ │ ├── auth.ts # 认证中间件
│ │ │ │ ├── cors.ts # CORS中间件
│ │ │ │ └── error.ts # 错误处理
│ │ │ ├── migrations/ # 数据库迁移脚本
│ │ │ ├── types/ # 类型定义
│ │ │ └── utils/ # 工具函数
│ │ └── package.json
│ └── shared/ # 共享代码
│ └── types/ # 共享类型定义
├── docker/ # Docker配置
├── docs/ # 文档
├── scripts/ # 部署脚本
└── package.json # 根package.json
mini/
├── config/ # 配置文件
│ ├── dev.js # 开发环境配置
│ ├── prod.js # 生产环境配置
│ └── index.js # 主配置
├── src/
│ ├── pages/ # 页面组件
│ │ ├── index/ # 首页
│ │ ├── auth/ # 认证页面
│ │ └── profile/ # 个人资料
│ ├── components/ # 通用组件
│ ├── utils/ # 工具函数
│ │ ├── api.ts # API调用
│ │ ├── auth.ts # 认证工具
│ │ └── request.ts # 请求封装
│ ├── services/ # 服务层
│ ├── stores/ # 状态管理
│ └── assets/ # 静态资源
├── types/ # 类型定义
├── app.config.ts # 应用配置
└── package.json
{
"dependencies": {
"react": "^19.0.0",
"react-dom": "^19.0.0",
"react-router-dom": "^7.0.0",
"@tanstack/react-query": "^5.0.0",
"react-hook-form": "^7.0.0",
"@hookform/resolvers": "^5.2.1",
"zod": "^4.0.14",
"lucide-react": "^0.300.0",
"@heroicons/react": "^2.0.0",
"clsx": "^2.0.0",
"tailwind-merge": "^2.0.0"
},
"devDependencies": {
"typescript": "^5.0.0",
"vite": "^7.0.0",
"@vitejs/plugin-react": "^5.0.0",
"tailwindcss": "^4.0.0",
"autoprefixer": "^10.0.0",
"postcss": "^8.0.0",
"eslint": "^9.0.0",
"prettier": "^3.0.0",
"vitest": "^3.0.0",
"@testing-library/react": "^16.0.0",
"cross-env": "^7.0.0"
}
}
与技术栈2.1.1相同,可根据业务需求调整组件库。
{
"dependencies": {
"@tarojs/taro": "^4.0.0",
"@tarojs/react": "^4.0.0",
"react": "^18.0.0",
"react-dom": "^18.0.0",
"@tanstack/react-query": "^5.0.0",
"react-hook-form": "^7.0.0",
"@hookform/resolvers": "^5.2.1",
"zod": "^4.0.14",
"@egoist/tailwindcss-icons": "^0.6.0",
"clsx": "^2.0.0"
},
"devDependencies": {
"typescript": "^5.0.0",
"@tarojs/plugin-framework-react": "^4.0.0",
"tailwindcss": "^4.0.0",
"vitest": "^3.0.0"
}
}
框架选型说明: 选用Hono框架而非Express,主要基于以下考虑:
部署灵活性: 支持多种运行时环境(Node.js, Deno, Bun, Cloudflare Workers等)
{
"dependencies": {
"hono": "^4.0.0",
"typeorm": "^0.3.0",
"mysql2": "^3.0.0",
"ioredis": "^5.0.0",
"bcrypt": "^5.0.0",
"jsonwebtoken": "^9.0.0",
"openai": "^4.0.0",
"minio": "^7.0.0",
"compression": "^1.7.0",
"dotenv": "^16.0.0",
"debug": "^4.3.0",
"uuid": "^9.0.0",
"dayjs": "^1.11.0",
"axios": "^1.0.0",
"zod": "^4.0.14"
},
"devDependencies": {
"typescript": "^5.0.0",
"@types/node": "^20.0.0",
"vitest": "^3.0.0",
"@types/bcrypt": "^5.0.0",
"@types/jsonwebtoken": "^9.0.0",
"@types/compression": "^1.7.0",
"@types/debug": "^4.1.0",
"@types/uuid": "^9.0.0",
"cross-env": "^7.0.0"
}
}
CREATE TABLE users (
id VARCHAR(36) PRIMARY KEY DEFAULT UUID(),
email VARCHAR(255) UNIQUE NOT NULL,
password_hash VARCHAR(255) NOT NULL,
name VARCHAR(100) NOT NULL,
role ENUM('admin', 'user', 'moderator') DEFAULT 'user',
status ENUM('active', 'inactive', 'suspended') DEFAULT 'active',
avatar_url VARCHAR(500),
last_login_at TIMESTAMP NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX idx_email (email),
INDEX idx_status (status),
INDEX idx_created_at (created_at)
);
由于我们使用了Redis,Session信息可以完全存储在Redis中,无需在数据库中创建Session表。Redis提供了更好的性能和自动过期功能。
Redis Session数据结构:
// Session数据格式
interface SessionData {
userId: string;
email: string;
name: string;
role: UserRole;
issuedAt: number; // 时间戳
expiresAt: number; // 时间戳
}
// Redis键格式: session:{token}
// 设置过期时间与JWT token过期时间一致
优势:
Redis配置示例:
// session服务示例
const sessionService = {
async createSession(token: string, user: User, expiresIn: number) {
const sessionData = {
userId: user.id,
email: user.email,
name: user.name,
role: user.role,
issuedAt: Date.now(),
expiresAt: Date.now() + expiresIn * 1000
};
await redis.setex(`session:${token}`, expiresIn, JSON.stringify(sessionData));
},
async getSession(token: string) {
const data = await redis.get(`session:${token}`);
return data ? JSON.parse(data) : null;
},
async deleteSession(token: string) {
await redis.del(`session:${token}`);
},
async deleteUserSessions(userId: string) {
// 可以使用Redis SCAN命令查找并删除用户的所有session
const keys = await redis.keys(`session:*`);
for (const key of keys) {
const session = await redis.get(key);
if (session && JSON.parse(session).userId === userId) {
await redis.del(key);
}
}
}
};
sequenceDiagram
participant Client as 前端应用
participant AuthAPI as 认证API
participant DB as 数据库
participant Redis as Redis缓存
Client->>AuthAPI: POST /auth/login
AuthAPI->>DB: 验证用户凭据
DB-->>AuthAPI: 用户数据
AuthAPI->>AuthAPI: 生成JWT Token
AuthAPI->>Redis: 存储Session
AuthAPI-->>Client: 返回Token
Client->>AuthAPI: 携带Token请求
AuthAPI->>Redis: 验证Token有效性
Redis-->>AuthAPI: Session信息
AuthAPI-->>Client: 授权数据
flowchart TD
A[用户列表请求] --> B[认证中间件]
B --> C{Token有效?}
C -->|是| D[查询用户数据]
C -->|否| E[返回401错误]
D --> F[数据库查询]
F --> G[数据格式化]
G --> H[返回分页结果]
I[创建用户请求] --> J[数据验证]
J --> K{验证通过?}
K -->|是| L[密码加密]
K -->|否| M[返回验证错误]
L --> N[保存用户数据]
N --> O[返回创建结果]
// POST /auth/login
interface LoginRequest {
email: string;
password: string;
}
interface LoginResponse {
token: string;
user: User;
expiresIn: number;
}
// POST /auth/register
interface RegisterRequest {
email: string;
password: string;
name: string;
}
// POST /auth/refresh
interface RefreshResponse {
token: string;
expiresIn: number;
}
// GET /users
interface GetUsersRequest {
page?: number;
limit?: number;
search?: string;
status?: UserStatus;
}
interface GetUsersResponse {
users: User[];
total: number;
page: number;
limit: number;
}
// POST /users
interface CreateUserRequest {
email: string;
password: string;
name: string;
role?: UserRole;
}
// PUT /users/:id
interface UpdateUserRequest {
name?: string;
role?: UserRole;
status?: UserStatus;
}
// DELETE /users/:id
interface DeleteUserResponse {
success: boolean;
message: string;
}
# docker-compose.dev.yml
version: '3.8'
services:
db:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: rootpassword
MYSQL_DATABASE: shadcn_admin
MYSQL_USER: admin
MYSQL_PASSWORD: admin123
ports:
- "3306:3306"
volumes:
- mysql_data:/var/lib/mysql
- ./init.sql:/docker-entrypoint-initdb.d/init.sql
redis:
image: redis:7-alpine
ports:
- "6379:6379"
volumes:
- redis_data:/data
minio:
image: minio/minio
ports:
- "9000:9000"
- "9001:9001"
environment:
MINIO_ROOT_USER: minioadmin
MINIO_ROOT_PASSWORD: minioadmin
command: server /data --console-address ":9001"
volumes:
- minio_data:/data
api:
build:
context: .
dockerfile: Dockerfile.api
ports:
- "3001:3001"
environment:
- NODE_ENV=development
- DATABASE_URL=mysql://admin:admin123@db:3306/shadcn_admin
- REDIS_URL=redis://redis:6379
- JWT_SECRET=your-jwt-secret
depends_on:
- db
- redis
volumes:
- ./packages/server:/app
- /app/node_modules
client:
build:
context: .
dockerfile: Dockerfile.client
ports:
- "3000:3000"
environment:
- VITE_API_URL=http://localhost:3001
depends_on:
- api
volumes:
- ./packages/client:/app
- /app/node_modules
volumes:
mysql_data:
redis_data:
minio_data:
# .env.example
# 数据库配置
DATABASE_URL=mysql://user:password@localhost:3306/shadcn_admin
# Redis配置
REDIS_URL=redis://localhost:6379
# JWT配置
JWT_SECRET=your-super-secret-jwt-key
JWT_EXPIRES_IN=7d
# 文件存储
MINIO_ENDPOINT=localhost
MINIO_PORT=9000
MINIO_ACCESS_KEY=minioadmin
MINIO_SECRET_KEY=minioadmin
MINIO_BUCKET=shadcn-admin
# 应用配置
NODE_ENV=development
PORT=3001
CORS_ORIGIN=http://localhost:3000
# 前端配置
VITE_API_URL=http://localhost:3001
VITE_APP_NAME=Shadcn Admin
pie title 测试策略分布
"单元测试" : 70
"集成测试" : 20
"端到端测试" : 10
graph LR
A[用户请求] --> B[CDN]
B --> C[负载均衡器]
C --> D[前端容器]
D --> E[API网关]
E --> F[API容器集群]
F --> G[MySQL主从]
F --> H[Redis集群]
F --> I[MinIO集群]
subgraph "监控系统"
J[Prometheus]
K[Grafana]
L[ELK日志]
end
F --> J
F --> L
flowchart LR
A[代码提交] --> B[代码扫描]
B --> C[单元测试]
C --> D[构建镜像]
D --> E[集成测试]
E --> F[安全扫描]
F --> G[部署预发布]
G --> H[端到端测试]
H --> I[生产部署]
I --> J[健康检查]
本文档根据PRD需求和技术规范创建,提供了完整的架构设计方案,可作为开发实施的蓝图。