- 重构sys模块架构,严格按admin/api/core分层 - 对齐所有sys实体与数据库表结构 - 实现完整的adminapi控制器,匹配PHP/Java契约 - 修复依赖注入问题,确保服务正确注册 - 添加自动迁移工具和契约验证 - 完善多租户支持和审计功能 - 统一命名规范,与PHP业务逻辑保持一致
11 KiB
11 KiB
代码生成器使用指南
概述
NiuCloud NestJS 代码生成器是一个强大的工具,可以根据数据库表结构自动生成符合项目规范的 NestJS 代码,包括 Controller、Service、Entity、DTO 等文件。
特性
- 🚀 自动生成: 基于数据库表结构自动生成代码
- 📝 规范对齐: 生成的代码完全符合项目命名和结构规范
- 🏗️ 模块化: 支持生成完整的模块结构
- 🔧 可配置: 支持自定义类名、模块名等参数
- 📦 多文件: 一次性生成 Controller、Service、Entity、DTO 等文件
- 🎯 类型安全: 生成的代码具有完整的 TypeScript 类型定义
架构设计
核心组件
src/common/generator/
├── generator.module.ts # 生成器模块
├── services/
│ ├── generator.service.ts # 核心生成服务
│ ├── template.service.ts # 模板服务
│ └── validation.service.ts # 验证服务
├── controllers/
│ └── generator.controller.ts # API控制器
├── interfaces/
│ └── generator.interface.ts # 接口定义
├── cli/
│ └── generate.command.ts # 命令行工具
└── index.ts # 模块导出
生成的文件类型
- Controller: 控制器文件,包含 CRUD 操作
- Service: 服务文件,包含业务逻辑
- Entity: 实体文件,对应数据库表
- DTO: 数据传输对象,包括创建、更新、查询 DTO
使用方法
1. API 接口使用
获取表信息
GET /api/adminapi/generator/table/sys_user
预览代码
POST /api/adminapi/generator/preview
Content-Type: application/json
{
"tableName": "sys_user",
"moduleName": "user",
"className": "SysUser",
"generateType": 1
}
生成代码
POST /api/adminapi/generator/generate
Content-Type: application/json
{
"tableName": "sys_user",
"moduleName": "user",
"className": "SysUser",
"generateType": 2
}
2. 编程方式使用
import { GeneratorService } from '@/common/generator';
@Injectable()
export class YourService {
constructor(private readonly generatorService: GeneratorService) {}
async generateCode() {
const options = {
tableName: 'sys_user',
moduleName: 'user',
className: 'SysUser',
generateType: 1
};
const files = await this.generatorService.generate(options);
return files;
}
}
Mapper 示例
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { SysUser } from '../entity/sysUser.entity';
/**
* 用户数据访问层
* @author NiuCloud Team
* @date 2024-01-01
*/
@Injectable()
export class SysUserMapper {
constructor(
@InjectRepository(SysUser)
private readonly repository: Repository<SysUser>,
) {}
/**
* 根据ID查找
*/
async findById(id: number): Promise<SysUser | null> {
return this.repository.findOne({ where: { id } });
}
/**
* 分页查询
*/
async findWithPagination(page: number, limit: number): Promise<[SysUser[], number]> {
return this.repository.findAndCount({
skip: (page - 1) * limit,
take: limit,
});
}
}
Event 示例
import { SysUser } from '../entity/sysUser.entity';
/**
* 用户创建事件
* @author NiuCloud Team
* @date 2024-01-01
*/
export class SysUserCreatedEvent {
constructor(public readonly sysUser: SysUser) {}
}
Listener 示例
import { Injectable } from '@nestjs/common';
import { OnEvent } from '@nestjs/event-emitter';
import { SysUserCreatedEvent } from '../events/sysUser.created.event';
/**
* 用户创建事件监听器
* @author NiuCloud Team
* @date 2024-01-01
*/
@Injectable()
export class SysUserCreatedListener {
@OnEvent('sysUser.created')
handleSysUserCreated(event: SysUserCreatedEvent) {
console.log('用户创建事件:', event.sysUser);
// 在这里添加业务逻辑
}
}
3. 命令行工具使用
import { GenerateCommand } from '@/common/generator';
const command = new GenerateCommand(generatorService);
// 生成完整模块
await command.generateModule({
table: 'sys_user',
module: 'user',
className: 'SysUser'
});
// 生成控制器
await command.generateController({
table: 'sys_user',
module: 'user'
});
// 生成服务
await command.generateService({
table: 'sys_user',
module: 'user'
});
// 生成实体
await command.generateEntity({
table: 'sys_user',
module: 'user'
});
配置参数
GeneratorOptions
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| tableName | string | ✅ | 数据库表名 |
| moduleName | string | ❌ | 模块名,默认从表名转换 |
| className | string | ❌ | 类名,默认从表名转换 |
| addonName | string | ❌ | 插件名,用于插件开发 |
| generateType | number | ✅ | 生成类型:1-预览,2-下载,3-同步 |
| outputDir | string | ❌ | 输出目录,默认项目根目录 |
| generateController | boolean | ❌ | 是否生成控制器,默认true |
| generateService | boolean | ❌ | 是否生成服务,默认true |
| generateEntity | boolean | ❌ | 是否生成实体,默认true |
| generateDto | boolean | ❌ | 是否生成DTO,默认true |
| generateMapper | boolean | ❌ | 是否生成数据访问层,默认false |
| generateEvents | boolean | ❌ | 是否生成事件,默认false |
| generateListeners | boolean | ❌ | 是否生成监听器,默认false |
| generateTest | boolean | ❌ | 是否生成测试文件,默认false |
命名转换规则
- 表名转模块名:
sys_user→sysUser(驼峰命名) - 表名转类名:
sys_user→SysUser(帕斯卡命名) - 文件名: 使用驼峰命名 + 后缀,如
sysUser.controller.ts - 字段名: 保持数据库原始命名
生成的文件结构
目录结构
src/common/{moduleName}/
├── controllers/
│ └── adminapi/
│ └── {moduleName}.controller.ts
├── services/
│ └── admin/
│ └── {moduleName}.service.ts
├── entity/
│ └── {moduleName}.entity.ts
├── dto/
│ ├── create-{moduleName}.dto.ts
│ ├── update-{moduleName}.dto.ts
│ └── query-{moduleName}.dto.ts
├── mapper/
│ └── {moduleName}.mapper.ts
├── events/
│ ├── {moduleName}.created.event.ts
│ ├── {moduleName}.updated.event.ts
│ └── {moduleName}.deleted.event.ts
└── listeners/
├── {moduleName}.created.listener.ts
├── {moduleName}.updated.listener.ts
└── {moduleName}.deleted.listener.ts
文件内容示例
Controller 示例
import { Controller, Get, Post, Put, Delete, Body, Param, Query } from '@nestjs/common';
import { ApiTags, ApiOperation, ApiResponse } from '@nestjs/swagger';
import { SysUserService } from '../services/admin/sysUser.service';
import { CreateSysUserDto } from '../dto/create-sysUser.dto';
import { UpdateSysUserDto } from '../dto/update-sysUser.dto';
import { QuerySysUserDto } from '../dto/query-sysUser.dto';
/**
* 用户管理控制器
* @author NiuCloud Team
* @date 2024-01-01
*/
@ApiTags('用户管理')
@Controller('adminapi/user')
export class SysUserController {
constructor(private readonly userService: SysUserService) {}
@Get()
@ApiOperation({ summary: '获取用户列表' })
@ApiResponse({ status: 200, description: '获取成功' })
async findAll(@Query() query: QuerySysUserDto) {
return this.userService.findAll(query);
}
// ... 其他方法
}
Entity 示例
import { Entity, PrimaryGeneratedColumn, Column, CreateDateColumn, UpdateDateColumn } from 'typeorm';
/**
* 用户实体
* @author NiuCloud Team
* @date 2024-01-01
*/
@Entity('sys_user')
export class SysUser {
@PrimaryGeneratedColumn()
id: number;
@Column({ name: 'username', length: 50 })
username: string;
@Column({ name: 'email', length: 100 })
email: string;
@CreateDateColumn({ name: 'created_at' })
createdAt: Date;
@UpdateDateColumn({ name: 'updated_at' })
updatedAt: Date;
}
最佳实践
1. 表设计规范
- 表名使用下划线命名:
sys_user,sys_role - 字段名使用下划线命名:
user_name,created_at - 必须包含主键字段
id - 建议包含时间戳字段
created_at,updated_at
2. 生成前准备
- 确保数据库表结构完整
- 检查表名和字段名符合命名规范
- 确认表注释信息完整
3. 生成后处理
- 检查生成的文件路径是否正确
- 验证生成的代码是否符合项目规范
- 根据需要调整生成的代码
- 添加必要的业务逻辑
4. 版本控制
- 生成的代码应该纳入版本控制
- 避免重复生成相同文件
- 使用 Git 跟踪代码变更
故障排除
常见问题
-
表不存在错误
- 检查表名是否正确
- 确认数据库连接正常
- 验证表是否在正确的数据库中
-
字段类型映射错误
- 检查数据库字段类型
- 确认类型映射规则
- 手动调整生成的代码
-
文件路径错误
- 检查模块名和类名设置
- 确认目录结构正确
- 验证文件权限
-
模板替换错误
- 检查模板变量是否正确
- 确认数据完整性
- 查看错误日志
调试技巧
-
启用详细日志
// 在生成器中添加日志 console.log('Table info:', tableInfo); console.log('Generated files:', files); -
分步生成
// 先生成单个文件类型 const controllerFile = await generateController(options); const serviceFile = await generateService(options); -
预览模式
// 使用预览模式查看生成内容 const files = await generatorService.preview(options); console.log(files[0].content);
扩展开发
自定义模板
- 修改
TemplateService中的模板内容 - 添加新的模板变量
- 扩展生成的文件类型
添加新的生成器
- 创建新的生成器类
- 实现生成逻辑
- 注册到生成器服务中
集成到 CI/CD
# GitHub Actions 示例
- name: Generate Code
run: |
npm run generate:module -- --table=sys_user --module=user
git add .
git commit -m "Auto-generated code for sys_user"
更新日志
v1.0.0 (2024-01-01)
- 初始版本发布
- 支持基本的 CRUD 代码生成
- 提供 API 和命令行两种使用方式
- 支持多种文件类型生成
贡献指南
欢迎贡献代码和提出建议!
- Fork 项目
- 创建功能分支
- 提交更改
- 发起 Pull Request
许可证
本项目采用 MIT 许可证。