feat: 更新代码生成功能-优化逻辑

This commit is contained in:
l90215
2025-07-27 00:33:33 +08:00
parent 915a393427
commit 7e60cb357f
20 changed files with 514 additions and 1090 deletions

View File

@@ -58,8 +58,16 @@ public class GenConfig {
GenConfig.autoRemovePre = autoRemovePre;
}
public static boolean getAutoRemovePre() {
return autoRemovePre;
}
@Value("${tablePrefix}")
public void setTablePrefix(String tablePrefix) {
GenConfig.tablePrefix = tablePrefix;
}
public static String getTablePrefix() {
return tablePrefix;
}
}

View File

@@ -1,70 +0,0 @@
package org.ruoyi.generator.constant;
/**
* 代码生成通用常量
*
* @author ruoyi
*/
public interface GenConstants {
/**
* 单表(增删改查)
*/
String TPL_CRUD = "crud";
/**
* 树表(增删改查)
*/
String TPL_TREE = "tree";
/**
* 树编码字段
*/
String TREE_CODE = "treeCode";
/**
* 树父编码字段
*/
String TREE_PARENT_CODE = "treeParentCode";
/**
* 树名称字段
*/
String TREE_NAME = "treeName";
/**
* 上级菜单ID字段
*/
String PARENT_MENU_ID = "parentMenuId";
/**
* Entity基类字段
*/
String[] BASE_ENTITY = {"createDept", "createBy", "createTime", "updateBy", "updateTime", "tenantId"};
/**
* 下拉框
*/
String HTML_SELECT = "select";
/**
* 单选框
*/
String HTML_RADIO = "radio";
/**
* 复选框
*/
String HTML_CHECKBOX = "checkbox";
/**
* 高精度计算类型
*/
String TYPE_BIGDECIMAL = "BigDecimal";
/**
* 时间类型
*/
String TYPE_DATE = "Date";
}

View File

