代码生成支持树

This commit is contained in:
2024-03-17 00:03:31 +08:00
parent f48319f5d8
commit a39e681e96

View File

@@ -21,7 +21,9 @@ import com.google.googlejavaformat.java.Formatter;
import com.google.googlejavaformat.java.JavaFormatterOptions;
import com.squareup.javapoet.*;
import jakarta.persistence.CascadeType;
import jakarta.persistence.Entity;
import jakarta.persistence.OneToMany;
import lombok.Data;
import lombok.SneakyThrows;
@@ -50,6 +52,8 @@ import java.io.Writer;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Scanner;
@@ -89,6 +93,11 @@ public class Codegen {
Objects.equals(
StringUtils.defaultIfBlank(new Scanner(System.in).nextLine(), "Y"), "Y");
System.out.print("树结构[N]:");
boolean tree =
Objects.equals(
StringUtils.defaultIfBlank(new Scanner(System.in).nextLine(), "N"), "Y");
String lModuleName = CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_CAMEL, moduleName);
String prefix = Codegen.class.getPackage().getName() + "." + lModuleName;
String entityPackage = prefix + ".entity";
@@ -150,6 +159,40 @@ public class Codegen {
.build();
}
if (tree) {
entity =
entity.toBuilder()
.addField(
FieldSpec.builder(
ClassName.get(entityPackage, entity.name),
"parent",
Modifier.PRIVATE)
.addAnnotation(
AnnotationSpec.builder(
jakarta.persistence.ManyToOne
.class)
.build())
.build())
.addField(
FieldSpec.builder(
ParameterizedTypeName.get(
ClassName.get(List.class),
ClassName.get(
entityPackage, entity.name)),
"children",
Modifier.PRIVATE)
.addAnnotation(
AnnotationSpec.builder(OneToMany.class)
.addMember("mappedBy", "$S", "parent")
.addMember(
"cascade",
"$T.ALL",
CascadeType.class)
.build())
.build())
.build();
}
saveFile(entityPackage, entity);
// 生成dto
@@ -176,6 +219,15 @@ public class Codegen {
.build();
}
if (tree) {
dto =
dto.toBuilder()
.addField(
FieldSpec.builder(String.class, "parent", Modifier.PRIVATE)
.build())
.build();
}
saveFile(dtoPackage, dto);
// 生成createDto
@@ -186,6 +238,15 @@ public class Codegen {
.addAnnotation(Data.class)
.build();
if (tree) {
createDto =
createDto.toBuilder()
.addField(
FieldSpec.builder(String.class, "parent", Modifier.PRIVATE)
.build())
.build();
}
saveFile(dtoPackage, createDto);
// 生成updateDto
@@ -196,8 +257,41 @@ public class Codegen {
.addAnnotation(Data.class)
.build();
if (tree) {
updateDto =
updateDto.toBuilder()
.addField(
FieldSpec.builder(String.class, "parent", Modifier.PRIVATE)
.build())
.build();
}
saveFile(dtoPackage, updateDto);
TypeSpec treeDto = null;
if (tree) {
// 生成treeDto
treeDto =
TypeSpec.classBuilder(StringUtils.capitalize(moduleName) + "TreeDto")
.addModifiers(Modifier.PUBLIC)
.superclass(orgMode ? OrgCommonDto.class : CommonDto.class)
.addAnnotation(Data.class)
.build();
treeDto =
treeDto.toBuilder()
.addField(
FieldSpec.builder(
ParameterizedTypeName.get(
ClassName.get(List.class),
ClassName.get(
dtoPackage, treeDto.name)),
"children",
Modifier.PRIVATE)
.build())
.build();
saveFile(dtoPackage, treeDto);
}
// 生成repository
TypeSpec repository =
TypeSpec.interfaceBuilder(StringUtils.capitalize(moduleName) + "Repository")
@@ -237,6 +331,20 @@ public class Codegen {
ClassName.get(dtoPackage, updateDto.name)))
.build();
if (tree) {
mapper =
mapper.toBuilder()
.addMethod(
MethodSpec.methodBuilder("toTreeDto")
.addModifiers(Modifier.PUBLIC, Modifier.ABSTRACT)
.returns(ClassName.get(dtoPackage, treeDto.name))
.addParameter(
ClassName.get(entityPackage, entity.name),
"entity")
.build())
.build();
}
saveFile(mapperPackage, mapper);
// 生成service
@@ -450,6 +558,53 @@ public class Codegen {
.build();
}
if (tree) {
service =
service.toBuilder()
.addMethod(
MethodSpec.methodBuilder("getRoots")
.addModifiers(Modifier.PUBLIC)
.returns(
ParameterizedTypeName.get(
ClassName.get(List.class),
ClassName.get(
dtoPackage, treeDto.name)))
.addStatement(
"""
var roots = this.repository.findAll((root, query, criteriaBuilder) -> criteriaBuilder.isNull(root.get("parent")));
return roots.stream().map(de -> this.mapper.toTreeDto(de)).collect($T.toList())
""",
ClassName.get(
java.util.stream.Collectors.class))
.build())
.addMethod(
MethodSpec.methodBuilder("getTreeByIds")
.addModifiers(Modifier.PUBLIC)
.returns(
ParameterizedTypeName.get(
ClassName.get(List.class),
ClassName.get(
dtoPackage, treeDto.name)))
.addParameter(ClassName.get(IdRequest.class), "request")
.addStatement(
"""
if (request.getIds().isEmpty()) {
return new $T<>();
}
var roots = this.repository.findAll((root, query, criteriaBuilder) -> root.get("id").in(request.getIds()));
return roots.stream().map(de -> this.mapper.toTreeDto(de)).collect($T.toList())
""",
ClassName.get(ArrayList.class),
ClassName.get(
java.util.stream.Collectors.class))
.build())
.build();
}
saveFile(servicePackage, service);
// 生成controller
@@ -626,6 +781,47 @@ public class Codegen {
.build());
}
if (tree) {
controllerBuilder
.addMethod(
MethodSpec.methodBuilder("roots")
.addModifiers(Modifier.PUBLIC)
.returns(
ParameterizedTypeName.get(
ClassName.get(List.class),
ClassName.get(dtoPackage, treeDto.name)))
.addAnnotation(
AnnotationSpec.builder(PostMapping.class)
.addMember("value", "$S", "/roots")
.build())
.addStatement(
"""
return this.service.getRoots()
""")
.build())
.addMethod(
MethodSpec.methodBuilder("treeByIds")
.addModifiers(Modifier.PUBLIC)
.returns(
ParameterizedTypeName.get(
ClassName.get(List.class),
ClassName.get(dtoPackage, treeDto.name)))
.addAnnotation(
AnnotationSpec.builder(PostMapping.class)
.addMember("value", "$S", "/treeByIds")
.build())
.addParameter(
ParameterSpec.builder(
ClassName.get(IdRequest.class), "request")
.addAnnotation(RequestBody.class)
.build())
.addStatement(
"""
return this.service.getTreeByIds(request)
""")
.build());
}
saveFile(controllerPackage, controllerBuilder.build());
genScript(lModuleName, controllerPackage, controllerBuilder.build());
@@ -658,7 +854,9 @@ public class Codegen {
.formatted(controllerPackage + "." + controller.name, controller.name);
Files.writeString(
Path.of("src/main/resources/scripts/dict/enum/%sDict.groovy".formatted(lModuleName)),
Path.of(
"src/main/resources/scripts/dict/enum/%sDict.groovy"
.formatted(lModuleName)),
script);
}