Commit 2afc2caf1d60b705b4876908603237acff0e1c5b

Authored by YunaiV
1 parent 53afc9d5

代码生成:主子表的部分实现

yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/mapper/BaseMapperX.java
@@ -132,4 +132,8 @@ public interface BaseMapperX<T> extends MPJBaseMapper<T> { @@ -132,4 +132,8 @@ public interface BaseMapperX<T> extends MPJBaseMapper<T> {
132 Db.saveOrUpdateBatch(collection); 132 Db.saveOrUpdateBatch(collection);
133 } 133 }
134 134
  135 + default int delete(String field, String value) {
  136 + return delete(new QueryWrapper<T>().eq(field, value));
  137 + }
  138 +
135 } 139 }
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/codegen/inner/CodegenEngine.java
1 package cn.iocoder.yudao.module.infra.service.codegen.inner; 1 package cn.iocoder.yudao.module.infra.service.codegen.inner;
2 2
3 import cn.hutool.core.map.MapUtil; 3 import cn.hutool.core.map.MapUtil;
  4 +import cn.hutool.core.util.ObjUtil;
4 import cn.hutool.core.util.StrUtil; 5 import cn.hutool.core.util.StrUtil;
5 import cn.hutool.extra.template.TemplateConfig; 6 import cn.hutool.extra.template.TemplateConfig;
6 import cn.hutool.extra.template.TemplateEngine; 7 import cn.hutool.extra.template.TemplateEngine;
@@ -25,6 +26,7 @@ import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.CodegenColumnDO; @@ -25,6 +26,7 @@ import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.CodegenColumnDO;
25 import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.CodegenTableDO; 26 import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.CodegenTableDO;
26 import cn.iocoder.yudao.module.infra.enums.codegen.CodegenFrontTypeEnum; 27 import cn.iocoder.yudao.module.infra.enums.codegen.CodegenFrontTypeEnum;
27 import cn.iocoder.yudao.module.infra.enums.codegen.CodegenSceneEnum; 28 import cn.iocoder.yudao.module.infra.enums.codegen.CodegenSceneEnum;
  29 +import cn.iocoder.yudao.module.infra.enums.codegen.CodegenTemplateTypeEnum;
28 import cn.iocoder.yudao.module.infra.framework.codegen.config.CodegenProperties; 30 import cn.iocoder.yudao.module.infra.framework.codegen.config.CodegenProperties;
29 import com.google.common.annotations.VisibleForTesting; 31 import com.google.common.annotations.VisibleForTesting;
30 import com.google.common.collect.ImmutableTable; 32 import com.google.common.collect.ImmutableTable;
@@ -34,11 +36,7 @@ import org.springframework.stereotype.Component; @@ -34,11 +36,7 @@ import org.springframework.stereotype.Component;
34 36
35 import javax.annotation.PostConstruct; 37 import javax.annotation.PostConstruct;
36 import javax.annotation.Resource; 38 import javax.annotation.Resource;
37 -import java.util.HashMap;  
38 -import java.util.LinkedHashMap;  
39 -import java.util.List;  
40 -import java.util.Map;  
41 -import java.util.function.Predicate; 39 +import java.util.*;
42 40
43 import static cn.hutool.core.map.MapUtil.getStr; 41 import static cn.hutool.core.map.MapUtil.getStr;
44 import static cn.hutool.core.text.CharSequenceUtil.*; 42 import static cn.hutool.core.text.CharSequenceUtil.*;
@@ -74,8 +72,12 @@ public class CodegenEngine { @@ -74,8 +72,12 @@ public class CodegenEngine {
74 javaModuleImplMainFilePath("convert/${table.businessName}/${table.className}Convert")) 72 javaModuleImplMainFilePath("convert/${table.businessName}/${table.className}Convert"))
75 .put(javaTemplatePath("dal/do"), 73 .put(javaTemplatePath("dal/do"),
76 javaModuleImplMainFilePath("dal/dataobject/${table.businessName}/${table.className}DO")) 74 javaModuleImplMainFilePath("dal/dataobject/${table.businessName}/${table.className}DO"))
  75 + .put(javaTemplatePath("dal/do_sub"), // 特殊:主子表专属逻辑
  76 + javaModuleImplMainFilePath("dal/dataobject/${table.businessName}/${subTable.className}DO"))
