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) { generateDto(javaDto, outputDir) {
const dtoName = this.namingUtils.generateDtoName(javaDto.className); const dtoName = this.namingUtils.generateDtoName(javaDto.className);
const fileName = this.namingUtils.generateFileName(javaDto.className, 'dto'); 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); fs.writeFileSync(filePath, content);
console.log(`✅ 生成DTO: ${filePath}`); console.log(`✅ 生成DTO: ${subPath}/${fileName}`);
return { fileName, content }; 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内容 * 生成DTO内容
*/ */
generateDtoContent(javaDto, dtoName) { generateDtoContent(javaDto, dtoName, subPath = '') {
const imports = this.generateImports(javaDto); const imports = this.generateImports(javaDto, subPath);
const fields = this.generateFields(javaDto); const fields = this.generateFields(javaDto);
return `${imports} 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 = [ const imports = [
"import { IsString, IsNumber, IsBoolean, IsOptional, IsArray, IsDateString, IsEmail, IsUrl, IsEnum } from 'class-validator';", "import { IsString, IsNumber, IsBoolean, IsOptional, IsArray, IsDateString, IsEmail, IsUrl, IsEnum } from 'class-validator';",
"import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';", "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 => { javaDto.enums.forEach(enumItem => {
const enumName = this.namingUtils.generateEnumName(enumItem); const enumName = this.namingUtils.generateEnumName(enumItem);
const enumFileName = this.namingUtils.generateFileName(enumItem, 'enum'); 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', '')}';`);
}); });
} }