@@ -1,59 +1,48 @@
package org.ruoyi.generator.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.io.IoUtil;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.NotNull;
import lombok.RequiredArgsConstructor;
import org.ruoyi.common.log.annotation.Log;
import org.ruoyi.common.log.enums.BusinessType;
import org.ruoyi.common.core.domain.R;
import org.ruoyi.common.web.core.BaseController;
import org.ruoyi.generator.service.IGenTableService;
import org.springframework.validation.annotation.Validated;
import org.ruoyi.generator.service.SchemaFieldService;
import org.springframework.context.annotation.Profile;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.io.IOException;
/**
* 代码生成 操作处理
*
* @author Lion Li
*/
@Validated
@Profile("dev")
@RequiredArgsConstructor
@RestController
@RequestMapping("/tool/gen")
public class GenController extends BaseController {
private final IGenTableService genTableService;
private final SchemaFieldService schemaFieldService;
/**
* 批量生成代码
* 根据表名获取代码生成元数据-前端代码生成
*
* @param tableIdStr 表名
* @param tableName 表名
*/
@SaCheckPermission("tool:gen:code")
@Log(title = "代码生成", businessType = BusinessType.GENCODE)
@GetMapping("/batchGenCode")
public void batchGenCode(HttpServletResponse response, String tableIdStr) throws IOException {
String[] tableIds = Convert.toStrArray(tableIdStr);
byte[] data = genTableService.downloadCode(tableIds);
genCode(response, data);
@GetMapping("/getByTableName")
public R<Object> getByTableName(@NotNull(message = "表名不能为空") String tableName) {
return R.ok(schemaFieldService.getMetaDataByTableName(tableName));
}
/**
* 生成zip文件
* 生成后端代码
*
* @param tableNameStr 表名
*/
private void genCode(HttpServletResponse response, byte[] data) throws IOException {
response.reset();
response.addHeader("Access-Control-Allow-Origin", "*");
response.addHeader("Access-Control-Expose-Headers", "Content-Disposition");
response.setHeader("Content-Disposition", "attachment; filename=\"ruoyi.zip\"");
response.addHeader("Content-Length", "" + data.length);
response.setContentType("application/octet-stream; charset=UTF-8");
IoUtil.write(response.getOutputStream(), false, data);
@GetMapping("/batchGenCode")
public R<String> batchGenCode(String tableNameStr) {
genTableService.generateCodeToClasspathByTableNames(tableNameStr);
return R.ok("代码生成成功");
}
}

View File

@@ -120,14 +120,4 @@ public class SchemaFieldController extends BaseController {
public R<List<SchemaFieldVo>> listBySchemaId(@NotNull(message = "模型ID不能为空") @PathVariable Long schemaId) {
return R.ok(schemaFieldService.queryListBySchemaId(schemaId));
}
/**
* 根据表名获取代码生成元数据
*
* @param tableName 表名
*/
@GetMapping("/getByTableName")
public R<Object> getByTableName(@NotNull(message = "表名不能为空") String tableName) {
return R.ok(schemaFieldService.getMetaDataByTableName(tableName));
}
}

View File

@@ -1,165 +0,0 @@
package org.ruoyi.generator.domain;
import com.baomidou.mybatisplus.annotation.FieldStrategy;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.ruoyi.core.domain.BaseEntity;
import java.util.List;
/**
* 业务表 gen_table
*
* @author Lion Li
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("gen_table")
public class GenTable extends BaseEntity {
/**
* 编号
*/
@TableId(value = "table_id")
private Long tableId;
/**
* 表名称
*/
@NotBlank(message = "表名称不能为空")
private String tableName;
/**
* 表描述
*/
@NotBlank(message = "表描述不能为空")
private String tableComment;
/**
* 关联父表的表名
*/
private String subTableName;
/**
* 本表关联父表的外键名
*/
private String subTableFkName;
/**
* 实体类名称(首字母大写)
*/
@NotBlank(message = "实体类名称不能为空")
private String className;
/**
* 使用的模板crud单表操作 tree树表操作 sub主子表操作
*/
private String tplCategory;
/**
* 生成包路径
*/
@NotBlank(message = "生成包路径不能为空")
private String packageName;
/**
* 生成模块名
*/
@NotBlank(message = "生成模块名不能为空")
private String moduleName;
/**
* 生成业务名
*/
@NotBlank(message = "生成业务名不能为空")
private String businessName;
/**
* 生成功能名
*/
@NotBlank(message = "生成功能名不能为空")
private String functionName;
/**
* 生成作者
*/
@NotBlank(message = "作者不能为空")
private String functionAuthor;
/**
* 生成代码方式0zip压缩包 1自定义路径
*/
private String genType;
/**
* 生成路径(不填默认项目路径)
*/
@TableField(updateStrategy = FieldStrategy.NOT_EMPTY)
private String genPath;
/**
* 主键信息
*/
@TableField(exist = false)
private GenTableColumn pkColumn;
/**
* 表列信息
*/
@Valid
@TableField(exist = false)
private List<GenTableColumn> columns;
/**
* 其它生成选项
*/
private String options;
/**
* 备注
*/
private String remark;
/**
* 树编码字段
*/
@TableField(exist = false)
private String treeCode;
/**
* 树父编码字段
*/
@TableField(exist = false)
private String treeParentCode;
/**
* 树名称字段
*/
@TableField(exist = false)
private String treeName;
/*
* 菜单id列表
*/
@TableField(exist = false)
private List<Long> menuIds;
/**
* 上级菜单ID字段
*/
@TableField(exist = false)
private String parentMenuId;
/**
* 上级菜单名称字段
*/
@TableField(exist = false)
private String parentMenuName;
}

View File

@@ -1,222 +0,0 @@
package org.ruoyi.generator.domain;
import com.baomidou.mybatisplus.annotation.FieldStrategy;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import jakarta.validation.constraints.NotBlank;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.apache.ibatis.type.JdbcType;
import org.ruoyi.common.core.utils.StringUtils;
import org.ruoyi.core.domain.BaseEntity;
/**
* 代码生成业务字段表 gen_table_column
*
* @author Lion Li
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("gen_table_column")
public class GenTableColumn extends BaseEntity {
/**
* 编号
*/
@TableId(value = "column_id")
private Long columnId;
/**
* 归属表编号
*/
private Long tableId;
/**
* 列名称
*/
private String columnName;
/**
* 列描述
*/
@TableField(updateStrategy = FieldStrategy.ALWAYS, jdbcType = JdbcType.VARCHAR)
private String columnComment;
/**
* 列类型
*/
private String columnType;
/**
* JAVA类型
*/
private String javaType;
/**
* JAVA字段名
*/
@NotBlank(message = "Java属性不能为空")
private String javaField;
/**
* 是否主键1是
*/
@TableField(updateStrategy = FieldStrategy.ALWAYS, jdbcType = JdbcType.VARCHAR)
private String isPk;
/**
* 是否自增1是
*/
@TableField(updateStrategy = FieldStrategy.ALWAYS, jdbcType = JdbcType.VARCHAR)
private String isIncrement;
/**
* 是否必填1是
*/
@TableField(updateStrategy = FieldStrategy.ALWAYS, jdbcType = JdbcType.VARCHAR)
private String isRequired;
/**
* 是否为插入字段1是
*/
@TableField(updateStrategy = FieldStrategy.ALWAYS, jdbcType = JdbcType.VARCHAR)
private String isInsert;
/**
* 是否编辑字段1是
*/
@TableField(updateStrategy = FieldStrategy.ALWAYS, jdbcType = JdbcType.VARCHAR)
private String isEdit;
/**
* 是否列表字段1是
*/
@TableField(updateStrategy = FieldStrategy.ALWAYS, jdbcType = JdbcType.VARCHAR)
private String isList;
/**
* 是否查询字段1是
*/
@TableField(updateStrategy = FieldStrategy.ALWAYS, jdbcType = JdbcType.VARCHAR)
private String isQuery;
/**
* 查询方式EQ等于、NE不等于、GT大于、LT小于、LIKE模糊、BETWEEN范围
*/
private String queryType;
/**
* 显示类型input文本框、textarea文本域、select下拉框、checkbox复选框、radio单选框、datetime日期控件、image图片上传控件、upload文件上传控件、editor富文本控件
*/
private String htmlType;
/**
* 字典类型
*/
private String dictType;
/**
* 排序
*/
private Integer sort;
public String getCapJavaField() {
return StringUtils.capitalize(javaField);
}
public boolean isPk() {
return isPk(this.isPk);
}
public boolean isPk(String isPk) {
return isPk != null && StringUtils.equals("1", isPk);
}
public boolean isIncrement() {
return isIncrement(this.isIncrement);
}
public boolean isIncrement(String isIncrement) {
return isIncrement != null && StringUtils.equals("1", isIncrement);
}
public boolean isRequired() {
return isRequired(this.isRequired);
}
public boolean isRequired(String isRequired) {
return isRequired != null && StringUtils.equals("1", isRequired);
}
public boolean isInsert() {
return isInsert(this.isInsert);
}
public boolean isInsert(String isInsert) {
return isInsert != null && StringUtils.equals("1", isInsert);
}
public boolean isEdit() {
return isInsert(this.isEdit);
}
public boolean isEdit(String isEdit) {
return isEdit != null && StringUtils.equals("1", isEdit);
}
public boolean isList() {
return isList(this.isList);
}
public boolean isList(String isList) {
return isList != null && StringUtils.equals("1", isList);
}
public boolean isQuery() {
return isQuery(this.isQuery);
}
public boolean isQuery(String isQuery) {
return isQuery != null && StringUtils.equals("1", isQuery);
}
public boolean isSuperColumn() {
return isSuperColumn(this.javaField);
}
public static boolean isSuperColumn(String javaField) {
return StringUtils.equalsAnyIgnoreCase(javaField,
// BaseEntity
"createBy", "createTime", "updateBy", "updateTime",
// TreeEntity
"parentName", "parentId");
}
public boolean isUsableColumn() {
return isUsableColumn(javaField);
}
public static boolean isUsableColumn(String javaField) {
// isSuperColumn()中的名单用于避免生成多余Domain属性若某些属性在生成页面时需要用到不能忽略则放在此处白名单
return StringUtils.equalsAnyIgnoreCase(javaField, "parentId", "orderNum", "remark");
}
public String readConverterExp() {
String remarks = StringUtils.substringBetween(this.columnComment, "", "");
StringBuffer sb = new StringBuffer();
if (StringUtils.isNotEmpty(remarks)) {
for (String value : remarks.split(" ")) {
if (StringUtils.isNotEmpty(value)) {
Object startStr = value.subSequence(0, 1);
String endStr = value.substring(1);
sb.append(StringUtils.EMPTY).append(startStr).append("=").append(endStr).append(StringUtils.SEPARATOR);
}
}
return sb.deleteCharAt(sb.length() - 1).toString();
} else {
return this.columnComment;
}
}
}

