fix: 严格保持Java目录层级结构 - DTO按admin/member/vo完整路径生成

This commit is contained in:
wanwu
2025-10-28 15:44:27 +08:00
parent e2df6745ff
commit 4a5838562a

View File

@@ -17,20 +17,59 @@ class DtoGenerator {
generateDto(javaDto, outputDir) {
const dtoName = this.namingUtils.generateDtoName(javaDto.className);
const fileName = this.namingUtils.generateFileName(javaDto.className, 'dto');
const filePath = path.join(outputDir, fileName);
const content = this.generateDtoContent(javaDto, dtoName);
// ✅ 严格保持Java目录结构
// 从Java路径中提取层级目录如: admin/member/vo, admin/member/param
const subPath = this.extractJavaSubPath(javaDto.filePath);
const targetDir = path.join(outputDir, subPath);
// 创建目录
if (!fs.existsSync(targetDir)) {
fs.mkdirSync(targetDir, { recursive: true });
}
const filePath = path.join(targetDir, fileName);
const content = this.generateDtoContent(javaDto, dtoName, subPath);
fs.writeFileSync(filePath, content);
console.log(`✅ 生成DTO: ${filePath}`);
return { fileName, content };
console.log(`✅ 生成DTO: ${subPath}/${fileName}`);
return { fileName, content, subPath };
}
/**
* 从Java文件路径中提取子路径
* 例如: com/niu/core/service/admin/member/vo/MemberListVo.java
* -> admin/member/vo
*/
extractJavaSubPath(javaFilePath) {
if (!javaFilePath) return '';
// 匹配 service/ 后面的路径,但排除 impl/ 目录
const match = javaFilePath.match(/service\/(.+?)\/(vo|param|dto)\//);
if (match) {
return `${match[1]}/${match[2]}`; // 如: admin/member/vo
}
// 兜底:如果在 enums 目录下
const enumMatch = javaFilePath.match(/enums\/(.+?)\/(vo|param|dto)\//);
if (enumMatch) {
return `${enumMatch[1]}/${enumMatch[2]}`;
}
// 兜底:如果在 common/loader 等特殊目录下
const loaderMatch = javaFilePath.match(/common\/loader\/(.+?)\/(vo|param|dto)\//);
if (loaderMatch) {
return `common/loader/${loaderMatch[1]}/${loaderMatch[2]}`;
}
return '';
}
/**
* 生成DTO内容
*/
generateDtoContent(javaDto, dtoName) {
const imports = this.generateImports(javaDto);
generateDtoContent(javaDto, dtoName, subPath = '') {
const imports = this.generateImports(javaDto, subPath);
const fields = this.generateFields(javaDto);
return `${imports}
@@ -44,11 +83,15 @@ ${fields}
/**
* 生成导入语句
*/
generateImports(javaDto) {
generateImports(javaDto, subPath = '') {
// 计算相对路径的 ../ 数量
const depth = subPath ? subPath.split('/').length : 0;
const basePath = '../'.repeat(depth + 1); // +1 是因为还要回到 dto/ 的上一级
const imports = [
"import { IsString, IsNumber, IsBoolean, IsOptional, IsArray, IsDateString, IsEmail, IsUrl, IsEnum } from 'class-validator';",
"import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';",
"import { BaseDto } from '../common/base.dto';"
`import { BaseDto } from '${basePath}common/base.dto';`
];
// 添加枚举导入
@@ -56,7 +99,7 @@ ${fields}
javaDto.enums.forEach(enumItem => {
const enumName = this.namingUtils.generateEnumName(enumItem);
const enumFileName = this.namingUtils.generateFileName(enumItem, 'enum');
imports.push(`import { ${enumName} } from '../enums/${enumFileName.replace('.enum.ts', '')}';`);
imports.push(`import { ${enumName} } from '${basePath}enums/${enumFileName.replace('.enum.ts', '')}';`);
});
}