- 重构LanguageUtils为LanguageService,实现ILanguageService接口 - 移除自定义验证管道和装饰器,使用标准NestJS验证 - 集成框架ValidatorService进行业务验证 - 简化目录结构,移除不必要的子目录 - 支持模块化语言包加载(common、user、order等) - 统一API响应格式(code、msg、data、timestamp) - 添加ValidationExceptionFilter处理多语言验证错误 - 完善多语言示例和文档
613 lines
17 KiB
Markdown
613 lines
17 KiB
Markdown
# 迁移工具正确使用基础设施指南
|
||
|
||
## 概述
|
||
|
||
本文档说明如何在迁移工具中正确使用NestJS的基础设施(Common层)和业务核心(Core层),确保生成的业务代码能够充分利用框架能力。
|
||
|
||
## 新架构层级概览
|
||
|
||
### 🏗️ Common层基础设施 (原Core层基础设施迁移到此)
|
||
|
||
### 🧠 Core层业务核心 (原Common业务迁移到此)
|
||
|
||
**Core层应该放置具体的业务模块:**
|
||
- **位置**: `src/core/{module_name}/`
|
||
- **模块示例**:
|
||
- `member/` - 会员管理业务模块
|
||
- `install/` - 安装向导业务模块
|
||
- `diy/` - DIY装修业务模块
|
||
- `dict/` - 数据字典业务模块
|
||
- **文件结构**: 各模块包含控制器、服务、实体、DTO等
|
||
- **用途**: 具体业务逻辑实现和业务流程控制
|
||
|
||
## Common层基础设施概览
|
||
|
||
### 1. 基础服务系统
|
||
- **位置**: `src/common/base/`
|
||
- **文件**: base.entity.ts, base.service.ts, base.repository.ts, base.module.ts
|
||
- **用途**: 通用基础服务、实体基类、仓储基类
|
||
|
||
### 2. 缓存系统
|
||
- **位置**: `src/common/cache/`
|
||
- **文件**: cache.service.ts, cache.module.ts, decorators/
|
||
- **用途**: 分布式缓存、缓存装饰器、性能优化
|
||
|
||
### 3. 上下文管理
|
||
- **位置**: `src/common/context/`
|
||
- **文件**: context.service.ts, context.module.ts
|
||
- **用途**: 请求上下文管理、多租户支持
|
||
|
||
### 4. 数据库服务
|
||
- **位置**: `src/common/database/`
|
||
- **文件**: database.module.ts, backup.service.ts
|
||
- **用途**: 数据库连接、备份服务
|
||
|
||
### 5. 异常处理系统
|
||
- **位置**: `src/common/exception/`
|
||
- **文件**: exception.filter.ts, business.exception.ts, base.exception.ts
|
||
- **用途**: 统一异常处理、业务异常、错误响应格式化
|
||
|
||
### 6. 事件系统
|
||
- **位置**: `src/common/event/`
|
||
- **文件**: event.module.ts
|
||
- **用途**: 事件驱动、应用事件处理
|
||
|
||
### 7. 拦截器系统
|
||
- **位置**: `src/common/interceptors/`
|
||
- **文件**: method-call.interceptor.ts, request-parameter.interceptor.ts
|
||
- **用途**: 请求拦截、方法调用统计、参数校验
|
||
|
||
### 8. 响应系统
|
||
- **位置**: `src/common/response/`
|
||
- **文件**: response.interceptor.ts, result.class.ts, result.interface.ts
|
||
- **用途**: 统一响应格式、结果封装、API标准化
|
||
|
||
### 9. 安全系统
|
||
- **位置**: `src/common/security/`
|
||
- **文件**: guards/, strategies/, decorators/
|
||
- **用途**: JWT认证、角色授权、权限控制
|
||
|
||
### 10. 日志系统
|
||
- **位置**: `src/common/logging/`
|
||
- **文件**: logging.service.ts, logging.module.ts
|
||
- **用途**: 统一日志管理、日志级别控制
|
||
|
||
### 11. 监控系统
|
||
- **位置**: `src/common/monitoring/`
|
||
- **文件**: monitoring.service.ts, monitoring.module.ts
|
||
- **用途**: 应用监控、性能指标、健康检查
|
||
|
||
### 12. 队列系统
|
||
- **位置**: `src/common/queue/`
|
||
- **文件**: queue.module.ts
|
||
- **用途**: 消息队列、异步任务处理
|
||
|
||
### 13. 调度系统
|
||
- **位置**: `src/common/scheduler/`
|
||
- **文件**: scheduler.module.ts
|
||
- **用途**: 定时任务、计划任务调度
|
||
|
||
### 14. 工具库系统
|
||
- **位置**: `src/common/libraries/`
|
||
- **文件**: redis/, dayjs/, lodash/, winston/, prometheus/, sharp/, uuid/
|
||
- **用途**: 第三方库集成、工具服务提供
|
||
|
||
### 15. 插件系统
|
||
- **位置**: `src/common/plugins/`
|
||
- **文件**: captcha/, qrcode/, wechat/
|
||
- **用途**: 功能插件、扩展能力
|
||
|
||
### 16. Swagger文档
|
||
- **位置**: `src/common/swagger/`
|
||
- **文件**: swagger.module.ts, swagger.service.ts
|
||
- **用途**: API文档生成、接口文档管理
|
||
|
||
### 17. 验证系统
|
||
- **位置**: `src/common/validation/`
|
||
- **文件**: base.dto.ts, custom-validators.ts
|
||
- **用途**: 数据验证、DTO基类、自定义验证器
|
||
|
||
### 18. 管道系统
|
||
- **位置**: `src/common/pipes/`
|
||
- **文件**: parse-diy-form.pipe.ts, pipes.module.ts
|
||
- **用途**: 数据转换、格式处理、参数解析
|
||
|
||
### 19. 工具类
|
||
- **位置**: `src/common/utils/`
|
||
- **文件**: clone.util.ts, crypto.util.ts, json.util.ts, system.util.ts
|
||
- **用途**: 通用工具函数、系统功能、加密解密
|
||
|
||
### 20. 语言系统
|
||
- **位置**: `src/common/language/`
|
||
- **文件**: language.utils.ts
|
||
- **用途**: 多语言支持、国际化处理
|
||
|
||
### 21. 追踪系统
|
||
- **位置**: `src/common/tracing/`
|
||
- **文件**: tracing.module.ts, tracing.service.ts
|
||
- **用途**: 链路追踪、性能监控、请求跟踪
|
||
|
||
### 22. 加载器系统
|
||
- **位置**: `src/common/loader/`
|
||
- **文件**: loader.module.ts, loader.utils.ts
|
||
- **用途**: 资源加载、配置加载、动态加载
|
||
|
||
### 23. 初始化系统
|
||
- **位置**: `src/common/init/`
|
||
- **文件**: init.module.ts, init.service.ts
|
||
- **用途**: 应用初始化、启动配置
|
||
|
||
### 24. 系统工具
|
||
- **位置**: `src/common/system/`
|
||
- **文件**: system.module.ts, system.utils.ts
|
||
- **用途**: 系统信息、环境管理
|
||
|
||
## 迁移工具使用基础设施的正确方式
|
||
|
||
### 1. 控制器生成器使用基础设施
|
||
|
||
#### 1.1 使用安全认证
|
||
```typescript
|
||
// 正确使用方式
|
||
import { Controller, Get, Post, Put, Delete, Body, Param, Query } from '@nestjs/common';
|
||
import { ApiTags, ApiOperation, ApiResponse } from '@nestjs/swagger';
|
||
import { RolesGuard } from '@wwjCommon/security/guards/roles.guard';
|
||
import { JwtAuthGuard } from '@wwjCommon/security/guards/jwt-auth.guard';
|
||
import { Roles } from '@wwjCommon/security/decorators/roles.decorator';
|
||
import { Public } from '@wwjCommon/security/decorators/public.decorator';
|
||
|
||
@ApiTags('diy')
|
||
@Controller('adminapi/diy')
|
||
@UseGuards(JwtAuthGuard, RolesGuard) // 使用Common层守卫
|
||
export class ConfigController {
|
||
constructor(
|
||
private readonly diyConfig: AdminDiyConfigService
|
||
) {}
|
||
|
||
@Get('list')
|
||
@Roles('admin') // 使用Core层角色装饰器
|
||
@ApiOperation({ summary: '获取配置列表' })
|
||
async getList(@Query() query: any) {
|
||
// 业务逻辑实现
|
||
}
|
||
|
||
@Post('create')
|
||
@Roles('admin')
|
||
@ApiOperation({ summary: '创建配置' })
|
||
async create(@Body() body: any) {
|
||
// 业务逻辑实现
|
||
}
|
||
}
|
||
```
|
||
|
||
#### 1.2 使用异常处理
|
||
```typescript
|
||
// 正确使用方式
|
||
import { BusinessException } from '@wwjCommon/exception/business.exception';
|
||
|
||
@Get('list')
|
||
async getList(@Query() query: any) {
|
||
try {
|
||
// 业务逻辑
|
||
return await this.diyConfig.getList(query);
|
||
} catch (error) {
|
||
// 使用Core层异常处理
|
||
throw new BusinessException('获取配置列表失败', error);
|
||
}
|
||
}
|
||
```
|
||
|
||
#### 1.3 使用管道验证
|
||
```typescript
|
||
// 正确使用方式
|
||
import { ParseDiyFormPipe } from '@wwjCommon/pipes/parse-diy-form.pipe';
|
||
|
||
@Post('create')
|
||
async create(
|
||
@Body(ParseDiyFormPipe) body: any // 使用Common层管道
|
||
) {
|
||
// 业务逻辑实现
|
||
}
|
||
```
|
||
|
||
### 2. 服务生成器使用基础设施
|
||
|
||
#### 2.1 使用数据库服务
|
||
```typescript
|
||
// 正确使用方式
|
||
import { Injectable } from '@nestjs/common';
|
||
import { InjectRepository } from '@nestjs/typeorm';
|
||
import { Repository } from 'typeorm';
|
||
import { BaseService } from '@wwjCommon/base/base.service';
|
||
import { DatabaseModule } from '@wwjCommon/database/database.module';
|
||
|
||
@Injectable()
|
||
export class DiyConfigService_adminService extends BaseService<any> {
|
||
constructor(
|
||
@InjectRepository(DiyConfig)
|
||
protected readonly repository: Repository<DiyConfig>,
|
||
// 使用Common层基础服务和数据库
|
||
) {
|
||
super(repository);
|
||
}
|
||
|
||
async getList(params: any) {
|
||
// 业务逻辑实现
|
||
return await this.repository.find(params);
|
||
}
|
||
|
||
async create(data: any) {
|
||
// 业务逻辑实现
|
||
return await this.repository.save(data);
|
||
}
|
||
}
|
||
```
|
||
|
||
#### 2.2 使用缓存服务
|
||
```typescript
|
||
// 正确使用方式
|
||
import { CacheService } from '@wwjCommon/cache/cache.service';
|
||
|
||
@Injectable()
|
||
export class DiyConfigService_adminService extends BaseService<any> {
|
||
constructor(
|
||
@InjectRepository(DiyConfig)
|
||
protected readonly repository: Repository<DiyConfig>,
|
||
private readonly cacheService: CacheService // 使用Common层缓存服务
|
||
) {
|
||
super(repository);
|
||
}
|
||
|
||
async getList(params: any) {
|
||
const cacheKey = `diy:config:list:${JSON.stringify(params)}`;
|
||
|
||
// 使用Common层缓存服务
|
||
let result = await this.cacheService.get(cacheKey);
|
||
if (!result) {
|
||
result = await this.repository.find(params);
|
||
await this.cacheService.set(cacheKey, result); // 缓存
|
||
}
|
||
|
||
return result;
|
||
}
|
||
|
||
async update(id: number, data: any) {
|
||
// 业务逻辑实现
|
||
const result = await this.repository.update(id, data);
|
||
|
||
// 清除相关缓存
|
||
await this.cacheService.del(`diy:config:list:*`);
|
||
|
||
return result;
|
||
}
|
||
}
|
||
```
|
||
|
||
#### 2.3 使用队列服务
|
||
```typescript
|
||
// 正确使用方式
|
||
import { QueueModule } from '@wwjCommon/queue/queue.module';
|
||
|
||
@Injectable()
|
||
export class DiyConfigService_adminService extends BaseService<any> {
|
||
constructor(
|
||
@InjectRepository(DiyConfig)
|
||
protected readonly repository: Repository<DiyConfig>,
|
||
private readonly queueService: UnifiedQueueService // 使用Core层队列服务
|
||
) {
|
||
super(repository);
|
||
}
|
||
|
||
async create(data: any) {
|
||
// 业务逻辑实现
|
||
const result = await this.repository.save(data);
|
||
|
||
// 使用Core层队列服务发送异步任务
|
||
await this.queueService.addTask('diy', 'configCreated', {
|
||
id: result.id,
|
||
data: result
|
||
});
|
||
|
||
return result;
|
||
}
|
||
}
|
||
```
|
||
|
||
### 3. 实体生成器使用基础设施
|
||
|
||
#### 3.1 使用基础实体
|
||
```typescript
|
||
// 正确使用方式
|
||
import { Entity, PrimaryGeneratedColumn, PrimaryColumn, Column, Index } from 'typeorm';
|
||
import { BaseEntity } from '@wwjCore';
|
||
|
||
@Entity('diy_page')
|
||
export class Diy extends BaseEntity {
|
||
@PrimaryColumn({ name: 'id', type: 'int' })
|
||
id: number;
|
||
|
||
@Column({ name: 'name', length: 100 })
|
||
name: string;
|
||
|
||
@Column({ name: 'content', type: 'text' })
|
||
content: string;
|
||
|
||
@Column({ name: 'status', type: 'tinyint', default: 1 })
|
||
status: number;
|
||
|
||
@Index('idx_site_id') // 使用Core层索引管理
|
||
@Column({ name: 'site_id', type: 'int' })
|
||
siteId: number;
|
||
}
|
||
```
|
||
|
||
### 4. DTO生成器使用基础设施
|
||
|
||
#### 4.1 使用验证管道
|
||
```typescript
|
||
// 正确使用方式
|
||
import { IsString, IsNumber, IsOptional, IsNotEmpty } from 'class-validator';
|
||
import { ApiProperty } from '@nestjs/swagger';
|
||
import { validateEvent } from '@wwjCore/event/contractValidator';
|
||
|
||
export class CreateDiyDto {
|
||
@ApiProperty({ description: '页面名称' })
|
||
@IsString()
|
||
@IsNotEmpty()
|
||
name: string;
|
||
|
||
@ApiProperty({ description: '页面内容' })
|
||
@IsString()
|
||
@IsNotEmpty()
|
||
content: string;
|
||
|
||
@ApiProperty({ description: '状态', required: false })
|
||
@IsNumber()
|
||
@IsOptional()
|
||
status?: number;
|
||
}
|
||
|
||
export class DiyDtoValidator {
|
||
static async validate(data: CreateDiyDto): Promise<boolean> {
|
||
// 使用Core层契约验证
|
||
return await validateEvent('diy.create', data);
|
||
}
|
||
}
|
||
```
|
||
|
||
### 5. 监听器生成器使用基础设施
|
||
|
||
#### 5.1 使用事件系统
|
||
```typescript
|
||
// 正确使用方式
|
||
import { Injectable } from '@nestjs/common';
|
||
import { DomainEventHandler, EventHandler } from '@wwjCore';
|
||
import { EventBusPublisher } from '@wwjCore/event/eventBusPublisher';
|
||
|
||
@Injectable()
|
||
@DomainEventHandler()
|
||
export class ThemeColorListener {
|
||
constructor(
|
||
private readonly eventBus: EventBusPublisher // 使用Core层事件总线
|
||
) {}
|
||
|
||
@EventHandler('themecolor.handle')
|
||
async handle(payload: any) {
|
||
try {
|
||
// 业务逻辑实现
|
||
const result = await this.processThemeColor(payload);
|
||
|
||
// 使用Core层事件总线发布新事件
|
||
await this.eventBus.publish('themecolor.processed', result);
|
||
|
||
return result;
|
||
} catch (error) {
|
||
// 使用Core层异常处理
|
||
throw new BusinessException('主题颜色处理失败', error);
|
||
}
|
||
}
|
||
|
||
private async processThemeColor(payload: any) {
|
||
// 业务逻辑实现
|
||
if (payload.key === 'app') {
|
||
return {
|
||
theme_color: [
|
||
{
|
||
title: '商务蓝',
|
||
name: 'blue',
|
||
value: '#1890ff'
|
||
}
|
||
]
|
||
};
|
||
}
|
||
return null;
|
||
}
|
||
}
|
||
```
|
||
|
||
### 6. 任务生成器使用基础设施
|
||
|
||
### 7. 中间件生成器已废弃
|
||
**重要说明**: 中间件生成器已废弃,请使用Core层Guards+Interceptors+Pipes
|
||
|
||
#### 废弃原因
|
||
- ❌ 原生NestMiddleware已过时
|
||
- ❌ 与Java框架不一致(Java使用拦截器而非中间件)
|
||
- ❌ Core层已提供完整的安全基础设施
|
||
|
||
#### 替代方案
|
||
使用Core层基础设施替代中间件:
|
||
|
||
```typescript
|
||
// 认证 - 使用Guards
|
||
@UseGuards(AdminCheckTokenGuard, RolesGuard)
|
||
@Controller('adminapi/user')
|
||
export class UserController {
|
||
// 业务逻辑
|
||
}
|
||
|
||
// 拦截 - 使用Interceptors
|
||
@UseInterceptors(TracingInterceptor, ResponseInterceptor)
|
||
export class UserService {
|
||
// 业务逻辑
|
||
}
|
||
|
||
// 验证 - 使用Pipes
|
||
@Post()
|
||
createUser(@Body(ValidationPipe) createUserDto: CreateUserDto) {
|
||
// 业务逻辑
|
||
}
|
||
```
|
||
|
||
#### Core层基础设施对比
|
||
| 功能 | 中间件 | Core层替代 | 说明 |
|
||
|------|--------|------------|------|
|
||
| 认证 | ❌ 过时 | ✅ AdminCheckTokenGuard | 与Java SaTokenInterceptor一致 |
|
||
| 授权 | ❌ 过时 | ✅ RolesGuard | 与Java权限控制一致 |
|
||
| 拦截 | ❌ 过时 | ✅ TracingInterceptor | 与Java AOP切面一致 |
|
||
| 验证 | ❌ 过时 | ✅ TimestampPipe | 与Java过滤器一致 |
|
||
|
||
#### 6.1 使用队列服务
|
||
```typescript
|
||
// 正确使用方式
|
||
import { Injectable } from '@nestjs/common';
|
||
import { UnifiedQueueService } from '@wwjCore';
|
||
|
||
@Injectable()
|
||
export class DiyJob {
|
||
constructor(
|
||
private readonly queueService: UnifiedQueueService // 使用Core层队列服务
|
||
) {}
|
||
|
||
async addJob(data: any, options?: any) {
|
||
try {
|
||
// 使用Core层队列服务添加任务
|
||
await this.queueService.addTask('diy', 'DiyJob', data, options);
|
||
console.log('Diy job added to queue:', data);
|
||
} catch (error) {
|
||
console.error('Failed to add Diy job to queue:', error);
|
||
throw error;
|
||
}
|
||
}
|
||
|
||
async processJob(data: any) {
|
||
try {
|
||
// 业务逻辑实现
|
||
const result = await this.processDiyData(data);
|
||
return result;
|
||
} catch (error) {
|
||
console.error('Failed to process Diy job:', error);
|
||
throw error;
|
||
}
|
||
}
|
||
|
||
private async processDiyData(data: any) {
|
||
// 业务逻辑实现
|
||
return { processed: true, data };
|
||
}
|
||
}
|
||
```
|
||
|
||
### 7. 命令生成器使用基础设施
|
||
|
||
#### 7.1 使用命令行工具
|
||
```typescript
|
||
// 正确使用方式
|
||
import { Injectable } from '@nestjs/common';
|
||
import { Command, CommandRunner, Option } from 'nest-commander';
|
||
import { Logger } from '@nestjs/common';
|
||
|
||
interface InstallCommandOptions {
|
||
name?: string;
|
||
verbose?: boolean;
|
||
force?: boolean;
|
||
}
|
||
|
||
@Injectable()
|
||
@Command({
|
||
name: 'install',
|
||
description: 'Install command description',
|
||
})
|
||
export class InstallCommand extends CommandRunner {
|
||
private readonly logger = new Logger(InstallCommand.name);
|
||
|
||
async run(
|
||
passedParams: string[],
|
||
options?: InstallCommandOptions,
|
||
): Promise<void> {
|
||
this.logger.log('Executing Install command...');
|
||
|
||
try {
|
||
// 业务逻辑实现
|
||
await this.executeInstall(options);
|
||
this.logger.log('Install command completed successfully');
|
||
} catch (error) {
|
||
this.logger.error('Install command failed:', error);
|
||
throw error;
|
||
}
|
||
}
|
||
|
||
private async executeInstall(options?: InstallCommandOptions) {
|
||
// 业务逻辑实现
|
||
this.logger.log(`Installing with options: ${JSON.stringify(options)}`);
|
||
}
|
||
}
|
||
```
|
||
|
||
## 迁移工具实现要求
|
||
|
||
### 1. 控制器生成器要求
|
||
- 必须使用Common层守卫(JwtAuthGuard、RolesGuard)
|
||
- 必须使用Common层装饰器(@Roles、@Public)
|
||
- 必须使用Common层异常处理(BusinessException)
|
||
- 必须使用Common层管道(ParseDiyFormPipe等)
|
||
- 必须生成完整的HTTP方法(@Get、@Post、@Put、@Delete)
|
||
|
||
### 2. 服务生成器要求
|
||
- 必须继承Common层BaseService
|
||
- 必须使用Common层缓存服务(CacheService)
|
||
- 必须使用Common层响应系统(Result响应格式)
|
||
- 必须使用Common层日志服务(LoggingService)
|
||
- 必须生成完整的业务方法实现
|
||
|
||
### 3. 实体生成器要求
|
||
- 必须继承Common层BaseEntity
|
||
- 必须使用正确的TypeORM装饰器
|
||
- 必须生成完整的业务字段
|
||
- 必须包含site_id多租户支持
|
||
|
||
### 4. DTO生成器要求
|
||
- 必须使用class-validator装饰器
|
||
- 必须继承Common层BaseDto
|
||
- 必须生成完整的字段定义
|
||
- 必须使用Swagger文档装饰器
|
||
|
||
### 5. 监听器生成器要求
|
||
- 必须使用Common层事件系统(EventModule)
|
||
- 必须使用Common层异常处理
|
||
- 必须生成完整的事件处理逻辑
|
||
- 必须使用Common层日志记录
|
||
|
||
### 6. 任务生成器要求
|
||
- 必须使用Common层队列服务(QueueModule)
|
||
- 必须生成完整的任务方法
|
||
- 必须使用Common层异常处理
|
||
- 必须生成完整的业务逻辑
|
||
|
||
### 7. 命令生成器要求
|
||
- 必须使用nest-commander框架
|
||
- 必须使用Common层日志服务
|
||
- 必须生成完整的命令逻辑
|
||
- 必须使用Common层异常处理
|
||
|
||
## 总结
|
||
|
||
迁移工具必须正确使用Common层的基础设施,确保生成的业务代码能够充分利用框架能力。只有这样,才能生成真正可用的业务代码,而不是空壳。
|
||
|
||
## 下一步行动
|
||
|
||
1. 修改所有生成器,正确使用Common层基础设施
|
||
2. 实现PHP源码解析器,提取真实的业务逻辑
|
||
3. 完善语法转换,确保PHP语法正确转换为TypeScript语法
|
||
4. 测试生成的业务代码,确保可以正常运行
|