935 lines
33 KiB
Markdown
935 lines
33 KiB
Markdown
|
|
# WWJ Cloud 企业级框架 - NestJS + VbenAdmin 实现
|
|||
|
|
|
|||
|
|
> 一款支持插件化+云安装+云编译 快速开发SAAS多用户系统后台管理框架!
|
|||
|
|
|
|||
|
|
使用 WWJ Cloud 企业级框架,我们开发一个软件系统,**一切插件化**!!!= WWJ Cloud 框架 + 应用1 + 应用2 + 应用N + 插件1 + 插件2 + 插件N + ...
|
|||
|
|
|
|||
|
|
如果对您有帮助,您可以点右上角 ⭐"Star" 收藏一下,获取第一时间更新,谢谢!
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 📖 框架介绍
|
|||
|
|
|
|||
|
|
WWJ Cloud 企业级框架是一款快速开发 SaaS 通用管理系统后台框架,基于 **NestJS + TypeORM + Redis + MySQL** 后端技术架构和 **VbenAdmin + Vue3 + TypeScript + Element Plus** 前端技术栈精心设计,易读易懂,没有任何其它重度依赖,架构设计小巧灵活,没有采用过度设计模式。是一款快速可以开发企业级应用的软件系统。
|
|||
|
|
|
|||
|
|
**【您不需要重复造轮子 – 框架内置已经实现基础组件功能,您只需要开发业务模块即可】!**
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 🔗 快速链接
|
|||
|
|
|
|||
|
|
- **Gitee 下载地址**:https://gitee.com/wwjauth/wwjcloud-nestjs
|
|||
|
|
- **GitHub 下载地址**:https://github.com/wwjauth/wwjcloud-nestjs
|
|||
|
|
- **演示地址**:http://demo.wwjauth.com/admin/ (账号:admin 密码:123456)
|
|||
|
|
- **文档地址**:https://docs.wwjauth.com
|
|||
|
|
- **云应用市场**:https://market.wwjauth.com
|
|||
|
|
- **VbenAdmin 官网**:https://vben.pro
|
|||
|
|
- **NestJS 官网**:https://nestjs.com
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 🌟 WWJ Cloud 开发者生态圈
|
|||
|
|
|
|||
|
|
WWJ Cloud 框架,目前已经实现有 **NestJS + VbenAdmin** 版本功能实现。整个 WWJ Cloud 开发者生态圈目前已经有众多用户。其中开发者上千人。WWJ Cloud 生态圈众多代理商、经销商、中介商都会采购插件及应用,自己运营或者分销给第三方商家用户。您只需要用心开发插件或应用,并发布到 WWJ Cloud 云应用市场,即会有人购买。依靠 WWJ Cloud 强大的生态圈,实现市场、资源、产品的研发销售闭环。从今天开始,加入 WWJ Cloud 生态圈,实现程序员创业梦想!付出就有回报。心动不如行动!
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 🎯 设计理念
|
|||
|
|
|
|||
|
|
### 强大的多应用+插件组合设计理念,低耦合,高内聚
|
|||
|
|
|
|||
|
|
基于**企业级框架底层设计**,采用**分层架构 + 领域驱动设计**,实现:
|
|||
|
|
- **清晰的依赖层次**:`App(业务开发层)` → `Common(框架通用服务层)` → `Core(核心基础设施层)` → `Vendor(第三方适配层)`
|
|||
|
|
- **框架化设计**:Common 层提供完整的企业级通用服务,App 层专注用户业务开发
|
|||
|
|
- **高内聚低耦合**:每层职责明确,接口清晰,支持插拔式扩展
|
|||
|
|
- **可扩展性**:支持 Addons 插件化扩展和微服务拆分
|
|||
|
|
- **企业级特性**:完整的配置系统、监控、日志、安全机制
|
|||
|
|
- **微服务就绪**:为未来微服务架构演进奠定基础
|
|||
|
|
|
|||
|
|
### 全新生态设计,多应用聚合+多插件组合运营模式全新升级
|
|||
|
|
|
|||
|
|
支持共同会员体系下多种应用+插件组合,DIY装修出最强的软件系统。
|
|||
|
|
|
|||
|
|
### 插件化,完全为开发者二次开发而生
|
|||
|
|
|
|||
|
|
WWJ Cloud 框架采用插件化模式设计,可以做到多种插件共存,组合使用。**一切皆为插件(应用)!** 比如您有一个项目是电商的项目,这个项目的要求是,既有商城的功能,又有CRM客户管理,还需要进行会员的管理,甚至于还要客服系统。传统的实现方式是,找多个源码,东拼西凑,二次开发,或者部署多套独立的系统,配合起来。而今天,使用 WWJ Cloud 框架,可以通过组装的方式,在一套体系中实现,随着发展,会有越来越多的各行各业的插件和应用上架。您对于项目的定制,可能只需要简单组装,装修页面,就可以最终实现功能交付。
|
|||
|
|
|
|||
|
|
### 首创强大的一键云安装,云编译,云发布,升级引擎
|
|||
|
|
|
|||
|
|
- WWJ Cloud 框架内置简单方便的一键云安装,云编译工具
|
|||
|
|
- WWJ Cloud 内置在线升级功能,系统会全自动化帮您升级文件。产品的更新只需一键完成
|
|||
|
|
- VSCode,WebStorm,微信小程序开发工具,打包,上传,发布!WWJ Cloud 框架强大的小程序一键傻瓜式发布系统,任何开发环境都不再需要搭建!鼠标一点完成小程序升级发布
|
|||
|
|
|
|||
|
|
### 🏗️ SaaS + 独立版双架构设计
|
|||
|
|
|
|||
|
|
WWJ Cloud 框架采用创新的 **SaaS + 独立版双架构设计**,一套代码同时支持两种部署模式:
|
|||
|
|
|
|||
|
|
#### 🔄 SaaS 多租户模式
|
|||
|
|
- **适用场景**:云服务商、多客户管理系统
|
|||
|
|
- **架构特点**:通过 `site_id` 字段实现多租户数据隔离
|
|||
|
|
- **数据隔离**:每个租户拥有独立的 `site_id`,数据完全隔离
|
|||
|
|
- **资源共享**:共享系统基础设施,降低运营成本
|
|||
|
|
- **扩展性**:支持无限租户扩展,满足 SaaS 服务商需求
|
|||
|
|
|
|||
|
|
#### 🏢 独立版部署模式
|
|||
|
|
- **适用场景**:企业内部系统、单客户项目、私有化部署
|
|||
|
|
- **架构特点**:所有数据 `site_id` 统一为 0
|
|||
|
|
- **数据独立**:完全独立的数据环境,无租户概念
|
|||
|
|
- **部署灵活**:支持私有化部署,数据完全自主可控
|
|||
|
|
- **定制化**:可根据客户需求进行深度定制
|
|||
|
|
|
|||
|
|
#### 🔧 技术实现
|
|||
|
|
```sql
|
|||
|
|
-- 数据库表结构示例
|
|||
|
|
CREATE TABLE users (
|
|||
|
|
id INT PRIMARY KEY AUTO_INCREMENT,
|
|||
|
|
site_id INT NOT NULL DEFAULT 0, -- 租户ID,0表示独立版
|
|||
|
|
username VARCHAR(50) NOT NULL,
|
|||
|
|
email VARCHAR(100) NOT NULL,
|
|||
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|||
|
|
INDEX idx_site_id (site_id) -- 租户索引,提升查询性能
|
|||
|
|
);
|
|||
|
|
|
|||
|
|
-- SaaS模式:每个租户有独立的site_id
|
|||
|
|
INSERT INTO users (site_id, username, email) VALUES (1, 'user1', 'user1@tenant1.com');
|
|||
|
|
INSERT INTO users (site_id, username, email) VALUES (2, 'user2', 'user2@tenant2.com');
|
|||
|
|
|
|||
|
|
-- 独立版模式:所有数据site_id为0
|
|||
|
|
INSERT INTO users (site_id, username, email) VALUES (0, 'admin', 'admin@company.com');
|
|||
|
|
INSERT INTO users (site_id, username, email) VALUES (0, 'user', 'user@company.com');
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 🎯 架构优势
|
|||
|
|
- **一套代码,两种模式**:无需维护两套代码,降低开发成本
|
|||
|
|
- **平滑切换**:可在 SaaS 和独立版之间平滑切换
|
|||
|
|
- **数据安全**:多租户数据完全隔离,独立版数据完全自主
|
|||
|
|
- **部署灵活**:支持云部署和私有化部署
|
|||
|
|
- **成本优化**:SaaS 模式资源共享,独立版模式完全控制
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 📊 依赖关系图
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
┌─────────────────┐
|
|||
|
|
│ App │ ← 业务开发层(用户自定义业务模块)
|
|||
|
|
│ (用户业务) │ 电商、CRM、ERP等具体业务逻辑
|
|||
|
|
└─────────────────┘
|
|||
|
|
↓
|
|||
|
|
┌─────────────────┐
|
|||
|
|
│ Common │ ← 框架通用服务层(企业级通用功能)
|
|||
|
|
│ (框架通用服务) │ 用户管理、权限管理、菜单管理
|
|||
|
|
└─────────────────┘ 文件上传、通知服务、系统设置
|
|||
|
|
↓ 数据字典、缓存服务、队列服务
|
|||
|
|
┌─────────────────┐
|
|||
|
|
│ Core │ ← 核心基础设施层(底层基础设施)
|
|||
|
|
│ (基础设施) │ 认证核心、数据库核心、验证核心
|
|||
|
|
└─────────────────┘ HTTP核心、缓存核心、队列核心
|
|||
|
|
↓
|
|||
|
|
┌─────────────────┐
|
|||
|
|
│ Vendor │ ← 第三方服务适配层
|
|||
|
|
│ (外部集成) │ 存储、支付、通信、云服务适配
|
|||
|
|
└─────────────────┘
|
|||
|
|
|
|||
|
|
┌─────────────────┐
|
|||
|
|
│ Addons │ ← 插件扩展层(可插拔功能模块)
|
|||
|
|
│ (插件扩展) │ 扩展框架功能,不影响核心稳定性
|
|||
|
|
└─────────────────┘
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 🚀 技术亮点
|
|||
|
|
|
|||
|
|
### 🏗️ 后端技术栈(NestJS 生态)
|
|||
|
|
|
|||
|
|
- **NestJS + TypeORM + MySQL8**:采用 SaaS + 独立版双架构设计,支持多租户 SaaS 模式和独立部署模式,通过 `site_id` 字段区分租户,当 `site_id = 0` 时为独立版模式,能够提供企业级软件服务运营,同时满足用户多站点,多商户,多门店等系统开发需求
|
|||
|
|
- **严格的 RESTful API 设计**:后端开发采用严格的 RESTful 的 API 设计开发,支持多语言设计开发
|
|||
|
|
- **Redis 分布式缓存**:高性能缓存系统,支持集群部署
|
|||
|
|
- **Bull 队列系统**:可靠的消息队列处理,支持任务调度和异步处理
|
|||
|
|
- **JWT + RBAC 权限系统**:完整的认证授权体系
|
|||
|
|
- **Winston 日志系统**:结构化日志记录和监控
|
|||
|
|
- **Swagger API 文档**:自动生成 API 文档,支持在线调试
|
|||
|
|
|
|||
|
|
### 🎨 前端技术栈(VbenAdmin 生态)
|
|||
|
|
|
|||
|
|
- **VbenAdmin + Vue3 + TypeScript + Vite**:采用最新的前端技术栈,VbenAdmin 是基于 Vue3、Vite、TypeScript 的现代化管理系统
|
|||
|
|
- **Element Plus UI 组件库**:丰富的企业级 UI 组件,开发者不需要详细了解前端,只需要用标准的 Element 组件就可以
|
|||
|
|
- **Pinia 状态管理**:现代化的 Vue 状态管理方案
|
|||
|
|
- **Vue Router 路由管理**:支持动态路由和权限控制
|
|||
|
|
- **Tailwind CSS**:原子化 CSS 框架,快速构建现代化界面
|
|||
|
|
- **i18n 国际化**:支持多语言切换,真正意义上实现多语言的开发需求
|
|||
|
|
- **响应式设计**:支持桌面端、平板端、移动端自适应
|
|||
|
|
|
|||
|
|
### 🏢 企业级特性
|
|||
|
|
|
|||
|
|
- **SaaS + 独立版双架构支持**:支持多租户 SaaS 架构和独立部署模式,通过 `site_id` 字段区分,当 `site_id = 0` 时为独立版模式
|
|||
|
|
- **多租户 SaaS 架构**:支持多租户隔离,满足 SaaS 服务商需求,每个租户拥有独立的 `site_id`
|
|||
|
|
- **独立版部署**:支持独立部署模式,适用于企业内部系统或单客户项目,所有数据 `site_id` 统一为 0
|
|||
|
|
- **微服务就绪**:分层架构设计,支持未来微服务拆分
|
|||
|
|
- **插件化扩展**:Addons 插件系统,支持功能模块热插拔
|
|||
|
|
- **云原生部署**:支持 Docker 容器化部署和 Kubernetes 编排
|
|||
|
|
- **监控告警**:完整的系统监控和告警机制
|
|||
|
|
- **数据备份**:自动化数据备份和恢复机制
|
|||
|
|
- **安全防护**:SQL 注入防护、XSS 防护、CSRF 防护等
|
|||
|
|
|
|||
|
|
### 🌐 多语言支持
|
|||
|
|
|
|||
|
|
WWJ Cloud 前端以及后端采用严格的多语言开发规范,包括前端展示,API 接口返回,数据验证,错误返回等全部使用多语言设计规范,使开发者能够真正意义上实现多语言的开发需求。
|
|||
|
|
|
|||
|
|
### 🛠️ 开发者友好
|
|||
|
|
|
|||
|
|
WWJ Cloud 结合当前市面上很多框架结构不规范,导致基础结构不稳定等情况,严格定义了分层设计的开发规范,同时 API 接口严格采用 RESTful 的开发规范,能够满足大型业务系统或者微服务的开发需求。
|
|||
|
|
|
|||
|
|
### 📦 内置功能模块
|
|||
|
|
|
|||
|
|
WWJ Cloud 已经搭建好常规系统的开发底层,具体功能包括:
|
|||
|
|
- **管理员管理**:完整的管理员账户体系
|
|||
|
|
- **权限管理**:基于 RBAC 的权限控制系统
|
|||
|
|
- **菜单管理**:动态菜单配置和权限绑定
|
|||
|
|
- **用户管理**:前台用户管理和会员体系
|
|||
|
|
- **应用管理**:多应用管理和配置
|
|||
|
|
- **文件管理**:文件上传、存储和管理
|
|||
|
|
- **系统设置**:灵活的系统配置管理
|
|||
|
|
- **数据字典**:系统数据字典管理
|
|||
|
|
- **通知消息**:站内消息和推送通知
|
|||
|
|
- **操作日志**:完整的操作审计日志
|
|||
|
|
- **定时任务**:计划任务管理和调度
|
|||
|
|
- **API 接口**:对外开放接口管理
|
|||
|
|
- **健康检查**:系统健康状态监控
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 📁 项目目录结构
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
src/
|
|||
|
|
├── app/ # 🏢 业务开发层(用户自定义业务模块)
|
|||
|
|
│ ├── demo/ # Demo 模块(标准模板示例)
|
|||
|
|
│ │ ├── demo.module.ts
|
|||
|
|
│ │ ├── controllers/
|
|||
|
|
│ │ │ └── demo.controller.ts
|
|||
|
|
│ │ ├── services/
|
|||
|
|
│ │ │ └── demo.service.ts
|
|||
|
|
│ │ ├── entities/
|
|||
|
|
│ │ │ └── demo.entity.ts
|
|||
|
|
│ │ ├── dto/
|
|||
|
|
│ │ │ └── demo.dto.ts
|
|||
|
|
│ │ └── README.md # 模块开发指南
|
|||
|
|
│ └── index.ts # App 层统一导出
|
|||
|
|
│
|
|||
|
|
├── common/ # 🔧 框架通用服务层(企业级通用功能)
|
|||
|
|
│ ├── users/ # 用户管理服务
|
|||
|
|
│ ├── rbac/ # 权限管理服务
|
|||
|
|
│ ├── menu/ # 菜单管理服务
|
|||
|
|
│ ├── apps/ # 应用管理服务
|
|||
|
|
│ ├── upload/ # 文件上传服务
|
|||
|
|
│ ├── notification/ # 通知服务
|
|||
|
|
│ ├── settings/ # 系统设置服务
|
|||
|
|
│ ├── dictionary/ # 数据字典服务
|
|||
|
|
│ ├── cache/ # 缓存服务
|
|||
|
|
│ ├── queue/ # 队列服务
|
|||
|
|
│ ├── health/ # 健康检查服务
|
|||
|
|
│ └── openapi/ # 对外开放接口服务
|
|||
|
|
│
|
|||
|
|
├── config/ # ⚙️ 配置层(运行时配置)
|
|||
|
|
│ ├── env/ # 环境配置
|
|||
|
|
│ ├── database/ # 数据库配置
|
|||
|
|
│ ├── cache/ # 缓存配置
|
|||
|
|
│ ├── queue/ # 队列配置
|
|||
|
|
│ ├── http/ # HTTP 配置
|
|||
|
|
│ ├── security/ # 安全配置
|
|||
|
|
│ ├── logger/ # 日志配置
|
|||
|
|
│ └── third-party/ # 第三方服务配置
|
|||
|
|
│
|
|||
|
|
├── core/ # 🏗️ 核心基础设施层(跨域通用)
|
|||
|
|
│ ├── auth/ # 认证核心
|
|||
|
|
│ ├── database/ # 数据库核心
|
|||
|
|
│ ├── validation/ # 验证核心
|
|||
|
|
│ ├── http/ # HTTP 核心
|
|||
|
|
│ ├── cache/ # 缓存核心
|
|||
|
|
│ ├── queue/ # 队列核心
|
|||
|
|
│ ├── logger/ # 日志核心
|
|||
|
|
│ ├── monitoring/ # 监控核心
|
|||
|
|
│ └── exceptions/ # 异常处理核心
|
|||
|
|
│
|
|||
|
|
├── vendor/ # 🔌 第三方服务适配层
|
|||
|
|
│ ├── storage/ # 存储服务适配
|
|||
|
|
│ ├── payment/ # 支付服务适配
|
|||
|
|
│ ├── communication/ # 通信服务适配
|
|||
|
|
│ ├── sms/ # 短信服务适配
|
|||
|
|
│ ├── email/ # 邮件服务适配
|
|||
|
|
|
|||
|
|
│
|
|||
|
|
├── addons/ # 🧩 插件扩展层(可插拔功能模块)
|
|||
|
|
│ └── README.md # 插件开发指南
|
|||
|
|
│
|
|||
|
|
├── app.module.ts # 根模块
|
|||
|
|
└── main.ts # 应用入口
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 🚀 快速开始
|
|||
|
|
|
|||
|
|
### 环境要求
|
|||
|
|
|
|||
|
|
- **Node.js** >= 18.0.0
|
|||
|
|
- **npm** >= 8.0.0 或 **pnpm** >= 7.0.0
|
|||
|
|
- **MySQL** >= 8.0 或 **PostgreSQL** >= 13
|
|||
|
|
- **Redis** >= 6.0
|
|||
|
|
|
|||
|
|
### 安装依赖
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
# 使用 npm
|
|||
|
|
$ npm install
|
|||
|
|
|
|||
|
|
# 或使用 pnpm(推荐)
|
|||
|
|
$ pnpm install
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 环境配置
|
|||
|
|
|
|||
|
|
1. 复制环境配置文件:
|
|||
|
|
```bash
|
|||
|
|
$ cp .env.example .env
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
2. 配置数据库连接、Redis 连接等必要参数:
|
|||
|
|
```bash
|
|||
|
|
# 数据库配置
|
|||
|
|
DB_HOST=localhost
|
|||
|
|
DB_PORT=3306
|
|||
|
|
DB_USERNAME=root
|
|||
|
|
DB_PASSWORD=your_password
|
|||
|
|
DB_DATABASE=wwjauth
|
|||
|
|
|
|||
|
|
# Redis 配置
|
|||
|
|
REDIS_HOST=localhost
|
|||
|
|
REDIS_PORT=6379
|
|||
|
|
REDIS_PASSWORD=
|
|||
|
|
|
|||
|
|
# JWT 配置
|
|||
|
|
JWT_SECRET=your_jwt_secret_key
|
|||
|
|
JWT_EXPIRES_IN=7d
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 数据库迁移
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
# 运行数据库迁移
|
|||
|
|
$ npm run migration:run
|
|||
|
|
|
|||
|
|
# 填充种子数据
|
|||
|
|
$ npm run seed:run
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 启动应用
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
# 开发模式
|
|||
|
|
$ npm run start:dev
|
|||
|
|
|
|||
|
|
# 生产模式
|
|||
|
|
$ npm run start:prod
|
|||
|
|
|
|||
|
|
# 调试模式
|
|||
|
|
$ npm run start:debug
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 访问应用
|
|||
|
|
|
|||
|
|
- **后端 API**:http://localhost:3000
|
|||
|
|
- **API 文档**:http://localhost:3000/api
|
|||
|
|
- **健康检查**:http://localhost:3000/health
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 🏗️ 开发指南
|
|||
|
|
|
|||
|
|
### 业务模块开发
|
|||
|
|
|
|||
|
|
1. **创建新模块**:参考 `src/app/demo` 模块结构
|
|||
|
|
2. **遵循分层架构**:Controller → Service → Repository → Entity
|
|||
|
|
3. **使用框架服务**:充分利用 Common 层提供的通用服务
|
|||
|
|
4. **统一错误处理**:使用框架提供的异常处理机制
|
|||
|
|
5. **API 文档**:使用 Swagger 注解生成 API 文档
|
|||
|
|
6. **单元测试**:编写完整的单元测试和集成测试
|
|||
|
|
|
|||
|
|
### 🏗️ 多租户架构开发规范
|
|||
|
|
|
|||
|
|
#### 📋 数据库设计规范
|
|||
|
|
- **必须包含 `site_id` 字段**:所有业务表都必须包含 `site_id` 字段
|
|||
|
|
- **默认值设置**:`site_id` 字段默认值为 0,表示独立版模式
|
|||
|
|
- **索引优化**:为 `site_id` 字段创建索引,提升查询性能
|
|||
|
|
- **外键约束**:跨表关联时需要考虑租户隔离
|
|||
|
|
|
|||
|
|
```sql
|
|||
|
|
-- 标准表结构示例
|
|||
|
|
CREATE TABLE products (
|
|||
|
|
id INT PRIMARY KEY AUTO_INCREMENT,
|
|||
|
|
site_id INT NOT NULL DEFAULT 0, -- 租户ID,0表示独立版
|
|||
|
|
name VARCHAR(100) NOT NULL,
|
|||
|
|
price DECIMAL(10,2) NOT NULL,
|
|||
|
|
status TINYINT DEFAULT 1,
|
|||
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|||
|
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
|||
|
|
INDEX idx_site_id (site_id), -- 租户索引
|
|||
|
|
INDEX idx_site_status (site_id, status) -- 复合索引
|
|||
|
|
);
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 🔧 实体类开发规范
|
|||
|
|
```typescript
|
|||
|
|
// src/app/demo/entities/demo.entity.ts
|
|||
|
|
import { Entity, Column, PrimaryGeneratedColumn, CreateDateColumn, UpdateDateColumn } from 'typeorm';
|
|||
|
|
|
|||
|
|
@Entity('demo')
|
|||
|
|
export class DemoEntity {
|
|||
|
|
@PrimaryGeneratedColumn()
|
|||
|
|
id: number;
|
|||
|
|
|
|||
|
|
@Column({ name: 'site_id', type: 'int', default: 0, comment: '租户ID,0表示独立版' })
|
|||
|
|
siteId: number;
|
|||
|
|
|
|||
|
|
@Column({ name: 'name', type: 'varchar', length: 100, comment: '名称' })
|
|||
|
|
name: string;
|
|||
|
|
|
|||
|
|
@Column({ name: 'status', type: 'tinyint', default: 1, comment: '状态:1启用,0禁用' })
|
|||
|
|
status: number;
|
|||
|
|
|
|||
|
|
@CreateDateColumn({ name: 'created_at', comment: '创建时间' })
|
|||
|
|
createdAt: Date;
|
|||
|
|
|
|||
|
|
@UpdateDateColumn({ name: 'updated_at', comment: '更新时间' })
|
|||
|
|
updatedAt: Date;
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 🛠️ 服务层开发规范
|
|||
|
|
```typescript
|
|||
|
|
// src/app/demo/services/demo.service.ts
|
|||
|
|
import { Injectable } from '@nestjs/common';
|
|||
|
|
import { InjectRepository } from '@nestjs/typeorm';
|
|||
|
|
import { Repository } from 'typeorm';
|
|||
|
|
import { DemoEntity } from '../entities/demo.entity';
|
|||
|
|
import { CreateDemoDto } from '../dto/create-demo.dto';
|
|||
|
|
import { UpdateDemoDto } from '../dto/update-demo.dto';
|
|||
|
|
|
|||
|
|
@Injectable()
|
|||
|
|
export class DemoService {
|
|||
|
|
constructor(
|
|||
|
|
@InjectRepository(DemoEntity)
|
|||
|
|
private readonly demoRepository: Repository<DemoEntity>,
|
|||
|
|
) {}
|
|||
|
|
|
|||
|
|
// 创建时自动设置租户ID
|
|||
|
|
async create(createDemoDto: CreateDemoDto, siteId: number = 0): Promise<DemoEntity> {
|
|||
|
|
const demo = this.demoRepository.create({
|
|||
|
|
...createDemoDto,
|
|||
|
|
siteId, // 自动设置租户ID
|
|||
|
|
});
|
|||
|
|
return this.demoRepository.save(demo);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 查询时自动过滤租户数据
|
|||
|
|
async findAll(siteId: number = 0): Promise<DemoEntity[]> {
|
|||
|
|
return this.demoRepository.find({
|
|||
|
|
where: { siteId },
|
|||
|
|
order: { createdAt: 'DESC' },
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 根据ID查询时验证租户权限
|
|||
|
|
async findOne(id: number, siteId: number = 0): Promise<DemoEntity> {
|
|||
|
|
const demo = await this.demoRepository.findOne({
|
|||
|
|
where: { id, siteId },
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
if (!demo) {
|
|||
|
|
throw new NotFoundException('数据不存在或无权限访问');
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return demo;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 更新时验证租户权限
|
|||
|
|
async update(id: number, updateDemoDto: UpdateDemoDto, siteId: number = 0): Promise<DemoEntity> {
|
|||
|
|
const demo = await this.findOne(id, siteId);
|
|||
|
|
|
|||
|
|
Object.assign(demo, updateDemoDto);
|
|||
|
|
return this.demoRepository.save(demo);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 删除时验证租户权限
|
|||
|
|
async remove(id: number, siteId: number = 0): Promise<void> {
|
|||
|
|
const demo = await this.findOne(id, siteId);
|
|||
|
|
await this.demoRepository.remove(demo);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 🎯 控制器层开发规范
|
|||
|
|
```typescript
|
|||
|
|
// src/app/demo/controllers/demo.controller.ts
|
|||
|
|
import { Controller, Get, Post, Body, Param, Delete, UseGuards, Req } from '@nestjs/common';
|
|||
|
|
import { ApiTags, ApiOperation, ApiBearerAuth } from '@nestjs/swagger';
|
|||
|
|
import { DemoService } from '../services/demo.service';
|
|||
|
|
import { CreateDemoDto } from '../dto/create-demo.dto';
|
|||
|
|
import { UpdateDemoDto } from '../dto/update-demo.dto';
|
|||
|
|
import { JwtAuthGuard } from '../../common/auth/guards/jwt-auth.guard';
|
|||
|
|
|
|||
|
|
@Controller('demo')
|
|||
|
|
@ApiTags('Demo管理')
|
|||
|
|
@UseGuards(JwtAuthGuard)
|
|||
|
|
@ApiBearerAuth()
|
|||
|
|
export class DemoController {
|
|||
|
|
constructor(private readonly demoService: DemoService) {}
|
|||
|
|
|
|||
|
|
@Post()
|
|||
|
|
@ApiOperation({ summary: '创建Demo' })
|
|||
|
|
async create(@Body() createDemoDto: CreateDemoDto, @Req() req: any) {
|
|||
|
|
// 从JWT token中获取租户ID,独立版默认为0
|
|||
|
|
const siteId = req.user?.siteId || 0;
|
|||
|
|
return this.demoService.create(createDemoDto, siteId);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
@Get()
|
|||
|
|
@ApiOperation({ summary: '获取Demo列表' })
|
|||
|
|
async findAll(@Req() req: any) {
|
|||
|
|
const siteId = req.user?.siteId || 0;
|
|||
|
|
return this.demoService.findAll(siteId);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
@Get(':id')
|
|||
|
|
@ApiOperation({ summary: '根据ID获取Demo' })
|
|||
|
|
async findOne(@Param('id') id: string, @Req() req: any) {
|
|||
|
|
const siteId = req.user?.siteId || 0;
|
|||
|
|
return this.demoService.findOne(+id, siteId);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
@Put(':id')
|
|||
|
|
@ApiOperation({ summary: '更新Demo' })
|
|||
|
|
async update(@Param('id') id: string, @Body() updateDemoDto: UpdateDemoDto, @Req() req: any) {
|
|||
|
|
const siteId = req.user?.siteId || 0;
|
|||
|
|
return this.demoService.update(+id, updateDemoDto, siteId);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
@Delete(':id')
|
|||
|
|
@ApiOperation({ summary: '删除Demo' })
|
|||
|
|
async remove(@Param('id') id: string, @Req() req: any) {
|
|||
|
|
const siteId = req.user?.siteId || 0;
|
|||
|
|
return this.demoService.remove(+id, siteId);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 🔐 认证授权规范
|
|||
|
|
```typescript
|
|||
|
|
// src/common/auth/strategies/jwt.strategy.ts
|
|||
|
|
import { Injectable } from '@nestjs/common';
|
|||
|
|
import { PassportStrategy } from '@nestjs/passport';
|
|||
|
|
import { ExtractJwt, Strategy } from 'passport-jwt';
|
|||
|
|
|
|||
|
|
@Injectable()
|
|||
|
|
export class JwtStrategy extends PassportStrategy(Strategy) {
|
|||
|
|
constructor() {
|
|||
|
|
super({
|
|||
|
|
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
|
|||
|
|
ignoreExpiration: false,
|
|||
|
|
secretOrKey: process.env.JWT_SECRET,
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
async validate(payload: any) {
|
|||
|
|
return {
|
|||
|
|
userId: payload.sub,
|
|||
|
|
username: payload.username,
|
|||
|
|
siteId: payload.siteId || 0, // 租户ID,默认为0(独立版)
|
|||
|
|
roles: payload.roles,
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 📊 数据迁移规范
|
|||
|
|
```typescript
|
|||
|
|
// src/migrations/1234567890-AddSiteIdToDemo.ts
|
|||
|
|
import { MigrationInterface, QueryRunner, TableColumn } from 'typeorm';
|
|||
|
|
|
|||
|
|
export class AddSiteIdToDemo1234567890 implements MigrationInterface {
|
|||
|
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
|||
|
|
// 添加site_id字段
|
|||
|
|
await queryRunner.addColumn(
|
|||
|
|
'demo',
|
|||
|
|
new TableColumn({
|
|||
|
|
name: 'site_id',
|
|||
|
|
type: 'int',
|
|||
|
|
default: 0,
|
|||
|
|
comment: '租户ID,0表示独立版',
|
|||
|
|
}),
|
|||
|
|
);
|
|||
|
|
|
|||
|
|
// 创建索引
|
|||
|
|
await queryRunner.createIndex('demo', 'idx_site_id', ['site_id']);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
|||
|
|
await queryRunner.dropColumn('demo', 'site_id');
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 模块结构规范
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
your-module/
|
|||
|
|
├── your-module.module.ts # 模块定义
|
|||
|
|
├── controllers/ # 控制器层
|
|||
|
|
│ └── your-module.controller.ts
|
|||
|
|
├── services/ # 服务层
|
|||
|
|
│ └── your-module.service.ts
|
|||
|
|
├── entities/ # 实体层
|
|||
|
|
│ └── your-module.entity.ts
|
|||
|
|
├── dto/ # 数据传输对象
|
|||
|
|
│ ├── create-your-module.dto.ts
|
|||
|
|
│ ├── update-your-module.dto.ts
|
|||
|
|
│ └── query-your-module.dto.ts
|
|||
|
|
├── repositories/ # 仓储层(可选)
|
|||
|
|
│ └── your-module.repository.ts
|
|||
|
|
├── interfaces/ # 接口定义(可选)
|
|||
|
|
│ └── your-module.interface.ts
|
|||
|
|
└── README.md # 模块文档
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 代码规范
|
|||
|
|
|
|||
|
|
- **TypeScript 严格模式**:启用所有严格类型检查
|
|||
|
|
- **ESLint + Prettier**:遵循代码格式化和质量检查
|
|||
|
|
- **命名规范**:使用驼峰命名法和语义化命名
|
|||
|
|
- **注释规范**:使用 JSDoc 格式编写注释
|
|||
|
|
- **Git 提交规范**:使用 Conventional Commits 规范
|
|||
|
|
|
|||
|
|
### API 开发规范
|
|||
|
|
|
|||
|
|
```typescript
|
|||
|
|
// 控制器示例
|
|||
|
|
@Controller('users')
|
|||
|
|
@ApiTags('用户管理')
|
|||
|
|
export class UsersController {
|
|||
|
|
@Get()
|
|||
|
|
@ApiOperation({ summary: '获取用户列表' })
|
|||
|
|
@ApiResponse({ status: 200, description: '成功获取用户列表' })
|
|||
|
|
async findAll(@Query() query: QueryUserDto) {
|
|||
|
|
return this.usersService.findAll(query);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
@Post()
|
|||
|
|
@ApiOperation({ summary: '创建用户' })
|
|||
|
|
@ApiResponse({ status: 201, description: '用户创建成功' })
|
|||
|
|
async create(@Body() createUserDto: CreateUserDto) {
|
|||
|
|
return this.usersService.create(createUserDto);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 🧪 测试
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
# 单元测试
|
|||
|
|
$ npm run test
|
|||
|
|
|
|||
|
|
# 端到端测试
|
|||
|
|
$ npm run test:e2e
|
|||
|
|
|
|||
|
|
# 测试覆盖率
|
|||
|
|
$ npm run test:cov
|
|||
|
|
|
|||
|
|
# 监听模式测试
|
|||
|
|
$ npm run test:watch
|
|||
|
|
|
|||
|
|
# 调试模式测试
|
|||
|
|
$ npm run test:debug
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 测试规范
|
|||
|
|
|
|||
|
|
- **单元测试**:每个服务和控制器都应有对应的单元测试
|
|||
|
|
- **集成测试**:测试模块间的集成功能
|
|||
|
|
- **端到端测试**:测试完整的用户场景
|
|||
|
|
- **测试覆盖率**:保持 80% 以上的代码覆盖率
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 📦 构建和部署
|
|||
|
|
|
|||
|
|
### 本地构建
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
# 构建生产版本
|
|||
|
|
$ npm run build
|
|||
|
|
|
|||
|
|
# 构建并启动
|
|||
|
|
$ npm run start:prod
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### Docker 部署
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
# 构建 Docker 镜像
|
|||
|
|
$ docker build -t wwjauth/wwjcloud-nestjs .
|
|||
|
|
|
|||
|
|
# 运行容器
|
|||
|
|
$ docker run -p 3000:3000 wwjauth/wwjcloud-nestjs
|
|||
|
|
|
|||
|
|
# 使用 Docker Compose
|
|||
|
|
$ docker-compose up -d
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 生产环境部署
|
|||
|
|
|
|||
|
|
1. **环境准备**:配置生产环境变量
|
|||
|
|
2. **数据库迁移**:运行数据库迁移脚本
|
|||
|
|
3. **应用启动**:使用 PM2 进程管理器启动应用
|
|||
|
|
4. **反向代理**:配置 Nginx 反向代理
|
|||
|
|
5. **SSL 证书**:配置 HTTPS 证书
|
|||
|
|
6. **监控告警**:配置系统监控和告警
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
# PM2 部署
|
|||
|
|
$ pm2 start ecosystem.config.js --env production
|
|||
|
|
|
|||
|
|
# Nginx 配置示例
|
|||
|
|
server {
|
|||
|
|
listen 80;
|
|||
|
|
server_name your-domain.com;
|
|||
|
|
|
|||
|
|
location / {
|
|||
|
|
proxy_pass http://localhost:3000;
|
|||
|
|
proxy_set_header Host $host;
|
|||
|
|
proxy_set_header X-Real-IP $remote_addr;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 🔧 配置说明
|
|||
|
|
|
|||
|
|
### 环境变量
|
|||
|
|
|
|||
|
|
| 变量名 | 描述 | 默认值 | 必填 |
|
|||
|
|
|--------|------|--------|------|
|
|||
|
|
| `NODE_ENV` | 运行环境 | `development` | ❌ |
|
|||
|
|
| `PORT` | 服务端口 | `3000` | ❌ |
|
|||
|
|
| `DB_HOST` | 数据库主机 | `localhost` | ✅ |
|
|||
|
|
| `DB_PORT` | 数据库端口 | `3306` | ❌ |
|
|||
|
|
| `DB_USERNAME` | 数据库用户名 | - | ✅ |
|
|||
|
|
| `DB_PASSWORD` | 数据库密码 | - | ✅ |
|
|||
|
|
| `DB_DATABASE` | 数据库名称 | - | ✅ |
|
|||
|
|
| `REDIS_HOST` | Redis 主机 | `localhost` | ✅ |
|
|||
|
|
| `REDIS_PORT` | Redis 端口 | `6379` | ❌ |
|
|||
|
|
| `REDIS_PASSWORD` | Redis 密码 | - | ❌ |
|
|||
|
|
| `JWT_SECRET` | JWT 密钥 | - | ✅ |
|
|||
|
|
| `JWT_EXPIRES_IN` | JWT 过期时间 | `7d` | ❌ |
|
|||
|
|
| `UPLOAD_PATH` | 文件上传路径 | `./uploads` | ❌ |
|
|||
|
|
| `LOG_LEVEL` | 日志级别 | `info` | ❌ |
|
|||
|
|
|
|||
|
|
### 功能特性配置
|
|||
|
|
|
|||
|
|
- **认证系统**:JWT + RBAC 权限控制,支持多租户隔离
|
|||
|
|
- **文件上传**:支持本地存储、阿里云 OSS、腾讯云 COS、AWS S3
|
|||
|
|
- **缓存系统**:Redis 分布式缓存,支持集群模式
|
|||
|
|
- **队列系统**:Bull 队列处理,支持任务调度和重试机制
|
|||
|
|
- **日志系统**:Winston 结构化日志,支持多种输出格式
|
|||
|
|
- **监控系统**:健康检查、性能监控、错误追踪
|
|||
|
|
- **API 文档**:Swagger 自动生成,支持在线调试
|
|||
|
|
- **国际化**:支持多语言切换,前后端统一
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 📚 API 文档
|
|||
|
|
|
|||
|
|
启动应用后,访问以下地址查看 API 文档:
|
|||
|
|
|
|||
|
|
- **Swagger UI**:http://localhost:3000/api
|
|||
|
|
- **ReDoc**:http://localhost:3000/api-docs
|
|||
|
|
- **OpenAPI JSON**:http://localhost:3000/api-json
|
|||
|
|
|
|||
|
|
### API 规范
|
|||
|
|
|
|||
|
|
- **RESTful 设计**:遵循 REST 架构风格
|
|||
|
|
- **统一响应格式**:标准化的 API 响应结构
|
|||
|
|
- **错误处理**:统一的错误码和错误信息
|
|||
|
|
- **分页查询**:标准化的分页参数和响应
|
|||
|
|
- **版本控制**:支持 API 版本管理
|
|||
|
|
|
|||
|
|
```typescript
|
|||
|
|
// 统一响应格式
|
|||
|
|
{
|
|||
|
|
"code": 200,
|
|||
|
|
"message": "success",
|
|||
|
|
"data": {},
|
|||
|
|
"timestamp": "2024-01-01T00:00:00.000Z",
|
|||
|
|
"path": "/api/users"
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 🔌 插件开发
|
|||
|
|
|
|||
|
|
### 插件结构
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
addons/your-plugin/
|
|||
|
|
├── package.json # 插件配置
|
|||
|
|
├── plugin.config.ts # 插件配置文件
|
|||
|
|
├── src/
|
|||
|
|
│ ├── controllers/ # 控制器
|
|||
|
|
│ ├── services/ # 服务
|
|||
|
|
│ ├── entities/ # 实体
|
|||
|
|
│ └── dto/ # DTO
|
|||
|
|
├── migrations/ # 数据库迁移
|
|||
|
|
├── seeds/ # 种子数据
|
|||
|
|
└── README.md # 插件文档
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 插件开发指南
|
|||
|
|
|
|||
|
|
1. **创建插件**:使用脚手架创建插件模板
|
|||
|
|
2. **定义配置**:配置插件元信息和依赖
|
|||
|
|
3. **开发功能**:实现插件核心功能
|
|||
|
|
4. **数据迁移**:编写数据库迁移脚本
|
|||
|
|
5. **测试验证**:编写插件测试用例
|
|||
|
|
6. **打包发布**:打包插件并发布到应用市场
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
# 创建插件
|
|||
|
|
$ npm run plugin:create your-plugin
|
|||
|
|
|
|||
|
|
# 安装插件
|
|||
|
|
$ npm run plugin:install your-plugin
|
|||
|
|
|
|||
|
|
# 启用插件
|
|||
|
|
$ npm run plugin:enable your-plugin
|
|||
|
|
|
|||
|
|
# 禁用插件
|
|||
|
|
$ npm run plugin:disable your-plugin
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 🤝 贡献指南
|
|||
|
|
|
|||
|
|
我们欢迎所有形式的贡献,包括但不限于:
|
|||
|
|
|
|||
|
|
- 🐛 **Bug 报告**:发现问题请提交 Issue
|
|||
|
|
- 💡 **功能建议**:提出新功能想法
|
|||
|
|
- 📝 **文档改进**:完善文档内容
|
|||
|
|
- 🔧 **代码贡献**:提交代码修复或新功能
|
|||
|
|
- 🧩 **插件开发**:开发和分享插件
|
|||
|
|
|
|||
|
|
### 贡献流程
|
|||
|
|
|
|||
|
|
1. **Fork 仓库**:Fork 本仓库到您的 GitHub 账户
|
|||
|
|
2. **创建分支**:`git checkout -b feature/AmazingFeature`
|
|||
|
|
3. **提交更改**:`git commit -m 'feat: Add some AmazingFeature'`
|
|||
|
|
4. **推送分支**:`git push origin feature/AmazingFeature`
|
|||
|
|
5. **创建 PR**:打开 Pull Request 并描述您的更改
|
|||
|
|
|
|||
|
|
### 代码贡献规范
|
|||
|
|
|
|||
|
|
- **提交信息**:使用 [Conventional Commits](https://conventionalcommits.org/) 规范
|
|||
|
|
- **代码风格**:遵循项目的 ESLint 和 Prettier 配置
|
|||
|
|
- **测试覆盖**:新功能需要包含相应的测试用例
|
|||
|
|
- **文档更新**:重要更改需要更新相关文档
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 📄 许可证
|
|||
|
|
|
|||
|
|
本项目采用 **MIT 许可证** - 查看 [LICENSE](LICENSE) 文件了解详情。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 🆘 支持与帮助
|
|||
|
|
|
|||
|
|
如果您在使用过程中遇到问题,请通过以下方式获取帮助:
|
|||
|
|
|
|||
|
|
### 📞 联系方式
|
|||
|
|
|
|||
|
|
- 📧 **邮件支持**:support@wwjauth.com
|
|||
|
|
- 💬 **在线客服**:https://wwjauth.com/support
|
|||
|
|
- 📖 **文档中心**:https://docs.wwjauth.com
|
|||
|
|
- 🐛 **问题反馈**:https://github.com/wwjauth/wwjcloud-nestjs/issues
|
|||
|
|
- 💡 **功能建议**:https://github.com/wwjauth/wwjcloud-nestjs/discussions
|
|||
|
|
|
|||
|
|
### 🌐 社区
|
|||
|
|
|
|||
|
|
- **QQ 群**:123456789
|
|||
|
|
- **微信群**:扫描二维码加入
|
|||
|
|
- **Discord**:https://discord.gg/wwjauth
|
|||
|
|
- **Telegram**:https://t.me/wwjauth
|
|||
|
|
|
|||
|
|
### 📚 学习资源
|
|||
|
|
|
|||
|
|
- **视频教程**:https://www.bilibili.com/wwjauth
|
|||
|
|
- **博客文章**:https://blog.wwjauth.com
|
|||
|
|
- **示例项目**:https://github.com/wwjauth/examples
|
|||
|
|
- **最佳实践**:https://docs.wwjauth.com/best-practices
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 🏆 致谢
|
|||
|
|
|
|||
|
|
感谢所有为本项目做出贡献的开发者和社区成员!
|
|||
|
|
|
|||
|
|
### 🙏 特别感谢
|
|||
|
|
|
|||
|
|
- **[NestJS](https://nestjs.com/)** - 优秀的 Node.js 企业级框架
|
|||
|
|
- **[VbenAdmin](https://vben.pro/)** - 现代化的 Vue3 管理系统框架
|
|||
|
|
- **[TypeORM](https://typeorm.io/)** - 强大的 TypeScript ORM 框架
|
|||
|
|
- **[Vue3](https://vuejs.org/)** - 渐进式 JavaScript 框架
|
|||
|
|
- **[Element Plus](https://element-plus.org/)** - 基于 Vue3 的企业级 UI 组件库
|
|||
|
|
- **[Redis](https://redis.io/)** - 高性能内存数据库
|
|||
|
|
- **[Bull](https://github.com/OptimalBits/bull)** - 可靠的 Node.js 队列系统
|
|||
|
|
- **[Winston](https://github.com/winstonjs/winston)** - 通用日志库
|
|||
|
|
- **[Swagger](https://swagger.io/)** - API 文档生成工具
|
|||
|
|
|
|||
|
|
### 🌟 贡献者
|
|||
|
|
|
|||
|
|
感谢以下贡献者对项目的支持:
|
|||
|
|
|
|||
|
|
<!-- 这里可以添加贡献者头像 -->
|
|||
|
|
<a href="https://github.com/wwjauth/wwjcloud-nestjs/graphs/contributors">
|
|||
|
|
<img src="https://contrib.rocks/image?repo=wwjauth/wwjcloud-nestjs" />
|
|||
|
|
</a>
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 📈 项目统计
|
|||
|
|
|
|||
|
|

|
|||
|
|

|
|||
|
|

|
|||
|
|

|
|||
|
|

|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
<div align="center">
|
|||
|
|
|
|||
|
|
**WWJ Cloud 企业级框架** - 让企业级应用开发更简单、更高效! 🚀
|
|||
|
|
|
|||
|
|
**基于 NestJS + VbenAdmin 的现代化企业级解决方案**
|
|||
|
|
|
|||
|
|
[⭐ 给个 Star](https://github.com/wwjauth/wwjcloud-nestjs) |
|
|||
|
|
[📖 查看文档](https://docs.wwjauth.com) |
|
|||
|
|
[🚀 在线演示](http://demo.wwjauth.com) |
|
|||
|
|
[💬 加入社区](https://wwjauth.com/community)
|
|||
|
|
|
|||
|
|
</div>
|