View File

@@ -0,0 +1,454 @@
package org.ruoyi.generator.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.incrementer.IdentifierGenerator;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;
import org.ruoyi.common.core.constant.Constants;
import org.ruoyi.generator.config.GenConfig;
import org.ruoyi.generator.service.IGenTableService;
import org.ruoyi.generator.service.SchemaFieldService;
import org.ruoyi.generator.service.SchemaService;
import org.ruoyi.generator.domain.vo.SchemaFieldVo;
import org.ruoyi.generator.domain.vo.SchemaVo;
import org.ruoyi.generator.util.VelocityInitializer;
import org.ruoyi.generator.util.VelocityUtils;
import org.springframework.stereotype.Service;
import java.io.File;
import java.io.FileWriter;
import java.io.StringWriter;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
/**
* 业务 服务层实现
*
* @author Lion Li
*/
@Slf4j
@RequiredArgsConstructor
@Service
public class GenTableServiceImpl implements IGenTableService {
private final IdentifierGenerator identifierGenerator;
private final SchemaService schemaService;
private final SchemaFieldService schemaFieldService;
/**
* 基于表名称批量生成代码到classpath路径
*
* @param tableName 表名称数组
*/
@Override
public void generateCodeToClasspathByTableNames(String tableName) {
try {
generateSchemaCodeToClasspathByTableName(tableName);
} catch (Exception e) {
throw new RuntimeException("基于表名称生成代码失败", e);
}
}
/**
* 根据表名称生成代码到classpath
*/
private void generateSchemaCodeToClasspathByTableName(String tableName) {
// 查询Schema信息
SchemaVo schema = schemaService.queryByTableName(tableName);
if (Objects.isNull(schema)) {
log.warn("Schema不存在表名: {}", tableName);
return;
}
// 查询Schema字段信息
List<SchemaFieldVo> fields = schemaFieldService.queryListByTableName(tableName);
if (CollUtil.isEmpty(fields)) {
log.warn("Schema字段为空表名: {}", tableName);
return;
}
generateCodeFromSchemaData(schema, fields);
}
/**
* 根据Schema数据生成代码
*/
private void generateCodeFromSchemaData(SchemaVo schema, List<SchemaFieldVo> fields) {
// 初始化Velocity
VelocityInitializer.initVelocity();
// 准备Velocity上下文 - 直接基于Schema数据
VelocityContext context = prepareSchemaContext(schema, fields);
// 获取模板列表
List<String> templates = VelocityUtils.getTemplateList();
// 获取项目根路径
String projectPath = getProjectRootPath();
for (String template : templates) {
try {
// 渲染模板
StringWriter sw = new StringWriter();
Template tpl = Velocity.getTemplate(template, Constants.UTF8);
tpl.merge(context, sw);
// 获取文件路径 - 直接基于Schema数据
String fileName = getSchemaFileName(template, schema);
String fullPath = projectPath + File.separator + fileName;
// 创建目录
File file = new File(fullPath);
File parentDir = file.getParentFile();
if (!parentDir.exists()) {
parentDir.mkdirs();
}
// 写入文件
try (FileWriter writer = new FileWriter(file, StandardCharsets.UTF_8)) {
writer.write(sw.toString());
}
log.info("生成文件: {}", fullPath);
} catch (Exception e) {
log.error("生成文件失败,模板: {}, Schema: {}", template, schema.getName(), e);
}
}
}
/**
* 准备基于Schema的Velocity上下文
*/
private VelocityContext prepareSchemaContext(SchemaVo schema, List<SchemaFieldVo> fields) {
VelocityContext context = new VelocityContext();
// 从配置文件读取基本配置
String packageName = GenConfig.getPackageName();
String author = GenConfig.getAuthor();
String tablePrefix = GenConfig.getTablePrefix();
boolean autoRemovePre = GenConfig.getAutoRemovePre();
// 处理表名和类名
String tableName = schema.getTableName();
String baseClassName = schema.getTableName();
// 自动去除表前缀
if (autoRemovePre && StrUtil.isNotBlank(tablePrefix)) {
String[] prefixes = tablePrefix.split(",");
for (String prefix : prefixes) {
if (baseClassName.startsWith(prefix.trim())) {
baseClassName = baseClassName.substring(prefix.trim().length());
break;
}
}
}
String className = toCamelCase(baseClassName, true); // 首字母大写的类名SysRole
String classname = toCamelCase(baseClassName, false); // 首字母小写的类名sysRole
String businessName = toCamelCase(baseClassName, false);
String moduleName = getModuleName(packageName);
// 基本信息
context.put("tableName", tableName);
context.put("tableComment", schema.getComment());
context.put("className", classname); // 首字母小写
context.put("classname", classname); // 首字母小写(兼容性)
context.put("ClassName", className); // 首字母大写
context.put("functionName", schema.getName());
context.put("functionAuthor", author);
context.put("author", author);
context.put("datetime", new Date());
context.put("packageName", packageName);
context.put("moduleName", moduleName);
context.put("businessName", businessName);
// 权限相关
context.put("permissionPrefix", moduleName + ":" + businessName);
context.put("parentMenuId", "2000"); // 默认父菜单ID可配置
// 生成菜单ID
List<Long> menuIds = new ArrayList<>();
for (int i = 0; i < 6; i++) {
menuIds.add(identifierGenerator.nextId(null).longValue());
}
context.put("menuIds", menuIds);
// 创建table对象包含menuIds等信息和方法
Map<String, Object> table = new HashMap<>();
table.put("menuIds", menuIds);
table.put("tableName", tableName);
table.put("tableComment", schema.getComment());
table.put("className", className);
table.put("classname", classname);
table.put("functionName", schema.getName());
// 添加表类型属性默认为crud类型
table.put("crud", true);
table.put("sub", false);
table.put("tree", false);
// 添加isSuperColumn方法
table.put("isSuperColumn", new Object() {
public boolean isSuperColumn(String javaField) {
// 定义超类字段BaseEntity中的字段
return "createBy".equals(javaField) || "createTime".equals(javaField)
|| "updateBy".equals(javaField) || "updateTime".equals(javaField)
|| "remark".equals(javaField) || "tenantId".equals(javaField);
}
});
context.put("table", table);
// 处理字段信息
List<Map<String, Object>> columns = new ArrayList<>();
Map<String, Object> pkColumn = null;
Set<String> importList = new HashSet<>();
// 添加基础导入
importList.add("java.io.Serializable");
for (SchemaFieldVo field : fields) {
Map<String, Object> column = new HashMap<>();
String javaType = getJavaType(field.getType());
String javaField = StrUtil.toCamelCase(field.getCode());
column.put("columnName", field.getCode());
column.put("columnComment", field.getName());
column.put("comment", field.getName()); // 添加comment别名
column.put("columnType", field.getType());
column.put("javaType", javaType);
column.put("javaField", javaField);
column.put("capJavaField", toCamelCase(field.getCode(), true));
// 布尔值属性(兼容两种格式)
boolean isPk = "1".equals(field.getIsPk());
boolean isRequired = "1".equals(field.getIsRequired());
boolean isInsert = "1".equals(field.getIsInsert());
boolean isEdit = "1".equals(field.getIsEdit());
boolean isList = "1".equals(field.getIsList());
boolean isQuery = "1".equals(field.getIsQuery());
column.put("isPk", isPk ? 1 : 0);
column.put("pk", isPk); // 添加pk别名
column.put("isRequired", isRequired);
column.put("required", isRequired); // 添加required别名
column.put("isInsert", isInsert);
column.put("insert", isInsert); // 添加insert别名
column.put("isEdit", isEdit);
column.put("edit", isEdit); // 添加edit别名
column.put("isList", isList);
column.put("list", isList); // 添加list别名
column.put("isQuery", isQuery);
column.put("query", isQuery); // 添加query别名
column.put("queryType", field.getQueryType());
column.put("htmlType", field.getHtmlType());
column.put("dictType", field.getDictType());
column.put("sort", field.getSort());
// 添加readConverterExp方法
column.put("readConverterExp", new Object() {
public String readConverterExp() {
// 从字段注释中提取转换表达式
String comment = field.getName();
if (StrUtil.isNotBlank(comment) && comment.contains("") && comment.contains("")) {
String exp = comment.substring(comment.indexOf("") + 1, comment.indexOf(""));
return exp.replace("", ",").replace(" ", "");
}
return "";
}
});
// 根据Java类型添加相应的导入
addImportForJavaType(javaType, importList);
columns.add(column);
// 设置主键列
if (isPk) {
pkColumn = column;
}
}
// 如果没有主键,使用第一个字段作为主键
if (pkColumn == null && !columns.isEmpty()) {
pkColumn = columns.get(0);
// 将第一个字段设置为主键
pkColumn.put("isPk", 1);
pkColumn.put("pk", true);
}
context.put("columns", columns);
context.put("pkColumn", pkColumn);
context.put("importList", new ArrayList<>(importList));
return context;
}
/**
* 根据Java类型添加相应的导入
*/
private void addImportForJavaType(String javaType, Set<String> importList) {
switch (javaType) {
case "BigDecimal":
importList.add("java.math.BigDecimal");
break;
case "Date":
importList.add("java.util.Date");
break;
case "LocalDateTime":
importList.add("java.time.LocalDateTime");
break;
case "LocalDate":
importList.add("java.time.LocalDate");
break;
case "LocalTime":
importList.add("java.time.LocalTime");
break;
default:
// 基本类型不需要导入
break;
}
}
/**
* 从包名中提取模块名
*/
private String getModuleName(String packageName) {
if (StrUtil.isBlank(packageName)) {
return "generator";
}
String[] parts = packageName.split("\\.");
if (parts.length >= 3) {
return parts[2]; // org.ruoyi.system -> system
}
return "generator";
}
/**
* 获取基于Schema的文件名
*/
private String getSchemaFileName(String template, SchemaVo schema) {
// 从配置文件读取配置
String packageName = GenConfig.getPackageName();
String tablePrefix = GenConfig.getTablePrefix();
boolean autoRemovePre = GenConfig.getAutoRemovePre();
// 处理类名
String baseClassName = schema.getTableName();
// 自动去除表前缀
if (autoRemovePre && StrUtil.isNotBlank(tablePrefix)) {
String[] prefixes = tablePrefix.split(",");
for (String prefix : prefixes) {
if (baseClassName.startsWith(prefix.trim())) {
baseClassName = baseClassName.substring(prefix.trim().length());
break;
}
}
}
String className = toCamelCase(baseClassName, true); // 首字母大写SysRole
String classname = toCamelCase(baseClassName, false); // 首字母小写sysRole
String moduleName = getModuleName(packageName);
String javaPath = "src/main/java/";
String mybatisPath = "src/main/resources/mapper/";
if (template.contains("domain.java.vm")) {
return javaPath + packageName.replace(".", "/") + "/domain/" + className + ".java";
} else if (template.contains("mapper.java.vm")) {
return javaPath + packageName.replace(".", "/") + "/mapper/" + className + "Mapper.java";
} else if (template.contains("service.java.vm")) {
return javaPath + packageName.replace(".", "/") + "/service/" + className + "Service.java";
} else if (template.contains("serviceImpl.java.vm")) {
return javaPath + packageName.replace(".", "/") + "/service/impl/" + className + "ServiceImpl.java";
} else if (template.contains("controller.java.vm")) {
return javaPath + packageName.replace(".", "/") + "/controller/" + className + "Controller.java";
} else if (template.contains("vo.java.vm")) {
return javaPath + packageName.replace(".", "/") + "/domain/vo/" + className + "Vo.java";
} else if (template.contains("bo.java.vm")) {
return javaPath + packageName.replace(".", "/") + "/domain/bo/" + className + "Bo.java";
} else if (template.contains("mapper.xml.vm")) {
return mybatisPath + moduleName + "/" + className + "Mapper.xml";
} else if (template.contains("sql.vm")) {
return javaPath + packageName.replace(".", "/") + "/sql/" + baseClassName + "_menu.sql";
}
return template.replace(".vm", "");
}
/**
* 获取项目根路径
*/
private String getProjectRootPath() {
// 获取当前类的路径,然后向上查找到项目根目录
String classPath = this.getClass().getProtectionDomain().getCodeSource().getLocation().getPath();
File currentDir = new File(classPath).getParentFile();
// 向上查找直到找到包含src目录的项目根目录
while (currentDir != null && currentDir.exists()) {
File srcDir = new File(currentDir, "src");
if (srcDir.exists() && srcDir.isDirectory()) {
return currentDir.getAbsolutePath();
}
currentDir = currentDir.getParentFile();
}
// 如果找不到,使用当前工作目录
return System.getProperty("user.dir");
}
/**
* 转换为驼峰命名
*/
private String toCamelCase(String str, boolean firstUpperCase) {
if (StrUtil.isBlank(str)) {
return str;
}
StringBuilder result = new StringBuilder();
String[] parts = str.split("_");
for (int i = 0; i < parts.length; i++) {
String part = parts[i].toLowerCase();
if (i == 0 && !firstUpperCase) {
result.append(part);
} else {
result.append(part.substring(0, 1).toUpperCase()).append(part.substring(1));
}
}
return result.toString();
}
/**
* 获取Java类型
*/
private String getJavaType(String dbType) {
if (StrUtil.isBlank(dbType)) {
return "String";
}
String type = dbType.toLowerCase();
if (type.contains("int") || type.contains("tinyint") || type.contains("smallint")) {
return "Integer";
} else if (type.contains("bigint")) {
return "Long";
} else if (type.contains("decimal") || type.contains("numeric") || type.contains("float") || type.contains(
"double")) {
return "BigDecimal";
} else if (type.contains("date") || type.contains("time")) {
return "Date";
} else if (type.contains("bit") || type.contains("boolean")) {
return "Boolean";
} else {
return "String";
}
}
}

