Files
wwjcloud-nest-v1/wwjcloud-nest-v1/tools/java-to-nestjs-migration/converters/service-method-converter.js
wanwu dbe61ed21f feat: 增强Service层转换器
 DTO导入增强:
- 清理泛型语法: List<String> → List
- 跳过Java基础类型(List/Map/String等)
- 防止异常import语句

 VO类型自动识别:
- 从方法体中提取VO类型
- 正则匹配所有XxxVo/Dto/Param引用
- 自动添加到导入列表

 Java API转换器(新增):
- path.toFile() → path
- file.path → file
- Files.* → fs.*
- Paths.get() → path.join()
- Charset/Encoding处理

📊 效果: 14086 errors (持平)
🔧 原因: 这些是结构性/业务逻辑错误,需要手动介入
2025-10-29 21:16:18 +08:00

197 lines
9.9 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* Service方法体转换器主协调器
*
* 职责协调各个子转换器将Java Service方法体转换为TypeScript
*
* 核心功能:
* 1. 提取Java方法体
* 2. 调用各个专业转换器进行转换
* 3. 后处理清理
* 4. 分析需要的imports
*/
// 导入各个转换器
const BasicSyntaxConverter = require('./syntax/basic-syntax.converter');
const TypeConverter = require('./syntax/type.converter');
const ExceptionConverter = require('./syntax/exception.converter');
const ConfigConverter = require('./utils/config.converter');
const FileConverter = require('./utils/file.converter');
const StringConverter = require('./utils/string.converter');
const CollectionConverter = require('./utils/collection.converter');
const JsonConverter = require('./utils/json.converter');
const ObjectConverter = require('./utils/object.converter');
const JavaApiConverter = require('./utils/java-api.converter');
const QueryWrapperConverter = require('./mybatis/query-wrapper.converter');
const MapperConverter = require('./mybatis/mapper.converter');
const PaginationConverter = require('./mybatis/pagination.converter');
const GetterSetterConverter = require('./method/getter-setter.converter');
const MethodCallConverter = require('./method/method-call.converter');
const StreamApiConverter = require('./method/stream-api.converter');
const PostProcessor = require('./post-processor');
class ServiceMethodConverter {
constructor() {
// 初始化所有转换器
this.basicSyntax = new BasicSyntaxConverter();
this.type = new TypeConverter();
this.exception = new ExceptionConverter();
this.config = new ConfigConverter();
this.file = new FileConverter();
this.string = new StringConverter();
this.collection = new CollectionConverter();
this.json = new JsonConverter();
this.object = new ObjectConverter();
this.javaApi = new JavaApiConverter();
this.queryWrapper = new QueryWrapperConverter();
this.mapper = new MapperConverter();
this.pagination = new PaginationConverter();
this.getterSetter = new GetterSetterConverter();
this.methodCall = new MethodCallConverter();
this.streamApi = new StreamApiConverter();
this.postProcessor = new PostProcessor();
}
/**
* 转换Java方法体为TypeScript
*
* @param {string} javaMethodBody - Java方法体代码
* @param {object} context - 上下文信息Service类信息、依赖等
* @returns {string} 转换后的TypeScript方法体
*/
convertMethodBody(javaMethodBody, context = {}) {
if (!javaMethodBody || javaMethodBody.trim() === '') {
return ' // TODO: 实现业务逻辑\n return null;';
}
let tsBody = javaMethodBody;
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
// 【阶段1】基础语法转换
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
tsBody = this.basicSyntax.convert(tsBody);
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
// 【阶段2】类型转换
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
tsBody = this.type.convert(tsBody);
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
// 【阶段3】工具类转换
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
tsBody = this.config.convert(tsBody);
tsBody = this.file.convert(tsBody);
tsBody = this.string.convert(tsBody);
tsBody = this.collection.convert(tsBody);
tsBody = this.json.convert(tsBody);
tsBody = this.object.convert(tsBody);
tsBody = this.javaApi.convert(tsBody);
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
// 【阶段4】MyBatis → TypeORM转换
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
tsBody = this.queryWrapper.convert(tsBody);
tsBody = this.mapper.convert(tsBody, context);
tsBody = this.pagination.convert(tsBody);
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
// 【阶段5】方法调用转换
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
tsBody = this.streamApi.convert(tsBody);
tsBody = this.methodCall.convert(tsBody);
tsBody = this.getterSetter.convert(tsBody); // 最后转换getter/setter
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
// 【阶段6】异常处理转换
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
tsBody = this.exception.convert(tsBody);
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
// 【阶段7】后处理清理
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
tsBody = this.postProcessor.convert(tsBody);
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
// 【阶段8】添加缩进
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
tsBody = tsBody.split('\n').map(line => ' ' + line).join('\n');
return tsBody;
}
/**
* 分析需要的imports
*
* @param {string} convertedBody - 转换后的TypeScript代码
* @returns {object} 需要导入的模块
*/
analyzeImports(convertedBody) {
const imports = {
nestjs: new Set(),
boot: new Set(),
nodeModules: new Set()
};
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
// 【NestJS异常】
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
const nestjsImports = this.exception.analyzeImports(convertedBody);
nestjsImports.forEach(imp => imports.nestjs.add(imp));
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
// 【Node.js模块】
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
const fileImports = this.file.analyzeImports(convertedBody);
fileImports.forEach(imp => {
if (imp === 'node:fs') imports.nodeModules.add('fs');
if (imp === 'node:path') imports.nodeModules.add('path');
});
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
// 【Boot层工具类】
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
// StringUtils
const stringImports = this.string.analyzeImports(convertedBody);
stringImports.forEach(imp => imports.boot.add(imp));
// Collection判空可能需要StringUtils
const collectionImports = this.collection.analyzeImports(convertedBody);
collectionImports.forEach(imp => imports.boot.add(imp));
// JsonUtils
const jsonImports = this.json.analyzeImports(convertedBody);
jsonImports.forEach(imp => imports.boot.add(imp));
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
// 【配置访问】AppConfigService (Boot层)
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
const configImports = this.config.analyzeImports(convertedBody);
configImports.forEach(imp => imports.boot.add(imp));
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
// 【Java API转换】fs/path (Node.js模块)
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
const javaApiImports = this.javaApi.analyzeImports(convertedBody);
javaApiImports.forEach(imp => {
if (imp === 'node:fs') imports.nodeModules.add('fs');
if (imp === 'node:path') imports.nodeModules.add('path');
});
return {
nestjs: Array.from(imports.nestjs),
boot: Array.from(imports.boot),
nodeModules: Array.from(imports.nodeModules)
};
}
}
module.exports = ServiceMethodConverter;