From 65c4a7a964280f7ff7f19139942f9222f7e90966 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=96=AF=E7=8B=82=E7=9A=84=E7=8B=AE=E5=AD=90Li?= <15040126243@163.com> Date: Wed, 1 Apr 2026 10:07:21 +0800 Subject: [PATCH] =?UTF-8?q?update=20=E9=87=8D=E6=9E=84=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=E7=94=9F=E6=88=90=E5=B7=A5=E5=85=B7=E9=93=BE=EF=BC=8C=E5=A4=8D?= =?UTF-8?q?=E7=94=A8=E4=BB=A3=E7=A0=81=E6=A8=A1=E6=9D=BF=E4=BB=A5=E6=8F=90?= =?UTF-8?q?=E5=8D=87=E4=BB=A3=E7=A0=81=E7=94=9F=E6=88=90=E6=80=A7=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 2 +- .../org/dromara/gen/config/GenConfig.java | 66 ------ .../gen/config/MyBatisDataSourceMonitor.java | 6 + .../gen/config/properties/GenProperties.java | 47 ++++ .../dromara/gen/constant/GenConstants.java | 59 ++++- .../dromara/gen/controller/GenController.java | 43 +++- .../java/org/dromara/gen/domain/GenTable.java | 45 +++- .../dromara/gen/domain/GenTableColumn.java | 109 +++++++++ .../gen/service/GenTableServiceImpl.java | 153 +++++++------ .../dromara/gen/service/IGenTableService.java | 12 +- .../java/org/dromara/gen/util/GenUtils.java | 29 ++- ...ityUtils.java => TemplateEngineUtils.java} | 210 ++++++++++-------- .../dromara/gen/util/VelocityInitializer.java | 35 --- .../gen/util/template/PathNamedTemplate.java | 68 ++++++ 14 files changed, 592 insertions(+), 292 deletions(-) delete mode 100644 ruoyi-modules/ruoyi-gen/src/main/java/org/dromara/gen/config/GenConfig.java create mode 100644 ruoyi-modules/ruoyi-gen/src/main/java/org/dromara/gen/config/properties/GenProperties.java rename ruoyi-modules/ruoyi-gen/src/main/java/org/dromara/gen/util/{VelocityUtils.java => TemplateEngineUtils.java} (64%) delete mode 100644 ruoyi-modules/ruoyi-gen/src/main/java/org/dromara/gen/util/VelocityInitializer.java create mode 100644 ruoyi-modules/ruoyi-gen/src/main/java/org/dromara/gen/util/template/PathNamedTemplate.java diff --git a/pom.xml b/pom.xml index cf6a4898e..7bcc5326c 100644 --- a/pom.xml +++ b/pom.xml @@ -25,7 +25,7 @@ 1.5.6 3.9.1 4.5.0 - 2.3 + 2.4.1 2.2.41 3.0.2 0.15.0 diff --git a/ruoyi-modules/ruoyi-gen/src/main/java/org/dromara/gen/config/GenConfig.java b/ruoyi-modules/ruoyi-gen/src/main/java/org/dromara/gen/config/GenConfig.java deleted file mode 100644 index 4b4fd16ce..000000000 --- a/ruoyi-modules/ruoyi-gen/src/main/java/org/dromara/gen/config/GenConfig.java +++ /dev/null @@ -1,66 +0,0 @@ -package org.dromara.gen.config; - -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.stereotype.Component; - -/** - * 代码生成相关配置 - * - * @author ruoyi - */ -@Component -@ConfigurationProperties(prefix = "gen") -public class GenConfig { - - /** - * 作者 - */ - public static String author; - - /** - * 生成包路径 - */ - public static String packageName; - - /** - * 自动去除表前缀,默认是false - */ - public static boolean autoRemovePre; - - /** - * 表前缀(类名不会包含表前缀) - */ - public static String tablePrefix; - - public static String getAuthor() { - return author; - } - - public void setAuthor(String author) { - GenConfig.author = author; - } - - public static String getPackageName() { - return packageName; - } - - public void setPackageName(String packageName) { - GenConfig.packageName = packageName; - } - - public static boolean getAutoRemovePre() { - return autoRemovePre; - } - - public void setAutoRemovePre(boolean autoRemovePre) { - GenConfig.autoRemovePre = autoRemovePre; - } - - public static String getTablePrefix() { - return tablePrefix; - } - - public void setTablePrefix(String tablePrefix) { - GenConfig.tablePrefix = tablePrefix; - } -} diff --git a/ruoyi-modules/ruoyi-gen/src/main/java/org/dromara/gen/config/MyBatisDataSourceMonitor.java b/ruoyi-modules/ruoyi-gen/src/main/java/org/dromara/gen/config/MyBatisDataSourceMonitor.java index f9deedbfa..6ddcc8985 100644 --- a/ruoyi-modules/ruoyi-gen/src/main/java/org/dromara/gen/config/MyBatisDataSourceMonitor.java +++ b/ruoyi-modules/ruoyi-gen/src/main/java/org/dromara/gen/config/MyBatisDataSourceMonitor.java @@ -25,6 +25,9 @@ import java.util.Map; @Component public class MyBatisDataSourceMonitor implements DataSourceMonitor { + /** + * 初始化 anyline 与动态数据源联动所需的元数据解析策略。 + */ public MyBatisDataSourceMonitor() { // 调整执行模式为自定义 ConfigTable.KEEP_ADAPTER = 2; @@ -72,6 +75,8 @@ public class MyBatisDataSourceMonitor implements DataSourceMonitor { /** * 数据源唯一标识 如果不实现则默认feature + * + * @param runtime 数据运行时上下文 * @param datasource 数据源 * @return String 返回null由上层自动提取 */ @@ -90,6 +95,7 @@ public class MyBatisDataSourceMonitor implements DataSourceMonitor { * ConfigTable.KEEP_ADAPTER=2 : 根据当前接口判断是否保持同一个数据源绑定同一个adapter
* DynamicRoutingDataSource类型的返回false,因为同一个DynamicRoutingDataSource可能对应多类数据库, 如果项目中只有一种数据库 应该直接返回true * + * @param runtime 数据运行时上下文 * @param datasource 数据源 * @return boolean */ diff --git a/ruoyi-modules/ruoyi-gen/src/main/java/org/dromara/gen/config/properties/GenProperties.java b/ruoyi-modules/ruoyi-gen/src/main/java/org/dromara/gen/config/properties/GenProperties.java new file mode 100644 index 000000000..eba7a9a14 --- /dev/null +++ b/ruoyi-modules/ruoyi-gen/src/main/java/org/dromara/gen/config/properties/GenProperties.java @@ -0,0 +1,47 @@ +package org.dromara.gen.config.properties; + +import cn.hutool.extra.template.TemplateConfig; +import lombok.Data; +import org.dromara.common.core.factory.YmlPropertySourceFactory; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.PropertySource; +import org.springframework.stereotype.Component; + +import java.nio.charset.StandardCharsets; + +/** + * 代码生成配置属性 + * + * @author 秋辞未寒 + */ +@Data +@Component +@ConfigurationProperties(prefix = "gen") +public class GenProperties { + + /** + * 作者 + */ + private String author; + + /** + * 生成包路径 + */ + private String packageName; + + /** + * 自动去除表前缀,默认是false + */ + private boolean autoRemovePre = false; + + /** + * 表前缀(类名不会包含表前缀) + */ + private String tablePrefix; + + /** + * 模板配置 + */ + private TemplateConfig templateConfig = new TemplateConfig(StandardCharsets.UTF_8, null, TemplateConfig.ResourceMode.CLASSPATH); + +} diff --git a/ruoyi-modules/ruoyi-gen/src/main/java/org/dromara/gen/constant/GenConstants.java b/ruoyi-modules/ruoyi-gen/src/main/java/org/dromara/gen/constant/GenConstants.java index 036252714..08d3a4e7d 100644 --- a/ruoyi-modules/ruoyi-gen/src/main/java/org/dromara/gen/constant/GenConstants.java +++ b/ruoyi-modules/ruoyi-gen/src/main/java/org/dromara/gen/constant/GenConstants.java @@ -1,5 +1,9 @@ package org.dromara.gen.constant; +import cn.hutool.core.collection.CollUtil; + +import java.util.Set; + /** * 代码生成通用常量 * @@ -69,25 +73,25 @@ public interface GenConstants { * BO对象 不需要添加字段 */ String[] COLUMNNAME_NOT_ADD = {"create_dept", "create_by", "create_time", "del_flag", "update_by", - "update_time", "version", "tenant_id"}; + "update_time", "version"}; /** * BO对象 不需要编辑字段 */ String[] COLUMNNAME_NOT_EDIT = {"create_dept", "create_by", "create_time", "del_flag", "update_by", - "update_time", "version", "tenant_id"}; + "update_time", "version"}; /** * VO对象 不需要返回字段 */ String[] COLUMNNAME_NOT_LIST = {"create_dept", "create_by", "create_time", "del_flag", "update_by", - "update_time", "version", "tenant_id"}; + "update_time", "version"}; /** * BO对象 不需要查询字段 */ String[] COLUMNNAME_NOT_QUERY = {"id", "create_dept", "create_by", "create_time", "del_flag", "update_by", - "update_time", "remark", "version", "tenant_id"}; + "update_time", "remark", "version"}; /** * Entity基类字段 @@ -178,14 +182,57 @@ public interface GenConstants { * 相等查询 */ String QUERY_EQ = "EQ"; - /** * 范围查询 */ String QUERY_BETWEEN = "BETWEEN"; /** - * 需要 + * 必填标识,对应前端表单规则中的必填字段配置。 */ String REQUIRE = "1"; + + // 后端源码模板 + String JAVA_DOMAIN_TEMPLATE_PATH = "vm/java/domain.java.vm"; + String JAVA_VO_TEMPLATE_PATH = "vm/java/vo.java.vm"; + String JAVA_BO_TEMPLATE_PATH = "vm/java/bo.java.vm"; + String JAVA_MAPPER_TEMPLATE_PATH = "vm/java/mapper.java.vm"; + String JAVA_SERVICE_TEMPLATE_PATH = "vm/java/service.java.vm"; + String JAVA_SERVICE_IMPL_TEMPLATE_PATH = "vm/java/serviceImpl.java.vm"; + String JAVA_CONTROLLER_TEMPLATE_PATH = "vm/java/controller.java.vm"; + // MyBatis MapperXML 模板 + String XML_MAPPER_TEMPLATE_PATH = "vm/xml/mapper.xml.vm"; + // 前端接口源码模板 + String TS_API_TEMPLATE_PATH = "vm/ts/api.ts.vm"; + String TS_TYPES_TEMPLATE_PATH = "vm/ts/types.ts.vm"; + // 前端页面源码模板 + String VUE_INDEX_TEMPLATE_PATH = "vm/vue/index.vue.vm"; + String VUE_INDEX_TREE_TEMPLATE_PATH = "vm/vue/index-tree.vue.vm"; + // 数据库SQL模板 + String SQL_ORACLE_TEMPLATE_PATH = "vm/sql/oracle.sql.vm"; + String SQL_POSTGRES_TEMPLATE_PATH = "vm/sql/postgres.sql.vm"; + String SQL_SQLSERVER_TEMPLATE_PATH = "vm/sql/sqlserver.sql.vm"; + String SQL_MYSQL_TEMPLATE_PATH = "vm/sql/mysql.sql.vm"; + + /** + * 所有模板路径集合 + */ + Set TEMPLATE_PATHS = CollUtil.newHashSet( + JAVA_DOMAIN_TEMPLATE_PATH + , JAVA_VO_TEMPLATE_PATH + , JAVA_BO_TEMPLATE_PATH + , JAVA_MAPPER_TEMPLATE_PATH + , JAVA_SERVICE_TEMPLATE_PATH + , JAVA_SERVICE_IMPL_TEMPLATE_PATH + , JAVA_CONTROLLER_TEMPLATE_PATH + , XML_MAPPER_TEMPLATE_PATH + , TS_API_TEMPLATE_PATH + , TS_TYPES_TEMPLATE_PATH + , VUE_INDEX_TEMPLATE_PATH + , VUE_INDEX_TREE_TEMPLATE_PATH + , SQL_ORACLE_TEMPLATE_PATH + , SQL_POSTGRES_TEMPLATE_PATH + , SQL_SQLSERVER_TEMPLATE_PATH + , SQL_MYSQL_TEMPLATE_PATH + ); } diff --git a/ruoyi-modules/ruoyi-gen/src/main/java/org/dromara/gen/controller/GenController.java b/ruoyi-modules/ruoyi-gen/src/main/java/org/dromara/gen/controller/GenController.java index 83df74d9e..3b5c1e1c4 100644 --- a/ruoyi-modules/ruoyi-gen/src/main/java/org/dromara/gen/controller/GenController.java +++ b/ruoyi-modules/ruoyi-gen/src/main/java/org/dromara/gen/controller/GenController.java @@ -6,13 +6,13 @@ import cn.hutool.core.io.IoUtil; import com.baomidou.lock.annotation.Lock4j; import jakarta.servlet.http.HttpServletResponse; import lombok.RequiredArgsConstructor; +import org.dromara.common.core.domain.PageResult; import org.dromara.common.core.domain.R; -import org.dromara.common.redis.annotation.RepeatSubmit; import org.dromara.common.log.annotation.Log; import org.dromara.common.log.enums.BusinessType; import org.dromara.common.mybatis.core.page.PageQuery; -import org.dromara.common.core.domain.PageResult; import org.dromara.common.mybatis.helper.DataBaseHelper; +import org.dromara.common.redis.annotation.RepeatSubmit; import org.dromara.common.web.core.BaseController; import org.dromara.gen.domain.GenTable; import org.dromara.gen.domain.GenTableColumn; @@ -39,7 +39,11 @@ public class GenController extends BaseController { private final IGenTableService genTableService; /** - * 查询代码生成列表 + * 分页查询代码生成业务列表。 + * + * @param genTable 查询条件 + * @param pageQuery 分页参数 + * @return 代码生成列表 */ @SaCheckPermission("tool:gen:list") @GetMapping("/list") @@ -51,6 +55,7 @@ public class GenController extends BaseController { * 修改代码生成业务 * * @param tableId 表ID + * @return 表、字段与可选业务表信息 */ @RepeatSubmit() @SaCheckPermission("tool:gen:query") @@ -67,7 +72,11 @@ public class GenController extends BaseController { } /** - * 查询数据库列表 + * 分页查询数据库表列表。 + * + * @param genTable 查询条件 + * @param pageQuery 分页参数 + * @return 数据库表列表 */ @SaCheckPermission("tool:gen:list") @GetMapping("/db/list") @@ -79,6 +88,7 @@ public class GenController extends BaseController { * 查询数据表字段列表 * * @param tableId 表ID + * @return 字段列表 */ @SaCheckPermission("tool:gen:list") @GetMapping(value = "/column/{tableId}") @@ -90,8 +100,9 @@ public class GenController extends BaseController { /** * 导入表结构(保存) * - * @param tables 表名串 + * @param tables 表名串 * @param dataName 数据源名称 + * @return 操作结果 */ @SaCheckPermission("tool:gen:import") @Log(title = "代码生成", businessType = BusinessType.IMPORT) @@ -107,7 +118,10 @@ public class GenController extends BaseController { } /** - * 修改保存代码生成业务 + * 保存代码生成业务配置。 + * + * @param genTable 业务配置 + * @return 操作结果 */ @SaCheckPermission("tool:gen:edit") @Log(title = "代码生成", businessType = BusinessType.UPDATE) @@ -123,6 +137,7 @@ public class GenController extends BaseController { * 删除代码生成 * * @param tableIds 表ID串 + * @return 操作结果 */ @SaCheckPermission("tool:gen:remove") @Log(title = "代码生成", businessType = BusinessType.DELETE) @@ -136,6 +151,7 @@ public class GenController extends BaseController { * 预览代码 * * @param tableId 表ID + * @return 模板路径与生成代码内容映射 */ @SaCheckPermission("tool:gen:preview") @GetMapping("/preview/{tableId}") @@ -147,6 +163,7 @@ public class GenController extends BaseController { /** * 生成代码(下载方式) * + * @param response HTTP 响应 * @param tableId 表ID */ @SaCheckPermission("tool:gen:code") @@ -161,6 +178,7 @@ public class GenController extends BaseController { * 生成代码(自定义路径) * * @param tableId 表ID + * @return 操作结果 */ @SaCheckPermission("tool:gen:code") @Log(title = "代码生成", businessType = BusinessType.GENCODE) @@ -174,6 +192,7 @@ public class GenController extends BaseController { * 同步数据库 * * @param tableId 表ID + * @return 操作结果 */ @SaCheckPermission("tool:gen:edit") @Log(title = "代码生成", businessType = BusinessType.UPDATE) @@ -187,6 +206,7 @@ public class GenController extends BaseController { /** * 批量生成代码 * + * @param response HTTP 响应 * @param tableIdStr 表ID串 */ @SaCheckPermission("tool:gen:code") @@ -199,7 +219,10 @@ public class GenController extends BaseController { } /** - * 生成zip文件 + * 将生成结果写出为 zip 文件流。 + * + * @param response HTTP 响应 + * @param data zip 二进制数据 */ private void genCode(HttpServletResponse response, byte[] data) throws IOException { response.reset(); @@ -212,11 +235,13 @@ public class GenController extends BaseController { } /** - * 查询数据源名称列表 + * 查询当前可用数据源名称列表。 + * + * @return 数据源名称集合 */ @SaCheckPermission("tool:gen:list") @GetMapping(value = "/getDataNames") - public R getCurrentDataSourceNameList(){ + public R getCurrentDataSourceNameList() { return R.ok(DataBaseHelper.getDataSourceNameList()); } } diff --git a/ruoyi-modules/ruoyi-gen/src/main/java/org/dromara/gen/domain/GenTable.java b/ruoyi-modules/ruoyi-gen/src/main/java/org/dromara/gen/domain/GenTable.java index cc2847898..fbfc3771e 100644 --- a/ruoyi-modules/ruoyi-gen/src/main/java/org/dromara/gen/domain/GenTable.java +++ b/ruoyi-modules/ruoyi-gen/src/main/java/org/dromara/gen/domain/GenTable.java @@ -12,7 +12,9 @@ import org.dromara.common.core.utils.StringUtils; import org.dromara.common.mybatis.core.domain.BaseEntity; import org.dromara.gen.constant.GenConstants; +import java.util.HashMap; import java.util.List; +import java.util.Map; /** * 业务表 gen_table @@ -152,7 +154,7 @@ public class GenTable extends BaseEntity { @TableField(exist = false) private String treeName; - /* + /** * 菜单id列表 */ @TableField(exist = false) @@ -170,26 +172,67 @@ public class GenTable extends BaseEntity { @TableField(exist = false) private String parentMenuName; + /** + * 请求参数 + */ + @TableField(exist = false) + private Map params = new HashMap<>(); + + /** + * 判断当前业务表是否采用树表模板。 + * + * @return 树表模板返回 {@code true} + */ public boolean isTree() { return isTree(this.tplCategory); } + /** + * 根据模板分类判断是否为树表模板。 + * + * @param tplCategory 模板分类 + * @return 树表模板返回 {@code true} + */ public static boolean isTree(String tplCategory) { return tplCategory != null && StringUtils.equals(GenConstants.TPL_TREE, tplCategory); } + /** + * 判断当前业务表是否采用普通 CRUD 模板。 + * + * @return 普通 CRUD 模板返回 {@code true} + */ public boolean isCrud() { return isCrud(this.tplCategory); } + /** + * 根据模板分类判断是否为普通 CRUD 模板。 + * + * @param tplCategory 模板分类 + * @return 普通 CRUD 模板返回 {@code true} + */ public static boolean isCrud(String tplCategory) { return tplCategory != null && StringUtils.equals(GenConstants.TPL_CRUD, tplCategory); } + /** + * 判断指定 Java 字段是否属于基类公共字段。 + * + * @param javaField Java 字段名 + * @return 基类公共字段返回 {@code true} + */ public boolean isSuperColumn(String javaField) { return isSuperColumn(this.tplCategory, javaField); } + /** + * 根据模板分类与字段名判断是否属于基类公共字段。 + * + * @param tplCategory 模板分类 + * @param javaField Java 字段名 + * @return 基类公共字段返回 {@code true} + */ public static boolean isSuperColumn(String tplCategory, String javaField) { return StringUtils.equalsAnyIgnoreCase(javaField, GenConstants.BASE_ENTITY); } diff --git a/ruoyi-modules/ruoyi-gen/src/main/java/org/dromara/gen/domain/GenTableColumn.java b/ruoyi-modules/ruoyi-gen/src/main/java/org/dromara/gen/domain/GenTableColumn.java index 4a79f39a8..eed90061f 100644 --- a/ruoyi-modules/ruoyi-gen/src/main/java/org/dromara/gen/domain/GenTableColumn.java +++ b/ruoyi-modules/ruoyi-gen/src/main/java/org/dromara/gen/domain/GenTableColumn.java @@ -122,70 +122,163 @@ public class GenTableColumn extends BaseEntity { */ private Integer sort; + /** + * 获取首字母大写后的 Java 字段名。 + * + * @return 首字母大写的 Java 字段名 + */ public String getCapJavaField() { return StringUtils.capitalize(javaField); } + /** + * 判断当前列是否为主键列。 + * + * @return 主键列返回 {@code true} + */ public boolean isPk() { return isPk(this.isPk); } + /** + * 根据标识判断是否为主键列。 + * + * @param isPk 主键标识 + * @return 主键列返回 {@code true} + */ public boolean isPk(String isPk) { return isPk != null && StringUtils.equals("1", isPk); } + /** + * 判断当前列是否为自增列。 + * + * @return 自增列返回 {@code true} + */ public boolean isIncrement() { return isIncrement(this.isIncrement); } + /** + * 根据标识判断是否为自增列。 + * + * @param isIncrement 自增标识 + * @return 自增列返回 {@code true} + */ public boolean isIncrement(String isIncrement) { return isIncrement != null && StringUtils.equals("1", isIncrement); } + /** + * 判断当前列是否必填。 + * + * @return 必填返回 {@code true} + */ public boolean isRequired() { return isRequired(this.isRequired); } + /** + * 根据标识判断当前列是否必填。 + * + * @param isRequired 必填标识 + * @return 必填返回 {@code true} + */ public boolean isRequired(String isRequired) { return isRequired != null && StringUtils.equals("1", isRequired); } + /** + * 判断当前列是否参与新增。 + * + * @return 参与新增返回 {@code true} + */ public boolean isInsert() { return isInsert(this.isInsert); } + /** + * 根据标识判断当前列是否参与新增。 + * + * @param isInsert 新增标识 + * @return 参与新增返回 {@code true} + */ public boolean isInsert(String isInsert) { return isInsert != null && StringUtils.equals("1", isInsert); } + /** + * 判断当前列是否参与编辑。 + * + * @return 参与编辑返回 {@code true} + */ public boolean isEdit() { return isEdit(this.isEdit); } + /** + * 根据标识判断当前列是否参与编辑。 + * + * @param isEdit 编辑标识 + * @return 参与编辑返回 {@code true} + */ public boolean isEdit(String isEdit) { return isEdit != null && StringUtils.equals("1", isEdit); } + /** + * 判断当前列是否参与列表展示。 + * + * @return 参与列表展示返回 {@code true} + */ public boolean isList() { return isList(this.isList); } + /** + * 根据标识判断当前列是否参与列表展示。 + * + * @param isList 列表展示标识 + * @return 参与列表展示返回 {@code true} + */ public boolean isList(String isList) { return isList != null && StringUtils.equals("1", isList); } + /** + * 判断当前列是否参与查询条件。 + * + * @return 参与查询返回 {@code true} + */ public boolean isQuery() { return isQuery(this.isQuery); } + /** + * 根据标识判断当前列是否参与查询条件。 + * + * @param isQuery 查询标识 + * @return 参与查询返回 {@code true} + */ public boolean isQuery(String isQuery) { return isQuery != null && StringUtils.equals("1", isQuery); } + /** + * 判断当前列是否为基类公共字段。 + * + * @return 基类公共字段返回 {@code true} + */ public boolean isSuperColumn() { return isSuperColumn(this.javaField); } + /** + * 根据字段名判断是否为基类公共字段。 + * + * @param javaField Java 字段名 + * @return 基类公共字段返回 {@code true} + */ public static boolean isSuperColumn(String javaField) { return StringUtils.equalsAnyIgnoreCase(javaField, // BaseEntity @@ -194,15 +287,31 @@ public class GenTableColumn extends BaseEntity { "parentName", "parentId"); } + /** + * 判断当前列是否属于生成页面需要保留的白名单字段。 + * + * @return 白名单字段返回 {@code true} + */ public boolean isUsableColumn() { return isUsableColumn(javaField); } + /** + * 根据字段名判断是否属于生成页面需要保留的白名单字段。 + * + * @param javaField Java 字段名 + * @return 白名单字段返回 {@code true} + */ public static boolean isUsableColumn(String javaField) { // isSuperColumn()中的名单用于避免生成多余Domain属性,若某些属性在生成页面时需要用到不能忽略,则放在此处白名单 return StringUtils.equalsAnyIgnoreCase(javaField, "parentId", "orderNum", "remark"); } + /** + * 从字段注释中解析字典读转换表达式。 + * + * @return 形如 `0=男,1=女` 的转换表达式,无法解析时返回原始注释 + */ public String readConverterExp() { String remarks = StringUtils.substringBetween(this.columnComment, "(", ")"); StringBuffer sb = new StringBuffer(); diff --git a/ruoyi-modules/ruoyi-gen/src/main/java/org/dromara/gen/service/GenTableServiceImpl.java b/ruoyi-modules/ruoyi-gen/src/main/java/org/dromara/gen/service/GenTableServiceImpl.java index 5b26a11c1..9857fa987 100644 --- a/ruoyi-modules/ruoyi-gen/src/main/java/org/dromara/gen/service/GenTableServiceImpl.java +++ b/ruoyi-modules/ruoyi-gen/src/main/java/org/dromara/gen/service/GenTableServiceImpl.java @@ -15,10 +15,7 @@ import lombok.extern.slf4j.Slf4j; import org.anyline.metadata.Column; import org.anyline.metadata.Table; import org.anyline.proxy.ServiceProxy; -import org.apache.velocity.Template; -import org.apache.velocity.VelocityContext; -import org.apache.velocity.app.Velocity; -import org.dromara.common.core.constant.Constants; +import org.dromara.common.core.domain.PageResult; import org.dromara.common.core.exception.ServiceException; import org.dromara.common.core.utils.SpringUtils; import org.dromara.common.core.utils.StreamUtils; @@ -26,7 +23,6 @@ import org.dromara.common.core.utils.StringUtils; import org.dromara.common.core.utils.file.FileUtils; import org.dromara.common.json.utils.JsonUtils; import org.dromara.common.mybatis.core.page.PageQuery; -import org.dromara.common.core.domain.PageResult; import org.dromara.common.mybatis.utils.IdGeneratorUtil; import org.dromara.gen.constant.GenConstants; import org.dromara.gen.domain.GenTable; @@ -34,15 +30,14 @@ import org.dromara.gen.domain.GenTableColumn; import org.dromara.gen.mapper.GenTableColumnMapper; import org.dromara.gen.mapper.GenTableMapper; import org.dromara.gen.util.GenUtils; -import org.dromara.gen.util.VelocityInitializer; -import org.dromara.gen.util.VelocityUtils; +import org.dromara.gen.util.TemplateEngineUtils; +import org.dromara.gen.util.template.PathNamedTemplate; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; -import java.io.StringWriter; import java.nio.charset.StandardCharsets; import java.util.*; import java.util.zip.ZipEntry; @@ -61,7 +56,7 @@ public class GenTableServiceImpl implements IGenTableService { private final GenTableMapper baseMapper; private final GenTableColumnMapper genTableColumnMapper; - private static final String[] TABLE_IGNORE = new String[]{"sj_", "act_", "flw_", "gen_"}; + private static final String[] TABLE_IGNORE = new String[]{"sj_", "flow_", "gen_"}; /** * 查询业务字段列表 @@ -89,12 +84,25 @@ public class GenTableServiceImpl implements IGenTableService { return genTable; } + /** + * 分页查询已导入的代码生成业务表。 + * + * @param genTable 业务表筛选条件 + * @param pageQuery 分页参数 + * @return 业务表分页结果 + */ @Override public PageResult selectPageGenTableList(GenTable genTable, PageQuery pageQuery) { Page page = baseMapper.selectPage(pageQuery.build(), this.buildGenTableQueryWrapper(genTable)); return PageResult.build(page.getRecords(), page.getTotal()); } + /** + * 构造代码生成业务表查询条件。 + * + * @param genTable 业务表筛选条件 + * @return 包含数据源、表名、表注释和时间区间的查询包装器 + */ private QueryWrapper buildGenTableQueryWrapper(GenTable genTable) { Map params = genTable.getParams(); QueryWrapper wrapper = Wrappers.query(); @@ -113,7 +121,7 @@ public class GenTableServiceImpl implements IGenTableService { * * @param genTable 包含查询条件的GenTable对象 * @param pageQuery 包含分页信息的PageQuery对象 - * @return 包含分页结果的 PageResult 对象 + * @return 包含分页结果的TableDataInfo对象 */ @DS("#genTable.dataName") @Override @@ -166,6 +174,10 @@ public class GenTableServiceImpl implements IGenTableService { return gen; }).sorted(Comparator.comparing(GenTable::getCreateTime).reversed()) .toList(); + // 根据原始数据列表和分页参数,构建表格分页数据对象(用于假分页) + if (CollUtil.isEmpty(tables)) { + return PageResult.build(); + } Page page = pageQuery.build(); List pageList = CollUtil.page((int) page.getCurrent() - 1, (int) page.getSize(), tables); return PageResult.build(pageList, tables.size()); @@ -229,9 +241,7 @@ public class GenTableServiceImpl implements IGenTableService { genTable.setOptions(options); int row = baseMapper.updateById(genTable); if (row > 0) { - for (GenTableColumn cenTableColumn : genTable.getColumns()) { - genTableColumnMapper.updateById(cenTableColumn); - } + genTableColumnMapper.updateBatchById(genTable.getColumns()); } } @@ -277,6 +287,7 @@ public class GenTableServiceImpl implements IGenTableService { } } } catch (Exception e) { + log.error("导入失败", e); throw new ServiceException("导入失败:" + e.getMessage()); } } @@ -320,27 +331,9 @@ public class GenTableServiceImpl implements IGenTableService { @Override public Map previewCode(Long tableId) { Map dataMap = new LinkedHashMap<>(); - // 查询表信息 - GenTable table = getGenTable(tableId); - List menuIds = new ArrayList<>(); - for (int i = 0; i < 6; i++) { - menuIds.add(IdGeneratorUtil.nextLongId()); - } - table.setMenuIds(menuIds); - // 设置主键列信息 - setPkColumn(table); - VelocityInitializer.initVelocity(); - - VelocityContext context = VelocityUtils.prepareContext(table); - - // 获取模板列表 - List templates = VelocityUtils.getTemplateList(table.getTplCategory()); - for (String template : templates) { - // 渲染模板 - StringWriter sw = new StringWriter(); - Template tpl = Velocity.getTemplate(template, Constants.UTF8); - tpl.merge(context, sw); - dataMap.put(template, sw.toString()); + RenderContext rc = buildRenderContext(tableId); + for (PathNamedTemplate template : rc.templates()) { + dataMap.put(template.getPathName(), template.render(rc.context())); } return dataMap; } @@ -372,21 +365,18 @@ public class GenTableServiceImpl implements IGenTableService { // 设置主键列信息 setPkColumn(table); - VelocityInitializer.initVelocity(); - - VelocityContext context = VelocityUtils.prepareContext(table); - + Dict context = TemplateEngineUtils.buildContext(table); // 获取模板列表 - List templates = VelocityUtils.getTemplateList(table.getTplCategory()); - for (String template : templates) { - if (!StringUtils.containsAny(template, "sql.vm", "api.ts.vm", "types.ts.vm", "index.vue.vm", "index-tree.vue.vm")) { + List templates = TemplateEngineUtils.getTemplateList(table.getTplCategory()); + for (PathNamedTemplate template : templates) { + String pathName = template.getPathName(); + // 渲染模板 + if (!StringUtils.containsAny(pathName, "sql.vm", "api.ts.vm", "types.ts.vm", "index.vue.vm", "index-tree.vue.vm")) { // 渲染模板 - StringWriter sw = new StringWriter(); - Template tpl = Velocity.getTemplate(template, Constants.UTF8); - tpl.merge(context, sw); try { - String path = getGenPath(table, template); - FileUtils.writeUtf8String(sw.toString(), path); + String render = template.render(context); + String path = getGenPath(table, pathName); + FileUtils.writeUtf8String(render, path); } catch (Exception e) { throw new ServiceException("渲染模板失败,表名:" + table.getTableName()); } @@ -464,40 +454,47 @@ public class GenTableServiceImpl implements IGenTableService { /** * 查询表信息并生成代码 + * + * @param tableId 业务表主键 + * @param zip 代码压缩输出流 */ private void generatorCode(Long tableId, ZipOutputStream zip) { - // 查询表信息 + RenderContext rc = buildRenderContext(tableId); + GenTable table = rc.table(); + for (PathNamedTemplate template : rc.templates()) { + String pathName = template.getPathName(); + try { + String render = template.render(rc.context()); + zip.putNextEntry(new ZipEntry(TemplateEngineUtils.getFileName(pathName, table))); + IoUtil.write(zip, StandardCharsets.UTF_8, false, render); + zip.flush(); + zip.closeEntry(); + } catch (IOException e) { + log.error("渲染模板失败,表名:{}", table.getTableName(), e); + } + } + } + + /** + * 构建代码渲染上下文(含表信息、菜单ID、主键列、模板列表) + * + * @param tableId 业务表主键 + * @return 渲染上下文 + */ + private RenderContext buildRenderContext(Long tableId) { GenTable table = getGenTable(tableId); List menuIds = new ArrayList<>(); for (int i = 0; i < 6; i++) { menuIds.add(IdGeneratorUtil.nextLongId()); } table.setMenuIds(menuIds); - // 设置主键列信息 setPkColumn(table); + Dict context = TemplateEngineUtils.buildContext(table); + List templates = TemplateEngineUtils.getTemplateList(table.getTplCategory()); + return new RenderContext(table, context, templates); + } - VelocityInitializer.initVelocity(); - - VelocityContext context = VelocityUtils.prepareContext(table); - - // 获取模板列表 - List templates = VelocityUtils.getTemplateList(table.getTplCategory()); - for (String template : templates) { - // 渲染模板 - StringWriter sw = new StringWriter(); - Template tpl = Velocity.getTemplate(template, Constants.UTF8); - tpl.merge(context, sw); - try { - // 添加到zip - zip.putNextEntry(new ZipEntry(VelocityUtils.getFileName(template, table))); - IoUtil.write(zip, StandardCharsets.UTF_8, false, sw.toString()); - IoUtil.close(sw); - zip.flush(); - zip.closeEntry(); - } catch (IOException e) { - log.error("渲染模板失败,表名:" + table.getTableName(), e); - } - } + private record RenderContext(GenTable table, Dict context, List templates) { } /** @@ -520,6 +517,12 @@ public class GenTableServiceImpl implements IGenTableService { } } + /** + * 查询业务表并补齐其列信息。 + * + * @param tableId 业务表主键 + * @return 包含字段集合的业务表实体 + */ private GenTable getGenTable(Long tableId) { GenTable table = baseMapper.selectById(tableId); if (ObjectUtil.isNull(table)) { @@ -529,6 +532,12 @@ public class GenTableServiceImpl implements IGenTableService { return table; } + /** + * 批量填充业务表对应的字段列表。 + * + * @param tables 业务表集合 + * @return 已填充字段信息的业务表集合 + */ private List fillTableColumns(List tables) { if (CollUtil.isEmpty(tables)) { return tables; @@ -596,9 +605,9 @@ public class GenTableServiceImpl implements IGenTableService { public static String getGenPath(GenTable table, String template) { String genPath = table.getGenPath(); if (StringUtils.equals(genPath, "/")) { - return System.getProperty("user.dir") + File.separator + "src" + File.separator + VelocityUtils.getFileName(template, table); + return System.getProperty("user.dir") + File.separator + "src" + File.separator + TemplateEngineUtils.getFileName(template, table); } - return genPath + File.separator + VelocityUtils.getFileName(template, table); + return genPath + File.separator + TemplateEngineUtils.getFileName(template, table); } } diff --git a/ruoyi-modules/ruoyi-gen/src/main/java/org/dromara/gen/service/IGenTableService.java b/ruoyi-modules/ruoyi-gen/src/main/java/org/dromara/gen/service/IGenTableService.java index 36dc4dee3..1dcc16a8a 100644 --- a/ruoyi-modules/ruoyi-gen/src/main/java/org/dromara/gen/service/IGenTableService.java +++ b/ruoyi-modules/ruoyi-gen/src/main/java/org/dromara/gen/service/IGenTableService.java @@ -1,7 +1,7 @@ package org.dromara.gen.service; -import org.dromara.common.mybatis.core.page.PageQuery; import org.dromara.common.core.domain.PageResult; +import org.dromara.common.mybatis.core.page.PageQuery; import org.dromara.gen.domain.GenTable; import org.dromara.gen.domain.GenTableColumn; @@ -26,16 +26,18 @@ public interface IGenTableService { /** * 查询业务列表 * - * @param genTable 业务信息 - * @return 业务集合 + * @param genTable 业务信息 + * @param pageQuery 分页参数 + * @return 业务分页集合 */ PageResult selectPageGenTableList(GenTable genTable, PageQuery pageQuery); /** * 查询据库列表 * - * @param genTable 业务信息 - * @return 数据库表集合 + * @param genTable 业务信息 + * @param pageQuery 分页参数 + * @return 数据库表分页集合 */ PageResult selectPageDbTableList(GenTable genTable, PageQuery pageQuery); diff --git a/ruoyi-modules/ruoyi-gen/src/main/java/org/dromara/gen/util/GenUtils.java b/ruoyi-modules/ruoyi-gen/src/main/java/org/dromara/gen/util/GenUtils.java index 2d8054ee0..27faa9799 100644 --- a/ruoyi-modules/ruoyi-gen/src/main/java/org/dromara/gen/util/GenUtils.java +++ b/ruoyi-modules/ruoyi-gen/src/main/java/org/dromara/gen/util/GenUtils.java @@ -3,8 +3,9 @@ package org.dromara.gen.util; import lombok.AccessLevel; import lombok.NoArgsConstructor; import org.apache.commons.lang3.RegExUtils; +import org.dromara.common.core.utils.SpringUtils; import org.dromara.common.core.utils.StringUtils; -import org.dromara.gen.config.GenConfig; +import org.dromara.gen.config.properties.GenProperties; import org.dromara.gen.constant.GenConstants; import org.dromara.gen.domain.GenTable; import org.dromara.gen.domain.GenTableColumn; @@ -19,22 +20,29 @@ import java.util.Arrays; @NoArgsConstructor(access = AccessLevel.PRIVATE) public class GenUtils { + private final static GenProperties PROPERTIES = SpringUtils.getBean(GenProperties.class); + /** * 初始化表信息 + * + * @param genTable 待初始化的业务表对象 */ public static void initTable(GenTable genTable) { genTable.setClassName(convertClassName(genTable.getTableName())); - genTable.setPackageName(GenConfig.getPackageName()); - genTable.setModuleName(getModuleName(GenConfig.getPackageName())); + genTable.setPackageName(PROPERTIES.getPackageName()); + genTable.setModuleName(getModuleName(PROPERTIES.getPackageName())); genTable.setBusinessName(getBusinessName(genTable.getTableName())); genTable.setFunctionName(replaceText(genTable.getTableComment())); - genTable.setFunctionAuthor(GenConfig.getAuthor()); + genTable.setFunctionAuthor(PROPERTIES.getAuthor()); genTable.setCreateTime(null); genTable.setUpdateTime(null); } /** * 初始化列属性字段 + * + * @param column 待初始化的列对象 + * @param table 所属业务表对象 */ public static void initColumnField(GenTableColumn column, GenTable table) { String dataType = getDbType(column.getColumnType()); @@ -152,8 +160,8 @@ public class GenUtils { * @return 类名 */ public static String convertClassName(String tableName) { - boolean autoRemovePre = GenConfig.getAutoRemovePre(); - String tablePrefix = GenConfig.getTablePrefix(); + boolean autoRemovePre = PROPERTIES.isAutoRemovePre(); + String tablePrefix = PROPERTIES.getTablePrefix(); if (autoRemovePre && StringUtils.isNotEmpty(tablePrefix)) { String[] searchList = StringUtils.split(tablePrefix, StringUtils.SEPARATOR); tableName = replaceFirst(tableName, searchList); @@ -166,12 +174,13 @@ public class GenUtils { * * @param replacementm 替换值 * @param searchList 替换列表 + * @return 去除命中前缀后的字符串 */ public static String replaceFirst(String replacementm, String[] searchList) { String text = replacementm; for (String searchString : searchList) { if (replacementm.startsWith(searchString)) { - text = replacementm.replaceFirst(searchString, StringUtils.EMPTY); + text = StringUtils.removeStart(replacementm, searchString); break; } } @@ -206,11 +215,15 @@ public class GenUtils { * 获取字段长度 * * @param columnType 列类型 - * @return 截取后的列类型 + * @return 字段长度,未声明长度时返回 0 */ public static Integer getColumnLength(String columnType) { if (StringUtils.indexOf(columnType, "(") > 0) { String length = StringUtils.substringBetween(columnType, "(", ")"); + // 处理 decimal(10,2) 这类带精度的类型,只取长度部分 + if (length.contains(",")) { + length = StringUtils.substringBefore(length, ","); + } return Integer.valueOf(length); } else { return 0; diff --git a/ruoyi-modules/ruoyi-gen/src/main/java/org/dromara/gen/util/VelocityUtils.java b/ruoyi-modules/ruoyi-gen/src/main/java/org/dromara/gen/util/TemplateEngineUtils.java similarity index 64% rename from ruoyi-modules/ruoyi-gen/src/main/java/org/dromara/gen/util/VelocityUtils.java rename to ruoyi-modules/ruoyi-gen/src/main/java/org/dromara/gen/util/TemplateEngineUtils.java index 0d8cc15d6..16e7b9ede 100644 --- a/ruoyi-modules/ruoyi-gen/src/main/java/org/dromara/gen/util/VelocityUtils.java +++ b/ruoyi-modules/ruoyi-gen/src/main/java/org/dromara/gen/util/TemplateEngineUtils.java @@ -3,27 +3,34 @@ package org.dromara.gen.util; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.convert.Convert; import cn.hutool.core.lang.Dict; +import cn.hutool.extra.template.TemplateEngine; +import cn.hutool.extra.template.TemplateUtil; import lombok.AccessLevel; import lombok.NoArgsConstructor; -import org.apache.velocity.VelocityContext; +import lombok.extern.slf4j.Slf4j; import org.dromara.common.core.utils.DateUtils; +import org.dromara.common.core.utils.SpringUtils; import org.dromara.common.core.utils.StringUtils; import org.dromara.common.json.utils.JsonUtils; import org.dromara.common.mybatis.enums.DataBaseType; import org.dromara.common.mybatis.helper.DataBaseHelper; +import org.dromara.gen.config.properties.GenProperties; import org.dromara.gen.constant.GenConstants; import org.dromara.gen.domain.GenTable; import org.dromara.gen.domain.GenTableColumn; +import org.dromara.gen.util.template.PathNamedTemplate; import java.util.*; +import java.util.function.Consumer; + +import static org.dromara.gen.constant.GenConstants.TS_TYPES_TEMPLATE_PATH; /** - * 模板处理工具类 - * - * @author ruoyi + * 模板引擎工具 */ +@Slf4j @NoArgsConstructor(access = AccessLevel.PRIVATE) -public class VelocityUtils { +public class TemplateEngineUtils { /** * 项目空间路径 @@ -40,62 +47,102 @@ public class VelocityUtils { */ private static final String DEFAULT_PARENT_MENU_ID = "3"; + // 模板引擎 + private static final TemplateEngine TEMPLATE_ENGINE; + private static final Map TEMPLATE_MAPPER; + + static { + // 模板引擎初始化 + GenProperties properties = SpringUtils.getBean(GenProperties.class); + TEMPLATE_ENGINE = TemplateUtil.createEngine(properties.getTemplateConfig()); + TEMPLATE_MAPPER = PathNamedTemplate.form(TEMPLATE_ENGINE, GenConstants.TEMPLATE_PATHS); + } + /** - * 设置模板变量信息 + * 构建模板上下文 * - * @return 模板列表 + * @param contextInit 模板上下文初始化函数 + * @return 模板上下文 */ - public static VelocityContext prepareContext(GenTable genTable) { + public static Dict buildContext(Consumer contextInit) { + Dict context = new Dict(); + contextInit.accept(context); + return context; + } + + /** + * 构建模板上下文 + * + * @param genTable 代码生成业务表对象 + * @return 模板上下文 + */ + public static Dict buildContext(GenTable genTable) { + // 构建上下文 + Dict context = new Dict(); String moduleName = genTable.getModuleName(); String businessName = genTable.getBusinessName(); String packageName = genTable.getPackageName(); String tplCategory = genTable.getTplCategory(); String functionName = genTable.getFunctionName(); - VelocityContext velocityContext = new VelocityContext(); - velocityContext.put("tplCategory", genTable.getTplCategory()); - velocityContext.put("tableName", genTable.getTableName()); - velocityContext.put("functionName", StringUtils.isNotEmpty(functionName) ? functionName : "【请填写功能名称】"); - velocityContext.put("ClassName", genTable.getClassName()); - velocityContext.put("className", StringUtils.uncapitalize(genTable.getClassName())); - velocityContext.put("moduleName", genTable.getModuleName()); - velocityContext.put("BusinessName", StringUtils.capitalize(genTable.getBusinessName())); - velocityContext.put("businessName", genTable.getBusinessName()); - velocityContext.put("basePackage", getPackagePrefix(packageName)); - velocityContext.put("packageName", packageName); - velocityContext.put("author", genTable.getFunctionAuthor()); - velocityContext.put("datetime", DateUtils.getDate()); - velocityContext.put("pkColumn", genTable.getPkColumn()); - velocityContext.put("importList", getImportList(genTable)); - velocityContext.put("permissionPrefix", getPermissionPrefix(moduleName, businessName)); - velocityContext.put("columns", genTable.getColumns()); - velocityContext.put("table", genTable); - velocityContext.put("dicts", getDicts(genTable)); - setMenuVelocityContext(velocityContext, genTable); - if (GenConstants.TPL_TREE.equals(tplCategory)) { - setTreeVelocityContext(velocityContext, genTable); - } - return velocityContext; - } - - public static void setMenuVelocityContext(VelocityContext context, GenTable genTable) { + context.put("tplCategory", genTable.getTplCategory()); + context.put("tableName", genTable.getTableName()); + context.put("functionName", StringUtils.isNotEmpty(functionName) ? functionName : "【请填写功能名称】"); + context.put("ClassName", genTable.getClassName()); + context.put("className", StringUtils.uncapitalize(genTable.getClassName())); + context.put("moduleName", moduleName); + context.put("BusinessName", StringUtils.capitalize(businessName)); + context.put("businessName", businessName); + context.put("basePackage", getPackagePrefix(packageName)); + context.put("packageName", packageName); + context.put("author", genTable.getFunctionAuthor()); + context.put("datetime", DateUtils.getDate()); + context.put("pkColumn", genTable.getPkColumn()); + context.put("importList", getImportList(genTable)); + context.put("permissionPrefix", getPermissionPrefix(moduleName, businessName)); + context.put("columns", genTable.getColumns()); + context.put("table", genTable); + context.put("dicts", getDicts(genTable)); + // 向模板上下文写入菜单相关变量 String options = genTable.getOptions(); Dict paramsObj = JsonUtils.parseMap(options); String parentMenuId = getParentMenuId(paramsObj); context.put("parentMenuId", parentMenuId); + + // 向树形模板上下文写入树字段相关变量 + if (GenConstants.TPL_TREE.equals(tplCategory)) { + setTreeContext(context, genTable, paramsObj); + } + + return context; } - public static void setTreeVelocityContext(VelocityContext context, GenTable genTable) { - String options = genTable.getOptions(); - Dict paramsObj = JsonUtils.parseMap(options); - String treeCode = getTreecode(paramsObj); + /** + * 向树形模板上下文写入树字段相关变量。 + * + * @param context 模板上下文 + * @param genTable 代码生成业务表对象 + * @param paramsObj 已解析的 options 参数(避免重复解析) + */ + public static void setTreeContext(Dict context, GenTable genTable, Dict paramsObj) { + String treeCode = getTreeCode(paramsObj); String treeParentCode = getTreeParentCode(paramsObj); String treeName = getTreeName(paramsObj); context.put("treeCode", treeCode); context.put("treeParentCode", treeParentCode); context.put("treeName", treeName); - context.put("expandColumn", getExpandColumn(genTable)); + String expandTreeName = paramsObj.getStr(GenConstants.TREE_NAME); + int expandColumn = 0; + for (GenTableColumn column : genTable.getColumns()) { + if (column.isList()) { + expandColumn++; + if (column.getColumnName().equals(expandTreeName)) { + break; + } + } + } + context.put("expandColumn", expandColumn); if (paramsObj.containsKey(GenConstants.TREE_PARENT_CODE)) { context.put("tree_parent_code", paramsObj.get(GenConstants.TREE_PARENT_CODE)); } @@ -109,38 +156,48 @@ public class VelocityUtils { * * @return 模板列表 */ - public static List getTemplateList(String tplCategory) { - List templates = new ArrayList<>(); - templates.add("vm/java/domain.java.vm"); - templates.add("vm/java/vo.java.vm"); - templates.add("vm/java/bo.java.vm"); - templates.add("vm/java/mapper.java.vm"); - templates.add("vm/java/service.java.vm"); - templates.add("vm/java/serviceImpl.java.vm"); - templates.add("vm/java/controller.java.vm"); - templates.add("vm/xml/mapper.xml.vm"); + public static List getTemplateList(String tplCategory) { + List templates = new ArrayList<>(); + // 后端源码模板 + templates.add(TEMPLATE_MAPPER.get(GenConstants.JAVA_DOMAIN_TEMPLATE_PATH)); + templates.add(TEMPLATE_MAPPER.get(GenConstants.JAVA_VO_TEMPLATE_PATH)); + templates.add(TEMPLATE_MAPPER.get(GenConstants.JAVA_BO_TEMPLATE_PATH)); + templates.add(TEMPLATE_MAPPER.get(GenConstants.JAVA_MAPPER_TEMPLATE_PATH)); + templates.add(TEMPLATE_MAPPER.get(GenConstants.JAVA_SERVICE_TEMPLATE_PATH)); + templates.add(TEMPLATE_MAPPER.get(GenConstants.JAVA_SERVICE_IMPL_TEMPLATE_PATH)); + templates.add(TEMPLATE_MAPPER.get(GenConstants.JAVA_CONTROLLER_TEMPLATE_PATH)); + // MyBatis MapperXML 模板 + templates.add(TEMPLATE_MAPPER.get(GenConstants.XML_MAPPER_TEMPLATE_PATH)); + // 前端接口源码模板 + templates.add(TEMPLATE_MAPPER.get(GenConstants.TS_API_TEMPLATE_PATH)); + templates.add(TEMPLATE_MAPPER.get(TS_TYPES_TEMPLATE_PATH)); + // 数据库模板 DataBaseType dataBaseType = DataBaseHelper.getDataBaseType(); if (dataBaseType.isOracle()) { - templates.add("vm/sql/oracle/sql.vm"); + templates.add(TEMPLATE_MAPPER.get(GenConstants.SQL_ORACLE_TEMPLATE_PATH)); } else if (dataBaseType.isPostgreSql()) { - templates.add("vm/sql/postgres/sql.vm"); + templates.add(TEMPLATE_MAPPER.get(GenConstants.SQL_POSTGRES_TEMPLATE_PATH)); } else if (dataBaseType.isSqlServer()) { - templates.add("vm/sql/sqlserver/sql.vm"); + templates.add(TEMPLATE_MAPPER.get(GenConstants.SQL_SQLSERVER_TEMPLATE_PATH)); } else { - templates.add("vm/sql/sql.vm"); + // 默认使用MySQL模板 + templates.add(TEMPLATE_MAPPER.get(GenConstants.SQL_MYSQL_TEMPLATE_PATH)); } - templates.add("vm/ts/api.ts.vm"); - templates.add("vm/ts/types.ts.vm"); + // 前端页面源码模板 if (GenConstants.TPL_CRUD.equals(tplCategory)) { - templates.add("vm/vue/index.vue.vm"); + templates.add(TEMPLATE_MAPPER.get(GenConstants.VUE_INDEX_TEMPLATE_PATH)); } else if (GenConstants.TPL_TREE.equals(tplCategory)) { - templates.add("vm/vue/index-tree.vue.vm"); + templates.add(TEMPLATE_MAPPER.get(GenConstants.VUE_INDEX_TREE_TEMPLATE_PATH)); } return templates; } /** * 获取文件名 + * + * @param template 模板路径 + * @param genTable 代码生成业务表对象 + * @return 模板对应的目标文件相对路径 */ public static String getFileName(String template, GenTable genTable) { // 文件名称 @@ -157,17 +214,15 @@ public class VelocityUtils { String javaPath = PROJECT_PATH + "/" + StringUtils.replace(packageName, ".", "/"); String mybatisPath = MYBATIS_PATH + "/" + moduleName; String vuePath = "vue"; - + // templatePath + // genFilePathFormat if (template.contains("domain.java.vm")) { fileName = StringUtils.format("{}/domain/{}.java", javaPath, className); - } - if (template.contains("vo.java.vm")) { + } else if (template.contains("vo.java.vm")) { fileName = StringUtils.format("{}/domain/vo/{}Vo.java", javaPath, className); - } - if (template.contains("bo.java.vm")) { + } else if (template.contains("bo.java.vm")) { fileName = StringUtils.format("{}/domain/bo/{}Bo.java", javaPath, className); - } - if (template.contains("mapper.java.vm")) { + } else if (template.contains("mapper.java.vm")) { fileName = StringUtils.format("{}/mapper/{}Mapper.java", javaPath, className); } else if (template.contains("service.java.vm")) { fileName = StringUtils.format("{}/service/I{}Service.java", javaPath, className); @@ -289,7 +344,7 @@ public class VelocityUtils { * @param paramsObj 生成其他选项 * @return 树编码 */ - public static String getTreecode(Map paramsObj) { + public static String getTreeCode(Map paramsObj) { if (CollUtil.isNotEmpty(paramsObj) && paramsObj.containsKey(GenConstants.TREE_CODE)) { return StringUtils.toCamelCase(Convert.toStr(paramsObj.get(GenConstants.TREE_CODE))); } @@ -321,27 +376,4 @@ public class VelocityUtils { } return StringUtils.EMPTY; } - - /** - * 获取需要在哪一列上面显示展开按钮 - * - * @param genTable 业务表对象 - * @return 展开按钮列序号 - */ - public static int getExpandColumn(GenTable genTable) { - String options = genTable.getOptions(); - Dict paramsObj = JsonUtils.parseMap(options); - String treeName = paramsObj.getStr(GenConstants.TREE_NAME); - int num = 0; - for (GenTableColumn column : genTable.getColumns()) { - if (column.isList()) { - num++; - String columnName = column.getColumnName(); - if (columnName.equals(treeName)) { - break; - } - } - } - return num; - } } diff --git a/ruoyi-modules/ruoyi-gen/src/main/java/org/dromara/gen/util/VelocityInitializer.java b/ruoyi-modules/ruoyi-gen/src/main/java/org/dromara/gen/util/VelocityInitializer.java deleted file mode 100644 index 68773b2f4..000000000 --- a/ruoyi-modules/ruoyi-gen/src/main/java/org/dromara/gen/util/VelocityInitializer.java +++ /dev/null @@ -1,35 +0,0 @@ -package org.dromara.gen.util; - -import lombok.AccessLevel; -import lombok.NoArgsConstructor; -import org.apache.velocity.app.Velocity; -import org.dromara.common.core.constant.Constants; - -import java.util.Properties; - -/** - * VelocityEngine工厂 - * - * @author ruoyi - */ -@NoArgsConstructor(access = AccessLevel.PRIVATE) -public class VelocityInitializer { - - /** - * 初始化vm方法 - */ - public static void initVelocity() { - Properties p = new Properties(); - try { - // 加载classpath目录下的vm文件 - p.setProperty("resource.loader.file.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader"); - // 定义字符集 - p.setProperty(Velocity.INPUT_ENCODING, Constants.UTF8); - // 初始化Velocity引擎,指定配置Properties - Velocity.init(p); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - -} diff --git a/ruoyi-modules/ruoyi-gen/src/main/java/org/dromara/gen/util/template/PathNamedTemplate.java b/ruoyi-modules/ruoyi-gen/src/main/java/org/dromara/gen/util/template/PathNamedTemplate.java new file mode 100644 index 000000000..e16548213 --- /dev/null +++ b/ruoyi-modules/ruoyi-gen/src/main/java/org/dromara/gen/util/template/PathNamedTemplate.java @@ -0,0 +1,68 @@ +package org.dromara.gen.util.template; + +import cn.hutool.extra.template.Template; +import cn.hutool.extra.template.TemplateEngine; +import lombok.Getter; + +import java.io.File; +import java.io.OutputStream; +import java.io.Writer; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +/** + * 基于路径命名的模板委托实现 + * + * @author 秋辞未寒 + */ +public class PathNamedTemplate implements Template { + + @Getter + private final String pathName; + + private final Template delegate; + + private PathNamedTemplate(String pathName, Template delegate) { + this.pathName = pathName; + this.delegate = delegate; + } + + @Override + public void render(Map bindingMap, Writer writer) { + delegate.render(bindingMap, writer); + } + + @Override + public void render(Map bindingMap, OutputStream out) { + delegate.render(bindingMap, out); + } + + @Override + public void render(Map bindingMap, File file) { + delegate.render(bindingMap, file); + } + + @Override + public String render(Map bindingMap) { + return delegate.render(bindingMap); + } + + public static PathNamedTemplate form(String pathName, Template delegate) { + return new PathNamedTemplate(pathName, delegate); + } + + public static PathNamedTemplate form(TemplateEngine templateEngine,String pathName) { + return new PathNamedTemplate(pathName,templateEngine.getTemplate(pathName)); + } + + public static Map form(TemplateEngine templateEngine, Set pathNames) { + Map result = new HashMap<>(); + for (String pathName : pathNames) { + PathNamedTemplate pathNamedTemplate = form(templateEngine, pathName); + result.put(pathName, pathNamedTemplate); + } + return result; + } + +}