View File

@@ -1,4 +1,4 @@
package org.ruoyi.generator.service.impl;
package org.ruoyi.generator.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
@@ -10,15 +10,15 @@ import org.ruoyi.common.core.utils.MapstructUtils;
import org.ruoyi.common.core.utils.StringUtils;
import org.ruoyi.core.page.PageQuery;
import org.ruoyi.core.page.TableDataInfo;
import org.ruoyi.generator.service.SchemaFieldService;
import org.ruoyi.generator.service.SchemaGroupService;
import org.ruoyi.generator.service.SchemaService;
import org.ruoyi.generator.domain.SchemaField;
import org.ruoyi.generator.domain.bo.SchemaFieldBo;
import org.ruoyi.generator.domain.vo.SchemaFieldVo;
import org.ruoyi.generator.domain.vo.SchemaGroupVo;
import org.ruoyi.generator.domain.vo.SchemaVo;
import org.ruoyi.generator.mapper.SchemaFieldMapper;
import org.ruoyi.generator.service.SchemaFieldService;
import org.ruoyi.generator.service.SchemaGroupService;
import org.ruoyi.generator.service.SchemaService;
import org.ruoyi.helper.DataBaseHelper;
import org.springframework.stereotype.Service;
@@ -154,6 +154,20 @@ public class SchemaFieldServiceImpl implements SchemaFieldService {
return baseMapper.selectVoList(lqw);
}
/**
* 根据表名称查询字段列表
*/
@Override
public List<SchemaFieldVo> queryListByTableName(String tableName) {
// 先根据表名查询Schema
SchemaVo schema = schemaService.queryByTableName(tableName);
if (schema == null) {
return new ArrayList<>();
}
// 再根据Schema ID查询字段列表
return queryListBySchemaId(schema.getId());
}
/**
* 根据表名获取代码生成元数据
*/

