Vue Pure Admin + NestJS 全栈架构设计文档
系统采用 前后端分离 架构,前端 Vue 3 + Vite,后端 NestJS,数据库 MySQL + Redis 缓存。
┌─────────────────────────────────────────────────────────────────────────┐ │ 【客户端层 — Client Layer】 │ │ ┌─────────────────────┐ ┌───────────────────┐ ┌───────────────────┐ │ │ │ 浏览器 (Chrome) │ │ API 客户端 │ │ Swagger UI │ │ │ │ localhost:8848 │ │ (Postman / Axios) │ │ :3001/api-docs │ │ │ └─────────┬───────────┘ └─────────┬─────────┘ └─────────┬─────────┘ │ └────────────┼────────────────────────┼──────────────────────┼──────────┘ │ │ │ ▼ ▼ ▼ ┌─────────────────────────────────────────────────────────────────────────┐ │ 【网关层 — Gateway Layer (Plan) │ │ ┌─────────────────────────────────────────────────────────────────┐ │ │ │ Nginx / Caddy — 反向代理 · 负载均衡 · HTTPS · 静态资源 │ │ │ └─────────────────────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────────────┐ │ 【前端层 — Frontend Vue 3 + Vite】 │ │ ┌───────────┐ ┌───────────┐ ┌────────────┐ ┌───────────────────┐ │ │ │ Vue Router │ │ Pinia │ │ Element Plus │ │ Axios (拦截器) │ │ │ │ 动态路由 │ │ 状态管理 │ │ 60+ 组件 │ │ JWT 注入 · 刷新 │ │ │ └───────────┘ └───────────┘ └────────────┘ └───────────────────┘ │ │ ┌─────────────────┐ ┌─────────────┐ ┌──────────────────────────┐ │ │ │ Vue I18n │ │ Echarts │ │ 权限指令 (v-permission) │ │ │ │ 中/英 国际化 │ │ 数据可视化 │ │ 按钮级权限 │ │ │ └─────────────────┘ └─────────────┘ └──────────────────────────┘ │ └─────────────────────────────────────────────────────────────────────────┘ │ HTTP · Bearer JWT · JSON ▼ ┌─────────────────────────────────────────────────────────────────────────┐ │ 【后端层 — Backend NestJS 11】 │ │ │ │ ┌──────────────────────────── 请求入口 ────────────────────────────┐ │ │ │ → CORS → Helmet → ThrottlerGuard │ │ │ │ 跨域白名单 安全头 全局限流 (60次/60s) │ │ │ └──────────────────────────────────────────────────────────────────┘ │ │ │ │ │ ┌────────────────────────── 中间件 ─────────────────────────────────┐ │ │ │ → Pino Logger → JwtAuthGuard → RolesGuard → ValidationPipe │ │ │ │ 结构化日志 JWT 鉴权 角色权限 DTO 校验 │ │ │ └──────────────────────────────────────────────────────────────────┘ │ │ │ │ │ ┌───────────────────────── 业务处理 ────────────────────────────────┐ │ │ │ │ │ │ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │ │ │ │ Auth │ │ User │ │ Role │ │ Menu │ │ │ │ │ │ 登录/刷新 │ │ 用户CURD │ │ 角色CURD │ │ 菜单CURD │ │ │ │ │ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │ │ │ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │ │ │ │ Dept │ │ Log │ │ Dict │ │ Mine │ │ │ │ │ │ 部门管理 │ │ 操作日志 │ │ 字典管理 │ │ 个人信息 │ │ │ │ │ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │ │ │ └───────────────────────────────────────────────────────────────────┘ │ │ │ │ │ ┌────────────────────────── 响应出口 ──────────────────────────────┐ │ │ │ → TransformInterceptor → LoggingInterceptor │ │ │ │ 统一响应 {code,data,msg} 请求耗时 · 参数记录 │ │ │ │ → PinoExceptionFilter │ │ │ │ 结构化异常 · 错误归类 │ │ │ └──────────────────────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────────────────┘ │ ┌────────┼────────┐ ▼ ▼ ▼ ┌────────┐ ┌──────┐ ┌──────────┐ │ MySQL 8 │ │Redis 7│ │ 文件存储 │ │ TypeORM│ │ioredis│ │ (待定) │ │ 9 张表 │ │ 缓存 │ │ MinIO/OSS │ └────────┘ └──────┘ └──────────┘
一个完整的 API 请求在 NestJS 后端经历的完整链路:
Authorization: Bearer <JWT>
req.user(userId + username)
@Roles() 装饰器声明的角色 → 对比 req.user.roles → 无权限返回 403
{ success, data, message } 格式
基于 用户 — 角色 — 菜单 三级模型的权限控制体系:
┌─────────────────────── RBAC 权限模型 ───────────────────────┐ │ │ │ ┌──────────┐ N:M ┌──────────┐ N:M ┌──────────┐ │ │ User │◄──────────►│ Role │◄──────────►│ Menu │ │ │──────────│ user_role │──────────│ role_menu │──────────│ │ │ id │ │ id │ │ id │ │ │ username │ │ name │ │ name │ │ │ password │ │ code │ │ path │ │ │ nickname │ │ status │ │ icon │ │ │ status │ │ remark │ │ type │ │ └──────────┘ └──────────┘ │ parentId │ │ │ │ sort │ │ │ 1:N │ visible │ │ ▼ │ keepAlive│ │ ┌──────────┐ └──────────┘ │ │ Dept │ │ │ │──────────│ ┌──────────┐ │ │ id │ │ Log │ │ │ name │ │──────────│ │ │ parentId │ │ 操作日志 │ │ │ sort │ └──────────┘ │ └──────────┘ │ ┌──────────┐ ┌──────────┐ │ ┌──────────┐ ┌──────────┐ │ DictType │ │ DictData │ │ │ UserRole │ │ RoleMenu │ │──────────│ │──────────│ │ │userId │ │roleId │ │ 字典类型 │ │ 字典数据 │ │ │roleId │ │menuId │ └──────────┘ └──────────┘ │ └──────────┘ └──────────┘ │ │ └─────────────────────────────────────────────────────────────┘
项目提供 开发 和 生产 两套 Docker 编排方案,新成员 docker compose up -d 即可一键启动完整环境。
┌────────────────────── Docker 开发环境 (docker-compose.yml) ──────────────────────┐ │ │ │ localhost:3001 localhost:3306 localhost:6379 │ │ │ │ │ ▼ ▼ ▼ │ ┌───────────────┐ ┌───────────────┐ ┌───────────────┐ │ │ vpa-server │ │ vpa-mysql │ │ vpa-redis │ │ │ NestJS 11 │ │ MySQL 8.0 │ │ Redis 7 │ │ │ Dockerfile │ │ utf8mb4 │ │ AOF 持久化 │ │ │ 端口 3001 │ │ 端口 3306 │ │ 端口 6379 │ │ │ healthcheck ✓ │ │ healthcheck ✓ │ │ healthcheck ✓ │ │ └───────────────┘ └───────────────┘ └───────────────┘ │ │ │ │ │ ┌─────┴─────────────┐ ┌──────┴────────┐ ┌───────┴───────┐ │ │ app-uploads 卷 │ │ mysql-data 卷 │ │ redis-data 卷 │ │ └───────────────────┘ └───────────────┘ └───────────────┘ │ ──── vpa-network (bridge) ──── │ └───────────────────────────────────────────────────────────────────────────────────┘ ┌────────────────────── Docker 生产环境 (docker-compose.prod.yml) ──────────────────┐ │ │ │ https://your-domain.com │ │ │ ▼ │ ┌──────────────────────────────────────────────────────────────┐ │ │ vpa-nginx-prod (Nginx Alpine) │ │ │ :80 → 301 → :443 SSL 终止 Gzip 限流 反向代理 │ │ └──────────────────────────────────────────────────────────────┘ │ │ proxy_pass http://vpa-server-prod:3001 │ ▼ │ ┌────────────────────────┐ ┌────────────────────────┐ │ │ vpa-server-prod │ │ vpa-redis-prod │ │ │ Dockerfile.prod │ │ Redis 7 · AOF · 密码 │ │ │ 多阶段构建 │ │ maxmemory 512mb │ │ │ 非 root 用户 │ │ LRU 淘汰策略 │ │ │ 资源限制 CPU/Mem │ └────────────────────────┘ │ └────────────────────────┘ │ │ │ │ 外部 MySQL(不在 compose 内) │ ▼ │ ┌────────────────────────┐ │ │ 生产 MySQL 实例 │ │ │ 独立部署 / RDS 云数据库 │ │ └────────────────────────┘ │ └───────────────────────────────────────────────────────────────────────────────────┘
多人协作时的代码风格与工具链约定:
| 配置项 | 文件 | 作用 |
|---|---|---|
| 编辑器统一 | .editorconfig |
缩进 2 空格、UTF-8、LF 换行 — 跨 IDE 统一 |
| 代码格式化 | .prettierrc.js |
单引号、尾逗号、100 字符换行 — pnpm run format |
| ESLint | eslint.config.mjs |
TypeScript 规范 — pnpm run lint |
| Docker 开发 | docker-compose.yml |
新成员无需安装 MySQL/Redis,一行命令启动 |
| 环境变量 | .env / .env.production.example |
开发与生产分离,敏感配置不入库 |
| 包管理器 | pnpm-lock.yaml |
锁定依赖版本,统一用 pnpm |
按类别列出的生产环境部署检查项,勾选即确认。
pnpm run lint)nest build)pnpm run test) 覆盖率 ≥ 60%synchronize: false(已在代码中固定)scripts/ 目录下的 *.sql)maxmemory-policy allkeys-lru 内存淘汰策略pnpm run build 生产构建成功,产物在 dist/Dockerfile + Dockerfile.prod 多阶段构建docker-compose.yml(开发)和 docker-compose.prod.yml(生产)ecosystem.config.js PM2 集群模式配置deploy.sh 一键部署脚本(Docker / PM2 / 回滚)nginx/ 反向代理配置(HTTPS + 负载均衡 + Gzip).env.production 中 [CHANGE_ME] 已替换为真实值GET /api/health 可访问(需实现)info(生产不输出 debug).env.production 模板文件NODE_ENV=production