# nbase **Repository Path**: z.smile/nbase ## Basic Information - **Project Name**: nbase - **Description**: nodejs base project - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-10-22 - **Last Updated**: 2025-12-02 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # nbase 一个基于 NestJS + React 的全栈 RBAC 权限管理系统脚手架,采用 Monorepo 架构,开箱即用。 ## 📋 目录 - [项目介绍](#项目介绍) - [技术架构](#技术架构) - [目录结构](#目录结构) - [环境要求](#环境要求) - [快速开始](#快速开始) - [配置说明](#配置说明) - [开发指南](#开发指南) - [打包部署](#打包部署) - [核心功能](#核心功能) - [核心模块说明](#核心模块说明) - [工具类使用](#工具类使用) - [API 文档](#api-文档) - [许可证](#许可证) --- ## 项目介绍 **nbase** 是一个企业级的 RBAC(基于角色的访问控制)权限管理系统脚手架,提供了完整的用户、角色、菜单、权限管理功能。项目采用 Monorepo 架构,前后端分离,支持快速开发企业级应用。 ### 核心特性 - 🎯 **完整的 RBAC 权限体系**:用户-角色-菜单权限管理 - 🚀 **开箱即用**:提供完整的基础功能模块 - 📦 **Monorepo 架构**:统一管理前后端代码和共享库 - 🔐 **JWT 认证**:支持 Token 黑名单、过期刷新 - 💾 **两级缓存**:内存 + Redis,自动回写 - 📝 **审计日志**:自动记录操作日志,支持装饰器配置 - 📊 **完善的日志系统**:基于 Pino,支持日志分割、分模块存储 - 🎨 **现代化 UI**:Ant Design 6.x + TailwindCSS - 🔧 **类型安全**:全栈 TypeScript,共享类型定义 - 📚 **Swagger 文档**:自动生成 API 文档 --- ## 技术架构 ### 后端技术栈 | 技术 | 版本 | 说明 | |------|------|------| | **Node.js** | 22.x | JavaScript 运行时 | | **NestJS** | 11.x | 企业级 Node.js 框架 | | **Fastify** | 5.x | 高性能 Web 框架 | | **TypeScript** | 5.9.x | 类型安全 | | **Drizzle ORM** | 0.44.x | 类型安全的 ORM | | **PostgreSQL** | 18.x | 关系型数据库 | | **Redis** | 8.x | 缓存数据库 | | **Pino** | 10.x | 高性能日志库 | | **Passport JWT** | 4.x | JWT 认证策略 | | **Class Validator** | 0.14.x | DTO 验证 | | **Bcrypt** | 6.x | 密码加密 | ### 前端技术栈 | 技术 | 版本 | 说明 | |------|------|------| | **React** | 19.x | UI 框架 | | **Vite** | 7.x | 构建工具 | | **TypeScript** | 5.9.x | 类型安全 | | **Ant Design** | 6.x | UI 组件库 | | **Ant Design Pro Components** | 2.x | 高级组件 | | **React Router** | 7.x | 路由管理 | | **Zustand** | 5.x | 状态管理 | | **Axios** | 1.x | HTTP 客户端 | | **TailwindCSS** | (通过 Ant Design 集成) | 样式工具 | ### 工程化工具 | 工具 | 版本 | 说明 | |------|------|------| | **pnpm** | 最新 | 包管理器 | | **Nx** | 21.6.x | Monorepo 构建系统 | | **ESLint** | 9.x | 代码检查 | | **Prettier** | 2.x | 代码格式化 | | **Webpack** | 5.x | 后端打包工具 | | **Vite** | 7.x | 前端构建工具 | --- ## 目录结构 ``` nbase/ ├── apps/ # 应用程序目录 │ ├── admin-api/ # 后端 API 服务 (NestJS + Fastify) │ │ ├── src/ │ │ │ ├── app.module.ts # 根模块 │ │ │ ├── main.ts # 入口文件 │ │ │ ├── config/ # 配置文件 │ │ │ │ └── swagger.config.ts # Swagger 配置 │ │ │ └── modules/ # 业务模块 │ │ │ ├── auth/ # 认证模块 (登录、个人中心) │ │ │ └── system/ # 系统管理模块 │ │ │ ├── user/ # 用户管理 │ │ │ ├── role/ # 角色管理 │ │ │ ├── menu/ # 菜单管理 │ │ │ ├── dept/ # 部门管理 │ │ │ ├── post/ # 岗位管理 │ │ │ ├── dict/ # 字典管理 │ │ │ └── audit-log/ # 审计日志 │ │ ├── env.template # 环境变量模板 │ │ ├── webpack.config.js # Webpack 配置 │ │ └── package.json │ │ │ └── admin-web/ # 前端 Web 应用 (React + Vite) │ ├── src/ │ │ ├── main.tsx # 入口文件 │ │ ├── app/ # 应用根组件 │ │ ├── components/ # 公共组件 │ │ │ ├── AuthRoute.tsx # 路由权限守卫 │ │ │ ├── DynamicRoutes.tsx # 动态路由生成 │ │ │ └── PermissionButton.tsx # 权限按钮 │ │ ├── layouts/ # 布局组件 │ │ │ └── BasicLayout/ # 基础布局 │ │ ├── pages/ # 页面组件 │ │ │ ├── Login/ # 登录页 │ │ │ ├── Home/ # 首页 │ │ │ └── System/ # 系统管理页面 │ │ ├── router/ # 路由配置 │ │ ├── services/ # API 服务层 │ │ ├── stores/ # 状态管理 │ │ │ ├── auth.store.ts # 认证状态 │ │ │ ├── route.store.ts # 路由状态 │ │ │ └── app.store.ts # 应用状态 │ │ ├── hooks/ # 自定义 Hooks │ │ ├── utils/ # 工具函数 │ │ │ ├── request.ts # Axios 封装 │ │ │ ├── storage.ts # 本地存储封装 │ │ │ ├── format.ts # 格式化工具 │ │ │ └── route.utils.tsx # 路由工具 │ │ ├── constants/ # 常量定义 │ │ └── config/ # 配置文件 │ ├── env.template # 环境变量模板 │ ├── vite.config.ts # Vite 配置 │ └── package.json │ ├── libs/ # 共享库目录 │ ├── db/ # 数据访问层 (Drizzle ORM) │ │ ├── src/ │ │ │ ├── client.ts # 数据库连接 │ │ │ ├── config.ts # 数据库配置 │ │ │ ├── schema/ # 数据表定义 │ │ │ │ ├── sys-user.schema.ts │ │ │ │ ├── sys-role.schema.ts │ │ │ │ ├── sys-menu.schema.ts │ │ │ │ ├── sys-dept.schema.ts │ │ │ │ ├── sys-post.schema.ts │ │ │ │ ├── sys-dict.schema.ts │ │ │ │ ├── sys-dict-data.schema.ts │ │ │ │ ├── sys-user-role.schema.ts │ │ │ │ ├── sys-role-menu.schema.ts │ │ │ │ ├── sys-user-post.schema.ts │ │ │ │ ├── sys-audit-log.schema.ts │ │ │ │ └── audit-fields.ts # 审计字段定义 │ │ │ ├── repository/ # 数据仓库 │ │ │ │ └── base.service.ts # 基础 CRUD 服务 │ │ │ ├── helpers/ # 辅助函数 │ │ │ │ ├── audit.helper.ts # 审计字段助手 │ │ │ │ └── pagination.helper.ts # 分页助手 │ │ │ ├── context/ # 上下文管理 │ │ │ │ └── audit-context.ts # 审计上下文 │ │ │ ├── seed/ # 种子数据 │ │ │ └── logger/ # SQL 日志 │ │ ├── drizzle/ # Drizzle 迁移文件 │ │ ├── drizzle.config.ts # Drizzle 配置 │ │ └── scripts/ # 数据库脚本 │ │ │ ├── nest-mods/ # NestJS 可复用模块 │ │ ├── src/ │ │ │ ├── auth/ # 认证模块 │ │ │ │ ├── common/ # 认证公共组件 │ │ │ │ │ ├── auth-common.module.ts │ │ │ │ │ ├── decorators/ # 装饰器 │ │ │ │ │ │ ├── current-user.decorator.ts │ │ │ │ │ │ ├── current-token.decorator.ts │ │ │ │ │ │ ├── current-user-id.decorator.ts │ │ │ │ │ │ └── public.decorator.ts │ │ │ │ │ ├── services/ # 服务 │ │ │ │ │ │ ├── request-context.service.ts # 请求上下文 │ │ │ │ │ │ └── token-blacklist.service.ts # Token 黑名单 │ │ │ │ │ └── utils/ # 工具类 │ │ │ │ │ └── crypto.util.ts # 加密工具 │ │ │ │ └── jwt/ # JWT 模块 │ │ │ │ ├── jwt.module.ts │ │ │ │ ├── jwt.service.ts │ │ │ │ ├── jwt.strategy.ts │ │ │ │ ├── jwt.guard.ts │ │ │ │ └── utils/ │ │ │ │ └── jwt-time.util.ts # JWT 时间工具 │ │ │ ├── rbac/ # RBAC 权限控制 │ │ │ │ ├── rbac.module.ts │ │ │ │ ├── rbac.service.ts │ │ │ │ ├── guards/ # 守卫 │ │ │ │ │ ├── roles.guard.ts │ │ │ │ │ └── permissions.guard.ts │ │ │ │ └── decorators/ # 装饰器 │ │ │ │ ├── roles.decorator.ts │ │ │ │ └── permissions.decorator.ts │ │ │ ├── logger/ # 日志模块 │ │ │ │ ├── logger.module.ts │ │ │ │ ├── logger.service.ts │ │ │ │ └── logger.factory.ts │ │ │ ├── audit-log/ # 审计日志 │ │ │ │ ├── audit-log.module.ts │ │ │ │ ├── audit-log.interceptor.ts │ │ │ │ └── decorators/ │ │ │ │ └── audit-log.decorator.ts │ │ │ └── common/ # 公共模块 │ │ │ ├── cache/ # 缓存模块 │ │ │ │ ├── cache.module.ts │ │ │ │ ├── cache.service.ts │ │ │ │ └── cache-key.factory.ts │ │ │ ├── database/ # 数据库模块 │ │ │ │ ├── database.module.ts │ │ │ │ └── inject-db.decorator.ts │ │ │ ├── dto/ # 数据传输对象 │ │ │ │ └── base-pagination.dto.ts │ │ │ ├── exceptions/ # 异常处理 │ │ │ │ └── business.exception.ts │ │ │ ├── filters/ # 过滤器 │ │ │ │ └── http-exception.filter.ts │ │ │ ├── interceptors/ # 拦截器 │ │ │ │ └── transform.interceptor.ts │ │ │ └── utils/ # 工具类 │ │ │ ├── request.util.ts │ │ │ ├── env.util.ts │ │ │ └── redis.util.ts │ │ └── package.json │ │ │ ├── shared/ # 前后端共享库 │ │ ├── src/ │ │ │ ├── constants/ # 常量定义 │ │ │ │ ├── common.constant.ts # 通用常量 │ │ │ │ ├── response.constant.ts # 响应码常量 │ │ │ │ ├── pagination.constant.ts # 分页常量 │ │ │ │ ├── user.constant.ts │ │ │ │ ├── role.constant.ts │ │ │ │ ├── menu.constant.ts │ │ │ │ ├── dept.constant.ts │ │ │ │ ├── post.constant.ts │ │ │ │ ├── dict.constant.ts │ │ │ │ └── audit-log.constant.ts │ │ │ ├── types/ # 类型定义 │ │ │ │ ├── common.type.ts # 通用类型 │ │ │ │ ├── auth.type.ts │ │ │ │ ├── user.type.ts │ │ │ │ ├── role.type.ts │ │ │ │ ├── menu.type.ts │ │ │ │ ├── dept.type.ts │ │ │ │ ├── post.type.ts │ │ │ │ ├── dict.type.ts │ │ │ │ └── audit-log.type.ts │ │ │ └── utils/ # 工具函数 │ │ └── package.json │ │ │ └── ui/ # UI 组件库 │ ├── src/ │ │ ├── components/ # 公共组件 │ │ └── icons/ # 图标库 │ └── package.json │ ├── scripts/ # 脚本目录 │ └── nbase.sql # 数据库初始化脚本 │ ├── package.json # 根 package.json ├── pnpm-workspace.yaml # pnpm workspace 配置 ├── nx.json # Nx 配置 ├── tsconfig.base.json # TypeScript 基础配置 └── README.md # 项目文档 ``` --- ## 环境要求 ### 必需环境 - **Node.js**: >= 22.x - **pnpm**: >= 9.x - **PostgreSQL**: >= 18.x (推荐使用 Docker) - **Redis**: >= 8.x (可选,用于缓存,未配置则自动使用内存缓存) ### 推荐开发工具 - **VSCode** / **WebStorm** (IDE) - **Navicat** / **DBeaver** (数据库管理工具) - **Redis Desktop Manager** / **Another Redis Desktop Manager** (Redis 管理工具) - **Postman** / **Insomnia** (API 测试工具,或直接使用 Swagger) --- ## 快速开始 ### 1. 克隆项目 ```bash git clone cd nbase ``` ### 2. 安装依赖 ```bash pnpm install ``` ### 3. 数据库初始化 #### 3.1 创建数据库 使用 PostgreSQL 客户端或命令行执行: ```bash # 方式一:使用提供的 SQL 脚本 psql -U postgres -f scripts/nbase.sql # 方式二:手动创建 createdb -U postgres nbase ``` #### 3.2 配置环境变量 复制 `apps/admin-api/env.template` 为 `.env.local` 和 `.env`: ```bash cd apps/admin-api cp env.template .env.local cp env.template .env ``` 编辑 `.env.local`,配置数据库连接: ```env # 数据库配置 DATABASE_URL=postgresql://postgres:postgres@localhost:5432/nbase # 服务器配置 PORT=3000 NODE_ENV=development # JWT 配置 JWT_SECRET=your-secret-key-change-me-in-production JWT_EXPIRES_IN=7d # Redis 配置 (可选) REDIS_HOST=localhost REDIS_PORT=6379 REDIS_PASSWORD= # CORS 配置 CORS_ORIGIN=http://localhost:4200 ``` #### 3.3 运行数据库迁移 ```bash # 在项目根目录执行 pnpm db:migrate ``` #### 3.4 初始化种子数据 ```bash pnpm db:seed ``` 这将创建默认管理员账号: - 用户名:`admin` - 密码:`123456` ### 4. 启动项目 #### 4.1 启动后端 ```bash # 方式一:使用 Nx (推荐) nx serve admin-api # 方式二:使用 npm scripts pnpm --filter @nbase/admin-api serve ``` 后端服务将运行在: - API 服务:http://localhost:3000/api - Swagger 文档:http://localhost:3000/api/docs #### 4.2 启动前端 ```bash # 在新的终端窗口 # 方式一:使用 Nx (推荐) nx serve admin-web # 方式二:使用 npm scripts pnpm --filter @nbase/admin-web serve ``` 前端应用将运行在:http://localhost:4200 #### 4.3 访问系统 打开浏览器访问 http://localhost:4200,使用默认账号登录: - 用户名:`admin` - 密码:`123456` --- ## 配置说明 ### 后端环境变量 (`apps/admin-api/.env`) | 变量名 | 说明 | 默认值 | 必填 | |--------|------|--------|------| | `DATABASE_URL` | PostgreSQL 连接字符串 | - | ✅ | | `PORT` | 服务端口 | 3000 | ❌ | | `NODE_ENV` | 运行环境 | development | ❌ | | `JWT_SECRET` | JWT 密钥 | - | ✅ | | `JWT_EXPIRES_IN` | JWT 过期时间 | 7d | ❌ | | `REDIS_HOST` | Redis 主机 | localhost | ❌ | | `REDIS_PORT` | Redis 端口 | 6379 | ❌ | | `REDIS_PASSWORD` | Redis 密码 | - | ❌ | | `REDIS_DB` | Redis 数据库编号 | 0 | ❌ | | `CORS_ORIGIN` | CORS 允许的源 | http://localhost:4200 | ❌ | | `CACHE_ENABLE_L1` | 是否启用 L1 内存缓存 | false | ❌ | | `CACHE_L1_MAX` | L1 缓存最大条目数 | 500 | ❌ | | `CACHE_L1_TTL` | L1 缓存过期时间(秒) | 300 | ❌ | | `CACHE_DEFAULT_TTL` | 默认缓存时间(秒) | 3600 | ❌ | ### 前端环境变量 (`apps/admin-web/.env`) 创建 `.env.local` 文件: ```env # API 基础地址 VITE_API_BASE_URL=http://localhost:3000/api ``` --- ## 开发指南 ### Monorepo 工作流 本项目使用 **pnpm workspace** + **Nx** 管理 Monorepo。 #### 常用命令 ```bash # 在根目录执行 # 运行特定应用 nx serve admin-api nx serve admin-web # 构建特定应用 nx build admin-api nx build admin-web # 构建所有应用 nx run-many --target=build --all # 查看依赖图 nx graph # 查看受影响的项目 nx affected:apps nx affected:libs ``` ### 数据库操作 ```bash # 生成 Drizzle 迁移文件 pnpm db:generate # 执行迁移 pnpm db:migrate # 直接推送 Schema 到数据库 (开发环境) pnpm db:push # 打开 Drizzle Studio (数据库可视化工具) pnpm db:studio # 运行种子数据 pnpm db:seed # 删除所有表 (危险操作) pnpm db:drop ``` ### 添加新的业务模块 #### 后端模块 1. **创建 Schema** (`libs/db/src/schema/`) ```typescript // sys-example.schema.ts import { pgTable, uuid, varchar, timestamp } from 'drizzle-orm/pg-core'; import { auditFields } from './audit-fields'; export const sysExample = pgTable('sys_example', { id: uuid('id').defaultRandom().primaryKey(), name: varchar('name', { length: 128 }).notNull(), ...auditFields, }); ``` 2. **生成迁移文件** ```bash pnpm db:generate pnpm db:migrate ``` 3. **创建 Service** (`apps/admin-api/src/modules/system/example/`) ```typescript // example.service.ts import { Injectable } from '@nestjs/common'; import { BaseService } from '@nbase/db'; import { sysExample } from '@nbase/db'; @Injectable() export class ExampleService extends BaseService { constructor() { super(sysExample); } // 自动继承: // - findAll() // - findById(id) // - create(data) // - update(id, data) // - softDelete(id) // - paginate(query, where) // ... 等方法 } ``` 4. **创建 Controller** ```typescript // example.controller.ts import { Controller, Get, Post, Body } from '@nestjs/common'; import { ApiTags } from '@nestjs/swagger'; import { ExampleService } from './example.service'; @ApiTags('示例模块') @Controller('system/example') export class ExampleController { constructor(private readonly exampleService: ExampleService) {} @Get() async findAll() { return this.exampleService.findAll(); } } ``` 5. **创建 Module** ```typescript // example.module.ts import { Module } from '@nestjs/common'; import { ExampleController } from './example.controller'; import { ExampleService } from './example.service'; @Module({ controllers: [ExampleController], providers: [ExampleService], exports: [ExampleService], }) export class ExampleModule {} ``` #### 前端模块 1. **创建 Service** (`apps/admin-web/src/services/`) ```typescript // example.service.ts import { get, post, put, del } from '~/utils/request'; export const exampleService = { getList: () => get('/system/example'), create: (data: any) => post('/system/example', data), update: (id: string, data: any) => put(`/system/example/${id}`, data), delete: (id: string) => del(`/system/example/${id}`), }; ``` 2. **创建页面组件** (`apps/admin-web/src/pages/System/Example/`) ```tsx // index.tsx import { useState, useEffect } from 'react'; import { ProTable } from '@ant-design/pro-components'; import { exampleService } from '~/services/example.service'; export default function ExamplePage() { return ( { const data = await exampleService.getList(); return { data, success: true }; }} columns={[ { title: '名称', dataIndex: 'name' }, // ... ]} /> ); } ``` 3. **配置路由** (`apps/admin-web/src/config/routes.config.ts`) ### 代码规范 #### TypeScript 规范 - 使用严格模式 (`strict: true`) - 避免使用 `any`,使用 `unknown` 或具体类型 - 导出的函数和类必须有 JSDoc 注释 - 使用 `interface` 定义对象结构,使用 `type` 定义联合/交叉类型 #### 命名规范 - 文件名:`kebab-case.ts` (例:`user.service.ts`) - 类名:`PascalCase` (例:`UserService`) - 函数名/变量名:`camelCase` (例:`getUserById`) - 常量:`UPPER_SNAKE_CASE` (例:`DEFAULT_PAGE_SIZE`) - 接口:`IPascalCase` (例:`IUserInfo`) - 类型:`TPascalCase` (例:`TUserStatus`) - 枚举:`EPascalCase` (例:`EUserStatus`) --- ## 打包部署 ### 后端打包 ```bash # 构建后端 nx build admin-api # 构建产物位于 # apps/admin-api/dist/ ``` 构建产物包含: - `main.js` - 打包后的应用 - `workspace_modules/` - 内部依赖库 - `package.json` - 依赖声明 - `pnpm-lock.yaml` - 锁定文件 ### 部署后端 #### 方式一:直接运行 ```bash cd apps/admin-api/dist # 安装生产依赖 pnpm install --prod # 设置环境变量 (复制 .env 到 dist 目录) cp ../.env . # 启动服务 node main.js ``` #### 方式二:使用 PM2 ```bash # 安装 PM2 npm install -g pm2 # 启动应用 pm2 start apps/admin-api/dist/main.js --name nbase-api # 查看状态 pm2 status # 查看日志 pm2 logs nbase-api # 设置开机自启 pm2 startup pm2 save ``` #### 方式三:Docker 创建 `Dockerfile`: ```dockerfile FROM node:22-alpine WORKDIR /app COPY apps/admin-api/dist ./ COPY apps/admin-api/.env ./ RUN npm install -g pnpm && \ pnpm install --prod EXPOSE 3000 CMD ["node", "main.js"] ``` 构建并运行: ```bash docker build -t nbase-api . docker run -d -p 3000:3000 --name nbase-api nbase-api ``` ### 前端打包 ```bash # 构建前端 nx build admin-web # 构建产物位于 # apps/admin-web/dist/ ``` ### 部署前端 #### 方式一:Nginx ```nginx server { listen 80; server_name your-domain.com; root /path/to/nbase/apps/admin-web/dist; index index.html; location / { try_files $uri $uri/ /index.html; } location /api { proxy_pass http://localhost:3000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } } ``` #### 方式二:静态托管 将 `apps/admin-web/dist/` 目录上传到: - **Vercel** - **Netlify** - **阿里云 OSS** - **腾讯云 COS** --- ## 核心功能 ### 1. 用户管理 - 用户列表查询(分页、排序、筛选) - 新增/编辑/删除用户 - 用户状态管理(启用/禁用) - 用户角色分配 - 用户岗位分配 - 修改密码 ### 2. 角色管理 - 角色列表查询 - 新增/编辑/删除角色 - 角色状态管理 - 角色权限分配(菜单权限) - 角色用户分配 ### 3. 菜单管理 - 菜单树形展示 - 新增/编辑/删除菜单 - 菜单类型(菜单/按钮) - 菜单图标、路由配置 - 菜单排序 ### 4. 部门管理 - 部门树形结构 - 新增/编辑/删除部门 - 部门排序 ### 5. 岗位管理 - 岗位列表查询 - 新增/编辑/删除岗位 - 岗位状态管理 ### 6. 字典管理 - 字典类型管理 - 字典数据管理 - 字典状态管理 ### 7. 审计日志 - 操作日志记录(自动/手动) - 日志查询(分页、筛选) - 支持记录:操作人、操作时间、操作类型、IP 地址、请求参数、响应结果 ### 8. 认证授权 - 用户登录(JWT) - Token 刷新 - Token 黑名单(登出后立即失效) - 修改密码 - 个人信息管理 ### 9. 权限控制 - 基于角色的访问控制(RBAC) - 菜单权限(前端路由控制) - 按钮权限(前端组件级控制) - API 权限(后端接口级控制) --- ## 核心模块说明 ### 1. @nbase/db - 数据访问层 提供数据库操作的基础设施。 #### BaseService 所有 Service 继承自 `BaseService`,自动获得以下能力: **基础查询** ```typescript // 查询所有 const users = await userService.findAll(); // 根据 ID 查询 const user = await userService.findById('xxx'); // 条件查询单条 const user = await userService.findOne(eq(sysUser.username, 'admin')); // 条件查询多条 const users = await userService.find( eq(sysUser.status, 1), { orderBy: desc(sysUser.createdAt), limit: 10 } ); // 根据 ID 数组查询 const users = await userService.findByIds(['id1', 'id2']); // 统计数量 const count = await userService.count(eq(sysUser.status, 1)); // 检查是否存在 const exists = await userService.exists(eq(sysUser.username, 'admin')); ``` **CRUD 操作** ```typescript // 创建 (自动填充 createdBy, createdAt) const user = await userService.create({ username: 'test', password: 'xxx', }); // 更新 (自动填充 updatedBy, updatedAt) const user = await userService.update('id', { nickname: '新昵称', }); // 批量更新 await userService.updateMany( eq(sysUser.status, 2), { status: 1 } ); // 软删除 (自动填充 isDeleted, updatedBy, updatedAt) await userService.softDelete('id'); // 物理删除 (慎用) await userService.hardDelete('id'); // 批量软删除 await userService.softDeleteMany(inArray(sysUser.id, ['id1', 'id2'])); // 恢复软删除 await userService.restore('id'); // 批量创建 await userService.createMany([ { username: 'user1', password: 'xxx' }, { username: 'user2', password: 'xxx' }, ]); ``` **分页查询** ```typescript // 基础分页 const result = await userService.paginate({ page: 1, pageSize: 10, sortBy: 'createdAt', sortOrder: 'desc', }); // 返回: { items, total, page, pageSize, totalPages } // 带条件分页 const result = await userService.paginate( { page: 1, pageSize: 10 }, eq(sysUser.status, 1) ); // QueryBuilder 分页 (联表查询) const queryBuilder = db .select({ id: sysUser.id, username: sysUser.username, roleName: sysRole.name, }) .from(sysUser) .leftJoin(sysUserRole, eq(sysUser.id, sysUserRole.userId)) .leftJoin(sysRole, eq(sysUserRole.roleId, sysRole.id)) .where(eq(sysUser.isDeleted, false)); const total = await userService.count(); const result = await userService.paginateQueryBuilder( queryBuilder, { page: 1, pageSize: 10 }, total ); // SQL 模板分页 (复杂查询) const result = await userService.paginateWithSql({ select: sql`SELECT u.id, u.username, COUNT(p.id) as post_count`, from: sql`FROM sys_user u LEFT JOIN posts p ON u.id = p.author_id`, where: sql`u.is_deleted = false`, groupBy: sql`u.id, u.username`, orderBy: sql`post_count DESC`, query: { page: 1, pageSize: 10 }, }); // 完整 SQL 分页 (CTE、窗口函数) const dataSql = sql`WITH RECURSIVE menu_tree AS (...) SELECT * FROM menu_tree`; const countSql = sql`WITH RECURSIVE menu_tree AS (...) SELECT COUNT(*) FROM menu_tree`; const result = await userService.paginateFullSql(dataSql, countSql, { page: 1, pageSize: 10 }); ``` #### 审计字段自动填充 所有表继承 `auditFields` 后,自动处理以下字段: ```typescript // 创建时自动填充 createdBy // 当前用户 ID createdAt // 创建时间 // 更新时自动填充 updatedBy // 当前用户 ID updatedAt // 更新时间 // 软删除时自动填充 isDeleted // true updatedBy // 当前用户 ID updatedAt // 删除时间 ``` 用户 ID 从 `AuditContextManager` 获取,由 `ClsUserMiddleware` 自动注入。 #### 分页助手 ```typescript import { paginate, buildPaginationMeta } from '@nbase/db'; // 基础分页 const result = await paginate(db, sysUser, { page: 1, pageSize: 10 }); // 构建分页元数据 const meta = buildPaginationMeta(total, page, pageSize); // 返回: { total, page, pageSize, totalPages } ``` ### 2. @nbase/nest-mods - NestJS 可复用模块 #### AuthCommonModule - 认证公共模块 提供认证基础设施: **装饰器** ```typescript // 获取当前用户 @CurrentUser() user: IUserPayload // 获取当前用户 ID @CurrentUserId() userId: string // 获取当前 Token @CurrentToken() token: string // 标记公开接口 (跳过 JWT 验证) @Public() @Get('public-data') getPublicData() {} ``` **服务** ```typescript // RequestContextService - 请求上下文 class RequestContextService { getUser(): IUserPayload | undefined; getUserId(): string | undefined; getToken(): string | undefined; } // TokenBlacklistService - Token 黑名单 class TokenBlacklistService { async addToBlacklist(token: string, expiresIn: number): Promise; async isBlacklisted(token: string): Promise; } ``` **工具类** ```typescript // CryptoUtil - 加密工具 CryptoUtil.hashPassword(password: string): Promise CryptoUtil.comparePassword(password: string, hash: string): Promise ``` #### JwtModule - JWT 认证模块 ```typescript // JwtService class JwtService { sign(payload: object): string; verify(token: string): any; decode(token: string): any; } // JwtGuard - 全局 JWT 守卫 (已在 AppModule 注册) // 所有接口默认需要 JWT 验证,使用 @Public() 跳过 // JwtTimeUtil - JWT 时间工具 JwtTimeUtil.parseExpiration('7d'): number // 转换为秒 JwtTimeUtil.toMilliseconds('7d'): number // 转换为毫秒 ``` #### RbacModule - RBAC 权限模块 ```typescript // 装饰器 @Roles('admin', 'user') // 角色守卫 @Permissions('user:create', 'user:update') // 权限守卫 // 示例 @Roles('admin') @Get('admin-only') adminOnly() {} @Permissions('user:delete') @Delete(':id') deleteUser(@Param('id') id: string) {} // RbacService - 权限服务 class RbacService { async getUserPermissions(userId: string): Promise; async getUserRoles(userId: string): Promise; async checkPermission(userId: string, permission: string): Promise; async checkRole(userId: string, role: string): Promise; } ``` #### LoggerModule - 日志模块 基于 Pino,支持日志分割、分模块存储。 ```typescript // 依赖注入方式 @Injectable() export class UserService { constructor(private readonly logger: LoggerService) { this.logger.setModule('user'); // 设置模块 (日志文件夹) this.logger.setContext('UserService'); // 设置上下文 (日志前缀) } async createUser() { this.logger.info('创建用户'); this.logger.error('创建失败', error); this.logger.warn('警告信息'); this.logger.debug('调试信息'); } } // 静态工厂方式 import { LoggerFactory } from '@nbase/nest-mods'; const logger = LoggerFactory.get('UserService', 'user'); logger.info('用户服务启动'); ``` 日志文件结构: ``` logs/ ├── app/ # 应用日志 │ ├── app.2025-11-24.1.log │ └── app-error.2025-11-24.1.log └── user/ # user 模块日志 ├── user.2025-11-24.1.log └── user-error.2025-11-24.1.log ``` #### CacheModule - 缓存模块 支持两级缓存:L1 内存 + L2 Redis。 ```typescript // CacheService class CacheService { async get(key: string): Promise; async set(key: string, value: any, ttl?: number): Promise; async del(key: string): Promise; async reset(): Promise; // 清空所有缓存 } // 使用示例 @Injectable() export class UserService { constructor(private readonly cacheService: CacheService) {} async getUser(id: string) { const cacheKey = CacheKeyFactory.user.detail(id); // 查询缓存 const cached = await this.cacheService.get(cacheKey); if (cached) return cached; // 查询数据库 const user = await this.findById(id); // 写入缓存 await this.cacheService.set(cacheKey, user, CACHE_TTL_PRESETS.HOUR_1); return user; } } // CacheKeyFactory - 缓存键工厂 CacheKeyFactory.user.detail(id) // 'user:detail:xxx' CacheKeyFactory.user.list() // 'user:list' CacheKeyFactory.role.permissions(id) // 'role:permissions:xxx' // CACHE_TTL_PRESETS - 预设过期时间 CACHE_TTL_PRESETS.MIN_1 // 1 分钟 CACHE_TTL_PRESETS.MIN_5 // 5 分钟 CACHE_TTL_PRESETS.MIN_15 // 15 分钟 CACHE_TTL_PRESETS.HOUR_1 // 1 小时 CACHE_TTL_PRESETS.HOUR_6 // 6 小时 CACHE_TTL_PRESETS.DAY_1 // 1 天 ``` 缓存策略: - **L1 内存**:默认 300 秒,LRU 500 条 - **L2 Redis**:默认 3600 秒 - 查询顺序:L1 → L2 → 数据库 - 自动回写:L2 命中自动回写 L1 环境变量配置: ```env # 是否启用 L1 内存缓存 CACHE_ENABLE_L1=true # L1 缓存配置 CACHE_L1_MAX=500 # 最大条目数 CACHE_L1_TTL=300 # 过期时间(秒) # L2 Redis 配置 CACHE_DEFAULT_TTL=3600 # 默认过期时间(秒) ``` #### AuditLogModule - 审计日志模块 自动记录 API 操作日志。 ```typescript // 装饰器方式 @AuditLog({ module: '用户管理', operation: '创建用户' }) @Post() async createUser(@Body() dto: CreateUserDto) { return this.userService.create(dto); } // 自定义日志内容 @AuditLog({ module: '用户管理', operation: '删除用户', getDetails: (req) => `删除用户 ID: ${req.params.id}`, }) @Delete(':id') async deleteUser(@Param('id') id: string) { return this.userService.softDelete(id); } ``` 记录内容: - 操作人 ID - 操作模块 - 操作类型 - 请求 IP - 请求路径 - 请求方法 - 请求参数 - 响应状态 - 响应数据 - 操作时间 - 耗时 #### 公共工具类 ```typescript // RequestUtil - 请求工具 RequestUtil.getIp(request): string RequestUtil.getUserAgent(request): string // EnvUtil - 环境变量工具 EnvUtil.isDevelopment(): boolean EnvUtil.isProduction(): boolean EnvUtil.get(key: string, defaultValue?: string): string EnvUtil.getNumber(key: string, defaultValue?: number): number // RedisUtil - Redis 工具 RedisUtil.createClient(config: IRedisConfig): Redis ``` ### 3. @nbase/shared - 前后端共享库 #### 常量 ```typescript // response.constant.ts export const RESPONSE_CODE = { SUCCESS: 0, BAD_REQUEST: 400, UNAUTHORIZED: 401, FORBIDDEN: 403, NOT_FOUND: 404, INTERNAL_ERROR: 500, }; // pagination.constant.ts export const DEFAULT_PAGE_SIZE = 10; export const MAX_PAGE_SIZE = 100; // user.constant.ts export enum USER_STATUS { ENABLED = 1, DISABLED = 2, } // menu.constant.ts export enum MENU_TYPE { MENU = 1, BUTTON = 2, } ``` #### 类型 ```typescript // common.type.ts export interface IResponse { code: number; message: string; data: T; timestamp: string; } export interface IPaginationQuery { page?: number; pageSize?: number; sortBy?: string; sortOrder?: 'asc' | 'desc'; } export interface IPaginationResponse { items: T[]; total: number; page: number; pageSize: number; totalPages: number; } // user.type.ts export interface IUserInfo { id: string; username: string; nickname?: string; email?: string; mobile?: string; avatar?: string; status: number; } // auth.type.ts export interface ILoginRequest { username: string; password: string; } export interface ILoginResponse { token: string; user: IUserInfo; } export interface IUserPayload { userId: string; username: string; } ``` ### 4. @nbase/ui - UI 组件库 集成 Ant Design 6.x,导出常用组件和图标。 ```typescript // 从 @nbase/ui 导入 import { message, Button, Modal } from '@nbase/ui'; // 使用 message.success('操作成功'); message.error('操作失败'); message.warning('警告'); message.info('提示'); ``` --- ## 工具类使用 ### 前端工具类 #### request.ts - HTTP 请求封装 基于 Axios 封装,支持三种响应模式。 ```typescript import { get, post, put, del } from '~/utils/request'; // 默认模式:返回 data const user = await get('/user/1'); // 等价于 response.data.data // body 模式:返回完整 IResponse const response = await get('/user/1', { _responseMode: 'body', }); // response = { code: 0, message: 'success', data: {...}, timestamp: '...' } // full 模式:返回完整 AxiosResponse const axiosResponse = await get('/user/1', { _responseMode: 'full', }); // 禁用业务错误提示 const result = await post('/user', data, { _showBizErrorMsg: false, }); ``` 特性: - 自动添加 `Authorization` 头 - 自动处理业务错误(code !== 0) - 自动处理 HTTP 错误(401 自动跳转登录) - 支持自定义错误提示 #### storage.ts - 本地存储封装 ```typescript import { storage, StorageKey } from '~/utils/storage'; // 保存 storage.set(StorageKey.AUTH_TOKEN, 'xxx'); storage.set(StorageKey.USER_INFO, userInfo); // 读取 const token = storage.get(StorageKey.AUTH_TOKEN); const userInfo = storage.get(StorageKey.USER_INFO); // 删除 storage.remove(StorageKey.AUTH_TOKEN); // 清空 storage.clear(); ``` 支持自动 JSON 序列化/反序列化。 #### format.ts - 格式化工具 ```typescript import { formatDate, formatDateTime, formatTime } from '~/utils/format'; formatDate(new Date()); // '2025-11-24' formatDateTime(new Date()); // '2025-11-24 15:30:45' formatTime(new Date()); // '15:30:45' ``` ### 后端工具类 #### CryptoUtil - 加密工具 ```typescript import { CryptoUtil } from '@nbase/nest-mods'; // 加密密码 const hash = await CryptoUtil.hashPassword('123456'); // 验证密码 const isValid = await CryptoUtil.comparePassword('123456', hash); ``` 使用 bcrypt,自动加盐(10 轮)。 #### JwtTimeUtil - JWT 时间工具 ```typescript import { JwtTimeUtil } from '@nbase/nest-mods'; // 解析过期时间 JwtTimeUtil.parseExpiration('7d'); // 604800 (秒) JwtTimeUtil.parseExpiration('24h'); // 86400 JwtTimeUtil.parseExpiration('30m'); // 1800 // 转换为毫秒 JwtTimeUtil.toMilliseconds('7d'); // 604800000 ``` 支持格式:`7d`, `24h`, `30m`, `60s`。 #### RequestUtil - 请求工具 ```typescript import { RequestUtil } from '@nbase/nest-mods'; // 获取客户端 IP const ip = RequestUtil.getIp(request); // 获取 User-Agent const ua = RequestUtil.getUserAgent(request); ``` 自动处理反向代理(`X-Forwarded-For`, `X-Real-IP`)。 #### EnvUtil - 环境变量工具 ```typescript import { EnvUtil } from '@nbase/nest-mods'; // 判断环境 EnvUtil.isDevelopment(); // true/false EnvUtil.isProduction(); // true/false // 读取环境变量 EnvUtil.get('JWT_SECRET', 'default-secret'); EnvUtil.getNumber('PORT', 3000); ``` --- ## API 文档 ### Swagger 文档 后端启动后,访问: **http://localhost:3000/api/docs** 提供完整的 API 接口文档,支持在线调试。 ### 主要接口 #### 认证接口 ``` POST /api/auth/login # 登录 POST /api/auth/logout # 登出 GET /api/auth/profile # 获取个人信息 PUT /api/auth/profile # 更新个人信息 PUT /api/auth/password # 修改密码 ``` #### 用户管理 ``` GET /api/system/user # 用户列表 (分页) GET /api/system/user/:id # 用户详情 POST /api/system/user # 创建用户 PUT /api/system/user/:id # 更新用户 DELETE /api/system/user/:id # 删除用户 POST /api/system/user/:id/roles # 分配角色 POST /api/system/user/:id/posts # 分配岗位 PUT /api/system/user/:id/status # 修改状态 PUT /api/system/user/:id/password # 重置密码 ``` #### 角色管理 ``` GET /api/system/role # 角色列表 GET /api/system/role/:id # 角色详情 POST /api/system/role # 创建角色 PUT /api/system/role/:id # 更新角色 DELETE /api/system/role/:id # 删除角色 POST /api/system/role/:id/permissions # 分配权限 POST /api/system/role/:id/users # 分配用户 ``` #### 菜单管理 ``` GET /api/system/menu # 菜单树 GET /api/system/menu/:id # 菜单详情 POST /api/system/menu # 创建菜单 PUT /api/system/menu/:id # 更新菜单 DELETE /api/system/menu/:id # 删除菜单 GET /api/system/menu/user-menus # 获取用户菜单树 ``` #### 部门管理 ``` GET /api/system/dept # 部门树 GET /api/system/dept/:id # 部门详情 POST /api/system/dept # 创建部门 PUT /api/system/dept/:id # 更新部门 DELETE /api/system/dept/:id # 删除部门 ``` #### 岗位管理 ``` GET /api/system/post # 岗位列表 GET /api/system/post/:id # 岗位详情 POST /api/system/post # 创建岗位 PUT /api/system/post/:id # 更新岗位 DELETE /api/system/post/:id # 删除岗位 POST /api/system/post/:id/users # 分配用户 ``` #### 字典管理 ``` GET /api/system/dict # 字典列表 GET /api/system/dict/:id # 字典详情 POST /api/system/dict # 创建字典 PUT /api/system/dict/:id # 更新字典 DELETE /api/system/dict/:id # 删除字典 GET /api/system/dict-data # 字典数据列表 GET /api/system/dict-data/:id # 字典数据详情 POST /api/system/dict-data # 创建字典数据 PUT /api/system/dict-data/:id # 更新字典数据 DELETE /api/system/dict-data/:id # 删除字典数据 ``` #### 审计日志 ``` GET /api/system/audit-log # 审计日志列表 (分页) GET /api/system/audit-log/:id # 审计日志详情 ``` --- ## 许可证 [MIT License](LICENSE) --- ## 贡献 欢迎提交 Issue 和 Pull Request! --- ## 联系方式 如有问题,请通过以下方式联系: - 提交 Issue - 发送邮件 --- **Happy Coding! 🎉**