View File

@@ -1,4 +1,4 @@
package org.ruoyi.generator.service.impl;
package org.ruoyi.generator.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;

View File

@@ -1,4 +1,4 @@
package org.ruoyi.generator.service.impl;
package org.ruoyi.generator.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
@@ -8,12 +8,12 @@ import org.ruoyi.common.core.utils.MapstructUtils;
import org.ruoyi.common.core.utils.StringUtils;
import org.ruoyi.core.page.PageQuery;
import org.ruoyi.core.page.TableDataInfo;
import org.ruoyi.generator.service.SchemaService;
import org.ruoyi.generator.domain.Schema;
import org.ruoyi.generator.domain.bo.SchemaBo;
import org.ruoyi.generator.domain.vo.SchemaVo;
import org.ruoyi.generator.event.SchemaAddedEvent;
import org.ruoyi.generator.mapper.SchemaMapper;
import org.ruoyi.generator.service.SchemaService;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;

View File

@@ -1,15 +0,0 @@
package org.ruoyi.generator.mapper;
import com.baomidou.mybatisplus.annotation.InterceptorIgnore;
import org.ruoyi.core.mapper.BaseMapperPlus;
import org.ruoyi.generator.domain.GenTableColumn;
/**
* 业务字段 数据层
*
* @author Lion Li
*/
@InterceptorIgnore(dataPermission = "true", tenantLine = "true")
public interface GenTableColumnMapper extends BaseMapperPlus<GenTableColumn, GenTableColumn> {
}