77 .put(javaTemplatePath("dal/mapper"), 77 .put(javaTemplatePath("dal/mapper"),
78 javaModuleImplMainFilePath("dal/mysql/${table.businessName}/${table.className}Mapper")) 78 javaModuleImplMainFilePath("dal/mysql/${table.businessName}/${table.className}Mapper"))
  79 + .put(javaTemplatePath("dal/mapper_sub"), // 特殊:主子表专属逻辑
  80 + javaModuleImplMainFilePath("dal/mysql/${table.businessName}/${subTable.className}Mapper"))
79 .put(javaTemplatePath("dal/mapper.xml"), mapperXmlFilePath()) 81 .put(javaTemplatePath("dal/mapper.xml"), mapperXmlFilePath())
80 .put(javaTemplatePath("service/serviceImpl"), 82 .put(javaTemplatePath("service/serviceImpl"),
81 javaModuleImplMainFilePath("service/${table.businessName}/${table.className}ServiceImpl")) 83 javaModuleImplMainFilePath("service/${table.businessName}/${table.className}ServiceImpl"))
@@ -196,11 +198,6 @@ public class CodegenEngine { @@ -196,11 +198,6 @@ public class CodegenEngine {
196 bindingMap.put("columns", columns); 198 bindingMap.put("columns", columns);
197 bindingMap.put("primaryColumn", CollectionUtils.findFirst(columns, CodegenColumnDO::getPrimaryKey)); // 主键字段 199 bindingMap.put("primaryColumn", CollectionUtils.findFirst(columns, CodegenColumnDO::getPrimaryKey)); // 主键字段
198 bindingMap.put("sceneEnum", CodegenSceneEnum.valueOf(table.getScene())); 200 bindingMap.put("sceneEnum", CodegenSceneEnum.valueOf(table.getScene()));
199 - if (subTable != null) {  
200 - bindingMap.put("subTable", subTable);  
201 - bindingMap.put("subColumns", subColumns);  
202 - bindingMap.put("subColumn", CollectionUtils.findFirst(subColumns, column -> column.getId().equals(table.getSubColumnId())));  
203 - }  
204 201
205 // className 相关 202 // className 相关
206 // 去掉指定前缀,将 TestDictType 转换成 DictType. 因为在 create 等方法后,不需要带上 Test 前缀 203 // 去掉指定前缀,将 TestDictType 转换成 DictType. 因为在 create 等方法后,不需要带上 Test 前缀
@@ -214,8 +211,21 @@ public class CodegenEngine { @@ -214,8 +211,21 @@ public class CodegenEngine {
214 // permission 前缀 211 // permission 前缀
215 bindingMap.put("permissionPrefix", table.getModuleName() + ":" + simpleClassNameStrikeCase); 212 bindingMap.put("permissionPrefix", table.getModuleName() + ":" + simpleClassNameStrikeCase);
216 213
  214 + // 特殊:主子表专属逻辑
  215 + if (subTable != null) {
  216 + // 创建 bindingMap
  217 + bindingMap.put("subTable", subTable);
  218 + bindingMap.put("subColumns", subColumns);
  219 + bindingMap.put("subColumn", CollectionUtils.findFirst(subColumns, // 关联的字段
  220 + column -> Objects.equals(column.getId(), table.getSubColumnId())));
  221 + // className 相关
  222 + String subSimpleClassName = removePrefix(subTable.getClassName(), upperFirst(subTable.getModuleName()));
  223 + bindingMap.put("subSimpleClassName", subSimpleClassName);
  224 + bindingMap.put("subClassNameVar", lowerFirst(subSimpleClassName)); // 将 DictType 转换成 dictType,用于变量
  225 + }
  226 +
217 // 执行生成 227 // 执行生成
218 - Map<String, String> templates = getTemplates(table.getFrontType()); 228 + Map<String, String> templates = getTemplates(table.getTemplateType(), table.getFrontType());
219 Map<String, String> result = Maps.newLinkedHashMapWithExpectedSize(templates.size()); // 有序 229 Map<String, String> result = Maps.newLinkedHashMapWithExpectedSize(templates.size()); // 有序
220 templates.forEach((vmPath, filePath) -> { 230 templates.forEach((vmPath, filePath) -> {
221 filePath = formatFilePath(filePath, bindingMap); 231 filePath = formatFilePath(filePath, bindingMap);
@@ -227,10 +237,15 @@ public class CodegenEngine { @@ -227,10 +237,15 @@ public class CodegenEngine {
227 return result; 237 return result;
228 } 238 }
229 239
230 - private Map<String, String> getTemplates(Integer frontType) { 240 + private Map<String, String> getTemplates(Integer templateType, Integer frontType) {
231 Map<String, String> templates = new LinkedHashMap<>(); 241 Map<String, String> templates = new LinkedHashMap<>();
232 templates.putAll(SERVER_TEMPLATES); 242 templates.putAll(SERVER_TEMPLATES);
233 templates.putAll(FRONT_TEMPLATES.row(frontType)); 243 templates.putAll(FRONT_TEMPLATES.row(frontType));
  244 + // 特殊:主子表专属逻辑
  245 + if (ObjUtil.notEqual(templateType, CodegenTemplateTypeEnum.MASTER_SUB.getType())) {
  246 + templates.remove(javaTemplatePath("dal/do_sub"));
  247 + templates.remove(javaTemplatePath("dal/mapper_sub"));
  248 + }
234 return templates; 249 return templates;
235 } 250 }
236 251
@@ -250,6 +265,11 @@ public class CodegenEngine { @@ -250,6 +265,11 @@ public class CodegenEngine {
250 filePath = StrUtil.replace(filePath, "${table.moduleName}", table.getModuleName()); 265 filePath = StrUtil.replace(filePath, "${table.moduleName}", table.getModuleName());
251 filePath = StrUtil.replace(filePath, "${table.businessName}", table.getBusinessName()); 266 filePath = StrUtil.replace(filePath, "${table.businessName}", table.getBusinessName());
252 filePath = StrUtil.replace(filePath, "${table.className}", table.getClassName()); 267 filePath = StrUtil.replace(filePath, "${table.className}", table.getClassName());
  268 + // 特殊:主子表专属逻辑
  269 + CodegenTableDO subTable = (CodegenTableDO) bindingMap.get("subTable");
  270 + if (subTable != null) {
  271 + filePath = StrUtil.replace(filePath, "${subTable.className}", subTable.getClassName());
  272 + }
253 return filePath; 273 return filePath;
254 } 274 }
255 275
yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/controller/vo/baseVO.vm
@@ -22,6 +22,10 @@ import static ${DateUtilsClassName}.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; @@ -22,6 +22,10 @@ import static ${DateUtilsClassName}.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
22 #break 22 #break
23 #end 23 #end
24 #end 24 #end
  25 +## 特殊:主子表专属逻辑
  26 +#if ( $subTable )
  27 +import ${basePackage}.module.${subTable.moduleName}.dal.dataobject.${subTable.businessName}.${subTable.className}DO;
  28 +#end
25 29
26 /** 30 /**
27 * ${table.classComment} Base VO,提供给添加、修改、详细的子 VO 使用 31 * ${table.classComment} Base VO,提供给添加、修改、详细的子 VO 使用
@@ -36,4 +40,9 @@ public class ${sceneEnum.prefixClass}${table.className}BaseVO { @@ -36,4 +40,9 @@ public class ${sceneEnum.prefixClass}${table.className}BaseVO {
36 40
37 #end 41 #end
38 #end 42 #end
39 -} 43 +## 特殊:主子表专属逻辑
  44 +#if ( $subTable )
  45 + private List<${subTable.className}DO> ${subClassNameVar}s;
  46 +
  47 +#end
  48 +}
40 \ No newline at end of file 49 \ No newline at end of file
yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/dal/do_sub.vm 0 → 100644
  1 +package ${basePackage}.module.${subTable.moduleName}.dal.dataobject.${subTable.businessName};
  2 +
  3 +import lombok.*;
  4 +import java.util.*;
  5 +#foreach ($column in $subColumns)
  6 +#if (${column.javaType} == "BigDecimal")
  7 +import java.math.BigDecimal;
  8 +#end
  9 +#if (${column.javaType} == "LocalDateTime")
  10 +import java.time.LocalDateTime;
  11 +#end
  12 +#end
  13 +import com.baomidou.mybatisplus.annotation.*;
  14 +import ${BaseDOClassName};
  15 +
  16 +/**
  17 + * ${subTable.classComment} DO
  18 + *
  19 + * @author ${subTable.author}
  20 + */
  21 +@TableName("${subTable.tableName.toLowerCase()}")
  22 +@KeySequence("${subTable.tableName.toLowerCase()}_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
  23 +@Data
  24 +@EqualsAndHashCode(callSuper = true)
  25 +@ToString(callSuper = true)
  26 +@Builder
  27 +@NoArgsConstructor
  28 +@AllArgsConstructor
  29 +public class ${subTable.className}DO extends BaseDO {
  30 +
  31 +#foreach ($column in $subColumns)
  32 +#if (!${baseDOFields.contains(${column.javaField})})##排除 BaseDO 的字段
  33 + /**
  34 + * ${column.columnComment}
  35 + #if ("$!column.dictType" != "")##处理枚举值
  36 + *
  37 + * 枚举 {@link TODO ${column.dictType} 对应的类}
  38 + #end
  39 + */
  40 + #if (${column.primaryKey})##处理主键
  41 + @TableId#if (${column.javaType} == 'String')(type = IdType.INPUT)#end
  42 + #end
  43 + private ${column.javaType} ${column.javaField};
  44 +#end
  45 +#end
  46 +
  47 +}
0 \ No newline at end of file 48 \ No newline at end of file
yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/dal/mapper_sub.vm 0 → 100644
  1 +package ${basePackage}.module.${subTable.moduleName}.dal.mysql.${subTable.businessName};
  2 +
  3 +import java.util.*;
  4 +
  5 +import ${BaseMapperClassName};
  6 +import ${basePackage}.module.${subTable.moduleName}.dal.dataobject.${subTable.businessName}.${subTable.className}DO;
  7 +import org.apache.ibatis.annotations.Mapper;
  8 +
  9 +#set ($SubColumnName = $subColumn.javaField.substring(0,1).toUpperCase() + ${subColumn.javaField.substring(1)})##首字母大写
  10 +/**
  11 + * ${subTable.classComment} Mapper
  12 + *
  13 + * @author ${subTable.author}
  14 + */
  15 +@Mapper
  16 +public interface ${subTable.className}Mapper extends BaseMapperX<${subTable.className}DO> {
  17 +
  18 + default List<${subTable.className}DO> selectListBy${SubColumnName}(${subColumn.javaType} ${subColumn.javaField}) {
  19 + return selectList(${subTable.className}DO::get${SubColumnName}, ${subColumn.javaField});
  20 + }
  21 +
  22 + default List<${subTable.className}DO> selectListBy${SubColumnName}(List<${subColumn.javaType}> ${subColumn.javaField}s) {
  23 + return selectList(${subTable.className}DO::get${SubColumnName}, ${subColumn.javaField}s);
  24 + }
  25 +
  26 +}
0 \ No newline at end of file 27 \ No newline at end of file
yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/service/serviceImpl.vm
@@ -7,10 +7,18 @@ import org.springframework.validation.annotation.Validated; @@ -7,10 +7,18 @@ import org.springframework.validation.annotation.Validated;
7 import java.util.*; 7 import java.util.*;
8 import ${basePackage}.module.${table.moduleName}.controller.${sceneEnum.basePackage}.${table.businessName}.vo.*; 8 import ${basePackage}.module.${table.moduleName}.controller.${sceneEnum.basePackage}.${table.businessName}.vo.*;
9 import ${basePackage}.module.${table.moduleName}.dal.dataobject.${table.businessName}.${table.className}DO; 9 import ${basePackage}.module.${table.moduleName}.dal.dataobject.${table.businessName}.${table.className}DO;
  10 +## 特殊:主子表专属逻辑
  11 +#if( $subTable )
  12 +import ${basePackage}.module.${subTable.moduleName}.dal.dataobject.${subTable.businessName}.${subTable.className}DO;
  13 +#end
10 import ${PageResultClassName}; 14 import ${PageResultClassName};
11 15
12 import ${basePackage}.module.${table.moduleName}.convert.${table.businessName}.${table.className}Convert; 16 import ${basePackage}.module.${table.moduleName}.convert.${table.businessName}.${table.className}Convert;
13 import ${basePackage}.module.${table.moduleName}.dal.mysql.${table.businessName}.${table.className}Mapper; 17 import ${basePackage}.module.${table.moduleName}.dal.mysql.${table.businessName}.${table.className}Mapper;
  18 +## 特殊:主子表专属逻辑
  19 +#if( $subTable )
  20 +import ${basePackage}.module.${subTable.moduleName}.dal.mysql.${subTable.businessName}.${subClassNameVar}Mapper;
  21 +#end
14 22
15 import static ${ServiceExceptionUtilClassName}.exception; 23 import static ${ServiceExceptionUtilClassName}.exception;
16 import static ${basePackage}.module.${table.moduleName}.enums.ErrorCodeConstants.*; 24 import static ${basePackage}.module.${table.moduleName}.enums.ErrorCodeConstants.*;
@@ -29,12 +37,22 @@ public class ${table.className}ServiceImpl implements ${table.className}Service @@ -29,12 +37,22 @@ public class ${table.className}ServiceImpl implements ${table.className}Service
29 37
30 @Resource 38 @Resource
31 private ${table.className}Mapper ${classNameVar}Mapper; 39 private ${table.className}Mapper ${classNameVar}Mapper;
  40 +## 特殊:主子表专属逻辑
  41 +#if( $subTable )
  42 + @Resource
  43 + private ${subTable.className}Mapper ${subClassNameVar}Mapper;
  44 +#end
32 45
33 @Override 46 @Override
34 public ${primaryColumn.javaType} create${simpleClassName}(${sceneEnum.prefixClass}${table.className}CreateReqVO createReqVO) { 47 public ${primaryColumn.javaType} create${simpleClassName}(${sceneEnum.prefixClass}${table.className}CreateReqVO createReqVO) {
35 // 插入 48 // 插入
36 ${table.className}DO ${classNameVar} = ${table.className}Convert.INSTANCE.convert(createReqVO); 49 ${table.className}DO ${classNameVar} = ${table.className}Convert.INSTANCE.convert(createReqVO);
37 ${classNameVar}Mapper.insert(${classNameVar}); 50 ${classNameVar}Mapper.insert(${classNameVar});
  51 +## 特殊:主子表专属逻辑
  52 +#if( $subTable )
  53 + // 插入子表
  54 + ${subClassNameVar}Mapper.insertBatch(createReqVO.get${subSimpleClassName}s);
  55 +#end
38 // 返回 56 // 返回
39 return ${classNameVar}.getId(); 57 return ${classNameVar}.getId();
40 } 58 }
yudao-module-infra/yudao-module-infra-biz/src/test/java/cn/iocoder/yudao/module/infra/service/codegen/inner/CodegenEngineTest.java
1 package cn.iocoder.yudao.module.infra.service.codegen.inner; 1 package cn.iocoder.yudao.module.infra.service.codegen.inner;
2 2
3 -import cn.hutool.core.io.FileUtil;  
4 -import cn.hutool.core.io.IoUtil;  
5 import cn.hutool.core.io.resource.ResourceUtil; 3 import cn.hutool.core.io.resource.ResourceUtil;
6 -import cn.hutool.core.util.ClassUtil;  
7 import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest; 4 import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;
8 import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.CodegenColumnDO; 5 import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.CodegenColumnDO;
9 import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.CodegenTableDO; 6 import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.CodegenTableDO;
@@ -13,16 +10,14 @@ import org.apache.ibatis.type.JdbcType; @@ -13,16 +10,14 @@ import org.apache.ibatis.type.JdbcType;
13 import org.junit.jupiter.api.BeforeEach; 10 import org.junit.jupiter.api.BeforeEach;
14 import org.junit.jupiter.api.Test; 11 import org.junit.jupiter.api.Test;
15 import org.mockito.InjectMocks; 12 import org.mockito.InjectMocks;
16 -import org.mockito.Mock;  
17 import org.mockito.Spy; 13 import org.mockito.Spy;
18 14
19 import java.util.Arrays; 15 import java.util.Arrays;
  16 +import java.util.Collections;
20 import java.util.List; 17 import java.util.List;
21 import java.util.Map; 18 import java.util.Map;
22 -import java.util.function.BiConsumer;  
23 19
24 import static org.junit.jupiter.api.Assertions.assertEquals; 20 import static org.junit.jupiter.api.Assertions.assertEquals;
25 -import static org.junit.jupiter.api.Assertions.assertTrue;  
26 21
27 /** 22 /**
28 * {@link CodegenEngine} 的单元测试 23 * {@link CodegenEngine} 的单元测试
@@ -118,7 +113,7 @@ public class CodegenEngineTest extends BaseMockitoUnitTest { @@ -118,7 +113,7 @@ public class CodegenEngineTest extends BaseMockitoUnitTest {
118 .setCreateOperation(true).setUpdateOperation(true).setListOperation(true) 113 .setCreateOperation(true).setUpdateOperation(true).setListOperation(true)
119 .setListOperationCondition(CodegenColumnListConditionEnum.BETWEEN.getCondition()).setListOperationResult(true) 114 .setListOperationCondition(CodegenColumnListConditionEnum.BETWEEN.getCondition()).setListOperationResult(true)
120 .setHtmlType(CodegenColumnHtmlTypeEnum.DATETIME.getType()); 115 .setHtmlType(CodegenColumnHtmlTypeEnum.DATETIME.getType());
121 - List<CodegenColumnDO> columns = Arrays.asList(idColumn, nameColumn, avatarColumn, descriptionColumn, 116 + List<CodegenColumnDO> columns = Arrays.asList(idColumn, nameColumn, avatarColumn, videoColumn, descriptionColumn,
122 sex1Column, sex2Column, sex3Column, birthdayColumn, memoColumn, createTimeColumn); 117 sex1Column, sex2Column, sex3Column, birthdayColumn, memoColumn, createTimeColumn);
123 118
124 // 调用 119 // 调用
@@ -168,14 +163,92 @@ public class CodegenEngineTest extends BaseMockitoUnitTest { @@ -168,14 +163,92 @@ public class CodegenEngineTest extends BaseMockitoUnitTest {
168 result, "yudao-ui-admin-vue3/src/views/system/user/UserForm.vue"); 163 result, "yudao-ui-admin-vue3/src/views/system/user/UserForm.vue");
169 assertPathContentEquals("vue3_crud/vue/api", 164 assertPathContentEquals("vue3_crud/vue/api",
170 result, "yudao-ui-admin-vue3/src/api/system/user/index.ts"); 165 result, "yudao-ui-admin-vue3/src/api/system/user/index.ts");
171 -// result.forEach(new BiConsumer<String, String>() {  
172 -// @Override  
173 -// public void accept(String s, String s2) {  
174 -// System.out.println(s);  
175 -// System.out.println(s2);  
176 -// System.out.println("=================");  
177 -// }  
178 -// }); 166 + }
  167 +
  168 + @Test
  169 + public void testExecute_vue3_masterSub() {
  170 + // 准备请求参数
  171 + // 主表
  172 + CodegenTableDO table = new CodegenTableDO().setScene(CodegenSceneEnum.ADMIN.getScene())
  173 + .setTableName("system_user").setTableComment("用户表")
  174 + .setModuleName("system").setBusinessName("user").setClassName("SystemUser")
  175 + .setClassComment("用户").setAuthor("芋道源码")
  176 + .setTemplateType(CodegenTemplateTypeEnum.MASTER_SUB.getType()).setSubColumnId(100L)
  177 + .setFrontType(CodegenFrontTypeEnum.VUE3.getType())
  178 + .setParentMenuId(10L);
  179 + CodegenColumnDO idColumn = new CodegenColumnDO().setColumnName("id").setDataType(JdbcType.BIGINT.name())
  180 + .setColumnComment("编号").setNullable(false).setPrimaryKey(true).setAutoIncrement(true)
  181 + .setOrdinalPosition(1).setJavaType("Long").setJavaField("id").setExample("1024")
  182 + .setCreateOperation(false).setUpdateOperation(true).setListOperation(false)
  183 + .setListOperationResult(true);
  184 + List<CodegenColumnDO> columns = Collections.singletonList(idColumn);
  185 + // 子表
  186 + CodegenTableDO subTable = new CodegenTableDO().setScene(CodegenSceneEnum.ADMIN.getScene())
  187 + .setTableName("system_user_contact").setTableComment("用户联系人表")
  188 + .setModuleName("system").setBusinessName("user").setClassName("SystemUserContact")
  189 + .setClassComment("用户联系人").setAuthor("芋道源码")
  190 + .setTemplateType(CodegenTemplateTypeEnum.CRUD.getType())
  191 + .setFrontType(CodegenFrontTypeEnum.VUE3.getType());
  192 + CodegenColumnDO subIdColumn = new CodegenColumnDO().setColumnName("id").setDataType(JdbcType.BIGINT.name())
  193 + .setColumnComment("编号").setNullable(false).setPrimaryKey(true).setAutoIncrement(true)
  194 + .setOrdinalPosition(1).setJavaType("Long").setJavaField("id").setExample("1024")
  195 + .setCreateOperation(false).setUpdateOperation(true).setListOperation(false)
  196 + .setListOperationResult(true);
  197 + CodegenColumnDO userIdColumn = new CodegenColumnDO().setColumnName("user_id").setDataType(JdbcType.BIGINT.name())
  198 + .setColumnComment("用户编号").setNullable(false).setPrimaryKey(false)
  199 + .setOrdinalPosition(2).setJavaType("Long").setJavaField("userId").setExample("2048")
  200 + .setCreateOperation(false).setUpdateOperation(true).setListOperation(false)
  201 + .setListOperationResult(true)
  202 + .setId(100L);
  203 + List<CodegenColumnDO> subColumns = Arrays.asList(subIdColumn, userIdColumn);
  204 +
  205 + // 调用
  206 + Map<String, String> result = codegenEngine.execute(table, columns, subTable, subColumns);
  207 +
  208 + // 断言
  209 + assertEquals(23, result.size());
  210 +// // 断言 vo 类
  211 +// for (String vo : new String[]{"SystemUserBaseVO", "SystemUserCreateReqVO", "SystemUserUpdateReqVO", "SystemUserRespVO",
  212 +// "SystemUserPageReqVO", "SystemUserExportReqVO", "SystemUserExcelVO"}) {
  213 +// assertPathContentEquals("vue3_crud/java/" + vo,
  214 +// result, "yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/module/system/controller/admin/user/vo/" + vo + ".java");
  215 +// }
  216 +// // 断言 controller 类
  217 +// assertPathContentEquals("vue3_crud/java/SystemUserController",
  218 +// result, "yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/module/system/controller/admin/user/SystemUserController.java");
  219 +// // 断言 service 类
  220 +// assertPathContentEquals("vue3_crud/java/SystemUserService",
  221 +// result, "yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/module/system/service/user/SystemUserService.java");
  222 +// assertPathContentEquals("vue3_crud/java/SystemUserServiceImpl",
  223 +// result, "yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/module/system/service/user/SystemUserServiceImpl.java");
  224 +// // 断言 convert 类
  225 +// assertPathContentEquals("vue3_crud/java/SystemUserConvert",
  226 +// result, "yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/module/system/convert/user/SystemUserConvert.java");
  227 +// // 断言 enums 类
  228 +// assertPathContentEquals("vue3_crud/java/ErrorCodeConstants",
  229 +// result, "yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/module/system/enums/ErrorCodeConstants_手动操作.java");
  230 +// // 断言 dal 类
  231 +// assertPathContentEquals("vue3_crud/java/SystemUserDO",
  232 +// result, "yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/module/system/dal/dataobject/user/SystemUserDO.java");
  233 +// assertPathContentEquals("vue3_crud/java/SystemUserMapper",
  234 +// result, "yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/module/system/dal/mysql/user/SystemUserMapper.java");
  235 +// assertPathContentEquals("vue3_crud/java/SystemUserMapper_xml",
  236 +// result, "yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/user/SystemUserMapper.xml");
  237 +// // 断言 test 类
  238 +// assertPathContentEquals("vue3_crud/java/SystemUserServiceImplTest",
  239 +// result, "yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/module/system/service/user/SystemUserServiceImplTest.java");
  240 +// // 断言 sql 语句
  241 +// assertPathContentEquals("vue3_crud/sql/h2",
  242 +// result, "sql/h2.sql");
  243 +// assertPathContentEquals("vue3_crud/sql/sql",
  244 +// result, "sql/sql.sql");
  245 +// // 断言 vue 语句
  246 +// assertPathContentEquals("vue3_crud/vue/index",
  247 +// result, "yudao-ui-admin-vue3/src/views/system/user/index.vue");
  248 +// assertPathContentEquals("vue3_crud/vue/form",
  249 +// result, "yudao-ui-admin-vue3/src/views/system/user/UserForm.vue");
  250 +// assertPathContentEquals("vue3_crud/vue/api",
  251 +// result, "yudao-ui-admin-vue3/src/api/system/user/index.ts");
179 } 252 }
180 253
181 private void assertPathContentEquals(String path, Map<String, String> result, String key) { 254 private void assertPathContentEquals(String path, Map<String, String> result, String key) {
@@ -184,4 +257,4 @@ public class CodegenEngineTest extends BaseMockitoUnitTest { @@ -184,4 +257,4 @@ public class CodegenEngineTest extends BaseMockitoUnitTest {
184 assertEquals(pathContent, valueContent); 257 assertEquals(pathContent, valueContent);
185 } 258 }
186 259
187 -}  
188 \ No newline at end of file 260 \ No newline at end of file
  261 +}
yudao-module-infra/yudao-module-infra-biz/src/test/resources/codegen/vue3_crud/java/SystemUserBaseVO
@@ -24,6 +24,9 @@ public class SystemUserBaseVO { @@ -24,6 +24,9 @@ public class SystemUserBaseVO {
24 @Schema(description = "头像", example = "https://www.iocoder.cn/1.png") 24 @Schema(description = "头像", example = "https://www.iocoder.cn/1.png")
25 private String avatar; 25 private String avatar;
26 26
  27 + @Schema(description = "视频", example = "https://www.iocoder.cn/1.mp4")
  28 + private String video;
  29 +
27 @Schema(description = "个人简介", example = "我是介绍") 30 @Schema(description = "个人简介", example = "我是介绍")
28 private String description; 31 private String description;
29 32
yudao-module-infra/yudao-module-infra-biz/src/test/resources/codegen/vue3_crud/java/SystemUserDO
@@ -36,6 +36,10 @@ public class SystemUserDO extends BaseDO { @@ -36,6 +36,10 @@ public class SystemUserDO extends BaseDO {
36 */ 36 */
37 private String avatar; 37 private String avatar;
38 /** 38 /**
  39 + * 视频
  40 + */
  41 + private String video;
  42 + /**
39 * 个人简介 43 * 个人简介
40 */ 44 */
41 private String description; 45 private String description;
yudao-module-infra/yudao-module-infra-biz/src/test/resources/codegen/vue3_crud/java/SystemUserExcelVO
@@ -28,6 +28,9 @@ public class SystemUserExcelVO { @@ -28,6 +28,9 @@ public class SystemUserExcelVO {
28 @ExcelProperty("头像") 28 @ExcelProperty("头像")
29 private String avatar; 29 private String avatar;
30 30
  31 + @ExcelProperty("视频")
  32 + private String video;
  33 +
31 @ExcelProperty("个人简介") 34 @ExcelProperty("个人简介")
32 private String description; 35 private String description;
33 36
yudao-module-infra/yudao-module-infra-biz/src/test/resources/codegen/vue3_crud/sql/h2
@@ -3,6 +3,7 @@ CREATE TABLE IF NOT EXISTS &quot;system_user&quot; ( @@ -3,6 +3,7 @@ CREATE TABLE IF NOT EXISTS &quot;system_user&quot; (
3 "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, 3 "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
4 "name" varchar NOT NULL, 4 "name" varchar NOT NULL,
5 "avatar" varchar, 5 "avatar" varchar,
  6 + "video" varchar,
6 "description" varchar, 7 "description" varchar,
7 "sex1" varchar, 8 "sex1" varchar,
8 "sex2" int, 9 "sex2" int,
yudao-module-infra/yudao-module-infra-biz/src/test/resources/codegen/vue3_crud/vue/api
@@ -4,6 +4,7 @@ export interface UserVO { @@ -4,6 +4,7 @@ export interface UserVO {
4 id: number 4 id: number
5 name: string 5 name: string
6 avatar: string 6 avatar: string
  7 + video: string
7 description: string 8 description: string
8 sex1: string 9 sex1: string
9 sex2: number 10 sex2: number
yudao-module-infra/yudao-module-infra-biz/src/test/resources/codegen/vue3_crud/vue/form
@@ -86,6 +86,7 @@ const formData = ref({ @@ -86,6 +86,7 @@ const formData = ref({
86 id: undefined, 86 id: undefined,
87 name: undefined, 87 name: undefined,
88 avatar: undefined, 88 avatar: undefined,
  89 + video: undefined,
89 description: undefined, 90 description: undefined,
90 sex1: undefined, 91 sex1: undefined,
91 sex2: [], 92 sex2: [],
@@ -149,6 +150,7 @@ const resetForm = () =&gt; { @@ -149,6 +150,7 @@ const resetForm = () =&gt; {
149 id: undefined, 150 id: undefined,
150 name: undefined, 151 name: undefined,
151 avatar: undefined, 152 avatar: undefined,
  153 + video: undefined,
152 description: undefined, 154 description: undefined,
153 sex1: undefined, 155 sex1: undefined,
154 sex2: [], 156 sex2: [],
yudao-module-infra/yudao-module-infra-biz/src/test/resources/codegen/vue3_crud/vue/index
@@ -95,6 +95,11 @@ @@ -95,6 +95,11 @@
95 <dict-tag :type="DICT_TYPE.$dictType.toUpperCase()" :value="scope.row.avatar" /> 95 <dict-tag :type="DICT_TYPE.$dictType.toUpperCase()" :value="scope.row.avatar" />
96 </template> 96 </template>
97 </el-table-column> 97 </el-table-column>
  98 + <el-table-column label="视频" align="center" prop="video">
  99 + <template #default="scope">
  100 + <dict-tag :type="DICT_TYPE.$dictType.toUpperCase()" :value="scope.row.video" />
  101 + </template>
  102 + </el-table-column>
98 <el-table-column label="个人简介" align="center" prop="description"> 103 <el-table-column label="个人简介" align="center" prop="description">
99 <template #default="scope"> 104 <template #default="scope">
100 <dict-tag :type="DICT_TYPE.$dictType.toUpperCase()" :value="scope.row.description" /> 105 <dict-tag :type="DICT_TYPE.$dictType.toUpperCase()" :value="scope.row.description" />