feat: 创建Service方法体转换器
This commit is contained in:
@@ -0,0 +1,313 @@
|
||||
const NamingUtils = require('../utils/naming-utils');
|
||||
|
||||
/**
|
||||
* Service方法体转换器
|
||||
*
|
||||
* 职责:将Java Service方法体转换为TypeScript
|
||||
*
|
||||
* 核心功能:
|
||||
* 1. 提取Java方法体
|
||||
* 2. Java语法 → TypeScript语法转换
|
||||
* 3. Java工具类 → NestJS Boot层映射
|
||||
*/
|
||||
class ServiceMethodConverter {
|
||||
constructor() {
|
||||
this.namingUtils = new NamingUtils();
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换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.convertBasicSyntax(tsBody);
|
||||
|
||||
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
// 【阶段2】类型转换
|
||||
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
tsBody = this.convertTypes(tsBody);
|
||||
|
||||
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
// 【阶段3】工具类映射(Java → NestJS Boot层)
|
||||
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
tsBody = this.convertUtilityClasses(tsBody);
|
||||
|
||||
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
// 【阶段4】Mapper/Service调用转换
|
||||
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
tsBody = this.convertDependencyCalls(tsBody, context);
|
||||
|
||||
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
// 【阶段5】添加缩进
|
||||
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
tsBody = tsBody.split('\n').map(line => ' ' + line).join('\n');
|
||||
|
||||
return tsBody;
|
||||
}
|
||||
|
||||
/**
|
||||
* 【阶段1】基础语法转换
|
||||
*/
|
||||
convertBasicSyntax(javaBody) {
|
||||
let tsBody = javaBody;
|
||||
|
||||
// 1. 变量声明:Type varName = value; → const varName: Type = value;
|
||||
tsBody = tsBody.replace(
|
||||
/(\b(?:Integer|Long|String|Boolean|Double|Float|BigDecimal|Object|List<[^>]+>|Map<[^>]+>|[\w<>,\s]+))\s+(\w+)\s*=\s*([^;]+);/g,
|
||||
(match, type, varName, value) => {
|
||||
const tsType = this.mapJavaTypeToTypeScript(type);
|
||||
return `const ${varName}: ${tsType} = ${value};`;
|
||||
}
|
||||
);
|
||||
|
||||
// 2. for-each循环:for (Type item : collection) → for (const item of collection)
|
||||
tsBody = tsBody.replace(/for\s*\(\s*[\w<>,\s]+\s+(\w+)\s*:\s*([^)]+)\)/g, 'for (const $1 of $2)');
|
||||
|
||||
// 3. Java实例化:new ArrayList<>() → []
|
||||
tsBody = tsBody.replace(/new\s+ArrayList<[^>]*>\(\)/g, '[]');
|
||||
tsBody = tsBody.replace(/new\s+LinkedList<[^>]*>\(\)/g, '[]');
|
||||
tsBody = tsBody.replace(/new\s+HashMap<[^>]*>\(\)/g, '{}');
|
||||
tsBody = tsBody.replace(/new\s+HashSet<[^>]*>\(\)/g, 'new Set()');
|
||||
|
||||
// 4. Lambda表达式:item -> expression → item => expression
|
||||
tsBody = tsBody.replace(/(\w+)\s*->\s*/g, '$1 => ');
|
||||
tsBody = tsBody.replace(/\(([^)]+)\)\s*->\s*/g, '($1) => ');
|
||||
|
||||
return tsBody;
|
||||
}
|
||||
|
||||
/**
|
||||
* 【阶段2】类型转换
|
||||
*/
|
||||
convertTypes(javaBody) {
|
||||
let tsBody = javaBody;
|
||||
|
||||
// 1. 基础类型
|
||||
tsBody = tsBody.replace(/\bInteger\b/g, 'number');
|
||||
tsBody = tsBody.replace(/\bLong\b/g, 'number');
|
||||
tsBody = tsBody.replace(/\bDouble\b/g, 'number');
|
||||
tsBody = tsBody.replace(/\bFloat\b/g, 'number');
|
||||
|
||||
// 2. Java对象类型
|
||||
tsBody = tsBody.replace(/\bJSONObject\b/g, 'Record<string, any>');
|
||||
tsBody = tsBody.replace(/\bId\b/g, 'number');
|
||||
|
||||
// 3. Java类型转换语法:(Type) value → value
|
||||
tsBody = tsBody.replace(/\(\s*(?:int|long|double|float|String|Integer|Long|Double|Float|number)\s*\)\s*/g, '');
|
||||
|
||||
return tsBody;
|
||||
}
|
||||
|
||||
/**
|
||||
* 【阶段3】工具类映射
|
||||
*/
|
||||
convertUtilityClasses(javaBody) {
|
||||
let tsBody = javaBody;
|
||||
|
||||
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
// 【配置访问】WebAppEnvs / GlobalConfig → ConfigService
|
||||
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
|
||||
// WebAppEnvs.get().property → this.config.get('property')
|
||||
tsBody = tsBody.replace(/WebAppEnvs\.get\(\)\.(\w+)/g, (match, prop) => {
|
||||
return `this.config.get('${prop}')`;
|
||||
});
|
||||
tsBody = tsBody.replace(/WebAppEnvs\.get\(\)/g, 'this.config');
|
||||
|
||||
// GlobalConfig.property → this.config.get('property')
|
||||
tsBody = tsBody.replace(/GlobalConfig\.(\w+)/g, (match, prop) => {
|
||||
return `this.config.get('${prop}')`;
|
||||
});
|
||||
|
||||
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
// 【文件操作】Java File API → Node.js fs/path
|
||||
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
|
||||
tsBody = tsBody.replace(/new\s+File\(([^)]+)\)/g, '$1');
|
||||
tsBody = tsBody.replace(/(\w+)\.exists\(\)/g, 'fs.existsSync($1)');
|
||||
tsBody = tsBody.replace(/(\w+)\.isDirectory\(\)/g, 'fs.lstatSync($1).isDirectory()');
|
||||
tsBody = tsBody.replace(/(\w+)\.getName\(\)/g, 'path.basename($1)');
|
||||
tsBody = tsBody.replace(/(\w+)\.listFiles\(\)/g, 'fs.readdirSync($1)');
|
||||
|
||||
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
// 【字符串方法】
|
||||
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
|
||||
// .equals() → ===
|
||||
tsBody = tsBody.replace(/([^!;,\s]+)\.equals\(([^)]+)\)/g, '$1 === $2');
|
||||
|
||||
// .equalsIgnoreCase() → .toLowerCase() === xxx.toLowerCase()
|
||||
tsBody = tsBody.replace(/([a-zA-Z_$][\w$.()]+)\.equalsIgnoreCase\(([^)]+)\)/g, '$1.toLowerCase() === $2.toLowerCase()');
|
||||
|
||||
// .contains() → .includes()
|
||||
tsBody = tsBody.replace(/\.contains\(/g, '.includes(');
|
||||
|
||||
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
// 【集合判空】
|
||||
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
|
||||
// CollectionUtil.isEmpty(list) → !list || list.length === 0
|
||||
tsBody = tsBody.replace(/(?:CollectionUtil|CollUtil)\.isEmpty\(([^)]+)\)/g, '(!$1 || $1.length === 0)');
|
||||
tsBody = tsBody.replace(/(?:CollectionUtil|CollUtil)\.isNotEmpty\(([^)]+)\)/g, '($1 && $1.length > 0)');
|
||||
|
||||
// list.isEmpty() → list.length === 0
|
||||
tsBody = tsBody.replace(/([a-zA-Z_$][\w$]*)\.isEmpty\(\)/g, '$1.length === 0');
|
||||
tsBody = tsBody.replace(/!([a-zA-Z_$][\w$]*)\.isEmpty\(\)/g, '$1.length > 0');
|
||||
|
||||
// StringUtils.isEmpty(str) → !str || str.trim() === ''
|
||||
tsBody = tsBody.replace(/StringUtils\.isEmpty\(([^)]+)\)/g, '(!$1 || $1.trim() === \'\')');
|
||||
tsBody = tsBody.replace(/StringUtils\.isNotEmpty\(([^)]+)\)/g, '($1 && $1.trim() !== \'\')');
|
||||
|
||||
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
// 【异常处理】
|
||||
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
|
||||
tsBody = tsBody.replace(/throw\s+new\s+CommonException\(/g, 'throw new BadRequestException(');
|
||||
tsBody = tsBody.replace(/throw\s+new\s+AuthException\(/g, 'throw new UnauthorizedException(');
|
||||
tsBody = tsBody.replace(/throw\s+new\s+RuntimeException\(/g, 'throw new Error(');
|
||||
tsBody = tsBody.replace(/throw\s+new\s+Exception\(/g, 'throw new Error(');
|
||||
|
||||
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
// 【其他】
|
||||
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
|
||||
// System.out.println → console.log
|
||||
tsBody = tsBody.replace(/System\.out\.println\(/g, 'console.log(');
|
||||
tsBody = tsBody.replace(/System\.err\.println\(/g, 'console.error(');
|
||||
|
||||
return tsBody;
|
||||
}
|
||||
|
||||
/**
|
||||
* 【阶段4】Mapper/Service调用转换
|
||||
*/
|
||||
convertDependencyCalls(javaBody, context) {
|
||||
let tsBody = javaBody;
|
||||
|
||||
// Mapper调用:xxxMapper.method() → this.xxxRepository.method()
|
||||
if (context.dependencies) {
|
||||
context.dependencies.forEach(dep => {
|
||||
if (dep.includes('Mapper')) {
|
||||
const mapperName = dep;
|
||||
const repoName = this.namingUtils.toCamelCase(dep.replace('Mapper', 'Repository'));
|
||||
tsBody = tsBody.replace(new RegExp(`${mapperName}\\.`, 'g'), `this.${repoName}.`);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Service调用:xxxService.method() → this.xxxService.method()
|
||||
if (context.dependencies) {
|
||||
context.dependencies.forEach(dep => {
|
||||
if (dep.includes('Service') && !dep.includes('ServiceImpl')) {
|
||||
const serviceName = this.namingUtils.toCamelCase(dep);
|
||||
tsBody = tsBody.replace(new RegExp(`${dep}\\.`, 'g'), `this.${serviceName}.`);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return tsBody;
|
||||
}
|
||||
|
||||
/**
|
||||
* 映射Java类型到TypeScript
|
||||
*/
|
||||
mapJavaTypeToTypeScript(javaType) {
|
||||
// 处理泛型
|
||||
if (javaType.includes('<')) {
|
||||
const genericMatch = javaType.match(/^(\w+)<(.+)>$/);
|
||||
if (genericMatch) {
|
||||
const baseType = genericMatch[1];
|
||||
const genericType = genericMatch[2];
|
||||
|
||||
if (baseType === 'List' || baseType === 'ArrayList' || baseType === 'LinkedList') {
|
||||
return `${this.mapJavaTypeToTypeScript(genericType)}[]`;
|
||||
} else if (baseType === 'Map' || baseType === 'HashMap') {
|
||||
return 'Record<string, any>';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const typeMap = {
|
||||
'Integer': 'number',
|
||||
'int': 'number',
|
||||
'Long': 'number',
|
||||
'long': 'number',
|
||||
'Double': 'number',
|
||||
'double': 'number',
|
||||
'Float': 'number',
|
||||
'float': 'number',
|
||||
'BigDecimal': 'number',
|
||||
'String': 'string',
|
||||
'Boolean': 'boolean',
|
||||
'boolean': 'boolean',
|
||||
'Object': 'any',
|
||||
'void': 'void',
|
||||
'File': 'string',
|
||||
'JSONObject': 'Record<string, any>',
|
||||
'Id': 'number',
|
||||
'Date': 'Date',
|
||||
'LocalDateTime': 'Date',
|
||||
'LocalDate': 'Date',
|
||||
'List': 'any[]',
|
||||
'Map': 'Record<string, any>'
|
||||
};
|
||||
|
||||
return typeMap[javaType] || javaType;
|
||||
}
|
||||
|
||||
/**
|
||||
* 分析需要的imports
|
||||
*
|
||||
* @param {string} convertedBody - 转换后的TypeScript代码
|
||||
* @returns {object} 需要导入的模块
|
||||
*/
|
||||
analyzeImports(convertedBody) {
|
||||
const imports = {
|
||||
nestjs: new Set(),
|
||||
boot: new Set(),
|
||||
nodeModules: new Set()
|
||||
};
|
||||
|
||||
// NestJS异常
|
||||
if (convertedBody.includes('BadRequestException')) {
|
||||
imports.nestjs.add('BadRequestException');
|
||||
}
|
||||
if (convertedBody.includes('UnauthorizedException')) {
|
||||
imports.nestjs.add('UnauthorizedException');
|
||||
}
|
||||
|
||||
// Node.js模块
|
||||
if (convertedBody.includes('fs.')) {
|
||||
imports.nodeModules.add('fs');
|
||||
}
|
||||
if (convertedBody.includes('path.')) {
|
||||
imports.nodeModules.add('path');
|
||||
}
|
||||
|
||||
// ConfigService
|
||||
if (convertedBody.includes('this.config.')) {
|
||||
imports.boot.add('ConfigService');
|
||||
}
|
||||
|
||||
return {
|
||||
nestjs: Array.from(imports.nestjs),
|
||||
boot: Array.from(imports.boot),
|
||||
nodeModules: Array.from(imports.nodeModules)
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = ServiceMethodConverter;
|
||||
|
||||
@@ -1,434 +0,0 @@
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const NamingUtils = require('../utils/naming-utils');
|
||||
const TypeMapper = require('../mappers/type-mapper');
|
||||
|
||||
/**
|
||||
* 业务逻辑转换器
|
||||
* 将Java业务逻辑转换为NestJS业务逻辑
|
||||
*/
|
||||
class BusinessLogicConverter {
|
||||
constructor() {
|
||||
this.namingUtils = new NamingUtils();
|
||||
this.typeMapper = new TypeMapper();
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换Java方法到NestJS方法
|
||||
*/
|
||||
convertMethod(javaMethod, javaClass) {
|
||||
const methodName = this.namingUtils.generateMethodName(javaMethod.methodName);
|
||||
const parameters = this.convertParameters(javaMethod.parameters);
|
||||
const returnType = this.convertReturnType(javaMethod.returnType);
|
||||
const body = this.convertMethodBody(javaMethod, javaClass);
|
||||
|
||||
return {
|
||||
methodName,
|
||||
parameters,
|
||||
returnType,
|
||||
body,
|
||||
decorators: this.generateMethodDecorators(javaMethod),
|
||||
imports: this.generateMethodImports(javaMethod)
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换方法参数
|
||||
*/
|
||||
convertParameters(javaParameters) {
|
||||
if (!javaParameters || javaParameters.length === 0) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return javaParameters.map(param => {
|
||||
const paramName = this.namingUtils.toCamelCase(param.name);
|
||||
const paramType = this.typeMapper.mapType(param.type);
|
||||
const decorator = this.generateParameterDecorator(param);
|
||||
|
||||
return `${decorator} ${paramName}: ${paramType.typescript}`;
|
||||
}).join(', ');
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换返回类型
|
||||
*/
|
||||
convertReturnType(javaReturnType) {
|
||||
if (!javaReturnType) {
|
||||
return 'void';
|
||||
}
|
||||
|
||||
const typeMapping = this.typeMapper.mapType(javaReturnType);
|
||||
return typeMapping.typescript;
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换方法体
|
||||
*/
|
||||
convertMethodBody(javaMethod, javaClass) {
|
||||
const methodName = javaMethod.methodName;
|
||||
const body = javaMethod.body || '';
|
||||
|
||||
// 根据方法名推断业务逻辑
|
||||
if (methodName.includes('create') || methodName.includes('add')) {
|
||||
return this.convertCreateMethod(body, javaClass);
|
||||
}
|
||||
|
||||
if (methodName.includes('update') || methodName.includes('modify')) {
|
||||
return this.convertUpdateMethod(body, javaClass);
|
||||
}
|
||||
|
||||
if (methodName.includes('delete') || methodName.includes('remove')) {
|
||||
return this.convertDeleteMethod(body, javaClass);
|
||||
}
|
||||
|
||||
if (methodName.includes('find') || methodName.includes('get') || methodName.includes('query')) {
|
||||
return this.convertQueryMethod(body, javaClass);
|
||||
}
|
||||
|
||||
if (methodName.includes('list') || methodName.includes('page')) {
|
||||
return this.convertListMethod(body, javaClass);
|
||||
}
|
||||
|
||||
if (methodName.includes('count') || methodName.includes('exists')) {
|
||||
return this.convertCountMethod(body, javaClass);
|
||||
}
|
||||
|
||||
// 默认转换
|
||||
return this.convertDefaultMethod(body, javaClass);
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换创建方法
|
||||
*/
|
||||
convertCreateMethod(javaBody, javaClass) {
|
||||
const entityName = this.namingUtils.generateEntityName(javaClass.className);
|
||||
const repositoryName = this.namingUtils.toCamelCase(javaClass.className) + 'Repository';
|
||||
|
||||
return ` try {
|
||||
const entity = this.${repositoryName}.create(data);
|
||||
const result = await this.${repositoryName}.save(entity);
|
||||
|
||||
// 发布领域事件
|
||||
await this.domainEventService.publish('${entityName}.created', result);
|
||||
|
||||
return Result.success(result);
|
||||
} catch (error) {
|
||||
return Result.error('创建失败: ' + error.message);
|
||||
}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换更新方法
|
||||
*/
|
||||
convertUpdateMethod(javaBody, javaClass) {
|
||||
const entityName = this.namingUtils.generateEntityName(javaClass.className);
|
||||
const repositoryName = this.namingUtils.toCamelCase(javaClass.className) + 'Repository';
|
||||
|
||||
return ` try {
|
||||
const existingEntity = await this.${repositoryName}.findOne({ where: { id } });
|
||||
if (!existingEntity) {
|
||||
return Result.error('记录不存在');
|
||||
}
|
||||
|
||||
await this.${repositoryName}.update(id, data);
|
||||
const result = await this.${repositoryName}.findOne({ where: { id } });
|
||||
|
||||
// 发布领域事件
|
||||
await this.domainEventService.publish('${entityName}.updated', result);
|
||||
|
||||
return Result.success(result);
|
||||
} catch (error) {
|
||||
return Result.error('更新失败: ' + error.message);
|
||||
}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换删除方法
|
||||
*/
|
||||
convertDeleteMethod(javaBody, javaClass) {
|
||||
const entityName = this.namingUtils.generateEntityName(javaClass.className);
|
||||
const repositoryName = this.namingUtils.toCamelCase(javaClass.className) + 'Repository';
|
||||
|
||||
return ` try {
|
||||
const existingEntity = await this.${repositoryName}.findOne({ where: { id } });
|
||||
if (!existingEntity) {
|
||||
return Result.error('记录不存在');
|
||||
}
|
||||
|
||||
await this.${repositoryName}.delete(id);
|
||||
|
||||
// 发布领域事件
|
||||
await this.domainEventService.publish('${entityName}.deleted', existingEntity);
|
||||
|
||||
return Result.success({ message: '删除成功' });
|
||||
} catch (error) {
|
||||
return Result.error('删除失败: ' + error.message);
|
||||
}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换查询方法
|
||||
*/
|
||||
convertQueryMethod(javaBody, javaClass) {
|
||||
const entityName = this.namingUtils.generateEntityName(javaClass.className);
|
||||
const repositoryName = this.namingUtils.toCamelCase(javaClass.className) + 'Repository';
|
||||
|
||||
return ` try {
|
||||
const result = await this.${repositoryName}.findOne({ where: { id } });
|
||||
|
||||
if (!result) {
|
||||
return Result.error('记录不存在');
|
||||
}
|
||||
|
||||
return Result.success(result);
|
||||
} catch (error) {
|
||||
return Result.error('查询失败: ' + error.message);
|
||||
}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换列表方法
|
||||
*/
|
||||
convertListMethod(javaBody, javaClass) {
|
||||
const entityName = this.namingUtils.generateEntityName(javaClass.className);
|
||||
const repositoryName = this.namingUtils.toCamelCase(javaClass.className) + 'Repository';
|
||||
|
||||
return ` try {
|
||||
const [data, total] = await this.${repositoryName}.findAndCount({
|
||||
skip: (page - 1) * limit,
|
||||
take: limit,
|
||||
where: this.buildWhereCondition(query)
|
||||
});
|
||||
|
||||
return Result.success({
|
||||
currentPage: page,
|
||||
perPage: limit,
|
||||
total,
|
||||
data
|
||||
});
|
||||
} catch (error) {
|
||||
return Result.error('查询失败: ' + error.message);
|
||||
}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换计数方法
|
||||
*/
|
||||
convertCountMethod(javaBody, javaClass) {
|
||||
const entityName = this.namingUtils.generateEntityName(javaClass.className);
|
||||
const repositoryName = this.namingUtils.toCamelCase(javaClass.className) + 'Repository';
|
||||
|
||||
return ` try {
|
||||
const count = await this.${repositoryName}.count({
|
||||
where: this.buildWhereCondition(query)
|
||||
});
|
||||
|
||||
return Result.success(count);
|
||||
} catch (error) {
|
||||
return Result.error('统计失败: ' + error.message);
|
||||
}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换默认方法
|
||||
*/
|
||||
convertDefaultMethod(javaBody, javaClass) {
|
||||
return ` try {
|
||||
// TODO: 实现业务逻辑
|
||||
return Result.success(null);
|
||||
} catch (error) {
|
||||
return Result.error('操作失败: ' + error.message);
|
||||
}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成方法装饰器
|
||||
*/
|
||||
generateMethodDecorators(javaMethod) {
|
||||
const decorators = [];
|
||||
|
||||
// 根据方法名添加装饰器
|
||||
if (javaMethod.methodName.includes('create') || javaMethod.methodName.includes('add')) {
|
||||
decorators.push('@Post()');
|
||||
} else if (javaMethod.methodName.includes('update') || javaMethod.methodName.includes('modify')) {
|
||||
decorators.push('@Put()');
|
||||
} else if (javaMethod.methodName.includes('delete') || javaMethod.methodName.includes('remove')) {
|
||||
decorators.push('@Delete()');
|
||||
} else {
|
||||
decorators.push('@Get()');
|
||||
}
|
||||
|
||||
// 添加API文档装饰器
|
||||
decorators.push('@ApiOperation({ summary: \'' + javaMethod.methodName + '\' })');
|
||||
decorators.push('@ApiResponse({ status: 200, description: \'成功\' })');
|
||||
|
||||
return decorators;
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成方法导入
|
||||
*/
|
||||
generateMethodImports(javaMethod) {
|
||||
const imports = [];
|
||||
|
||||
// 根据方法名添加导入
|
||||
if (javaMethod.methodName.includes('create') || javaMethod.methodName.includes('add')) {
|
||||
imports.push("import { Post } from '@nestjs/common';");
|
||||
} else if (javaMethod.methodName.includes('update') || javaMethod.methodName.includes('modify')) {
|
||||
imports.push("import { Put } from '@nestjs/common';");
|
||||
} else if (javaMethod.methodName.includes('delete') || javaMethod.methodName.includes('remove')) {
|
||||
imports.push("import { Delete } from '@nestjs/common';");
|
||||
} else {
|
||||
imports.push("import { Get } from '@nestjs/common';");
|
||||
}
|
||||
|
||||
// 添加API文档导入
|
||||
imports.push("import { ApiOperation, ApiResponse } from '@nestjs/swagger';");
|
||||
|
||||
return imports;
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成参数装饰器
|
||||
*/
|
||||
generateParameterDecorator(javaParameter) {
|
||||
if (javaParameter.annotation === '@RequestBody') {
|
||||
return '@Body()';
|
||||
} else if (javaParameter.annotation === '@PathVariable') {
|
||||
return '@Param()';
|
||||
} else if (javaParameter.annotation === '@RequestParam') {
|
||||
return '@Query()';
|
||||
} else if (javaParameter.annotation === '@RequestHeader') {
|
||||
return '@Headers()';
|
||||
} else if (javaParameter.annotation === '@CookieValue') {
|
||||
return '@Cookies()';
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换Java表达式到TypeScript表达式
|
||||
*/
|
||||
convertExpression(javaExpression) {
|
||||
let expression = javaExpression;
|
||||
|
||||
// 转换Java语法到TypeScript语法
|
||||
expression = expression.replace(/\.equals\(/g, ' === ');
|
||||
expression = expression.replace(/\.equalsIgnoreCase\(/g, '.toLowerCase() === ');
|
||||
expression = expression.replace(/\.isEmpty\(\)/g, ' === \'\'');
|
||||
expression = expression.replace(/\.isNotEmpty\(\)/g, ' !== \'\'');
|
||||
expression = expression.replace(/\.size\(\)/g, '.length');
|
||||
expression = expression.replace(/\.length\(\)/g, '.length');
|
||||
|
||||
// 转换字符串操作
|
||||
expression = expression.replace(/\.substring\(/g, '.substring(');
|
||||
expression = expression.replace(/\.indexOf\(/g, '.indexOf(');
|
||||
expression = expression.replace(/\.contains\(/g, '.includes(');
|
||||
expression = expression.replace(/\.startsWith\(/g, '.startsWith(');
|
||||
expression = expression.replace(/\.endsWith\(/g, '.endsWith(');
|
||||
|
||||
// 转换集合操作
|
||||
expression = expression.replace(/\.add\(/g, '.push(');
|
||||
expression = expression.replace(/\.remove\(/g, '.splice(');
|
||||
expression = expression.replace(/\.clear\(\)/g, '.length = 0');
|
||||
|
||||
// 转换空值检查
|
||||
expression = expression.replace(/== null/g, '=== null');
|
||||
expression = expression.replace(/!= null/g, '!== null');
|
||||
expression = expression.replace(/== undefined/g, '=== undefined');
|
||||
expression = expression.replace(/!= undefined/g, '!== undefined');
|
||||
|
||||
return expression;
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换Java条件语句到TypeScript条件语句
|
||||
*/
|
||||
convertConditionalStatement(javaCondition) {
|
||||
let condition = javaCondition;
|
||||
|
||||
// 转换逻辑操作符
|
||||
condition = condition.replace(/&&/g, '&&');
|
||||
condition = condition.replace(/||/g, '||');
|
||||
condition = condition.replace(/!/g, '!');
|
||||
|
||||
// 转换比较操作符
|
||||
condition = condition.replace(/==/g, '===');
|
||||
condition = condition.replace(/!=/g, '!==');
|
||||
condition = condition.replace(/<=/g, '<=');
|
||||
condition = condition.replace(/>=/g, '>=');
|
||||
condition = condition.replace(/</g, '<');
|
||||
condition = condition.replace(/>/g, '>');
|
||||
|
||||
return condition;
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换Java循环语句到TypeScript循环语句
|
||||
*/
|
||||
convertLoopStatement(javaLoop) {
|
||||
let loop = javaLoop;
|
||||
|
||||
// 转换for循环
|
||||
loop = loop.replace(/for\s*\(\s*int\s+(\w+)\s*=\s*(\d+)\s*;\s*\1\s*<\s*(\w+)\.length\s*;\s*\1\+\+\)/g, 'for (let $1 = $2; $1 < $3.length; $1++)');
|
||||
|
||||
// 转换增强for循环
|
||||
loop = loop.replace(/for\s*\(\s*(\w+)\s+(\w+)\s*:\s*(\w+)\s*\)/g, 'for (const $2 of $3)');
|
||||
|
||||
// 转换while循环
|
||||
loop = loop.replace(/while\s*\(/g, 'while (');
|
||||
|
||||
// 转换do-while循环
|
||||
loop = loop.replace(/do\s*\{/g, 'do {');
|
||||
loop = loop.replace(/\}\s*while\s*\(/g, '} while (');
|
||||
|
||||
return loop;
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换Java异常处理到TypeScript异常处理
|
||||
*/
|
||||
convertExceptionHandling(javaException) {
|
||||
let exception = javaException;
|
||||
|
||||
// 转换try-catch语句
|
||||
exception = exception.replace(/try\s*\{/g, 'try {');
|
||||
exception = exception.replace(/catch\s*\(\s*(\w+)\s+(\w+)\s*\)/g, 'catch ($2)');
|
||||
exception = exception.replace(/finally\s*\{/g, 'finally {');
|
||||
|
||||
// 转换异常类型
|
||||
exception = exception.replace(/Exception/g, 'Error');
|
||||
exception = exception.replace(/RuntimeException/g, 'Error');
|
||||
exception = exception.replace(/IllegalArgumentException/g, 'Error');
|
||||
exception = exception.replace(/NullPointerException/g, 'Error');
|
||||
|
||||
return exception;
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证业务逻辑转换一致性
|
||||
*/
|
||||
validateBusinessLogicConsistency(javaMethod, nestJSMethod) {
|
||||
const issues = [];
|
||||
|
||||
// 验证方法名
|
||||
if (javaMethod.methodName !== nestJSMethod.methodName) {
|
||||
issues.push(`方法名不一致: ${javaMethod.methodName} vs ${nestJSMethod.methodName}`);
|
||||
}
|
||||
|
||||
// 验证参数数量
|
||||
if (javaMethod.parameters.length !== nestJSMethod.parameters.length) {
|
||||
issues.push(`参数数量不一致: ${javaMethod.parameters.length} vs ${nestJSMethod.parameters.length}`);
|
||||
}
|
||||
|
||||
// 验证返回类型
|
||||
if (javaMethod.returnType !== nestJSMethod.returnType) {
|
||||
issues.push(`返回类型不一致: ${javaMethod.returnType} vs ${nestJSMethod.returnType}`);
|
||||
}
|
||||
|
||||
return issues;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = BusinessLogicConverter;
|
||||
@@ -1,18 +0,0 @@
|
||||
{
|
||||
"timestamp": "2025-10-29T02:54:59.685Z",
|
||||
"stats": {
|
||||
"startTime": "2025-10-29T02:54:58.550Z",
|
||||
"endTime": null,
|
||||
"filesProcessed": 1215,
|
||||
"modulesGenerated": 6,
|
||||
"errors": []
|
||||
},
|
||||
"modules": [
|
||||
"CommonModule - 通用功能模块",
|
||||
"EntityModule - 实体模块",
|
||||
"ServiceModule - 服务模块",
|
||||
"ControllerModule - 控制器模块",
|
||||
"ListenerModule - 监听器模块",
|
||||
"JobModule - 任务模块"
|
||||
]
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@@ -1,12 +0,0 @@
|
||||
{
|
||||
"nodeVersion": "v20.13.1",
|
||||
"nodeEnv": "development",
|
||||
"timestamp": 1761545674856,
|
||||
"redis": {
|
||||
"enabled": false,
|
||||
"connected": false,
|
||||
"host": "127.0.0.1",
|
||||
"port": 6380
|
||||
},
|
||||
"envMissing": []
|
||||
}
|
||||
Reference in New Issue
Block a user