View File

@@ -1,24 +0,0 @@
package org.ruoyi.generator.mapper;
import com.baomidou.mybatisplus.annotation.InterceptorIgnore;
import org.ruoyi.core.mapper.BaseMapperPlus;
import org.ruoyi.generator.domain.GenTable;
/**
* 业务 数据层
*
* @author Lion Li
*/
@InterceptorIgnore(dataPermission = "true", tenantLine = "true")
public interface GenTableMapper extends BaseMapperPlus<GenTable, GenTable> {
/**
* 查询表ID业务信息
*
* @param id 业务ID
* @return 业务信息
*/
GenTable selectGenTableById(Long id);
}

View File

@@ -7,13 +7,10 @@ package org.ruoyi.generator.service;
*/
public interface IGenTableService {
/**
* 批量生成代码(下载方式)
* 基于表名称批量生成代码到classpath路径
*
* @param tableIds 表数组
* @return 数据
* @param tableName 表名称数组
*/
byte[] downloadCode(String[] tableIds);
void generateCodeToClasspathByTableNames(String tableName);
}

View File

@@ -63,4 +63,12 @@ public interface SchemaFieldService {
* @param tableName 表名
*/
boolean batchInsertFieldsByTableName(Long schemaId, String tableName);
/**
* 根据表名称查询字段列表
*
* @param tableName 表名称
* @return 字段列表
*/
List<SchemaFieldVo> queryListByTableName(String tableName);
}

View File

@@ -1,122 +0,0 @@
package org.ruoyi.generator.service.impl;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.incrementer.IdentifierGenerator;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;
import org.ruoyi.common.core.constant.Constants;
import org.ruoyi.generator.domain.GenTable;
import org.ruoyi.generator.domain.GenTableColumn;
import org.ruoyi.generator.mapper.GenTableMapper;
import org.ruoyi.generator.service.IGenTableService;
import org.ruoyi.generator.util.VelocityInitializer;
import org.ruoyi.generator.util.VelocityUtils;
import org.springframework.stereotype.Service;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.StringWriter;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
/**
* 业务 服务层实现
*
* @author Lion Li
*/
//@DS("#header.datasource")
@Slf4j
@RequiredArgsConstructor
@Service
public class GenTableServiceImpl implements IGenTableService {
private final GenTableMapper baseMapper;
private final IdentifierGenerator identifierGenerator;
/**
* 生成代码(下载方式)
*
* @param tableIds 表名称
* @return 数据
*/
@Override
public byte[] downloadCode(String[] tableIds) {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
ZipOutputStream zip = new ZipOutputStream(outputStream);
for (String tableId : tableIds) {
generatorCode(Long.parseLong(tableId), zip);
}
IoUtil.close(zip);
return outputStream.toByteArray();
}
/**
* 查询表信息并生成代码
*/
/**
* 查询表信息并生成代码
*/
private void generatorCode(Long tableId, ZipOutputStream zip) {
// 查询表信息
GenTable table = baseMapper.selectGenTableById(tableId);
List<Long> menuIds = new ArrayList<>();
for (int i = 0; i < 6; i++) {
menuIds.add(identifierGenerator.nextId(null).longValue());
}
table.setMenuIds(menuIds);
// 设置主键列信息
setPkColumn(table);
VelocityInitializer.initVelocity();
VelocityContext context = VelocityUtils.prepareContext(table);
// 获取模板列表
List<String> templates = VelocityUtils.getTemplateList();
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);
}
}
}
/**
* 设置主键列信息
*
* @param table 业务表信息
*/
public void setPkColumn(GenTable table) {
for (GenTableColumn column : table.getColumns()) {
if (column.isPk()) {
table.setPkColumn(column);
break;
}
}
if (ObjectUtil.isNull(table.getPkColumn())) {
table.setPkColumn(table.getColumns().get(0));
}
}
}

View File

