858 lines
26 KiB
Plaintext
858 lines
26 KiB
Plaintext
---
|
||
description: Java后端迁移到v1框架的系统性迁移方案和规则
|
||
globs:
|
||
alwaysApply: true
|
||
---
|
||
|
||
# Java后端迁移到v1框架 - 系统性迁移方案
|
||
|
||
## 📋 迁移目标
|
||
|
||
**核心目标**:将Java后端完全替换为NestJS v1框架,保持数据库和前端100%不变
|
||
|
||
**约束条件**:
|
||
- ✅ 数据库:完全复用Java的数据库结构(表结构、字段、索引、数据)
|
||
- ✅ 前端:完全复用Java的前端代码(API接口、响应格式、权限逻辑)
|
||
- ✅ 业务逻辑:100%对齐Java的业务逻辑(方法签名、参数、返回值、异常处理)
|
||
|
||
## 🏗️ 架构对齐方案
|
||
|
||
### 1. 分层架构映射
|
||
|
||
```
|
||
Java (Spring Boot) → NestJS v1 Framework
|
||
═══════════════════════════════════════════════════════════════
|
||
Controller层 → Controller层 (controllers/)
|
||
├─ @RestController → @Controller
|
||
├─ @RequestMapping → @Get/@Post/@Put/@Delete
|
||
└─ @RequestParam/@RequestBody → @Query/@Body/@Param
|
||
|
||
Service层 → Service层 (services/)
|
||
├─ @Service → @Injectable
|
||
├─ Interface (IService) → Interface (Service)
|
||
└─ Impl (ServiceImpl) → Impl (ServiceImpl)
|
||
|
||
Repository层 → Entity层 (entities/)
|
||
├─ JpaRepository<T, ID> → @InjectRepository(Entity)
|
||
└─ Entity → @Entity + TypeORM
|
||
|
||
DTO/VO/Param → DTO层 (dtos/)
|
||
├─ VO (View Object) → VO (vo/*.dto.ts) - 保持Vo原样
|
||
├─ DTO (Data Transfer Object) → DTO (dto/*.dto.ts) - 保持Dto原样
|
||
└─ Param → Param (param/*.dto.ts) - 保持Param原样
|
||
|
||
配置层 → 配置层 (config/)
|
||
├─ @Configuration → @Module
|
||
├─ @Bean → providers/exports
|
||
└─ application.yml → ConfigModule + 环境变量
|
||
|
||
框架能力层(v1框架提供) → 框架能力层 (@wwjBoot)
|
||
├─ 基础设施服务
|
||
│ ├─ RequestContextService → 请求上下文服务
|
||
│ ├─ HttpClientService → HTTP客户端服务
|
||
│ ├─ MetricsService → 指标服务
|
||
│ └─ ConfigService/AppConfigService → 配置服务
|
||
├─ 认证授权
|
||
│ ├─ AuthService → JWT认证服务
|
||
│ ├─ AuthGuard → 认证守卫
|
||
│ ├─ RbacGuard → 权限守卫
|
||
│ └─ @Public()/@Admin()/@Api() → 路由装饰器
|
||
├─ 缓存服务
|
||
│ ├─ CacheService → 缓存服务
|
||
│ ├─ LockService → 分布式锁服务
|
||
│ └─ CacheManagerService → 缓存管理服务
|
||
├─ 队列与事件
|
||
│ ├─ QueueService → 队列服务
|
||
│ ├─ EventBus → 事件总线
|
||
│ ├─ EventListenerService → 事件监听服务
|
||
│ └─ JobSchedulerService → 任务调度服务
|
||
├─ 工具类(vendor/utils)
|
||
│ ├─ StringUtils → 字符串工具
|
||
│ ├─ JsonUtils → JSON工具(含命名转换)
|
||
│ ├─ FileUtils → 文件工具
|
||
│ ├─ DateUtils → 日期工具
|
||
│ ├─ CryptoUtils → 加密工具(bcrypt)
|
||
│ ├─ ImageUtils → 图片工具(Base64转换)
|
||
│ ├─ WwjcloudUtils → Wwjcloud API工具
|
||
│ └─ ZipUtils → ZIP压缩工具
|
||
├─ 线程本地存储(infra/context)
|
||
│ └─ ThreadLocalHolder → 线程本地变量工具类(对齐Java component/base/ThreadLocalHolder)
|
||
├─ 供应商服务(vendor)
|
||
│ ├─ PayService → 支付服务
|
||
│ ├─ SmsService → 短信服务
|
||
│ ├─ NoticeService → 通知服务
|
||
│ └─ UploadService → 上传服务
|
||
├─ 响应包装
|
||
│ └─ Result<T> → 统一响应格式
|
||
├─ 中间件
|
||
│ ├─ RequestIdMiddleware → 请求ID中间件
|
||
│ ├─ RequestContextMiddleware → 请求上下文中间件
|
||
│ ├─ TenantMiddleware → 租户中间件
|
||
│ └─ IpFilterMiddleware → IP过滤中间件
|
||
├─ 拦截器
|
||
│ ├─ LoggingInterceptor → 日志拦截器
|
||
│ ├─ MetricsInterceptor → 指标拦截器
|
||
│ └─ ResponseInterceptor → 响应拦截器
|
||
├─ 过滤器
|
||
│ └─ HttpExceptionFilter → 异常过滤器
|
||
├─ 守卫
|
||
│ └─ RateLimitGuard → 限流守卫
|
||
└─ 动态模块加载
|
||
├─ EntityModule.register() → 动态加载实体
|
||
├─ ServiceModule.register() → 动态加载服务
|
||
└─ ControllerModule.register() → 动态加载控制器
|
||
```
|
||
|
||
### 2. 模块组织映射
|
||
|
||
```
|
||
Java模块结构 → NestJS模块结构
|
||
═══════════════════════════════════════════════════════════════
|
||
com.niu.core.controller.* → controllers/adminapi/*
|
||
com.niu.core.service.* → services/admin/*
|
||
com.niu.core.service.impl.* → services/admin/impl/*
|
||
com.niu.core.entity.* → entities/*
|
||
com.niu.core.dto.* → dtos/admin/*
|
||
com.niu.core.job.* → jobs/*
|
||
com.niu.core.listener.* → listeners/*
|
||
com.niu.core.common.component.base.ThreadLocalHolder → boot/infra/context/thread-local-holder.ts
|
||
```
|
||
|
||
### 3. 动态模块加载机制
|
||
|
||
v1框架采用**动态模块加载**,自动扫描并注册所有组件:
|
||
|
||
```typescript
|
||
// EntityModule - 动态加载所有实体
|
||
EntityModule.register()
|
||
→ 扫描 entities/*.entity.ts
|
||
→ 注册到 TypeOrmModule.forFeature(entities)
|
||
|
||
// ServiceModule - 动态加载所有服务
|
||
ServiceModule.register()
|
||
→ 扫描 services/**/*.service.ts
|
||
→ 自动注册为 providers
|
||
|
||
// ControllerModule - 动态加载所有控制器
|
||
ControllerModule.register()
|
||
→ 扫描 controllers/**/*.controller.ts
|
||
→ 自动注册为 controllers
|
||
```
|
||
|
||
## 🔄 迁移流程(5个阶段)
|
||
|
||
### 阶段1:扫描与分析(Scanning)
|
||
|
||
**目标**:全面扫描Java项目,建立完整的元数据索引
|
||
|
||
**执行步骤**:
|
||
1. **扫描Java项目结构**
|
||
```bash
|
||
tools/java-to-nestjs-migration/migration-coordinator.js
|
||
```
|
||
- 扫描所有Controller、Service、Entity、DTO文件
|
||
- 提取方法签名、参数类型、返回值类型
|
||
- 分析依赖关系(Service依赖、Repository依赖)
|
||
|
||
2. **构建中央数据仓库(CDR)**
|
||
- Service方法签名索引(1038个方法)
|
||
- DTO类型映射(732个类型)
|
||
- 实体映射关系(89个实体)
|
||
- 依赖关系图
|
||
|
||
3. **生成映射报告**
|
||
- Java文件 → NestJS文件映射表
|
||
- 方法签名对比表
|
||
- 依赖关系分析报告
|
||
|
||
**输出产物**:
|
||
- `migration-report.json` - 迁移报告
|
||
- CDR索引数据
|
||
- 文件映射关系表
|
||
|
||
### 阶段2:代码生成(Generation)
|
||
|
||
**目标**:使用迁移工具自动生成NestJS代码骨架
|
||
|
||
**执行步骤**:
|
||
1. **生成实体(Entity)**
|
||
- 从Java Entity生成TypeORM Entity
|
||
- 保持表名、字段名、索引完全一致
|
||
- 生成文件:`entities/*.entity.ts`
|
||
|
||
2. **生成DTO**
|
||
- 从Java DTO/VO/Param生成NestJS DTO
|
||
- 保持字段名、类型、验证规则一致
|
||
- 生成文件:`dtos/admin/*/*.dto.ts`
|
||
|
||
3. **生成服务接口和实现**
|
||
- 从Java Interface生成NestJS Service接口
|
||
- 从Java ServiceImpl生成NestJS Service实现骨架
|
||
- 生成文件:`services/admin/*/*.service.ts`
|
||
|
||
4. **生成控制器**
|
||
- 从Java Controller生成NestJS Controller
|
||
- 保持路由路径、HTTP方法、参数一致
|
||
- 生成文件:`controllers/adminapi/*/*.controller.ts`
|
||
|
||
5. **生成模块文件**
|
||
- 动态模块:`EntityModule.register()`
|
||
- 动态模块:`ServiceModule.register()`
|
||
- 动态模块:`ControllerModule.register()`
|
||
|
||
**输出产物**:
|
||
- 所有Entity文件(89个)
|
||
- 所有DTO文件(732个)
|
||
- 所有Service文件(158个)
|
||
- 所有Controller文件(110个)
|
||
- 模块注册文件
|
||
|
||
### 阶段3:业务逻辑对齐(Alignment)
|
||
|
||
**目标**:逐个模块对齐Java的业务逻辑
|
||
|
||
**执行策略**:**按模块优先级逐步对齐**
|
||
|
||
#### 优先级排序:
|
||
1. **核心模块(P0)**:认证、权限、用户管理
|
||
- `services/admin/auth/*`
|
||
- `services/admin/user/*`
|
||
- `services/admin/rbac/*`
|
||
|
||
2. **基础模块(P1)**:配置、菜单、字典
|
||
- `services/admin/sys/*`
|
||
- `services/core/config/*`
|
||
|
||
3. **业务模块(P2)**:业务功能模块
|
||
- `services/admin/member/*`
|
||
- `services/admin/order/*`
|
||
- `services/admin/pay/*`
|
||
|
||
4. **扩展模块(P3)**:插件、扩展功能
|
||
- `services/admin/addon/*`
|
||
|
||
#### 对齐检查清单(每个Service方法):
|
||
|
||
- [ ] **方法签名对齐**
|
||
```typescript
|
||
// Java
|
||
public PageResult<MemberVo> getPage(MemberSearchParam param)
|
||
|
||
// NestJS - 必须完全一致(保持Vo/Param原样,不添加Dto后缀)
|
||
async getPage(param: MemberSearchParam): Promise<PageResult<MemberVo>>
|
||
```
|
||
|
||
- [ ] **参数处理对齐**
|
||
```typescript
|
||
// Java: @RequestParam("pageNo") Integer pageNo
|
||
// NestJS: @Query('pageNo') pageNo: number
|
||
```
|
||
|
||
- [ ] **返回值对齐**
|
||
```typescript
|
||
// Java: return Result.success(data)
|
||
// NestJS: return Result.success(data)
|
||
```
|
||
|
||
- [ ] **异常处理对齐**
|
||
```typescript
|
||
// Java: throw new BusinessException("错误信息")
|
||
// NestJS: throw new BadRequestException("错误信息")
|
||
```
|
||
|
||
- [ ] **数据库操作对齐**
|
||
```typescript
|
||
// Java: repository.findByXxx()
|
||
// NestJS: repository.find({ where: { xxx } })
|
||
```
|
||
|
||
- [ ] **事务处理对齐**
|
||
```typescript
|
||
// Java: @Transactional
|
||
// NestJS: @Transaction() 或使用EntityManager
|
||
```
|
||
|
||
### 阶段4:框架能力集成(Integration)
|
||
|
||
**目标**:将业务代码集成到v1框架能力体系中
|
||
|
||
#### 4.1 认证授权集成
|
||
|
||
```typescript
|
||
// 使用框架的AuthService
|
||
import { AuthService } from '@wwjBoot';
|
||
|
||
// 生成Token
|
||
const token = this.authService.signToken({ uid, username });
|
||
|
||
// 验证Token
|
||
const claims = this.authService.verifyToken(token);
|
||
```
|
||
|
||
#### 4.2 缓存集成
|
||
|
||
```typescript
|
||
// 使用框架的CacheService
|
||
import { CacheService } from '@wwjBoot';
|
||
|
||
// 缓存操作
|
||
await this.cacheService.set(key, value, ttl);
|
||
const value = await this.cacheService.get(key);
|
||
```
|
||
|
||
#### 4.3 配置管理集成
|
||
|
||
```typescript
|
||
// 使用框架的AppConfigService
|
||
import { AppConfigService } from '@wwjBoot';
|
||
|
||
// 读取配置
|
||
const config = this.appConfig.webRoot;
|
||
```
|
||
|
||
#### 4.4 工具类集成
|
||
|
||
```typescript
|
||
// 使用框架的工具类
|
||
import { JsonUtils, FileUtils, StringUtils } from '@wwjBoot';
|
||
|
||
// JSON操作
|
||
const obj = JsonUtils.parseObject<Type>(jsonStr);
|
||
const jsonStr = JsonUtils.toCamelCaseJSONString(obj);
|
||
|
||
// 文件操作
|
||
const content = FileUtils.readFile(filePath);
|
||
FileUtils.writeFile(filePath, content);
|
||
```
|
||
|
||
#### 4.5 线程本地存储集成
|
||
|
||
```typescript
|
||
// 使用框架的ThreadLocalHolder(对齐Java component/base/ThreadLocalHolder)
|
||
import { ThreadLocalHolder } from '@wwjBoot';
|
||
|
||
// 存储任意key-value
|
||
ThreadLocalHolder.put('current-user', userInfo);
|
||
ThreadLocalHolder.put('current-site-id', siteId);
|
||
|
||
// 获取值
|
||
const userInfo = ThreadLocalHolder.get('current-user');
|
||
const userInfoTyped = ThreadLocalHolder.getTyped<UserInfo>('current-user');
|
||
|
||
// 便捷方法
|
||
ThreadLocalHolder.putString('key', 'value');
|
||
const value = ThreadLocalHolder.getString('key');
|
||
ThreadLocalHolder.putInteger('count', 10);
|
||
const count = ThreadLocalHolder.getInteger('count');
|
||
|
||
// 注意:RequestContextService.runWith()会自动初始化ThreadLocalHolder上下文
|
||
// 在请求处理过程中,ThreadLocalHolder可以直接使用
|
||
```
|
||
|
||
### 阶段5:测试与验证(Validation)
|
||
|
||
**目标**:确保迁移后的功能与Java版本100%一致
|
||
|
||
#### 5.1 单元测试
|
||
|
||
```typescript
|
||
// 测试Service方法
|
||
describe('LoginServiceImpl', () => {
|
||
it('should login successfully', async () => {
|
||
const result = await service.login({ username: 'admin', password: '123456' });
|
||
expect(result.token).toBeDefined();
|
||
});
|
||
});
|
||
```
|
||
|
||
#### 5.2 集成测试
|
||
|
||
```bash
|
||
# 使用Docker进行完整环境测试
|
||
docker-compose up -d
|
||
# 测试登录接口
|
||
curl -X GET "http://localhost:3000/adminapi/login/admin?username=admin&password=123456"
|
||
```
|
||
|
||
#### 5.3 API兼容性测试
|
||
|
||
**检查点**:
|
||
- [ ] 所有API路径与Java一致
|
||
- [ ] 请求参数格式与Java一致
|
||
- [ ] 响应格式与Java一致(Result包装)
|
||
- [ ] 错误码与Java一致
|
||
- [ ] 异常消息与Java一致
|
||
|
||
#### 5.4 数据库兼容性测试
|
||
|
||
**检查点**:
|
||
- [ ] 表结构完全一致
|
||
- [ ] 字段类型完全一致
|
||
- [ ] 索引结构完全一致
|
||
- [ ] 数据读写完全一致
|
||
|
||
## 🎯 关键迁移原则
|
||
|
||
### 原则1:优先对齐Java逻辑,再优化框架特性
|
||
|
||
**错误做法**:
|
||
```typescript
|
||
// ❌ 直接使用NestJS特性,忽略Java逻辑
|
||
@Get(':id')
|
||
async getById(@Param('id') id: string) {
|
||
return await this.service.findOne(id);
|
||
}
|
||
```
|
||
|
||
**正确做法**:
|
||
```typescript
|
||
// ✅ 先对齐Java逻辑,再考虑优化
|
||
@Get(':id')
|
||
async getById(@Param('id') id: string) {
|
||
// Java: MemberController.getById(Integer id)
|
||
// 必须保持参数类型、返回值类型一致
|
||
const member = await this.service.getById(Number(id));
|
||
return Result.success(member);
|
||
}
|
||
```
|
||
|
||
### 原则2:数据库100%对齐,禁止修改
|
||
|
||
**绝对禁止**:
|
||
- ❌ 修改表名
|
||
- ❌ 修改字段名
|
||
- ❌ 修改字段类型
|
||
- ❌ 添加或删除字段
|
||
- ❌ 修改索引结构
|
||
|
||
**正确做法**:
|
||
```typescript
|
||
// ✅ 完全对齐Java的Entity定义
|
||
@Entity('nc_sys_user') // 表名必须与Java一致
|
||
export class SysUser {
|
||
@Column({ name: 'user_name' }) // 字段名必须与Java一致
|
||
userName: string;
|
||
}
|
||
```
|
||
|
||
### 原则3:API接口100%对齐,确保前端兼容
|
||
|
||
**检查清单**:
|
||
- [ ] 路由路径一致:`/adminapi/member/list`
|
||
- [ ] HTTP方法一致:`GET`、`POST`、`PUT`、`DELETE`
|
||
- [ ] 参数名一致:`pageNo`、`pageSize`、`keyword`
|
||
- [ ] 响应格式一致:`Result<T>` 包装
|
||
- [ ] 错误码一致:`error_code`、`msg_key`
|
||
|
||
### 原则4:业务逻辑100%对齐,禁止自创逻辑
|
||
|
||
**错误做法**:
|
||
```typescript
|
||
// ❌ 自创业务逻辑
|
||
async login(param: LoginParam) {
|
||
// Java中没有这个逻辑,不要添加
|
||
if (param.username.length < 3) {
|
||
throw new BadRequestException('用户名太短');
|
||
}
|
||
// ...
|
||
}
|
||
```
|
||
|
||
**正确做法**:
|
||
```typescript
|
||
// ✅ 严格对齐Java逻辑(保持Param原样)
|
||
async login(param: LoginParam) {
|
||
// 完全按照Java的LoginServiceImpl.login()实现
|
||
const user = await this.repository.findOne({ where: { username: param.username } });
|
||
if (!user || !await CryptoUtils.match(param.password, user.password)) {
|
||
// ✅ 使用NestJS的HttpException系列(不要使用BaseException)
|
||
throw new UnauthorizedException({ msg_key: 'error.auth.invalid_credentials' });
|
||
}
|
||
// ...
|
||
}
|
||
```
|
||
|
||
### 原则5:异常处理使用NestJS原生特性
|
||
|
||
**错误做法**:
|
||
```typescript
|
||
// ❌ 使用机械迁移的BaseException
|
||
import { BaseException } from '../../common/exception';
|
||
throw new BaseException('操作失败');
|
||
```
|
||
|
||
**正确做法**:
|
||
```typescript
|
||
// ✅ 使用NestJS的HttpException系列
|
||
import { BadRequestException, UnauthorizedException, ForbiddenException } from '@nestjs/common';
|
||
throw new BadRequestException({ msg_key: 'error.common.operation_failed' });
|
||
throw new UnauthorizedException({ msg_key: 'error.auth.invalid_token' });
|
||
throw new ForbiddenException({ msg_key: 'error.auth.insufficient_permission' });
|
||
```
|
||
|
||
**配置访问使用依赖注入**:
|
||
```typescript
|
||
// ❌ 静态配置类(已删除)
|
||
import { GlobalConfig } from '../../common/config';
|
||
const prefix = GlobalConfig.tablePrefix;
|
||
|
||
// ✅ 使用AppConfigService(依赖注入)
|
||
constructor(private readonly appConfig: AppConfigService) {}
|
||
const prefix = this.appConfig.tablePrefix;
|
||
```
|
||
|
||
## 🔧 迁移工具使用指南
|
||
|
||
### 1. 运行迁移工具
|
||
|
||
```bash
|
||
cd tools/java-to-nestjs-migration
|
||
node migration-coordinator.js
|
||
```
|
||
|
||
**输出**:
|
||
- 扫描Java项目(1215个文件)
|
||
- 生成NestJS代码骨架
|
||
- 生成映射报告
|
||
|
||
### 2. 迁移工具生成的内容
|
||
|
||
```
|
||
wwjcloud/libs/wwjcloud-core/src/
|
||
├── entities/ # 89个实体文件(自动生成)
|
||
├── dtos/ # 732个DTO文件(自动生成)
|
||
├── services/ # 158个服务文件(自动生成)
|
||
├── controllers/ # 110个控制器文件(自动生成)
|
||
├── entity.module.ts # 动态实体模块(自动生成)
|
||
├── service.module.ts # 动态服务模块(自动生成)
|
||
└── controller.module.ts # 动态控制器模块(自动生成)
|
||
```
|
||
|
||
### 3. 迁移工具的限制
|
||
|
||
**不会自动生成的内容**:
|
||
- ❌ Service方法的业务逻辑实现(只生成方法签名)
|
||
- ❌ Controller的参数解析逻辑(需要手动对齐)
|
||
- ❌ 复杂的查询逻辑(需要手动实现)
|
||
- ❌ 事务处理逻辑(需要手动添加)
|
||
|
||
**需要手动对齐的内容**:
|
||
- ✅ Service方法的业务逻辑
|
||
- ✅ Controller的参数处理
|
||
- ✅ 异常处理逻辑
|
||
- ✅ 数据库查询优化
|
||
|
||
## 📊 质量控制检查点
|
||
|
||
### 检查点1:编译通过
|
||
|
||
```bash
|
||
cd wwjcloud
|
||
npm run build
|
||
```
|
||
|
||
**要求**:
|
||
- ✅ 无TypeScript编译错误
|
||
- ✅ 无依赖注入错误
|
||
- ✅ 无类型错误
|
||
|
||
### 检查点2:服务启动
|
||
|
||
```bash
|
||
docker-compose up -d
|
||
docker logs wwjcloud-api-v1
|
||
```
|
||
|
||
**要求**:
|
||
- ✅ 服务成功启动
|
||
- ✅ 所有模块正确加载
|
||
- ✅ 数据库连接成功
|
||
- ✅ Redis连接成功
|
||
|
||
### 检查点3:API测试
|
||
|
||
```bash
|
||
# 测试登录接口
|
||
curl -X GET "http://localhost:3000/adminapi/login/admin?username=admin&password=123456"
|
||
```
|
||
|
||
**要求**:
|
||
- ✅ 接口返回200状态码
|
||
- ✅ 响应格式正确(Result包装)
|
||
- ✅ Token生成正确
|
||
- ✅ 错误处理正确
|
||
|
||
### 检查点4:数据库操作验证
|
||
|
||
```typescript
|
||
// 验证CRUD操作
|
||
await service.create(data); // 创建
|
||
await service.getById(id); // 查询
|
||
await service.update(id, data); // 更新
|
||
await service.delete(id); // 删除
|
||
```
|
||
|
||
**要求**:
|
||
- ✅ 数据正确写入数据库
|
||
- ✅ 数据正确从数据库读取
|
||
- ✅ 字段映射正确
|
||
- ✅ 类型转换正确
|
||
|
||
## 🚨 常见问题与解决方案
|
||
|
||
### 问题1:Repository无法注入
|
||
|
||
**症状**:
|
||
```
|
||
UnknownDependenciesException: Nest can't resolve dependencies of the XxxServiceImpl (?, ?).
|
||
Please make sure that the argument "XxxRepository" at index [1] is available.
|
||
```
|
||
|
||
**原因**:
|
||
- EntityModule没有正确注册
|
||
- Entity没有正确导出
|
||
- ServiceModule没有导入EntityModule
|
||
|
||
**解决方案**:
|
||
```typescript
|
||
// 1. 确保EntityModule正确注册
|
||
EntityModule.register()
|
||
|
||
// 2. 确保Entity正确导出
|
||
@Entity('nc_sys_user')
|
||
export class SysUser { ... }
|
||
|
||
// 3. 确保ServiceModule导入EntityModule
|
||
ServiceModule.register()
|
||
→ imports: [EntityModule.register()]
|
||
```
|
||
|
||
### 问题2:DTO类型不匹配
|
||
|
||
**症状**:
|
||
```
|
||
TS2345: Argument of type 'Record<string, any>' is not assignable to parameter of type 'XxxDto'.
|
||
```
|
||
|
||
**原因**:
|
||
- Controller参数类型错误
|
||
- DTO定义不完整
|
||
|
||
**解决方案**:
|
||
```typescript
|
||
// ✅ 正确使用DTO(保持Param原样,不添加Dto后缀)
|
||
@Get(':id')
|
||
async getById(@Param('id') id: string, @Query() query: XxxSearchParam) {
|
||
// query已经是XxxSearchParam类型,不需要转换
|
||
return await this.service.getPage(query);
|
||
}
|
||
```
|
||
|
||
### 问题3:业务逻辑不一致
|
||
|
||
**症状**:
|
||
- 功能行为与Java版本不一致
|
||
- 数据计算结果不同
|
||
|
||
**原因**:
|
||
- 业务逻辑实现有偏差
|
||
- 工具类使用不当
|
||
|
||
**解决方案**:
|
||
1. 对比Java源码,逐行对齐
|
||
2. 使用框架提供的工具类(JsonUtils、FileUtils等)
|
||
3. 确保异常处理逻辑一致
|
||
4. 使用NestJS的HttpException系列,不要使用已删除的BaseException
|
||
|
||
### 问题4:使用了已删除的机械Java迁移内容
|
||
|
||
**症状**:
|
||
- 编译错误:Cannot find module './exception/base-exception'
|
||
- 编译错误:Cannot find module './config/global-config'
|
||
- 编译错误:Cannot find module './annotation/sa-not-check-login'
|
||
|
||
**原因**:
|
||
- 使用了已删除的机械Java迁移内容
|
||
|
||
**解决方案**:
|
||
```typescript
|
||
// ❌ 已删除:BaseException
|
||
import { BaseException } from '../../common/exception';
|
||
throw new BaseException('错误');
|
||
|
||
// ✅ 替换为:HttpException系列
|
||
import { BadRequestException } from '@nestjs/common';
|
||
throw new BadRequestException({ msg_key: 'error.common.operation_failed' });
|
||
|
||
// ❌ 已删除:GlobalConfig
|
||
import { GlobalConfig } from '../../common/config';
|
||
const prefix = GlobalConfig.tablePrefix;
|
||
|
||
// ✅ 替换为:AppConfigService
|
||
constructor(private readonly appConfig: AppConfigService) {}
|
||
const prefix = this.appConfig.tablePrefix;
|
||
|
||
// ❌ 已删除:SaNotCheckLogin
|
||
import { SaNotCheckLogin } from '../../common/annotation';
|
||
@SaNotCheckLogin()
|
||
async publicMethod() {}
|
||
|
||
// ✅ 替换为:@Public
|
||
import { Public } from '@wwjBoot';
|
||
@Public()
|
||
async publicMethod() {}
|
||
```
|
||
|
||
## 📈 迁移进度跟踪
|
||
|
||
### 模块迁移状态
|
||
|
||
| 模块 | 实体 | DTO | Service | Controller | 状态 |
|
||
|------|------|-----|---------|------------|------|
|
||
| Auth | ✅ | ✅ | ✅ | ✅ | ✅ 完成 |
|
||
| User | ✅ | ✅ | ⚠️ | ⚠️ | 🔄 进行中 |
|
||
| Member | ✅ | ✅ | ⚠️ | ⚠️ | 🔄 进行中 |
|
||
| Order | ✅ | ✅ | ❌ | ❌ | 📋 待开始 |
|
||
| Pay | ✅ | ✅ | ❌ | ❌ | 📋 待开始 |
|
||
| Addon | ✅ | ✅ | ⚠️ | ⚠️ | 🔄 进行中 |
|
||
|
||
**图例**:
|
||
- ✅ 完成:已对齐Java逻辑,测试通过
|
||
- ⚠️ 进行中:代码已生成,业务逻辑对齐中
|
||
- ❌ 待开始:代码已生成,未开始业务逻辑对齐
|
||
|
||
### 统计数据
|
||
|
||
- **实体文件**:89/89 (100%)
|
||
- **DTO文件**:732/732 (100%)
|
||
- **Service文件**:158/158 (100%) - 骨架完成,业务逻辑对齐中
|
||
- **Controller文件**:110/110 (100%) - 骨架完成,业务逻辑对齐中
|
||
|
||
## 🎓 最佳实践
|
||
|
||
### 1. 一次对齐一个模块
|
||
|
||
**不要**:同时修改多个模块
|
||
**要**:按模块优先级,逐个完整对齐
|
||
|
||
### 2. 先对齐核心流程,再对齐边界情况
|
||
|
||
**优先级**:
|
||
1. 正常流程(happy path)
|
||
2. 异常处理
|
||
3. 边界情况
|
||
4. 性能优化
|
||
|
||
### 3. 保持Java代码对照
|
||
|
||
**方法**:
|
||
- 左侧打开Java源码
|
||
- 右侧编写NestJS代码
|
||
- 逐行对比,确保一致
|
||
|
||
### 4. 使用框架能力,不要重复造轮子
|
||
|
||
**使用框架提供的**:
|
||
- ✅ AuthService(认证)
|
||
- ✅ CacheService(缓存)
|
||
- ✅ AppConfigService(配置,替代GlobalConfig)
|
||
- ✅ JsonUtils、FileUtils(工具类)
|
||
- ✅ HttpException系列(异常处理,替代BaseException)
|
||
- ✅ @Public装饰器(替代SaNotCheckLogin)
|
||
- ✅ ConfigService(配置服务,替代静态配置类)
|
||
|
||
**不要自创**:
|
||
- ❌ 自定义认证逻辑(使用框架的AuthService)
|
||
- ❌ 自定义缓存逻辑(使用框架的CacheService)
|
||
- ❌ 自定义工具类(使用框架的工具类)
|
||
- ❌ 自定义异常类(使用NestJS的HttpException系列)
|
||
- ❌ 静态配置类(使用AppConfigService/ConfigService)
|
||
- ❌ Java反射加载(使用NestJS动态模块)
|
||
|
||
**已删除的机械Java迁移内容**:
|
||
- ❌ BaseException系列 → ✅ 使用HttpException/BadRequestException/UnauthorizedException等
|
||
- ❌ GlobalConfig静态配置 → ✅ 使用AppConfigService(依赖注入)
|
||
- ❌ SaNotCheckLogin装饰器 → ✅ 使用@Public装饰器
|
||
- ❌ SystemLoader动态加载 → ✅ 使用NestJS动态模块(DynamicModule)
|
||
- ❌ EnumUtils工具类 → ✅ 直接使用TypeScript枚举
|
||
- ❌ ServletUtils工具类 → ✅ 使用@Query/@Body/@Param装饰器
|
||
|
||
## 📝 迁移成功标准
|
||
|
||
1. ✅ **编译通过**:无TypeScript编译错误
|
||
2. ✅ **服务启动**:所有模块正确加载
|
||
3. ✅ **API兼容**:所有接口与Java版本100%一致
|
||
4. ✅ **数据兼容**:数据库操作100%正确
|
||
5. ✅ **功能一致**:业务逻辑100%对齐
|
||
|
||
### 迁移完成标志
|
||
|
||
- [ ] 所有模块编译通过
|
||
- [ ] 所有服务启动成功
|
||
- [ ] 所有API测试通过
|
||
- [ ] 所有数据库操作验证通过
|
||
- [ ] 与Java版本功能100%一致
|
||
|
||
---
|
||
|
||
**最后更新**:2025-01-11
|
||
**版本**:v1.0
|
||
**维护者**:AI Migration Team
|
||
|
||
### 3. 保持Java代码对照
|
||
|
||
**方法**:
|
||
- 左侧打开Java源码
|
||
- 右侧编写NestJS代码
|
||
- 逐行对比,确保一致
|
||
|
||
### 4. 使用框架能力,不要重复造轮子
|
||
|
||
**使用框架提供的**:
|
||
- ✅ AuthService(认证)
|
||
- ✅ CacheService(缓存)
|
||
- ✅ AppConfigService(配置,替代GlobalConfig)
|
||
- ✅ JsonUtils、FileUtils(工具类)
|
||
- ✅ HttpException系列(异常处理,替代BaseException)
|
||
- ✅ @Public装饰器(替代SaNotCheckLogin)
|
||
- ✅ ConfigService(配置服务,替代静态配置类)
|
||
|
||
**不要自创**:
|
||
- ❌ 自定义认证逻辑(使用框架的AuthService)
|
||
- ❌ 自定义缓存逻辑(使用框架的CacheService)
|
||
- ❌ 自定义工具类(使用框架的工具类)
|
||
- ❌ 自定义异常类(使用NestJS的HttpException系列)
|
||
- ❌ 静态配置类(使用AppConfigService/ConfigService)
|
||
- ❌ Java反射加载(使用NestJS动态模块)
|
||
|
||
**已删除的机械Java迁移内容**:
|
||
- ❌ BaseException系列 → ✅ 使用HttpException/BadRequestException/UnauthorizedException等
|
||
- ❌ GlobalConfig静态配置 → ✅ 使用AppConfigService(依赖注入)
|
||
- ❌ SaNotCheckLogin装饰器 → ✅ 使用@Public装饰器
|
||
- ❌ SystemLoader动态加载 → ✅ 使用NestJS动态模块(DynamicModule)
|
||
- ❌ EnumUtils工具类 → ✅ 直接使用TypeScript枚举
|
||
- ❌ ServletUtils工具类 → ✅ 使用@Query/@Body/@Param装饰器
|
||
|
||
## 📝 迁移成功标准
|
||
|
||
1. ✅ **编译通过**:无TypeScript编译错误
|
||
2. ✅ **服务启动**:所有模块正确加载
|
||
3. ✅ **API兼容**:所有接口与Java版本100%一致
|
||
4. ✅ **数据兼容**:数据库操作100%正确
|
||
5. ✅ **功能一致**:业务逻辑100%对齐
|
||
|
||
### 迁移完成标志
|
||
|
||
- [ ] 所有模块编译通过
|
||
- [ ] 所有服务启动成功
|
||
- [ ] 所有API测试通过
|
||
- [ ] 所有数据库操作验证通过
|
||
- [ ] 与Java版本功能100%一致
|
||
|
||
---
|
||
|
||
**最后更新**:2025-01-11
|
||
**版本**:v1.0
|
||
**维护者**:AI Migration Team
|
||
|