diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/constant/GenConstants.java b/ruoyi-common/src/main/java/com/ruoyi/common/constant/GenConstants.java index b9b92538..1d5d8842 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/constant/GenConstants.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/constant/GenConstants.java @@ -13,6 +13,9 @@ public class GenConstants /** 树表(增删改查) */ public static final String TPL_TREE = "tree"; + /** 主子表(增删改查) */ + public static final String TPL_SUB = "sub"; + /** 树编码字段 */ public static final String TREE_CODE = "treeCode"; diff --git a/ruoyi-generator/src/main/java/com/ruoyi/generator/controller/GenController.java b/ruoyi-generator/src/main/java/com/ruoyi/generator/controller/GenController.java index 9de4d447..21b1cc53 100644 --- a/ruoyi-generator/src/main/java/com/ruoyi/generator/controller/GenController.java +++ b/ruoyi-generator/src/main/java/com/ruoyi/generator/controller/GenController.java @@ -63,10 +63,12 @@ public class GenController extends BaseController public AjaxResult getInfo(@PathVariable Long talbleId) { GenTable table = genTableService.selectGenTableById(talbleId); + List<GenTable> tables = genTableService.selectGenTableAll(); List<GenTableColumn> list = genTableColumnService.selectGenTableColumnListByTableId(talbleId); Map<String, Object> map = new HashMap<String, Object>(); map.put("info", table); map.put("rows", list); + map.put("tables", tables); return AjaxResult.success(map); } diff --git a/ruoyi-generator/src/main/java/com/ruoyi/generator/domain/GenTable.java b/ruoyi-generator/src/main/java/com/ruoyi/generator/domain/GenTable.java index 4f4aea40..2abb94fa 100644 --- a/ruoyi-generator/src/main/java/com/ruoyi/generator/domain/GenTable.java +++ b/ruoyi-generator/src/main/java/com/ruoyi/generator/domain/GenTable.java @@ -28,11 +28,17 @@ public class GenTable extends BaseEntity @NotBlank(message = "表描述不能为空") private String tableComment; + /** 关联父表的表名 */ + private String subTableName; + + /** 本表关联父表的外键名 */ + private String subTableFkName; + /** 实体类名称(首字母大写) */ @NotBlank(message = "实体类名称不能为空") private String className; - /** 使用的模板(crud单表操作 tree树表操作) */ + /** 使用的模板(crud单表操作 tree树表操作 sub主子表操作) */ private String tplCategory; /** 生成包路径 */ @@ -64,6 +70,9 @@ public class GenTable extends BaseEntity /** 主键信息 */ private GenTableColumn pkColumn; + /** 子表信息 */ + private GenTable subTable; + /** 表列信息 */ @Valid private List<GenTableColumn> columns; @@ -116,6 +125,26 @@ public class GenTable extends BaseEntity this.tableComment = tableComment; } + public String getSubTableName() + { + return subTableName; + } + + public void setSubTableName(String subTableName) + { + this.subTableName = subTableName; + } + + public String getSubTableFkName() + { + return subTableFkName; + } + + public void setSubTableFkName(String subTableFkName) + { + this.subTableFkName = subTableFkName; + } + public String getClassName() { return className; @@ -216,6 +245,16 @@ public class GenTable extends BaseEntity this.pkColumn = pkColumn; } + public GenTable getSubTable() + { + return subTable; + } + + public void setSubTable(GenTable subTable) + { + this.subTable = subTable; + } + public List<GenTableColumn> getColumns() { return columns; @@ -286,6 +325,16 @@ public class GenTable extends BaseEntity this.parentMenuName = parentMenuName; } + public boolean isSub() + { + return isSub(this.tplCategory); + } + + public static boolean isSub(String tplCategory) + { + return tplCategory != null && StringUtils.equals(GenConstants.TPL_SUB, tplCategory); + } + public boolean isTree() { return isTree(this.tplCategory); diff --git a/ruoyi-generator/src/main/java/com/ruoyi/generator/domain/GenTableColumn.java b/ruoyi-generator/src/main/java/com/ruoyi/generator/domain/GenTableColumn.java index b4b74765..9140d4da 100644 --- a/ruoyi-generator/src/main/java/com/ruoyi/generator/domain/GenTableColumn.java +++ b/ruoyi-generator/src/main/java/com/ruoyi/generator/domain/GenTableColumn.java @@ -138,6 +138,11 @@ public class GenTableColumn extends BaseEntity return javaField; } + public String getCapJavaField() + { + return StringUtils.capitalize(javaField); + } + public void setIsPk(String isPk) { this.isPk = isPk; diff --git a/ruoyi-generator/src/main/java/com/ruoyi/generator/mapper/GenTableMapper.java b/ruoyi-generator/src/main/java/com/ruoyi/generator/mapper/GenTableMapper.java index 4288d889..c2fdf71f 100644 --- a/ruoyi-generator/src/main/java/com/ruoyi/generator/mapper/GenTableMapper.java +++ b/ruoyi-generator/src/main/java/com/ruoyi/generator/mapper/GenTableMapper.java @@ -34,6 +34,13 @@ public interface GenTableMapper */ public List<GenTable> selectDbTableListByNames(String[] tableNames); + /** + * 查询所有表信息 + * + * @return 表信息集合 + */ + public List<GenTable> selectGenTableAll(); + /** * 查询表ID业务信息 * diff --git a/ruoyi-generator/src/main/java/com/ruoyi/generator/service/GenTableServiceImpl.java b/ruoyi-generator/src/main/java/com/ruoyi/generator/service/GenTableServiceImpl.java index 4f663021..c7fd2dd1 100644 --- a/ruoyi-generator/src/main/java/com/ruoyi/generator/service/GenTableServiceImpl.java +++ b/ruoyi-generator/src/main/java/com/ruoyi/generator/service/GenTableServiceImpl.java @@ -102,6 +102,17 @@ public class GenTableServiceImpl implements IGenTableService return genTableMapper.selectDbTableListByNames(tableNames); } + /** + * 查询所有表信息 + * + * @return 表信息集合 + */ + @Override + public List<GenTable> selectGenTableAll() + { + return genTableMapper.selectGenTableAll(); + } + /** * 修改业务 * @@ -185,9 +196,10 @@ public class GenTableServiceImpl implements IGenTableService Map<String, String> dataMap = new LinkedHashMap<>(); // 查询表信息 GenTable table = genTableMapper.selectGenTableById(tableId); - // 查询列信息 - List<GenTableColumn> columns = table.getColumns(); - setPkColumn(table, columns); + // 设置主子表信息 + setSubTable(table); + // 设置主键列信息 + setPkColumn(table); VelocityInitializer.initVelocity(); VelocityContext context = VelocityUtils.prepareContext(table); @@ -231,9 +243,10 @@ public class GenTableServiceImpl implements IGenTableService { // 查询表信息 GenTable table = genTableMapper.selectGenTableByName(tableName); - // 查询列信息 - List<GenTableColumn> columns = table.getColumns(); - setPkColumn(table, columns); + // 设置主子表信息 + setSubTable(table); + // 设置主键列信息 + setPkColumn(table); VelocityInitializer.initVelocity(); @@ -276,6 +289,10 @@ public class GenTableServiceImpl implements IGenTableService List<String> tableColumnNames = tableColumns.stream().map(GenTableColumn::getColumnName).collect(Collectors.toList()); List<GenTableColumn> dbTableColumns = genTableColumnMapper.selectDbTableColumnsByName(tableName); + if (StringUtils.isEmpty(dbTableColumns)) + { + throw new CustomException("同步数据失败,原表结构不存在"); + } List<String> dbTableColumnNames = dbTableColumns.stream().map(GenTableColumn::getColumnName).collect(Collectors.toList()); dbTableColumns.forEach(column -> { @@ -319,9 +336,10 @@ public class GenTableServiceImpl implements IGenTableService { // 查询表信息 GenTable table = genTableMapper.selectGenTableByName(tableName); - // 查询列信息 - List<GenTableColumn> columns = table.getColumns(); - setPkColumn(table, columns); + // 设置主子表信息 + setSubTable(table); + // 设置主键列信息 + setPkColumn(table); VelocityInitializer.initVelocity(); @@ -375,6 +393,17 @@ public class GenTableServiceImpl implements IGenTableService { throw new CustomException("树名称字段不能为空"); } + else if (GenConstants.TPL_SUB.equals(genTable.getTplCategory())) + { + if (StringUtils.isEmpty(genTable.getSubTableName())) + { + throw new CustomException("关联子表的表名不能为空"); + } + else if (StringUtils.isEmpty(genTable.getSubTableFkName())) + { + throw new CustomException("子表关联的外键名不能为空"); + } + } } } @@ -382,11 +411,10 @@ public class GenTableServiceImpl implements IGenTableService * 设置主键列信息 * * @param table 业务表信息 - * @param columns 业务字段列表 */ - public void setPkColumn(GenTable table, List<GenTableColumn> columns) + public void setPkColumn(GenTable table) { - for (GenTableColumn column : columns) + for (GenTableColumn column : table.getColumns()) { if (column.isPk()) { @@ -396,7 +424,36 @@ public class GenTableServiceImpl implements IGenTableService } if (StringUtils.isNull(table.getPkColumn())) { - table.setPkColumn(columns.get(0)); + table.setPkColumn(table.getColumns().get(0)); + } + if (GenConstants.TPL_SUB.equals(table.getTplCategory())) + { + for (GenTableColumn column : table.getSubTable().getColumns()) + { + if (column.isPk()) + { + table.getSubTable().setPkColumn(column); + break; + } + } + if (StringUtils.isNull(table.getSubTable().getPkColumn())) + { + table.getSubTable().setPkColumn(table.getSubTable().getColumns().get(0)); + } + } + } + + /** + * 设置主子表信息 + * + * @param table 业务表信息 + */ + public void setSubTable(GenTable table) + { + String subTableName = table.getSubTableName(); + if (StringUtils.isNotEmpty(subTableName)) + { + table.setSubTable(genTableMapper.selectGenTableByName(subTableName)); } } diff --git a/ruoyi-generator/src/main/java/com/ruoyi/generator/service/IGenTableService.java b/ruoyi-generator/src/main/java/com/ruoyi/generator/service/IGenTableService.java index cb2f0437..955b326b 100644 --- a/ruoyi-generator/src/main/java/com/ruoyi/generator/service/IGenTableService.java +++ b/ruoyi-generator/src/main/java/com/ruoyi/generator/service/IGenTableService.java @@ -35,6 +35,13 @@ public interface IGenTableService */ public List<GenTable> selectDbTableListByNames(String[] tableNames); + /** + * 查询所有表信息 + * + * @return 表信息集合 + */ + public List<GenTable> selectGenTableAll(); + /** * 查询业务信息 * diff --git a/ruoyi-generator/src/main/java/com/ruoyi/generator/util/VelocityInitializer.java b/ruoyi-generator/src/main/java/com/ruoyi/generator/util/VelocityInitializer.java index 8f9ee07b..889ae9fd 100644 --- a/ruoyi-generator/src/main/java/com/ruoyi/generator/util/VelocityInitializer.java +++ b/ruoyi-generator/src/main/java/com/ruoyi/generator/util/VelocityInitializer.java @@ -7,7 +7,7 @@ import com.ruoyi.common.constant.Constants; /** * VelocityEngine工厂 * - * @author RuoYi + * @author ruoyi */ public class VelocityInitializer { diff --git a/ruoyi-generator/src/main/java/com/ruoyi/generator/util/VelocityUtils.java b/ruoyi-generator/src/main/java/com/ruoyi/generator/util/VelocityUtils.java index 0be5fbb6..a6743132 100644 --- a/ruoyi-generator/src/main/java/com/ruoyi/generator/util/VelocityUtils.java +++ b/ruoyi-generator/src/main/java/com/ruoyi/generator/util/VelocityUtils.java @@ -54,7 +54,7 @@ public class VelocityUtils velocityContext.put("author", genTable.getFunctionAuthor()); velocityContext.put("datetime", DateUtils.getDate()); velocityContext.put("pkColumn", genTable.getPkColumn()); - velocityContext.put("importList", getImportList(genTable.getColumns())); + velocityContext.put("importList", getImportList(genTable)); velocityContext.put("permissionPrefix", getPermissionPrefix(moduleName, businessName)); velocityContext.put("columns", genTable.getColumns()); velocityContext.put("table", genTable); @@ -63,6 +63,10 @@ public class VelocityUtils { setTreeVelocityContext(velocityContext, genTable); } + if (GenConstants.TPL_SUB.equals(tplCategory)) + { + setSubVelocityContext(velocityContext, genTable); + } return velocityContext; } @@ -96,6 +100,24 @@ public class VelocityUtils } } + public static void setSubVelocityContext(VelocityContext context, GenTable genTable) + { + GenTable subTable = genTable.getSubTable(); + String subTableName = genTable.getSubTableName(); + String subTableFkName = genTable.getSubTableFkName(); + String subClassName = genTable.getSubTable().getClassName(); + String subTableFkClassName = StringUtils.convertToCamelCase(subTableFkName); + + context.put("subTable", subTable); + context.put("subTableName", subTableName); + context.put("subTableFkName", subTableFkName); + context.put("subTableFkClassName", subTableFkClassName); + context.put("subTableFkclassName", StringUtils.uncapitalize(subTableFkClassName)); + context.put("subClassName", subClassName); + context.put("subclassName", StringUtils.uncapitalize(subClassName)); + context.put("subImportList", getImportList(genTable.getSubTable())); + } + /** * 获取模板信息 * @@ -120,6 +142,11 @@ public class VelocityUtils { templates.add("vm/vue/index-tree.vue.vm"); } + else if (GenConstants.TPL_SUB.equals(tplCategory)) + { + templates.add("vm/vue/index.vue.vm"); + templates.add("vm/java/sub-domain.java.vm"); + } return templates; } @@ -147,6 +174,10 @@ public class VelocityUtils { fileName = StringUtils.format("{}/domain/{}.java", javaPath, className); } + if (template.contains("sub-domain.java.vm") && StringUtils.equals(GenConstants.TPL_SUB, genTable.getTplCategory())) + { + fileName = StringUtils.format("{}/domain/{}.java", javaPath, genTable.getSubTable().getClassName()); + } else if (template.contains("mapper.java.vm")) { fileName = StringUtils.format("{}/mapper/{}Mapper.java", javaPath, className); @@ -201,13 +232,19 @@ public class VelocityUtils /** * 根据列类型获取导入包 - * - * @param columns 列集合 + * + * @param genTable 业务表对象 * @return 返回需要导入的包列表 */ - public static HashSet<String> getImportList(List<GenTableColumn> columns) + public static HashSet<String> getImportList(GenTable genTable) { + List<GenTableColumn> columns = genTable.getColumns(); + GenTable subGenTable = genTable.getSubTable(); HashSet<String> importList = new HashSet<String>(); + if (StringUtils.isNotNull(subGenTable)) + { + importList.add("java.util.List"); + } for (GenTableColumn column : columns) { if (!column.isSuperColumn() && GenConstants.TYPE_DATE.equals(column.getJavaType())) diff --git a/ruoyi-generator/src/main/resources/mapper/generator/GenTableMapper.xml b/ruoyi-generator/src/main/resources/mapper/generator/GenTableMapper.xml index 83ba469d..cda04f0f 100644 --- a/ruoyi-generator/src/main/resources/mapper/generator/GenTableMapper.xml +++ b/ruoyi-generator/src/main/resources/mapper/generator/GenTableMapper.xml @@ -5,24 +5,26 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" <mapper namespace="com.ruoyi.generator.mapper.GenTableMapper"> <resultMap type="GenTable" id="GenTableResult"> - <id property="tableId" column="table_id" /> - <result property="tableName" column="table_name" /> - <result property="tableComment" column="table_comment" /> - <result property="className" column="class_name" /> - <result property="tplCategory" column="tpl_category" /> - <result property="packageName" column="package_name" /> - <result property="moduleName" column="module_name" /> - <result property="businessName" column="business_name" /> - <result property="functionName" column="function_name" /> - <result property="functionAuthor" column="function_author" /> - <result property="genType" column="gen_type" /> - <result property="genPath" column="gen_path" /> - <result property="options" column="options" /> - <result property="createBy" column="create_by" /> - <result property="createTime" column="create_time" /> - <result property="updateBy" column="update_by" /> - <result property="updateTime" column="update_time" /> - <result property="remark" column="remark" /> + <id property="tableId" column="table_id" /> + <result property="tableName" column="table_name" /> + <result property="tableComment" column="table_comment" /> + <result property="subTableName" column="sub_table_name" /> + <result property="subTableFkName" column="sub_table_fk_name" /> + <result property="className" column="class_name" /> + <result property="tplCategory" column="tpl_category" /> + <result property="packageName" column="package_name" /> + <result property="moduleName" column="module_name" /> + <result property="businessName" column="business_name" /> + <result property="functionName" column="function_name" /> + <result property="functionAuthor" column="function_author" /> + <result property="genType" column="gen_type" /> + <result property="genPath" column="gen_path" /> + <result property="options" column="options" /> + <result property="createBy" column="create_by" /> + <result property="createTime" column="create_time" /> + <result property="updateBy" column="update_by" /> + <result property="updateTime" column="update_time" /> + <result property="remark" column="remark" /> <collection property="columns" javaType="java.util.List" resultMap="GenTableColumnResult" /> </resultMap> @@ -52,7 +54,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" </resultMap> <sql id="selectGenTableVo"> - select table_id, table_name, table_comment, class_name, tpl_category, package_name, module_name, business_name, function_name, function_author, gen_type, gen_path, options, create_by, create_time, update_by, update_time, remark from gen_table + select table_id, table_name, table_comment, sub_table_name, sub_table_fk_name, class_name, tpl_category, package_name, module_name, business_name, function_name, function_author, gen_type, gen_path, options, create_by, create_time, update_by, update_time, remark from gen_table </sql> <select id="selectGenTableList" parameterType="GenTable" resultMap="GenTableResult"> @@ -108,7 +110,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" </select> <select id="selectGenTableById" parameterType="Long" resultMap="GenTableResult"> - SELECT t.table_id, t.table_name, t.table_comment, 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, + 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 @@ -116,13 +118,21 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" </select> <select id="selectGenTableByName" parameterType="String" resultMap="GenTableResult"> - SELECT t.table_id, t.table_name, t.table_comment, 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, + 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_name = #{tableName} order by c.sort </select> + <select id="selectGenTableAll" parameterType="String" 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.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 + order by c.sort + </select> + <insert id="insertGenTable" parameterType="GenTable" useGeneratedKeys="true" keyProperty="tableId"> insert into gen_table ( <if test="tableName != null">table_name,</if> @@ -162,6 +172,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" <set> <if test="tableName != null">table_name = #{tableName},</if> <if test="tableComment != null and tableComment != ''">table_comment = #{tableComment},</if> + <if test="subTableName != null">sub_table_name = #{subTableName},</if> + <if test="subTableFkName != null">sub_table_fk_name = #{subTableFkName},</if> <if test="className != null and className != ''">class_name = #{className},</if> <if test="functionAuthor != null and functionAuthor != ''">function_author = #{functionAuthor},</if> <if test="genType != null and genType != ''">gen_type = #{genType},</if> diff --git a/ruoyi-generator/src/main/resources/vm/java/controller.java.vm b/ruoyi-generator/src/main/resources/vm/java/controller.java.vm index 6c349df1..f3c2153c 100644 --- a/ruoyi-generator/src/main/resources/vm/java/controller.java.vm +++ b/ruoyi-generator/src/main/resources/vm/java/controller.java.vm @@ -18,7 +18,7 @@ import com.ruoyi.common.enums.BusinessType; import ${packageName}.domain.${ClassName}; import ${packageName}.service.I${ClassName}Service; import com.ruoyi.common.utils.poi.ExcelUtil; -#if($table.crud) +#if($table.crud || $table.sub) import com.ruoyi.common.core.page.TableDataInfo; #elseif($table.tree) #end @@ -41,7 +41,7 @@ public class ${ClassName}Controller extends BaseController */ @PreAuthorize("@ss.hasPermi('${permissionPrefix}:list')") @GetMapping("/list") -#if($table.crud) +#if($table.crud || $table.sub) public TableDataInfo list(${ClassName} ${className}) { startPage(); diff --git a/ruoyi-generator/src/main/resources/vm/java/domain.java.vm b/ruoyi-generator/src/main/resources/vm/java/domain.java.vm index 9dd82478..94a40a96 100644 --- a/ruoyi-generator/src/main/resources/vm/java/domain.java.vm +++ b/ruoyi-generator/src/main/resources/vm/java/domain.java.vm @@ -6,7 +6,7 @@ import ${import}; import org.apache.commons.lang3.builder.ToStringBuilder; import org.apache.commons.lang3.builder.ToStringStyle; import com.ruoyi.common.annotation.Excel; -#if($table.crud) +#if($table.crud || $table.sub) import com.ruoyi.common.core.domain.BaseEntity; #elseif($table.tree) import com.ruoyi.common.core.domain.TreeEntity; @@ -18,7 +18,7 @@ import com.ruoyi.common.core.domain.TreeEntity; * @author ${author} * @date ${datetime} */ -#if($table.crud) +#if($table.crud || $table.sub) #set($Entity="BaseEntity") #elseif($table.tree) #set($Entity="TreeEntity") @@ -49,6 +49,11 @@ public class ${ClassName} extends ${Entity} private $column.javaType $column.javaField; #end +#end +#if($table.sub) + /** $table.subTable.functionName信息 */ + private List<${subClassName}> ${subclassName}List; + #end #foreach ($column in $columns) #if(!$table.isSuperColumn($column.javaField)) @@ -69,6 +74,18 @@ public class ${ClassName} extends ${Entity} #end #end +#if($table.sub) + public List<${subClassName}> get${subClassName}List() + { + return ${subclassName}List; + } + + public void set${subClassName}List(List<${subClassName}> ${subclassName}List) + { + this.${subclassName}List = ${subclassName}List; + } + +#end @Override public String toString() { return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) @@ -79,6 +96,9 @@ public class ${ClassName} extends ${Entity} #set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)}) #end .append("${column.javaField}", get${AttrName}()) +#end +#if($table.sub) + .append("${subclassName}List", get${subClassName}List()) #end .toString(); } diff --git a/ruoyi-generator/src/main/resources/vm/java/mapper.java.vm b/ruoyi-generator/src/main/resources/vm/java/mapper.java.vm index 5502baf6..4c02b0f4 100644 --- a/ruoyi-generator/src/main/resources/vm/java/mapper.java.vm +++ b/ruoyi-generator/src/main/resources/vm/java/mapper.java.vm @@ -2,6 +2,9 @@ package ${packageName}.mapper; import java.util.List; import ${packageName}.domain.${ClassName}; +#if($table.sub) +import ${packageName}.domain.${subClassName}; +#end /** * ${functionName}Mapper接口 @@ -58,4 +61,31 @@ public interface ${ClassName}Mapper * @return 结果 */ public int delete${ClassName}ByIds(${pkColumn.javaType}[] ${pkColumn.javaField}s); +#if($table.sub) + + /** + * 批量删除${subTable.functionName} + * + * @param customerIds 需要删除的数据ID + * @return 结果 + */ + public int delete${subClassName}By${subTableFkClassName}s(${pkColumn.javaType}[] ${pkColumn.javaField}s); + + /** + * 批量新增${subTable.functionName} + * + * @param ${subclassName}List ${subTable.functionName}列表 + * @return 结果 + */ + public int batch${subClassName}(List<${subClassName}> ${subclassName}List); + + + /** + * 通过${functionName}ID删除${subTable.functionName}信息 + * + * @param roleId 角色ID + * @return 结果 + */ + public int delete${subClassName}By${subTableFkClassName}(${pkColumn.javaType} ${pkColumn.javaField}); +#end } diff --git a/ruoyi-generator/src/main/resources/vm/java/serviceImpl.java.vm b/ruoyi-generator/src/main/resources/vm/java/serviceImpl.java.vm index 05a3de84..b1b3c40e 100644 --- a/ruoyi-generator/src/main/resources/vm/java/serviceImpl.java.vm +++ b/ruoyi-generator/src/main/resources/vm/java/serviceImpl.java.vm @@ -9,6 +9,12 @@ import com.ruoyi.common.utils.DateUtils; #end import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +#if($table.sub) +import java.util.ArrayList; +import com.ruoyi.common.utils.StringUtils; +import org.springframework.transaction.annotation.Transactional; +import ${packageName}.domain.${subClassName}; +#end import ${packageName}.mapper.${ClassName}Mapper; import ${packageName}.domain.${ClassName}; import ${packageName}.service.I${ClassName}Service; @@ -55,6 +61,9 @@ public class ${ClassName}ServiceImpl implements I${ClassName}Service * @param ${className} ${functionName} * @return 结果 */ +#if($table.sub) + @Transactional +#end @Override public int insert${ClassName}(${ClassName} ${className}) { @@ -63,7 +72,13 @@ public class ${ClassName}ServiceImpl implements I${ClassName}Service ${className}.setCreateTime(DateUtils.getNowDate()); #end #end +#if($table.sub) + int rows = ${className}Mapper.insert${ClassName}(${className}); + insert${subClassName}(${className}); + return rows; +#else return ${className}Mapper.insert${ClassName}(${className}); +#end } /** @@ -72,6 +87,9 @@ public class ${ClassName}ServiceImpl implements I${ClassName}Service * @param ${className} ${functionName} * @return 结果 */ +#if($table.sub) + @Transactional +#end @Override public int update${ClassName}(${ClassName} ${className}) { @@ -79,6 +97,10 @@ public class ${ClassName}ServiceImpl implements I${ClassName}Service #if($column.javaField == 'updateTime') ${className}.setUpdateTime(DateUtils.getNowDate()); #end +#end +#if($table.sub) + ${className}Mapper.delete${subClassName}By${subTableFkClassName}(${className}.get${pkColumn.capJavaField}()); + insert${subClassName}(${className}); #end return ${className}Mapper.update${ClassName}(${className}); } @@ -89,9 +111,15 @@ public class ${ClassName}ServiceImpl implements I${ClassName}Service * @param ${pkColumn.javaField}s 需要删除的${functionName}ID * @return 结果 */ +#if($table.sub) + @Transactional +#end @Override public int delete${ClassName}ByIds(${pkColumn.javaType}[] ${pkColumn.javaField}s) { +#if($table.sub) + ${className}Mapper.delete${subClassName}By${subTableFkClassName}s(${pkColumn.javaField}s); +#end return ${className}Mapper.delete${ClassName}ByIds(${pkColumn.javaField}s); } @@ -104,6 +132,35 @@ public class ${ClassName}ServiceImpl implements I${ClassName}Service @Override public int delete${ClassName}ById(${pkColumn.javaType} ${pkColumn.javaField}) { +#if($table.sub) + ${className}Mapper.delete${subClassName}By${subTableFkClassName}(${pkColumn.javaField}); +#end return ${className}Mapper.delete${ClassName}ById(${pkColumn.javaField}); } +#if($table.sub) + + /** + * 新增${subTable.functionName}信息 + * + * @param ${className} ${functionName}对象 + */ + public void insert${subClassName}(${ClassName} ${className}) + { + List<${subClassName}> ${subclassName}List = ${className}.get${subClassName}List(); + Long ${pkColumn.javaField} = ${className}.get${pkColumn.capJavaField}(); + if (StringUtils.isNotNull(${subclassName}List)) + { + List<${subClassName}> list = new ArrayList<${subClassName}>(); + for (${subClassName} ${subclassName} : ${subclassName}List) + { + ${subclassName}.set${subTableFkClassName}(${pkColumn.javaField}); + list.add(${subclassName}); + } + if (list.size() > 0) + { + ${className}Mapper.batch${subClassName}(list); + } + } + } +#end } diff --git a/ruoyi-generator/src/main/resources/vm/java/sub-domain.java.vm b/ruoyi-generator/src/main/resources/vm/java/sub-domain.java.vm new file mode 100644 index 00000000..b5e308cf --- /dev/null +++ b/ruoyi-generator/src/main/resources/vm/java/sub-domain.java.vm @@ -0,0 +1,76 @@ +package ${packageName}.domain; + +#foreach ($import in $subImportList) +import ${import}; +#end +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import com.ruoyi.common.annotation.Excel; +import com.ruoyi.common.core.domain.BaseEntity; + +/** + * ${subTable.functionName}对象 ${subTableName} + * + * @author ${author} + * @date ${datetime} + */ +public class ${subClassName} extends BaseEntity +{ + private static final long serialVersionUID = 1L; + +#foreach ($column in $subTable.columns) +#if(!$table.isSuperColumn($column.javaField)) + /** $column.columnComment */ +#if($column.list) +#set($parentheseIndex=$column.columnComment.indexOf("(")) +#if($parentheseIndex != -1) +#set($comment=$column.columnComment.substring(0, $parentheseIndex)) +#else +#set($comment=$column.columnComment) +#end +#if($parentheseIndex != -1) + @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()") +#elseif($column.javaType == 'Date') + @JsonFormat(pattern = "yyyy-MM-dd") + @Excel(name = "${comment}", width = 30, dateFormat = "yyyy-MM-dd") +#else + @Excel(name = "${comment}") +#end +#end + private $column.javaType $column.javaField; + +#end +#end +#foreach ($column in $subTable.columns) +#if(!$table.isSuperColumn($column.javaField)) +#if($column.javaField.length() > 2 && $column.javaField.substring(1,2).matches("[A-Z]")) +#set($AttrName=$column.javaField) +#else +#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)}) +#end + public void set${AttrName}($column.javaType $column.javaField) + { + this.$column.javaField = $column.javaField; + } + + public $column.javaType get${AttrName}() + { + return $column.javaField; + } +#end +#end + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) +#foreach ($column in $subTable.columns) +#if($column.javaField.length() > 2 && $column.javaField.substring(1,2).matches("[A-Z]")) +#set($AttrName=$column.javaField) +#else +#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)}) +#end + .append("${column.javaField}", get${AttrName}()) +#end + .toString(); + } +} diff --git a/ruoyi-generator/src/main/resources/vm/vue/index-tree.vue.vm b/ruoyi-generator/src/main/resources/vm/vue/index-tree.vue.vm index 501de87b..ecc0fbcc 100644 --- a/ruoyi-generator/src/main/resources/vm/vue/index-tree.vue.vm +++ b/ruoyi-generator/src/main/resources/vm/vue/index-tree.vue.vm @@ -73,7 +73,7 @@ <el-col :span="1.5"> <el-button type="primary" - plain + plain icon="el-icon-plus" size="mini" @click="handleAdd" diff --git a/ruoyi-generator/src/main/resources/vm/vue/index.vue.vm b/ruoyi-generator/src/main/resources/vm/vue/index.vue.vm index 32167a28..cbf3e649 100644 --- a/ruoyi-generator/src/main/resources/vm/vue/index.vue.vm +++ b/ruoyi-generator/src/main/resources/vm/vue/index.vue.vm @@ -73,7 +73,7 @@ <el-col :span="1.5"> <el-button type="primary" - plain + plain icon="el-icon-plus" size="mini" @click="handleAdd" @@ -83,7 +83,7 @@ <el-col :span="1.5"> <el-button type="success" - plain + plain icon="el-icon-edit" size="mini" :disabled="single" @@ -94,7 +94,7 @@ <el-col :span="1.5"> <el-button type="danger" - plain + plain icon="el-icon-delete" size="mini" :disabled="multiple" @@ -105,7 +105,7 @@ <el-col :span="1.5"> <el-button type="warning" - plain + plain icon="el-icon-download" size="mini" @click="handleExport" @@ -265,6 +265,38 @@ #end #end #end +#end +#if($table.sub) + <el-divider content-position="center">${subTable.functionName}信息</el-divider> + <el-row :gutter="10" class="mb8"> + <el-col :span="1.5"> + <el-button type="primary" icon="el-icon-plus" size="mini" @click="handleAdd${subClassName}">添加</el-button> + </el-col> + <el-col :span="1.5"> + <el-button type="danger" icon="el-icon-delete" size="mini" @click="handleDelete${subClassName}">删除</el-button> + </el-col> + </el-row> + <el-table :data="${subclassName}List" :row-class-name="row${subClassName}Index" @selection-change="handle${subClassName}SelectionChange" ref="${subclassName}"> + <el-table-column type="selection" width="50" align="center" /> + <el-table-column label="序号" align="center" prop="index" width="50"/> +#foreach($column in $subTable.columns) +#set($javaField=$column.javaField) +#set($parentheseIndex=$column.columnComment.indexOf("(")) +#if($parentheseIndex != -1) +#set($comment=$column.columnComment.substring(0, $parentheseIndex)) +#else +#set($comment=$column.columnComment) +#end +#if($column.pk || $javaField == ${subTableFkclassName}) +#elseif($column.list && "" != $javaField) + <el-table-column label="$comment" prop="${javaField}"> + <template slot-scope="scope"> + <el-input v-model="scope.row.$javaField" placeholder="请输入$comment" /> + </template> + </el-table-column> +#end +#end + </el-table> #end </el-form> <div slot="footer" class="dialog-footer"> @@ -324,6 +356,10 @@ export default { loading: true, // 选中数组 ids: [], +#if($table.sub) + // 子表选中数据 + checked${subClassName}: [], +#end // 非单个禁用 single: true, // 非多个禁用 @@ -334,6 +370,10 @@ export default { total: 0, // ${functionName}表格数据 ${businessName}List: [], +#if($table.sub) + // ${subTable.functionName}表格数据 + ${subclassName}List: [], +#end // 弹出层标题 title: "", // 是否显示弹出层 @@ -456,6 +496,9 @@ export default { #end #end }; +#if($table.sub) + this.${subclassName}List = []; +#end this.resetForm("form"); }, /** 搜索按钮操作 */ @@ -496,6 +539,9 @@ export default { #if($column.htmlType == "checkbox") this.form.$column.javaField = this.form.${column.javaField}.split(","); #end +#end +#if($table.sub) + this.${subclassName}List = response.data.${subclassName}List; #end this.open = true; this.title = "修改${functionName}"; @@ -509,6 +555,9 @@ export default { #if($column.htmlType == "checkbox") this.form.$column.javaField = this.form.${column.javaField}.join(","); #end +#end +#if($table.sub) + this.form.${subclassName}List = this.${subclassName}List; #end if (this.form.${pkColumn.javaField} != null) { update${BusinessName}(this.form).then(response => { @@ -540,6 +589,40 @@ export default { this.msgSuccess("删除成功"); }) }, +#if($table.sub) + /** ${subTable.functionName}序号 */ + row${subClassName}Index({ row, rowIndex }) { + row.index = rowIndex + 1; + }, + /** ${subTable.functionName}添加按钮操作 */ + handleAdd${subClassName}() { + let obj = {}; +#foreach($column in $subTable.columns) +#if($column.pk || $column.javaField == ${subTableFkclassName}) +#elseif($column.list && "" != $javaField) + obj.$column.javaField = ""; +#end +#end + this.${subclassName}List.push(obj); + }, + /** ${subTable.functionName}删除按钮操作 */ + handleDelete${subClassName}() { + if (this.checked${subClassName}.length == 0) { + this.$alert("请先选择要删除的${subTable.functionName}数据", "提示", { confirmButtonText: "确定", }); + } else { + this.${subclassName}List.splice(this.checked${subClassName}[0].index - 1, 1); + } + }, + /** 单选框选中数据 */ + handle${subClassName}SelectionChange(selection) { + if (selection.length > 1) { + this.$refs.${subclassName}.clearSelection(); + this.$refs.${subclassName}.toggleRowSelection(selection.pop()); + } else { + this.checked${subClassName} = selection; + } + }, +#end /** 导出按钮操作 */ handleExport() { const queryParams = this.queryParams; diff --git a/ruoyi-generator/src/main/resources/vm/xml/mapper.xml.vm b/ruoyi-generator/src/main/resources/vm/xml/mapper.xml.vm index 6c490a4b..93963ea3 100644 --- a/ruoyi-generator/src/main/resources/vm/xml/mapper.xml.vm +++ b/ruoyi-generator/src/main/resources/vm/xml/mapper.xml.vm @@ -9,6 +9,18 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" <result property="${column.javaField}" column="${column.columnName}" /> #end </resultMap> +#if($table.sub) + + <resultMap id="${ClassName}${subClassName}Result" type="${ClassName}" extends="${ClassName}Result"> + <collection property="${subclassName}List" notNullColumn="${subTable.pkColumn.columnName}" javaType="java.util.List" resultMap="${subClassName}Result" /> + </resultMap> + + <resultMap type="${subClassName}" id="${subClassName}Result"> +#foreach ($column in $subTable.columns) + <result property="${column.javaField}" column="${column.columnName}" /> +#end + </resultMap> +#end <sql id="select${ClassName}Vo"> select#foreach($column in $columns) $column.columnName#if($velocityCount != $columns.size()),#end#end from ${tableName} @@ -46,9 +58,18 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" </where> </select> - <select id="select${ClassName}ById" parameterType="${pkColumn.javaType}" resultMap="${ClassName}Result"> + <select id="select${ClassName}ById" parameterType="${pkColumn.javaType}" resultMap="#if($table.sub)${ClassName}${subClassName}Result#else${ClassName}Result#end"> +#if($table.crud || $table.tree) <include refid="select${ClassName}Vo"/> where ${pkColumn.columnName} = #{${pkColumn.javaField}} +#elseif($table.sub) + select#foreach($column in $columns) a.$column.columnName#if($velocityCount != $columns.size()),#end#end, + #foreach($column in $subTable.columns) b.$column.columnName#if($velocityCount != $subTable.columns.size()),#end#end + + from ${tableName} a + left join ${subTableName} b on b.${subTableFkName} = a.${pkColumn.columnName} + where a.${pkColumn.columnName} = #{${pkColumn.javaField}} +#end </select> <insert id="insert${ClassName}" parameterType="${ClassName}"#if($pkColumn.increment) useGeneratedKeys="true" keyProperty="$pkColumn.javaField"#end> @@ -91,5 +112,24 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" #{${pkColumn.javaField}} </foreach> </delete> +#if($table.sub) + <delete id="delete${subClassName}By${subTableFkClassName}s" parameterType="String"> + delete from ${subTableName} where ${subTableFkName} in + <foreach item="${subTableFkclassName}" collection="array" open="(" separator="," close=")"> + #{${subTableFkclassName}} + </foreach> + </delete> + + <delete id="delete${subClassName}By${subTableFkClassName}" parameterType="Long"> + delete from ${subTableName} where ${subTableFkName} = #{${subTableFkclassName}} + </delete> + + <insert id="batch${subClassName}"> + insert into ${subTableName}(#foreach($column in $subTable.columns) $column.columnName#if($velocityCount != $subTable.columns.size()),#end#end) values + <foreach item="item" index="index" collection="list" separator=","> + (#foreach($column in $subTable.columns) #{item.$column.javaField}#if($velocityCount != $subTable.columns.size()),#end#end) + </foreach> + </insert> +#end </mapper> \ No newline at end of file diff --git a/ruoyi-ui/src/views/tool/gen/editTable.vue b/ruoyi-ui/src/views/tool/gen/editTable.vue index 329fce66..39071894 100644 --- a/ruoyi-ui/src/views/tool/gen/editTable.vue +++ b/ruoyi-ui/src/views/tool/gen/editTable.vue @@ -113,7 +113,7 @@ </el-table> </el-tab-pane> <el-tab-pane label="生成信息" name="genInfo"> - <gen-info-form ref="genInfo" :info="info" :menus="menus"/> + <gen-info-form ref="genInfo" :info="info" :tables="tables" :menus="menus"/> </el-tab-pane> </el-tabs> <el-form label-width="100px"> @@ -144,6 +144,8 @@ export default { activeName: "cloum", // 表格的高度 tableHeight: document.documentElement.scrollHeight - 245 + "px", + // 表信息 + tables: [], // 表列信息 cloumns: [], // 字典信息 @@ -161,6 +163,7 @@ export default { getGenTable(tableId).then(res => { this.cloumns = res.data.rows; this.info = res.data.info; + this.tables = res.data.tables; }); /** 查询字典下拉列表 */ getDictOptionselect().then(response => { diff --git a/ruoyi-ui/src/views/tool/gen/genInfoForm.vue b/ruoyi-ui/src/views/tool/gen/genInfoForm.vue index 6fcf27b4..926376c9 100644 --- a/ruoyi-ui/src/views/tool/gen/genInfoForm.vue +++ b/ruoyi-ui/src/views/tool/gen/genInfoForm.vue @@ -4,9 +4,10 @@ <el-col :span="12"> <el-form-item prop="tplCategory"> <span slot="label">生成模板</span> - <el-select v-model="info.tplCategory"> + <el-select v-model="info.tplCategory" @change="tplSelectChange"> <el-option label="单表(增删改查)" value="crud" /> <el-option label="树表(增删改查)" value="tree" /> + <el-option label="主子表(增删改查)" value="sub" /> </el-select> </el-form-item> </el-col> @@ -126,8 +127,8 @@ </span> <el-select v-model="info.treeCode" placeholder="请选择"> <el-option - v-for="column in info.columns" - :key="column.columnName" + v-for="(column, index) in info.columns" + :key="index" :label="column.columnName + ':' + column.columnComment" :value="column.columnName" ></el-option> @@ -144,8 +145,8 @@ </span> <el-select v-model="info.treeParentCode" placeholder="请选择"> <el-option - v-for="column in info.columns" - :key="column.columnName" + v-for="(column, index) in info.columns" + :key="index" :label="column.columnName + ':' + column.columnComment" :value="column.columnName" ></el-option> @@ -162,8 +163,47 @@ </span> <el-select v-model="info.treeName" placeholder="请选择"> <el-option - v-for="column in info.columns" - :key="column.columnName" + v-for="(column, index) in info.columns" + :key="index" + :label="column.columnName + ':' + column.columnComment" + :value="column.columnName" + ></el-option> + </el-select> + </el-form-item> + </el-col> + </el-row> + <el-row v-show="info.tplCategory == 'sub'"> + <h4 class="form-header">关联信息</h4> + <el-col :span="12"> + <el-form-item> + <span slot="label"> + 关联子表的表名 + <el-tooltip content="关联子表的表名, 如:sys_user" placement="top"> + <i class="el-icon-question"></i> + </el-tooltip> + </span> + <el-select v-model="info.subTableName" placeholder="请选择" @change="subSelectChange"> + <el-option + v-for="(table, index) in tables" + :key="index" + :label="table.tableName + ':' + table.tableComment" + :value="table.tableName" + ></el-option> + </el-select> + </el-form-item> + </el-col> + <el-col :span="12"> + <el-form-item> + <span slot="label"> + 子表关联的外键名 + <el-tooltip content="子表关联的外键名, 如:user_id" placement="top"> + <i class="el-icon-question"></i> + </el-tooltip> + </span> + <el-select v-model="info.subTableFkName" placeholder="请选择"> + <el-option + v-for="(column, index) in subColumns" + :key="index" :label="column.columnName + ':' + column.columnComment" :value="column.columnName" ></el-option> @@ -185,6 +225,10 @@ export default { type: Object, default: null }, + tables: { + type: Array, + default: null + }, menus: { type: Array, default: [] @@ -192,6 +236,7 @@ export default { }, data() { return { + subColumns: [], rules: { tplCategory: [ { required: true, message: "请选择生成模板", trigger: "blur" } @@ -212,6 +257,11 @@ export default { }; }, created() {}, + watch: { + 'info.subTableName': function(val) { + this.setSubTableColumns(val); + } + }, methods: { /** 转换菜单数据结构 */ normalizer(node) { @@ -223,6 +273,27 @@ export default { label: node.menuName, children: node.children }; + }, + /** 选择子表名触发 */ + subSelectChange(value) { + this.info.subTableFkName = ''; + }, + /** 选择生成模板触发 */ + tplSelectChange(value) { + if(value !== 'sub') { + this.info.subTableName = ''; + this.info.subTableFkName = ''; + } + }, + /** 设置关联外键 */ + setSubTableColumns(value) { + for (var item in this.tables) { + const name = this.tables[item].tableName; + if (value === name) { + this.subColumns = this.tables[item].columns; + break; + } + } } } }; diff --git a/ruoyi-ui/src/views/tool/gen/index.vue b/ruoyi-ui/src/views/tool/gen/index.vue index 9557a929..113f3540 100644 --- a/ruoyi-ui/src/views/tool/gen/index.vue +++ b/ruoyi-ui/src/views/tool/gen/index.vue @@ -84,7 +84,7 @@ </el-row> <el-table v-loading="loading" :data="tableList" @selection-change="handleSelectionChange"> - <el-table-column type="selection" width="55"></el-table-column> + <el-table-column type="selection" align="center" width="55"></el-table-column> <el-table-column label="序号" type="index" width="50" align="center"> <template slot-scope="scope"> <span>{{(queryParams.pageNum - 1) * queryParams.pageSize + scope.$index + 1}}</span> diff --git a/sql/ry_20201128.sql b/sql/ry_20210108.sql similarity index 98% rename from sql/ry_20201128.sql rename to sql/ry_20210108.sql index 1db0d5af..9e5dc88f 100644 --- a/sql/ry_20201128.sql +++ b/sql/ry_20210108.sql @@ -633,6 +633,8 @@ create table gen_table ( table_id bigint(20) not null auto_increment comment '编号', table_name varchar(200) default '' comment '表名称', table_comment varchar(500) default '' comment '表描述', + sub_table_name varchar(64) default null comment '关联子表的表名', + sub_table_fk_name varchar(64) default null comment '子表关联的外键名', class_name varchar(100) default '' comment '实体类名称', tpl_category varchar(200) default 'crud' comment '使用的模板(crud单表操作 tree树表操作)', package_name varchar(100) comment '生成包路径',