@@ -22,8 +22,8 @@ public class VelocityInitializer {
Properties p = new Properties();
try {
// 加载classpath目录下的vm文件
p.setProperty("resource.loader.file.class", "org.apache.velocity.runtime.resource.loader"
+ ".ClasspathResourceLoader");
p.setProperty("resource.loader.file.class",
"org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
// 定义字符集
p.setProperty(Velocity.INPUT_ENCODING, Constants.UTF8);
// 初始化Velocity引擎指定配置Properties

View File

@@ -1,26 +1,11 @@
package org.ruoyi.generator.util;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.lang.Dict;
import cn.hutool.core.util.ObjectUtil;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import org.apache.velocity.VelocityContext;
import org.ruoyi.common.core.utils.DateUtils;
import org.ruoyi.common.core.utils.StringUtils;
import org.ruoyi.common.json.utils.JsonUtils;
import org.ruoyi.generator.constant.GenConstants;
import org.ruoyi.generator.domain.GenTable;
import org.ruoyi.generator.domain.GenTableColumn;
import org.ruoyi.helper.DataBaseHelper;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
/**
* 模板处理工具类
@@ -30,105 +15,6 @@ import java.util.Set;
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class VelocityUtils {
/**
* 项目空间路径
*/
private static final String PROJECT_PATH = "main/java";
/**
* mybatis空间路径
*/
private static final String MYBATIS_PATH = "main/resources/mapper";
/**
* 默认上级菜单,系统工具
*/
private static final String DEFAULT_PARENT_MENU_ID = "3";
/**
* 设置模板变量信息
*
* @return 模板列表
*/
public static VelocityContext prepareContext(GenTable genTable) {
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);
}
// 判断是modal还是drawer
Dict paramsObj = JsonUtils.parseMap(genTable.getOptions());
if (ObjectUtil.isNotNull(paramsObj)) {
String popupComponent = Optional
.ofNullable(paramsObj.getStr("popupComponent"))
.orElse("modal");
velocityContext.put("popupComponent", popupComponent);
velocityContext.put("PopupComponent", StringUtils.capitalize(popupComponent));
} else {
velocityContext.put("popupComponent", "modal");
velocityContext.put("PopupComponent", "Modal");
}
// 判断是原生antd表单还是useForm表单
// native 原生antd表单
// useForm useVbenForm
if (ObjectUtil.isNotNull(paramsObj)) {
String formComponent = Optional
.ofNullable(paramsObj.getStr("formComponent"))
.orElse("useForm");
velocityContext.put("formComponent", formComponent);
}
return velocityContext;
}
public static void setMenuVelocityContext(VelocityContext context, GenTable genTable) {
String options = genTable.getOptions();
Dict paramsObj = JsonUtils.parseMap(options);
String parentMenuId = getParentMenuId(paramsObj);
context.put("parentMenuId", parentMenuId);
}
public static void setTreeVelocityContext(VelocityContext context, GenTable genTable) {
String options = genTable.getOptions();
Dict paramsObj = JsonUtils.parseMap(options);
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));
if (paramsObj.containsKey(GenConstants.TREE_PARENT_CODE)) {
context.put("tree_parent_code", paramsObj.get(GenConstants.TREE_PARENT_CODE));
}
if (paramsObj.containsKey(GenConstants.TREE_NAME)) {
context.put("tree_name", paramsObj.get(GenConstants.TREE_NAME));
}
}
/**
* 获取模板信息
@@ -157,239 +43,5 @@ public class VelocityUtils {
return templates;
}
/**
* 获取文件名
*/
public static String getFileName(String template, GenTable genTable) {
// 文件名称
String fileName = "";
// 包路径
String packageName = genTable.getPackageName();
// 模块名
String moduleName = genTable.getModuleName();
// 大写类名
String className = genTable.getClassName();
// 业务名称
String businessName = genTable.getBusinessName();
String javaPath = PROJECT_PATH + "/" + StringUtils.replace(packageName, ".", "/");
String mybatisPath = MYBATIS_PATH + "/" + moduleName;
String vuePath = "vue";
if (template.contains("domain.java.vm")) {
fileName = StringUtils.format("{}/domain/{}.java", javaPath, className);
}
if (template.contains("vo.java.vm")) {
fileName = StringUtils.format("{}/domain/vo/{}Vo.java", javaPath, className);
}
if (template.contains("bo.java.vm")) {
fileName = StringUtils.format("{}/domain/bo/{}Bo.java", javaPath, className);
}
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);
} else if (template.contains("serviceImpl.java.vm")) {
fileName = StringUtils.format("{}/service/impl/{}ServiceImpl.java", javaPath, className);
} else if (template.contains("controller.java.vm")) {
fileName = StringUtils.format("{}/controller/{}Controller.java", javaPath, className);
} else if (template.contains("mapper.xml.vm")) {
fileName = StringUtils.format("{}/{}Mapper.xml", mybatisPath, className);
} else if (template.contains("sql.vm")) {
fileName = businessName + "Menu.sql";
} else if (template.contains("api.ts.vm")) {
fileName = StringUtils.format("{}/api/{}/{}/index.ts", vuePath, moduleName, businessName);
} else if (template.contains("types.ts.vm")) {
fileName = StringUtils.format("{}/api/{}/{}/types.ts", vuePath, moduleName, businessName);
} else if (template.contains("index.vue.vm")) {
fileName = StringUtils.format("{}/views/{}/{}/index.vue", vuePath, moduleName, businessName);
} else if (template.contains("index-tree.vue.vm")) {
fileName = StringUtils.format("{}/views/{}/{}/index.vue", vuePath, moduleName, businessName);
}
// 判断是modal还是drawer
Dict paramsObj = JsonUtils.parseMap(genTable.getOptions());
String popupComponent = "modal";
if (ObjectUtil.isNotNull(paramsObj)) {
popupComponent = Optional
.ofNullable(paramsObj.getStr("popupComponent"))
.orElse("modal");
}
String vben5Path = "vben5";
if (template.contains("vm/vben5/api/index.ts.vm")) {
fileName = StringUtils.format("{}/api/{}/{}/index.ts", vben5Path, moduleName, businessName);
}
if (template.contains("vm/vben5/api/model.d.ts.vm")) {
fileName = StringUtils.format("{}/api/{}/{}/model.d.ts", vben5Path, moduleName, businessName);
}
if (template.contains("vm/vben5/views/index_vben.vue.vm")) {
fileName = StringUtils.format("{}/views/{}/{}/index.vue", vben5Path, moduleName, businessName);
}
if (template.contains("vm/vben5/views/index_vben_tree.vue.vm")) {
fileName = StringUtils.format("{}/views/{}/{}/index.vue", vben5Path, moduleName, businessName);
}
if (template.contains("vm/vben5/views/data.ts.vm")) {
fileName = StringUtils.format("{}/views/{}/{}/data.ts", vben5Path, moduleName, businessName);
}
if (template.contains("vm/vben5/views/popup.vue.vm")) {
fileName = StringUtils.format("{}/views/{}/{}/{}-{}.vue", vben5Path, moduleName, businessName,
businessName, popupComponent);
}
if (template.contains("vm/vben5/views/popup_tree.vue.vm")) {
fileName = StringUtils.format("{}/views/{}/{}/{}-{}.vue", vben5Path, moduleName, businessName,
businessName, popupComponent);
}
return fileName;
}
/**
* 获取包前缀
*
* @param packageName 包名称
* @return 包前缀名称
*/
public static String getPackagePrefix(String packageName) {
int lastIndex = packageName.lastIndexOf(".");
return StringUtils.substring(packageName, 0, lastIndex);
}
/**
* 根据列类型获取导入包
*
* @param genTable 业务表对象
* @return 返回需要导入的包列表
*/
public static HashSet<String> getImportList(GenTable genTable) {
List<GenTableColumn> columns = genTable.getColumns();
HashSet<String> importList = new HashSet<>();
for (GenTableColumn column : columns) {
if (!column.isSuperColumn() && GenConstants.TYPE_DATE.equals(column.getJavaType())) {
importList.add("java.util.Date");
importList.add("com.fasterxml.jackson.annotation.JsonFormat");
} else if (!column.isSuperColumn() && GenConstants.TYPE_BIGDECIMAL.equals(column.getJavaType())) {
importList.add("java.math.BigDecimal");
} else if (!column.isSuperColumn() && "imageUpload".equals(column.getHtmlType())) {
importList.add("org.ruoyi.common.translation.annotation.Translation");
importList.add("org.ruoyi.common.translation.constant.TransConstant");
}
}
return importList;
}
/**
* 根据列类型获取字典组
*
* @param genTable 业务表对象
* @return 返回字典组
*/
public static String getDicts(GenTable genTable) {
List<GenTableColumn> columns = genTable.getColumns();
Set<String> dicts = new HashSet<>();
addDicts(dicts, columns);
return StringUtils.join(dicts, ", ");
}
/**
* 添加字典列表
*
* @param dicts 字典列表
* @param columns 列集合
*/
public static void addDicts(Set<String> dicts, List<GenTableColumn> columns) {
for (GenTableColumn column : columns) {
if (!column.isSuperColumn() && StringUtils.isNotEmpty(column.getDictType()) && StringUtils.equalsAny(
column.getHtmlType(),
new String[]{GenConstants.HTML_SELECT, GenConstants.HTML_RADIO, GenConstants.HTML_CHECKBOX})) {
dicts.add("'" + column.getDictType() + "'");
}
}
}
/**
* 获取权限前缀
*
* @param moduleName 模块名称
* @param businessName 业务名称
* @return 返回权限前缀
*/
public static String getPermissionPrefix(String moduleName, String businessName) {
return StringUtils.format("{}:{}", moduleName, businessName);
}
/**
* 获取上级菜单ID字段
*
* @param paramsObj 生成其他选项
* @return 上级菜单ID字段
*/
public static String getParentMenuId(Dict paramsObj) {
if (CollUtil.isNotEmpty(paramsObj) && paramsObj.containsKey(GenConstants.PARENT_MENU_ID)
&& StringUtils.isNotEmpty(paramsObj.getStr(GenConstants.PARENT_MENU_ID))) {
return paramsObj.getStr(GenConstants.PARENT_MENU_ID);
}
return DEFAULT_PARENT_MENU_ID;
}
/**
* 获取树编码
*
* @param paramsObj 生成其他选项
* @return 树编码
*/
public static String getTreecode(Map<String, Object> paramsObj) {
if (CollUtil.isNotEmpty(paramsObj) && paramsObj.containsKey(GenConstants.TREE_CODE)) {
return StringUtils.toCamelCase(Convert.toStr(paramsObj.get(GenConstants.TREE_CODE)));
}
return StringUtils.EMPTY;
}
/**
* 获取树父编码
*
* @param paramsObj 生成其他选项
* @return 树父编码
*/
public static String getTreeParentCode(Dict paramsObj) {
if (CollUtil.isNotEmpty(paramsObj) && paramsObj.containsKey(GenConstants.TREE_PARENT_CODE)) {
return StringUtils.toCamelCase(paramsObj.getStr(GenConstants.TREE_PARENT_CODE));
}
return StringUtils.EMPTY;
}
/**
* 获取树名称
*
* @param paramsObj 生成其他选项
* @return 树名称
*/
public static String getTreeName(Dict paramsObj) {
if (CollUtil.isNotEmpty(paramsObj) && paramsObj.containsKey(GenConstants.TREE_NAME)) {
return StringUtils.toCamelCase(paramsObj.getStr(GenConstants.TREE_NAME));
}
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;
}
}

