|
@@ -4,8 +4,10 @@ import cn.hutool.core.collection.CollUtil;
|
|
|
import cn.hutool.core.map.MapUtil;
|
|
|
import cn.hutool.core.util.ObjectUtil;
|
|
|
import cn.hutool.core.util.StrUtil;
|
|
|
+import cn.hutool.extra.template.Template;
|
|
|
import cn.hutool.extra.template.TemplateConfig;
|
|
|
import cn.hutool.extra.template.TemplateEngine;
|
|
|
+import cn.hutool.extra.template.TemplateUtil;
|
|
|
import cn.hutool.extra.template.engine.velocity.VelocityEngine;
|
|
|
import cn.hutool.system.SystemUtil;
|
|
|
import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
|
|
@@ -28,6 +30,7 @@ import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
|
|
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
|
|
|
import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.CodegenColumnDO;
|
|
|
import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.CodegenTableDO;
|
|
|
+import cn.iocoder.yudao.module.infra.dal.dataobject.codegentemple.CodegenTempleDO;
|
|
|
import cn.iocoder.yudao.module.infra.enums.codegen.CodegenFrontTypeEnum;
|
|
|
import cn.iocoder.yudao.module.infra.enums.codegen.CodegenSceneEnum;
|
|
|
import cn.iocoder.yudao.module.infra.enums.codegen.CodegenTemplateTypeEnum;
|
|
@@ -145,10 +148,16 @@ public class CodegenEngine {
|
|
|
.put(CodegenFrontTypeEnum.VUE3_VBEN.getType(), vue3VbenTemplatePath("api/api.ts"),
|
|
|
vue3FilePath("api/${table.moduleName}/${table.businessName}/index.ts"))
|
|
|
.build();
|
|
|
-
|
|
|
+ /**
|
|
|
+ * 模板引擎,由 hutool 实现
|
|
|
+ */
|
|
|
+ private final TemplateEngine templateEngine;
|
|
|
+ /**
|
|
|
+ * 全局通用变量映射
|
|
|
+ */
|
|
|
+ private final Map<String, Object> globalBindingMap = new HashMap<>();
|
|
|
@Resource
|
|
|
private CodegenProperties codegenProperties;
|
|
|
-
|
|
|
/**
|
|
|
* 是否使用 jakarta 包,用于解决 Spring Boot 2.X 和 3.X 的兼容性问题
|
|
|
*
|
|
@@ -158,15 +167,6 @@ public class CodegenEngine {
|
|
|
@Setter // 允许设置的原因,是因为单测需要手动改变
|
|
|
private Boolean jakartaEnable;
|
|
|
|
|
|
- /**
|
|
|
- * 模板引擎,由 hutool 实现
|
|
|
- */
|
|
|
- private final TemplateEngine templateEngine;
|
|
|
- /**
|
|
|
- * 全局通用变量映射
|
|
|
- */
|
|
|
- private final Map<String, Object> globalBindingMap = new HashMap<>();
|
|
|
-
|
|
|
public CodegenEngine() {
|
|
|
// 初始化 TemplateEngine 属性
|
|
|
TemplateConfig config = new TemplateConfig();
|
|
@@ -175,7 +175,79 @@ public class CodegenEngine {
|
|
|
// 设置 javaxEnable,按照是否使用 JDK17 来判断
|
|
|
this.jakartaEnable = SystemUtil.getJavaInfo().isJavaVersionAtLeast(1700); // 17.00 * 100
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
+ private static String javaTemplatePath(String path) {
|
|
|
+ return "codegen/java/" + path + ".vm";
|
|
|
+ }
|
|
|
+
|
|
|
+ private static String javaModuleImplVOFilePath(String path) {
|
|
|
+ return javaModuleFilePath("controller/${sceneEnum.basePackage}/${table.businessName}/" +
|
|
|
+ "vo/${sceneEnum.prefixClass}${table.className}" + path, "biz", "main");
|
|
|
+ }
|
|
|
+
|
|
|
+ private static String javaModuleImplControllerFilePath() {
|
|
|
+ return javaModuleFilePath("controller/${sceneEnum.basePackage}/${table.businessName}/" +
|
|
|
+ "${sceneEnum.prefixClass}${table.className}Controller", "biz", "main");
|
|
|
+ }
|
|
|
+
|
|
|
+ private static String javaModuleImplMainFilePath(String path) {
|
|
|
+ return javaModuleFilePath(path, "biz", "main");
|
|
|
+ }
|
|
|
+
|
|
|
+ private static String javaModuleApiMainFilePath(String path) {
|
|
|
+ return javaModuleFilePath(path, "api", "main");
|
|
|
+ }
|
|
|
+
|
|
|
+ private static String javaModuleImplTestFilePath(String path) {
|
|
|
+ return javaModuleFilePath(path, "biz", "test");
|
|
|
+ }
|
|
|
+
|
|
|
+ private static String javaModuleFilePath(String path, String module, String src) {
|
|
|
+ return "yudao-module-${table.moduleName}/" + // 顶级模块
|
|
|
+ "yudao-module-${table.moduleName}-" + module + "/" + // 子模块
|
|
|
+ "src/" + src + "/java/${basePackage}/module/${table.moduleName}/" + path + ".java";
|
|
|
+ }
|
|
|
+
|
|
|
+ private static String mapperXmlFilePath() {
|
|
|
+ return "yudao-module-${table.moduleName}/" + // 顶级模块
|
|
|
+ "yudao-module-${table.moduleName}-biz/" + // 子模块
|
|
|
+ "src/main/resources/mapper/${table.businessName}/${table.className}Mapper.xml";
|
|
|
+ }
|
|
|
+
|
|
|
+ private static String vueTemplatePath(String path) {
|
|
|
+ return "codegen/vue/" + path + ".vm";
|
|
|
+ }
|
|
|
+
|
|
|
+ private static String vueFilePath(String path) {
|
|
|
+ return "yudao-ui-${sceneEnum.basePackage}-vue2/" + // 顶级目录
|
|
|
+ "src/" + path;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static String vue3TemplatePath(String path) {
|
|
|
+ return "codegen/vue3/" + path + ".vm";
|
|
|
+ }
|
|
|
+
|
|
|
+ private static String vue3FilePath(String path) {
|
|
|
+ return "yudao-ui-${sceneEnum.basePackage}-vue3/" + // 顶级目录
|
|
|
+ "src/" + path;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static String vue3VbenTemplatePath(String path) {
|
|
|
+ return "codegen/vue3_vben/" + path + ".vm";
|
|
|
+ }
|
|
|
+
|
|
|
+ private static boolean isSubTemplate(String path) {
|
|
|
+ return path.contains("_sub");
|
|
|
+ }
|
|
|
+
|
|
|
+ private static boolean isPageReqVOTemplate(String path) {
|
|
|
+ return path.contains("pageReqVO");
|
|
|
+ }
|
|
|
+
|
|
|
+ private static boolean isListReqVOTemplate(String path) {
|
|
|
+ return path.contains("listReqVO");
|
|
|
+ }
|
|
|
+
|
|
|
@PostConstruct
|
|
|
@VisibleForTesting
|
|
|
void initGlobalBindingMap() {
|
|
@@ -247,6 +319,32 @@ public class CodegenEngine {
|
|
|
});
|
|
|
return result;
|
|
|
}
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 生成代码
|
|
|
+ *
|
|
|
+ * @param table 表定义
|
|
|
+ * @param columns table 的字段定义数组
|
|
|
+ * @param subTables 子表数组,当且仅当主子表时使用
|
|
|
+ * @param subColumnsList subTables 的字段定义数组
|
|
|
+ * @return 生成的代码,key 是路径,value 是对应代码
|
|
|
+ */
|
|
|
+ public Map<String, String> executeNew(List<CodegenTempleDO> templates, CodegenTableDO table,
|
|
|
+ List<CodegenColumnDO> columns,
|
|
|
+ List<CodegenTableDO> subTables, List<List<CodegenColumnDO>> subColumnsList) {
|
|
|
+ // 1.1 初始化 bindMap 上下文
|
|
|
+ Map<String, Object> bindingMap = initBindingMap(table, columns, subTables, subColumnsList);
|
|
|
+ // 1.2 获得模版
|
|
|
+ // Map<String, String> templates = getTemplates(table.getFrontType());
|
|
|
+
|
|
|
+ // 2. 执行生成
|
|
|
+ Map<String, String> result = Maps.newLinkedHashMapWithExpectedSize(templates.size()); // 有序
|
|
|
+
|
|
|
+ for (CodegenTempleDO template : templates) {
|
|
|
+ generateCodeNew(result, template, bindingMap);
|
|
|
+ }
|
|
|
+ return result;
|
|
|
+ }
|
|
|
|
|
|
private void generateCode(Map<String, String> result, String vmPath,
|
|
|
String filePath, Map<String, Object> bindingMap) {
|
|
@@ -256,7 +354,30 @@ public class CodegenEngine {
|
|
|
content = prettyCode(content);
|
|
|
result.put(filePath, content);
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 生成代码 新增
|
|
|
+ *
|
|
|
+ * @param result 结果
|
|
|
+ * @param templateDO template do
|
|
|
+ * @param bindingMap 绑定映射
|
|
|
+ */
|
|
|
+ private void generateCodeNew(Map<String, String> result, CodegenTempleDO templateDO,
|
|
|
+ Map<String, Object> bindingMap) {
|
|
|
+ String filePath = formatFilePath(templateDO.getTargetPackage() + "/" + templateDO.getFileName(), bindingMap);
|
|
|
+
|
|
|
+ // 创建模板引擎,Hutool默认使用的是Velocity模板引擎,也可以指定其他引擎如Freemarker等
|
|
|
+ TemplateEngine engine = TemplateUtil.createEngine();
|
|
|
+
|
|
|
+ // 将模板字符串包装成StringResource对象,以便模板引擎能够识别并解析
|
|
|
+ Template template = engine.getTemplate(templateDO.getTempleComment());
|
|
|
+ String content = template.render(bindingMap);
|
|
|
+ // 格式化代码
|
|
|
+ content = prettyCode(content);
|
|
|
+ result.put(filePath, content);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
private void generateSubCode(CodegenTableDO table, List<CodegenTableDO> subTables,
|
|
|
Map<String, String> result, String vmPath,
|
|
|
String filePath, Map<String, Object> bindingMap) {
|
|
@@ -423,6 +544,7 @@ public class CodegenEngine {
|
|
|
filePath = StrUtil.replace(filePath, "${table.moduleName}", table.getModuleName());
|
|
|
filePath = StrUtil.replace(filePath, "${table.businessName}", table.getBusinessName());
|
|
|
filePath = StrUtil.replace(filePath, "${table.className}", table.getClassName());
|
|
|
+ filePath = StrUtil.replace(filePath, "${}", table.getClassName());
|
|
|
// 特殊:主子表专属逻辑
|
|
|
Integer subIndex = (Integer) bindingMap.get("subIndex");
|
|
|
if (subIndex != null) {
|
|
@@ -436,76 +558,4 @@ public class CodegenEngine {
|
|
|
return filePath;
|
|
|
}
|
|
|
|
|
|
- private static String javaTemplatePath(String path) {
|
|
|
- return "codegen/java/" + path + ".vm";
|
|
|
- }
|
|
|
-
|
|
|
- private static String javaModuleImplVOFilePath(String path) {
|
|
|
- return javaModuleFilePath("controller/${sceneEnum.basePackage}/${table.businessName}/" +
|
|
|
- "vo/${sceneEnum.prefixClass}${table.className}" + path, "biz", "main");
|
|
|
- }
|
|
|
-
|
|
|
- private static String javaModuleImplControllerFilePath() {
|
|
|
- return javaModuleFilePath("controller/${sceneEnum.basePackage}/${table.businessName}/" +
|
|
|
- "${sceneEnum.prefixClass}${table.className}Controller", "biz", "main");
|
|
|
- }
|
|
|
-
|
|
|
- private static String javaModuleImplMainFilePath(String path) {
|
|
|
- return javaModuleFilePath(path, "biz", "main");
|
|
|
- }
|
|
|
-
|
|
|
- private static String javaModuleApiMainFilePath(String path) {
|
|
|
- return javaModuleFilePath(path, "api", "main");
|
|
|
- }
|
|
|
-
|
|
|
- private static String javaModuleImplTestFilePath(String path) {
|
|
|
- return javaModuleFilePath(path, "biz", "test");
|
|
|
- }
|
|
|
-
|
|
|
- private static String javaModuleFilePath(String path, String module, String src) {
|
|
|
- return "yudao-module-${table.moduleName}/" + // 顶级模块
|
|
|
- "yudao-module-${table.moduleName}-" + module + "/" + // 子模块
|
|
|
- "src/" + src + "/java/${basePackage}/module/${table.moduleName}/" + path + ".java";
|
|
|
- }
|
|
|
-
|
|
|
- private static String mapperXmlFilePath() {
|
|
|
- return "yudao-module-${table.moduleName}/" + // 顶级模块
|
|
|
- "yudao-module-${table.moduleName}-biz/" + // 子模块
|
|
|
- "src/main/resources/mapper/${table.businessName}/${table.className}Mapper.xml";
|
|
|
- }
|
|
|
-
|
|
|
- private static String vueTemplatePath(String path) {
|
|
|
- return "codegen/vue/" + path + ".vm";
|
|
|
- }
|
|
|
-
|
|
|
- private static String vueFilePath(String path) {
|
|
|
- return "yudao-ui-${sceneEnum.basePackage}-vue2/" + // 顶级目录
|
|
|
- "src/" + path;
|
|
|
- }
|
|
|
-
|
|
|
- private static String vue3TemplatePath(String path) {
|
|
|
- return "codegen/vue3/" + path + ".vm";
|
|
|
- }
|
|
|
-
|
|
|
- private static String vue3FilePath(String path) {
|
|
|
- return "yudao-ui-${sceneEnum.basePackage}-vue3/" + // 顶级目录
|
|
|
- "src/" + path;
|
|
|
- }
|
|
|
-
|
|
|
- private static String vue3VbenTemplatePath(String path) {
|
|
|
- return "codegen/vue3_vben/" + path + ".vm";
|
|
|
- }
|
|
|
-
|
|
|
- private static boolean isSubTemplate(String path) {
|
|
|
- return path.contains("_sub");
|
|
|
- }
|
|
|
-
|
|
|
- private static boolean isPageReqVOTemplate(String path) {
|
|
|
- return path.contains("pageReqVO");
|
|
|
- }
|
|
|
-
|
|
|
- private static boolean isListReqVOTemplate(String path) {
|
|
|
- return path.contains("listReqVO");
|
|
|
- }
|
|
|
-
|
|
|
}
|