View File

@@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.ruoyi.generator.mapper.GenTableColumnMapper">
</mapper>

View File

@@ -1,59 +0,0 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.ruoyi.generator.mapper.GenTableMapper">
<!-- 多结构嵌套自动映射需带上每个实体的主键id 否则映射会失败 -->
<resultMap type="org.ruoyi.generator.domain.GenTable" id="GenTableResult">
<id property="tableId" column="table_id"/>
<collection property="columns" javaType="java.util.List" resultMap="GenTableColumnResult"/>
</resultMap>
<resultMap type="org.ruoyi.generator.domain.GenTableColumn" id="GenTableColumnResult">
<id property="columnId" column="column_id"/>
</resultMap>
<select id="selectGenTableById" parameterType="Long" resultMap="GenTableResult">
SELECT t.table_id,
t.table_name,
t.table_comment,
t.sub_table_name,
t.sub_table_fk_name,
t.class_name,
t.tpl_category,
t.package_name,
t.module_name,
t.business_name,
t.function_name,
t.function_author,
t.gen_type,
t.gen_path,
t.options,
t.remark,
c.column_id,
c.column_name,
c.column_comment,
c.column_type,
c.java_type,
c.java_field,
c.is_pk,
c.is_increment,
c.is_required,
c.is_insert,
c.is_edit,
c.is_list,
c.is_query,
c.query_type,
c.html_type,
c.dict_type,
c.sort
FROM gen_table t
LEFT JOIN gen_table_column c ON t.table_id = c.table_id
where t.table_id = #{tableId}
order by c.sort
</select>
</mapper>

View File

@@ -1,3 +0,0 @@
java包使用 `.` 分割 resource 目录使用 `/` 分割
<br>
此文件目的 防止文件夹粘连找不到 `xml` 文件