✅ 增加 codegen 模块的单测覆盖率
This commit is contained in:
parent
e4c62c34b3
commit
6210bde1de
@ -73,6 +73,23 @@ public class CollectionUtils {
|
||||
return from.stream().filter(filter).map(func).filter(Objects::nonNull).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public static <T, U> List<U> convertListByFlatMap(Collection<T> from,
|
||||
Function<T, ? extends Stream<? extends U>> func) {
|
||||
if (CollUtil.isEmpty(from)) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
return from.stream().flatMap(func).filter(Objects::nonNull).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public static <T, U, R> List<R> convertListByFlatMap(Collection<T> from,
|
||||
Function<? super T, ? extends U> mapper,
|
||||
Function<U, ? extends Stream<? extends R>> func) {
|
||||
if (CollUtil.isEmpty(from)) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
return from.stream().map(mapper).flatMap(func).filter(Objects::nonNull).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public static <K, V> List<V> mergeValuesFromMap(Map<K, List<V>> map) {
|
||||
return map.values()
|
||||
.stream()
|
||||
@ -101,6 +118,23 @@ public class CollectionUtils {
|
||||
return from.stream().filter(filter).collect(Collectors.toMap(keyFunc, v -> v));
|
||||
}
|
||||
|
||||
public static <T, U> Set<U> convertSetByFlatMap(Collection<T> from,
|
||||
Function<T, ? extends Stream<? extends U>> func) {
|
||||
if (CollUtil.isEmpty(from)) {
|
||||
return new HashSet<>();
|
||||
}
|
||||
return from.stream().flatMap(func).filter(Objects::nonNull).collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
public static <T, U, R> Set<R> convertSetByFlatMap(Collection<T> from,
|
||||
Function<? super T, ? extends U> mapper,
|
||||
Function<U, ? extends Stream<? extends R>> func) {
|
||||
if (CollUtil.isEmpty(from)) {
|
||||
return new HashSet<>();
|
||||
}
|
||||
return from.stream().map(mapper).flatMap(func).filter(Objects::nonNull).collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
public static <T, K> Map<K, T> convertMap(Collection<T> from, Function<T, K> keyFunc) {
|
||||
if (CollUtil.isEmpty(from)) {
|
||||
return new HashMap<>();
|
||||
@ -272,38 +306,4 @@ public class CollectionUtils {
|
||||
return deptId == null ? Collections.emptyList() : Collections.singleton(deptId);
|
||||
}
|
||||
|
||||
public static <T, U> List<U> convertListByFlatMap(Collection<T> from,
|
||||
Function<T, ? extends Stream<? extends U>> func) {
|
||||
if (CollUtil.isEmpty(from)) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
return from.stream().flatMap(func).filter(Objects::nonNull).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public static <T, U, R> List<R> convertListByFlatMap(Collection<T> from,
|
||||
Function<? super T, ? extends U> mapper,
|
||||
Function<U, ? extends Stream<? extends R>> func) {
|
||||
if (CollUtil.isEmpty(from)) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
return from.stream().map(mapper).flatMap(func).filter(Objects::nonNull).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public static <T, U> Set<U> convertSetByFlatMap(Collection<T> from,
|
||||
Function<T, ? extends Stream<? extends U>> func) {
|
||||
if (CollUtil.isEmpty(from)) {
|
||||
return new HashSet<>();
|
||||
}
|
||||
return from.stream().flatMap(func).filter(Objects::nonNull).collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
public static <T, U, R> Set<R> convertSetByFlatMap(Collection<T> from,
|
||||
Function<? super T, ? extends U> mapper,
|
||||
Function<U, ? extends Stream<? extends R>> func) {
|
||||
if (CollUtil.isEmpty(from)) {
|
||||
return new HashSet<>();
|
||||
}
|
||||
return from.stream().map(mapper).flatMap(func).filter(Objects::nonNull).collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ package cn.iocoder.yudao.framework.common.util.spring;
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.map.MapUtil;
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
import org.aspectj.lang.ProceedingJoinPoint;
|
||||
import org.aspectj.lang.JoinPoint;
|
||||
import org.aspectj.lang.reflect.MethodSignature;
|
||||
import org.springframework.core.DefaultParameterNameDiscoverer;
|
||||
import org.springframework.core.ParameterNameDiscoverer;
|
||||
@ -25,7 +25,7 @@ import java.util.Map;
|
||||
public class SpringExpressionUtils {
|
||||
|
||||
/**
|
||||
* spel表达式解析器
|
||||
* Spring EL 表达式解析器
|
||||
*/
|
||||
private static final ExpressionParser EXPRESSION_PARSER = new SpelExpressionParser();
|
||||
/**
|
||||
@ -43,7 +43,7 @@ public class SpringExpressionUtils {
|
||||
* @param expressionString EL 表达式数组
|
||||
* @return 执行界面
|
||||
*/
|
||||
public static Object parseExpression(ProceedingJoinPoint joinPoint, String expressionString) {
|
||||
public static Object parseExpression(JoinPoint joinPoint, String expressionString) {
|
||||
Map<String, Object> result = parseExpressions(joinPoint, Collections.singletonList(expressionString));
|
||||
return result.get(expressionString);
|
||||
}
|
||||
@ -55,7 +55,7 @@ public class SpringExpressionUtils {
|
||||
* @param expressionStrings EL 表达式数组
|
||||
* @return 结果,key 为表达式,value 为对应值
|
||||
*/
|
||||
public static Map<String, Object> parseExpressions(ProceedingJoinPoint joinPoint, List<String> expressionStrings) {
|
||||
public static Map<String, Object> parseExpressions(JoinPoint joinPoint, List<String> expressionStrings) {
|
||||
// 如果为空,则不进行解析
|
||||
if (CollUtil.isEmpty(expressionStrings)) {
|
||||
return MapUtil.newHashMap();
|
||||
|
@ -4,6 +4,7 @@ import cn.hutool.core.io.IoUtil;
|
||||
import cn.hutool.core.util.ZipUtil;
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||
import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils;
|
||||
import cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.CodegenCreateListReqVO;
|
||||
import cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.CodegenDetailRespVO;
|
||||
@ -66,7 +67,7 @@ public class CodegenController {
|
||||
@PreAuthorize("@ss.hasPermission('infra:codegen:query')")
|
||||
public CommonResult<List<CodegenTableRespVO>> getCodegenTableList(@RequestParam(value = "dataSourceConfigId") Long dataSourceConfigId) {
|
||||
List<CodegenTableDO> list = codegenService.getCodegenTableList(dataSourceConfigId);
|
||||
return success(CodegenConvert.INSTANCE.convertList05(list));
|
||||
return success(BeanUtils.toBean(list, CodegenTableRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/table/page")
|
||||
@ -74,7 +75,7 @@ public class CodegenController {
|
||||
@PreAuthorize("@ss.hasPermission('infra:codegen:query')")
|
||||
public CommonResult<PageResult<CodegenTableRespVO>> getCodegenTablePage(@Valid CodegenTablePageReqVO pageReqVO) {
|
||||
PageResult<CodegenTableDO> pageResult = codegenService.getCodegenTablePage(pageReqVO);
|
||||
return success(CodegenConvert.INSTANCE.convertPage(pageResult));
|
||||
return success(BeanUtils.toBean(pageResult, CodegenTableRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/detail")
|
||||
@ -82,7 +83,7 @@ public class CodegenController {
|
||||
@Parameter(name = "tableId", description = "表编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('infra:codegen:query')")
|
||||
public CommonResult<CodegenDetailRespVO> getCodegenDetail(@RequestParam("tableId") Long tableId) {
|
||||
CodegenTableDO table = codegenService.getCodegenTablePage(tableId);
|
||||
CodegenTableDO table = codegenService.getCodegenTable(tableId);
|
||||
List<CodegenColumnDO> columns = codegenService.getCodegenColumnListByTableId(tableId);
|
||||
// 拼装返回
|
||||
return success(CodegenConvert.INSTANCE.convert(table, columns));
|
||||
|
@ -1,18 +1,11 @@
|
||||
package cn.iocoder.yudao.module.infra.controller.admin.codegen.vo;
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.column.CodegenColumnBaseVO;
|
||||
import cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.table.CodegenTableBaseVO;
|
||||
import cn.iocoder.yudao.module.infra.enums.codegen.CodegenSceneEnum;
|
||||
import cn.iocoder.yudao.module.infra.enums.codegen.CodegenTemplateTypeEnum;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.column.CodegenColumnSaveReqVO;
|
||||
import cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.table.CodegenTableSaveReqVO;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import javax.validation.constraints.AssertTrue;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.util.List;
|
||||
|
||||
@ -22,55 +15,10 @@ public class CodegenUpdateReqVO {
|
||||
|
||||
@Valid // 校验内嵌的字段
|
||||
@NotNull(message = "表定义不能为空")
|
||||
private Table table;
|
||||
private CodegenTableSaveReqVO table;
|
||||
|
||||
@Valid // 校验内嵌的字段
|
||||
@NotNull(message = "字段定义不能为空")
|
||||
private List<Column> columns;
|
||||
|
||||
@Schema(description = "更新表定义")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
@Valid
|
||||
public static class Table extends CodegenTableBaseVO {
|
||||
|
||||
@Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private Long id;
|
||||
|
||||
@AssertTrue(message = "上级菜单不能为空,请前往 [修改生成配置 -> 生成信息] 界面,设置“上级菜单”字段")
|
||||
@JsonIgnore
|
||||
public boolean isParentMenuIdValid() {
|
||||
// 生成场景为管理后台时,必须设置上级菜单,不然生成的菜单 SQL 是无父级菜单的
|
||||
return ObjectUtil.notEqual(getScene(), CodegenSceneEnum.ADMIN.getScene())
|
||||
|| getParentMenuId() != null;
|
||||
}
|
||||
|
||||
@AssertTrue(message = "关联的父表信息不全")
|
||||
@JsonIgnore
|
||||
public boolean isSubValid() {
|
||||
return ObjectUtil.notEqual(getTemplateType(), CodegenTemplateTypeEnum.SUB)
|
||||
|| (ObjectUtil.isAllNotEmpty(getMasterTableId(), getSubJoinColumnId(), getSubJoinMany()));
|
||||
}
|
||||
|
||||
@AssertTrue(message = "关联的树表信息不全")
|
||||
@JsonIgnore
|
||||
public boolean isTreeValid() {
|
||||
return ObjectUtil.notEqual(getTemplateType(), CodegenTemplateTypeEnum.TREE)
|
||||
|| (ObjectUtil.isAllNotEmpty(getTreeParentColumnId(), getTreeNameColumnId()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Schema(description = "更新表定义")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public static class Column extends CodegenColumnBaseVO {
|
||||
|
||||
@Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private Long id;
|
||||
|
||||
}
|
||||
private List<CodegenColumnSaveReqVO> columns;
|
||||
|
||||
}
|
||||
|
@ -2,20 +2,70 @@ package cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.column;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Schema(description = "管理后台 - 代码生成字段定义 Response VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class CodegenColumnRespVO extends CodegenColumnBaseVO {
|
||||
public class CodegenColumnRespVO {
|
||||
|
||||
@Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "表编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private Long tableId;
|
||||
|
||||
@Schema(description = "字段名", requiredMode = Schema.RequiredMode.REQUIRED, example = "user_age")
|
||||
private String columnName;
|
||||
|
||||
@Schema(description = "字段类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "int(11)")
|
||||
private String dataType;
|
||||
|
||||
@Schema(description = "字段描述", requiredMode = Schema.RequiredMode.REQUIRED, example = "年龄")
|
||||
private String columnComment;
|
||||
|
||||
@Schema(description = "是否允许为空", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
|
||||
private Boolean nullable;
|
||||
|
||||
@Schema(description = "是否主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "false")
|
||||
private Boolean primaryKey;
|
||||
|
||||
@Schema(description = "是否自增", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
|
||||
private Boolean autoIncrement;
|
||||
|
||||
@Schema(description = "排序", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
|
||||
private Integer ordinalPosition;
|
||||
|
||||
@Schema(description = "Java 属性类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "userAge")
|
||||
private String javaType;
|
||||
|
||||
@Schema(description = "Java 属性名", requiredMode = Schema.RequiredMode.REQUIRED, example = "Integer")
|
||||
private String javaField;
|
||||
|
||||
@Schema(description = "字典类型", example = "sys_gender")
|
||||
private String dictType;
|
||||
|
||||
@Schema(description = "数据示例", example = "1024")
|
||||
private String example;
|
||||
|
||||
@Schema(description = "是否为 Create 创建操作的字段", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
|
||||
private Boolean createOperation;
|
||||
|
||||
@Schema(description = "是否为 Update 更新操作的字段", requiredMode = Schema.RequiredMode.REQUIRED, example = "false")
|
||||
private Boolean updateOperation;
|
||||
|
||||
@Schema(description = "是否为 List 查询操作的字段", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
|
||||
private Boolean listOperation;
|
||||
|
||||
@Schema(description = "List 查询操作的条件类型,参见 CodegenColumnListConditionEnum 枚举", requiredMode = Schema.RequiredMode.REQUIRED, example = "LIKE")
|
||||
private String listOperationCondition;
|
||||
|
||||
@Schema(description = "是否为 List 查询操作的返回字段", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
|
||||
private Boolean listOperationResult;
|
||||
|
||||
@Schema(description = "显示类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "input")
|
||||
private String htmlType;
|
||||
|
||||
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private LocalDateTime createTime;
|
||||
|
||||
|
@ -5,12 +5,12 @@ import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
/**
|
||||
* 代码生成字段定义 Base VO,提供给添加、修改、详细的子 VO 使用
|
||||
* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
|
||||
*/
|
||||
@Schema(description = "管理后台 - 代码生成字段定义创建/修改 Request VO")
|
||||
@Data
|
||||
public class CodegenColumnBaseVO {
|
||||
public class CodegenColumnSaveReqVO {
|
||||
|
||||
@Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "表编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@NotNull(message = "表编号不能为空")
|
||||
@ -38,7 +38,7 @@ public class CodegenColumnBaseVO {
|
||||
|
||||
@Schema(description = "是否自增", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
|
||||
@NotNull(message = "是否自增不能为空")
|
||||
private String autoIncrement;
|
||||
private Boolean autoIncrement;
|
||||
|
||||
@Schema(description = "排序", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
|
||||
@NotNull(message = "排序不能为空")
|
@ -2,20 +2,64 @@ package cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.table;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Schema(description = "管理后台 - 代码生成表定义 Response VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class CodegenTableRespVO extends CodegenTableBaseVO {
|
||||
public class CodegenTableRespVO {
|
||||
|
||||
@Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "生成场景,参见 CodegenSceneEnum 枚举", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private Integer scene;
|
||||
|
||||
@Schema(description = "表名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "yudao")
|
||||
private String tableName;
|
||||
|
||||
@Schema(description = "表描述", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋道")
|
||||
private String tableComment;
|
||||
|
||||
@Schema(description = "备注", example = "我是备注")
|
||||
private String remark;
|
||||
|
||||
@Schema(description = "模块名", requiredMode = Schema.RequiredMode.REQUIRED, example = "system")
|
||||
private String moduleName;
|
||||
|
||||
@Schema(description = "业务名", requiredMode = Schema.RequiredMode.REQUIRED, example = "codegen")
|
||||
private String businessName;
|
||||
|
||||
@Schema(description = "类名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "CodegenTable")
|
||||
private String className;
|
||||
|
||||
@Schema(description = "类描述", requiredMode = Schema.RequiredMode.REQUIRED, example = "代码生成器的表定义")
|
||||
private String classComment;
|
||||
|
||||
@Schema(description = "作者", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋道源码")
|
||||
private String author;
|
||||
|
||||
@Schema(description = "模板类型,参见 CodegenTemplateTypeEnum 枚举", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private Integer templateType;
|
||||
|
||||
@Schema(description = "前端类型,参见 CodegenFrontTypeEnum 枚举", requiredMode = Schema.RequiredMode.REQUIRED, example = "20")
|
||||
private Integer frontType;
|
||||
|
||||
@Schema(description = "父菜单编号", example = "1024")
|
||||
private Long parentMenuId;
|
||||
|
||||
@Schema(description = "主表的编号", example = "2048")
|
||||
private Long masterTableId;
|
||||
@Schema(description = "子表关联主表的字段编号", example = "4096")
|
||||
private Long subJoinColumnId;
|
||||
@Schema(description = "主表与子表是否一对多", example = "4096")
|
||||
private Boolean subJoinMany;
|
||||
|
||||
@Schema(description = "树表的父字段编号", example = "8192")
|
||||
private Long treeParentColumnId;
|
||||
@Schema(description = "树表的名字字段编号", example = "16384")
|
||||
private Long treeNameColumnId;
|
||||
|
||||
@Schema(description = "主键编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
private Integer dataSourceConfigId;
|
||||
|
||||
|
@ -1,16 +1,21 @@
|
||||
package cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.table;
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.iocoder.yudao.module.infra.enums.codegen.CodegenSceneEnum;
|
||||
import cn.iocoder.yudao.module.infra.enums.codegen.CodegenTemplateTypeEnum;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.AssertTrue;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
/**
|
||||
* 代码生成 Base VO,提供给添加、修改、详细的子 VO 使用
|
||||
* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
|
||||
*/
|
||||
@Schema(description = "管理后台 - 代码生成表定义创建/修改 Response VO")
|
||||
@Data
|
||||
public class CodegenTableBaseVO {
|
||||
public class CodegenTableSaveReqVO {
|
||||
|
||||
@Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "生成场景,参见 CodegenSceneEnum 枚举", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@NotNull(message = "导入类型不能为空")
|
||||
@ -70,4 +75,26 @@ public class CodegenTableBaseVO {
|
||||
@Schema(description = "树表的名字字段编号", example = "16384")
|
||||
private Long treeNameColumnId;
|
||||
|
||||
@AssertTrue(message = "上级菜单不能为空,请前往 [修改生成配置 -> 生成信息] 界面,设置“上级菜单”字段")
|
||||
@JsonIgnore
|
||||
public boolean isParentMenuIdValid() {
|
||||
// 生成场景为管理后台时,必须设置上级菜单,不然生成的菜单 SQL 是无父级菜单的
|
||||
return ObjectUtil.notEqual(getScene(), CodegenSceneEnum.ADMIN.getScene())
|
||||
|| getParentMenuId() != null;
|
||||
}
|
||||
|
||||
@AssertTrue(message = "关联的父表信息不全")
|
||||
@JsonIgnore
|
||||
public boolean isSubValid() {
|
||||
return ObjectUtil.notEqual(getTemplateType(), CodegenTemplateTypeEnum.SUB)
|
||||
|| (ObjectUtil.isAllNotEmpty(masterTableId, subJoinColumnId, subJoinMany));
|
||||
}
|
||||
|
||||
@AssertTrue(message = "关联的树表信息不全")
|
||||
@JsonIgnore
|
||||
public boolean isTreeValid() {
|
||||
return ObjectUtil.notEqual(templateType, CodegenTemplateTypeEnum.TREE)
|
||||
|| (ObjectUtil.isAllNotEmpty(treeParentColumnId, treeNameColumnId));
|
||||
}
|
||||
|
||||
}
|
@ -1,12 +1,11 @@
|
||||
package cn.iocoder.yudao.module.infra.convert.codegen;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||
import cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.CodegenDetailRespVO;
|
||||
import cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.CodegenPreviewRespVO;
|
||||
import cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.CodegenUpdateReqVO;
|
||||
import cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.column.CodegenColumnRespVO;
|
||||
import cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.table.CodegenTableRespVO;
|
||||
import cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.table.DatabaseTableRespVO;
|
||||
import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.CodegenColumnDO;
|
||||
import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.CodegenTableDO;
|
||||
import com.baomidou.mybatisplus.generator.config.po.TableField;
|
||||
@ -20,7 +19,6 @@ import org.mapstruct.factory.Mappers;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Mapper
|
||||
public interface CodegenConvert {
|
||||
@ -54,40 +52,18 @@ public interface CodegenConvert {
|
||||
return jdbcType.name();
|
||||
}
|
||||
|
||||
// ========== CodegenTableDO 相关 ==========
|
||||
|
||||
List<CodegenTableRespVO> convertList05(List<CodegenTableDO> list);
|
||||
|
||||
CodegenTableRespVO convert(CodegenTableDO bean);
|
||||
|
||||
PageResult<CodegenTableRespVO> convertPage(PageResult<CodegenTableDO> page);
|
||||
|
||||
// ========== CodegenTableDO 相关 ==========
|
||||
|
||||
List<CodegenColumnRespVO> convertList02(List<CodegenColumnDO> list);
|
||||
|
||||
CodegenTableDO convert(CodegenUpdateReqVO.Table bean);
|
||||
|
||||
List<CodegenColumnDO> convertList03(List<CodegenUpdateReqVO.Column> columns);
|
||||
|
||||
List<DatabaseTableRespVO> convertList04(List<TableInfo> list);
|
||||
|
||||
// ========== 其它 ==========
|
||||
|
||||
default CodegenDetailRespVO convert(CodegenTableDO table, List<CodegenColumnDO> columns) {
|
||||
CodegenDetailRespVO respVO = new CodegenDetailRespVO();
|
||||
respVO.setTable(convert(table));
|
||||
respVO.setColumns(convertList02(columns));
|
||||
respVO.setTable(BeanUtils.toBean(table, CodegenTableRespVO.class));
|
||||
respVO.setColumns(BeanUtils.toBean(columns, CodegenColumnRespVO.class));
|
||||
return respVO;
|
||||
}
|
||||
|
||||
default List<CodegenPreviewRespVO> convert(Map<String, String> codes) {
|
||||
return codes.entrySet().stream().map(entry -> {
|
||||
CodegenPreviewRespVO respVO = new CodegenPreviewRespVO();
|
||||
respVO.setFilePath(entry.getKey());
|
||||
respVO.setCode(entry.getValue());
|
||||
return respVO;
|
||||
}).collect(Collectors.toList());
|
||||
return CollectionUtils.convertList(codes.entrySet(),
|
||||
entry -> new CodegenPreviewRespVO().setFilePath(entry.getKey()).setCode(entry.getValue()));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -70,7 +70,7 @@ public interface CodegenService {
|
||||
* @param id 表编号
|
||||
* @return 表定义
|
||||
*/
|
||||
CodegenTableDO getCodegenTablePage(Long id);
|
||||
CodegenTableDO getCodegenTable(Long id);
|
||||
|
||||
/**
|
||||
* 获得指定表的字段定义数组
|
||||
@ -91,7 +91,6 @@ public interface CodegenService {
|
||||
/**
|
||||
* 获得数据库自带的表定义列表
|
||||
*
|
||||
*
|
||||
* @param dataSourceConfigId 数据源的配置编号
|
||||
* @param name 表名称
|
||||
* @param comment 表描述
|
||||
|
@ -3,12 +3,11 @@ package cn.iocoder.yudao.module.infra.service.codegen;
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||
import cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.CodegenCreateListReqVO;
|
||||
import cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.CodegenUpdateReqVO;
|
||||
import cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.table.CodegenTablePageReqVO;
|
||||
import cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.table.DatabaseTableRespVO;
|
||||
import cn.iocoder.yudao.module.infra.convert.codegen.CodegenConvert;
|
||||
import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.CodegenColumnDO;
|
||||
import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.CodegenTableDO;
|
||||
import cn.iocoder.yudao.module.infra.dal.mysql.codegen.CodegenColumnMapper;
|
||||
@ -22,6 +21,7 @@ import cn.iocoder.yudao.module.infra.service.db.DatabaseTableService;
|
||||
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
|
||||
import com.baomidou.mybatisplus.generator.config.po.TableField;
|
||||
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@ -31,6 +31,8 @@ import java.util.function.BiPredicate;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
|
||||
import static cn.iocoder.yudao.module.infra.enums.ErrorCodeConstants.*;
|
||||
|
||||
/**
|
||||
@ -69,7 +71,7 @@ public class CodegenServiceImpl implements CodegenService {
|
||||
return ids;
|
||||
}
|
||||
|
||||
public Long createCodegen(Long userId, Long dataSourceConfigId, String tableName) {
|
||||
private Long createCodegen(Long userId, Long dataSourceConfigId, String tableName) {
|
||||
// 从数据库中,获得数据库表结构
|
||||
TableInfo tableInfo = databaseTableService.getTable(dataSourceConfigId, tableName);
|
||||
// 导入
|
||||
@ -103,7 +105,8 @@ public class CodegenServiceImpl implements CodegenService {
|
||||
return table.getId();
|
||||
}
|
||||
|
||||
private void validateTableInfo(TableInfo tableInfo) {
|
||||
@VisibleForTesting
|
||||
void validateTableInfo(TableInfo tableInfo) {
|
||||
if (tableInfo == null) {
|
||||
throw exception(CODEGEN_IMPORT_TABLE_NULL);
|
||||
}
|
||||
@ -139,10 +142,10 @@ public class CodegenServiceImpl implements CodegenService {
|
||||
}
|
||||
|
||||
// 更新 table 表定义
|
||||
CodegenTableDO updateTableObj = CodegenConvert.INSTANCE.convert(updateReqVO.getTable());
|
||||
CodegenTableDO updateTableObj = BeanUtils.toBean(updateReqVO.getTable(), CodegenTableDO.class);
|
||||
codegenTableMapper.updateById(updateTableObj);
|
||||
// 更新 column 字段定义
|
||||
List<CodegenColumnDO> updateColumnObjs = CodegenConvert.INSTANCE.convertList03(updateReqVO.getColumns());
|
||||
List<CodegenColumnDO> updateColumnObjs = BeanUtils.toBean(updateReqVO.getColumns(), CodegenColumnDO.class);
|
||||
updateColumnObjs.forEach(updateColumnObj -> codegenColumnMapper.updateById(updateColumnObj));
|
||||
}
|
||||
|
||||
@ -161,29 +164,28 @@ public class CodegenServiceImpl implements CodegenService {
|
||||
}
|
||||
|
||||
private void syncCodegen0(Long tableId, TableInfo tableInfo) {
|
||||
// 校验导入的表和字段非空
|
||||
// 1. 校验导入的表和字段非空
|
||||
validateTableInfo(tableInfo);
|
||||
List<TableField> tableFields = tableInfo.getFields();
|
||||
|
||||
// 构建 CodegenColumnDO 数组,只同步新增的字段
|
||||
// 2. 构建 CodegenColumnDO 数组,只同步新增的字段
|
||||
List<CodegenColumnDO> codegenColumns = codegenColumnMapper.selectListByTableId(tableId);
|
||||
Set<String> codegenColumnNames = CollectionUtils.convertSet(codegenColumns, CodegenColumnDO::getColumnName);
|
||||
Set<String> codegenColumnNames = convertSet(codegenColumns, CodegenColumnDO::getColumnName);
|
||||
|
||||
//计算需要修改的字段,插入时重新插入,删除时将原来的删除
|
||||
BiPredicate<TableField, CodegenColumnDO> pr =
|
||||
// 3.1 计算需要【修改】的字段,插入时重新插入,删除时将原来的删除
|
||||
Map<String, CodegenColumnDO> codegenColumnDOMap = convertMap(codegenColumns, CodegenColumnDO::getColumnName);
|
||||
BiPredicate<TableField, CodegenColumnDO> primaryKeyPredicate =
|
||||
(tableField, codegenColumn) -> tableField.getMetaInfo().getJdbcType().name().equals(codegenColumn.getDataType())
|
||||
&& tableField.getMetaInfo().isNullable() == codegenColumn.getNullable()
|
||||
&& tableField.isKeyFlag() == codegenColumn.getPrimaryKey()
|
||||
&& tableField.getComment().equals(codegenColumn.getColumnComment());
|
||||
Map<String, CodegenColumnDO> codegenColumnDOMap = CollectionUtils.convertMap(codegenColumns, CodegenColumnDO::getColumnName);
|
||||
//需要修改的字段
|
||||
Set<String> modifyFieldNames = tableFields.stream()
|
||||
.filter(tableField -> codegenColumnDOMap.get(tableField.getColumnName()) != null
|
||||
&& !pr.test(tableField, codegenColumnDOMap.get(tableField.getColumnName())))
|
||||
&& !primaryKeyPredicate.test(tableField, codegenColumnDOMap.get(tableField.getColumnName())))
|
||||
.map(TableField::getColumnName)
|
||||
.collect(Collectors.toSet());
|
||||
// 计算需要删除的字段
|
||||
Set<String> tableFieldNames = CollectionUtils.convertSet(tableFields, TableField::getName);
|
||||
// 3.2 计算需要【删除】的字段
|
||||
Set<String> tableFieldNames = convertSet(tableFields, TableField::getName);
|
||||
Set<Long> deleteColumnIds = codegenColumns.stream()
|
||||
.filter(column -> (!tableFieldNames.contains(column.getColumnName())) || modifyFieldNames.contains(column.getColumnName()))
|
||||
.map(CodegenColumnDO::getId).collect(Collectors.toSet());
|
||||
@ -193,10 +195,10 @@ public class CodegenServiceImpl implements CodegenService {
|
||||
throw exception(CODEGEN_SYNC_NONE_CHANGE);
|
||||
}
|
||||
|
||||
// 插入新增的字段
|
||||
// 4.1 插入新增的字段
|
||||
List<CodegenColumnDO> columns = codegenBuilder.buildColumns(tableId, tableFields);
|
||||
codegenColumnMapper.insertBatch(columns);
|
||||
// 删除不存在的字段
|
||||
// 4.2 删除不存在的字段
|
||||
if (CollUtil.isNotEmpty(deleteColumnIds)) {
|
||||
codegenColumnMapper.deleteBatchIds(deleteColumnIds);
|
||||
}
|
||||
@ -227,7 +229,7 @@ public class CodegenServiceImpl implements CodegenService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public CodegenTableDO getCodegenTablePage(Long id) {
|
||||
public CodegenTableDO getCodegenTable(Long id) {
|
||||
return codegenTableMapper.selectById(id);
|
||||
}
|
||||
|
||||
@ -277,10 +279,10 @@ public class CodegenServiceImpl implements CodegenService {
|
||||
public List<DatabaseTableRespVO> getDatabaseTableList(Long dataSourceConfigId, String name, String comment) {
|
||||
List<TableInfo> tables = databaseTableService.getTableList(dataSourceConfigId, name, comment);
|
||||
// 移除在 Codegen 中,已经存在的
|
||||
Set<String> existsTables = CollectionUtils.convertSet(
|
||||
Set<String> existsTables = convertSet(
|
||||
codegenTableMapper.selectListByDataSourceConfigId(dataSourceConfigId), CodegenTableDO::getTableName);
|
||||
tables.removeIf(table -> existsTables.contains(table.getName()));
|
||||
return CodegenConvert.INSTANCE.convertList04(tables);
|
||||
return BeanUtils.toBean(tables, DatabaseTableRespVO.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -269,7 +269,7 @@ const queryParams = reactive({
|
||||
#foreach ($column in $columns)
|
||||
#if ($column.listOperation)
|
||||
#if ($column.listOperationCondition != 'BETWEEN')
|
||||
$column.javaField: null,
|
||||
$column.javaField: undefined,
|
||||
#end
|
||||
#if ($column.htmlType == "datetime" || $column.listOperationCondition == "BETWEEN")
|
||||
$column.javaField: [],
|
||||
|
@ -0,0 +1,557 @@
|
||||
package cn.iocoder.yudao.module.infra.service.codegen;
|
||||
|
||||
import cn.hutool.core.collection.ListUtil;
|
||||
import cn.hutool.core.map.MapUtil;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
|
||||
import cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.CodegenCreateListReqVO;
|
||||
import cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.CodegenUpdateReqVO;
|
||||
import cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.column.CodegenColumnSaveReqVO;
|
||||
import cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.table.CodegenTablePageReqVO;
|
||||
import cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.table.DatabaseTableRespVO;
|
||||
import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.CodegenColumnDO;
|
||||
import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.CodegenTableDO;
|
||||
import cn.iocoder.yudao.module.infra.dal.mysql.codegen.CodegenColumnMapper;
|
||||
import cn.iocoder.yudao.module.infra.dal.mysql.codegen.CodegenTableMapper;
|
||||
import cn.iocoder.yudao.module.infra.enums.codegen.CodegenFrontTypeEnum;
|
||||
import cn.iocoder.yudao.module.infra.enums.codegen.CodegenSceneEnum;
|
||||
import cn.iocoder.yudao.module.infra.enums.codegen.CodegenTemplateTypeEnum;
|
||||
import cn.iocoder.yudao.module.infra.framework.codegen.config.CodegenProperties;
|
||||
import cn.iocoder.yudao.module.infra.service.codegen.inner.CodegenBuilder;
|
||||
import cn.iocoder.yudao.module.infra.service.codegen.inner.CodegenEngine;
|
||||
import cn.iocoder.yudao.module.infra.service.db.DatabaseTableService;
|
||||
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
|
||||
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
|
||||
import com.baomidou.mybatisplus.generator.config.po.TableField;
|
||||
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildBetweenTime;
|
||||
import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildTime;
|
||||
import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*;
|
||||
import static cn.iocoder.yudao.module.infra.enums.ErrorCodeConstants.*;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.ArgumentMatchers.*;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
/**
|
||||
* {@link CodegenServiceImpl} 的单元测试类
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Import(CodegenServiceImpl.class)
|
||||
public class CodegenServiceImplTest extends BaseDbUnitTest {
|
||||
|
||||
@Resource
|
||||
private CodegenServiceImpl codegenService;
|
||||
|
||||
@Resource
|
||||
private CodegenTableMapper codegenTableMapper;
|
||||
@Resource
|
||||
private CodegenColumnMapper codegenColumnMapper;
|
||||
|
||||
@MockBean
|
||||
private DatabaseTableService databaseTableService;
|
||||
|
||||
@MockBean
|
||||
private AdminUserApi userApi;
|
||||
|
||||
@MockBean
|
||||
private CodegenBuilder codegenBuilder;
|
||||
@MockBean
|
||||
private CodegenEngine codegenEngine;
|
||||
|
||||
@MockBean
|
||||
private CodegenProperties codegenProperties;
|
||||
|
||||
@Test
|
||||
public void testCreateCodegenList() {
|
||||
// 准备参数
|
||||
Long userId = randomLongId();
|
||||
CodegenCreateListReqVO reqVO = randomPojo(CodegenCreateListReqVO.class,
|
||||
o -> o.setDataSourceConfigId(1L).setTableNames(Collections.singletonList("t_yunai")));
|
||||
// mock 方法(TableInfo)
|
||||
TableInfo tableInfo = mock(TableInfo.class);
|
||||
when(databaseTableService.getTable(eq(1L), eq("t_yunai")))
|
||||
.thenReturn(tableInfo);
|
||||
when(tableInfo.getComment()).thenReturn("芋艿");
|
||||
// mock 方法(TableInfo fields)
|
||||
TableField field01 = mock(TableField.class);
|
||||
when(field01.getComment()).thenReturn("主键");
|
||||
TableField field02 = mock(TableField.class);
|
||||
when(field02.getComment()).thenReturn("名字");
|
||||
List<TableField> fields = Arrays.asList(field01, field02);
|
||||
when(tableInfo.getFields()).thenReturn(fields);
|
||||
// mock 方法(CodegenTableDO)
|
||||
CodegenTableDO table = randomPojo(CodegenTableDO.class);
|
||||
when(codegenBuilder.buildTable(same(tableInfo))).thenReturn(table);
|
||||
// mock 方法(AdminUserRespDTO)
|
||||
AdminUserRespDTO user = randomPojo(AdminUserRespDTO.class, o -> o.setNickname("芋头"));
|
||||
when(userApi.getUser(eq(userId))).thenReturn(success(user));
|
||||
// mock 方法(CodegenColumnDO)
|
||||
List<CodegenColumnDO> columns = randomPojoList(CodegenColumnDO.class);
|
||||
when(codegenBuilder.buildColumns(eq(table.getId()), same(fields)))
|
||||
.thenReturn(columns);
|
||||
// mock 方法(CodegenProperties)
|
||||
when(codegenProperties.getFrontType()).thenReturn(CodegenFrontTypeEnum.VUE3.getType());
|
||||
|
||||
// 调用
|
||||
List<Long> result = codegenService.createCodegenList(userId, reqVO);
|
||||
// 断言
|
||||
assertEquals(1, result.size());
|
||||
// 断言(CodegenTableDO)
|
||||
CodegenTableDO dbTable = codegenTableMapper.selectList().get(0);
|
||||
assertPojoEquals(table, dbTable);
|
||||
assertEquals(1L, dbTable.getDataSourceConfigId());
|
||||
assertEquals(CodegenSceneEnum.ADMIN.getScene(), dbTable.getScene());
|
||||
assertEquals(CodegenFrontTypeEnum.VUE3.getType(), dbTable.getFrontType());
|
||||
assertEquals("芋头", dbTable.getAuthor());
|
||||
// 断言(CodegenColumnDO)
|
||||
List<CodegenColumnDO> dbColumns = codegenColumnMapper.selectList();
|
||||
assertEquals(columns.size(), dbColumns.size());
|
||||
assertTrue(dbColumns.get(0).getPrimaryKey());
|
||||
for (int i = 0; i < dbColumns.size(); i++) {
|
||||
assertPojoEquals(columns.get(i), dbColumns.get(i));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateTableInfo() {
|
||||
// 情况一
|
||||
assertServiceException(() -> codegenService.validateTableInfo(null),
|
||||
CODEGEN_IMPORT_TABLE_NULL);
|
||||
// 情况二
|
||||
TableInfo tableInfo = mock(TableInfo.class);
|
||||
assertServiceException(() -> codegenService.validateTableInfo(tableInfo),
|
||||
CODEGEN_TABLE_INFO_TABLE_COMMENT_IS_NULL);
|
||||
// 情况三
|
||||
when(tableInfo.getComment()).thenReturn("芋艿");
|
||||
assertServiceException(() -> codegenService.validateTableInfo(tableInfo),
|
||||
CODEGEN_IMPORT_COLUMNS_NULL);
|
||||
// 情况四
|
||||
TableField field = mock(TableField.class);
|
||||
when(field.getName()).thenReturn("name");
|
||||
when(tableInfo.getFields()).thenReturn(Collections.singletonList(field));
|
||||
assertServiceException(() -> codegenService.validateTableInfo(tableInfo),
|
||||
CODEGEN_TABLE_INFO_COLUMN_COMMENT_IS_NULL, field.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateCodegen_notExists() {
|
||||
// 准备参数
|
||||
CodegenUpdateReqVO updateReqVO = randomPojo(CodegenUpdateReqVO.class);
|
||||
// mock 方法
|
||||
|
||||
// 调用,并断言
|
||||
assertServiceException(() -> codegenService.updateCodegen(updateReqVO),
|
||||
CODEGEN_TABLE_NOT_EXISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateCodegen_sub_masterNotExists() {
|
||||
// mock 数据
|
||||
CodegenTableDO table = randomPojo(CodegenTableDO.class,
|
||||
o -> o.setTemplateType(CodegenTemplateTypeEnum.SUB.getType())
|
||||
.setScene(CodegenSceneEnum.ADMIN.getScene()));
|
||||
codegenTableMapper.insert(table);
|
||||
// 准备参数
|
||||
CodegenUpdateReqVO updateReqVO = randomPojo(CodegenUpdateReqVO.class,
|
||||
o -> o.getTable().setId(table.getId())
|
||||
.setTemplateType(CodegenTemplateTypeEnum.SUB.getType()));
|
||||
|
||||
// 调用,并断言
|
||||
assertServiceException(() -> codegenService.updateCodegen(updateReqVO),
|
||||
CODEGEN_MASTER_TABLE_NOT_EXISTS, updateReqVO.getTable().getMasterTableId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateCodegen_sub_columnNotExists() {
|
||||
// mock 数据
|
||||
CodegenTableDO subTable = randomPojo(CodegenTableDO.class,
|
||||
o -> o.setTemplateType(CodegenTemplateTypeEnum.SUB.getType())
|
||||
.setScene(CodegenSceneEnum.ADMIN.getScene()));
|
||||
codegenTableMapper.insert(subTable);
|
||||
// mock 数据(master)
|
||||
CodegenTableDO masterTable = randomPojo(CodegenTableDO.class,
|
||||
o -> o.setTemplateType(CodegenTemplateTypeEnum.MASTER_ERP.getType())
|
||||
.setScene(CodegenSceneEnum.ADMIN.getScene()));
|
||||
codegenTableMapper.insert(masterTable);
|
||||
// 准备参数
|
||||
CodegenUpdateReqVO updateReqVO = randomPojo(CodegenUpdateReqVO.class,
|
||||
o -> o.getTable().setId(subTable.getId())
|
||||
.setTemplateType(CodegenTemplateTypeEnum.SUB.getType())
|
||||
.setMasterTableId(masterTable.getId()));
|
||||
|
||||
// 调用,并断言
|
||||
assertServiceException(() -> codegenService.updateCodegen(updateReqVO),
|
||||
CODEGEN_SUB_COLUMN_NOT_EXISTS, updateReqVO.getTable().getSubJoinColumnId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateCodegen_success() {
|
||||
// mock 数据
|
||||
CodegenTableDO table = randomPojo(CodegenTableDO.class,
|
||||
o -> o.setTemplateType(CodegenTemplateTypeEnum.ONE.getType())
|
||||
.setScene(CodegenSceneEnum.ADMIN.getScene()));
|
||||
codegenTableMapper.insert(table);
|
||||
CodegenColumnDO column01 = randomPojo(CodegenColumnDO.class, o -> o.setTableId(table.getId()));
|
||||
codegenColumnMapper.insert(column01);
|
||||
CodegenColumnDO column02 = randomPojo(CodegenColumnDO.class, o -> o.setTableId(table.getId()));
|
||||
codegenColumnMapper.insert(column02);
|
||||
// 准备参数
|
||||
CodegenUpdateReqVO updateReqVO = randomPojo(CodegenUpdateReqVO.class,
|
||||
o -> o.getTable().setId(table.getId())
|
||||
.setTemplateType(CodegenTemplateTypeEnum.ONE.getType())
|
||||
.setScene(CodegenSceneEnum.ADMIN.getScene()));
|
||||
CodegenColumnSaveReqVO columnVO01 = randomPojo(CodegenColumnSaveReqVO.class,
|
||||
o -> o.setId(column01.getId()).setTableId(table.getId()));
|
||||
CodegenColumnSaveReqVO columnVO02 = randomPojo(CodegenColumnSaveReqVO.class,
|
||||
o -> o.setId(column02.getId()).setTableId(table.getId()));
|
||||
updateReqVO.setColumns(Arrays.asList(columnVO01, columnVO02));
|
||||
|
||||
// 调用
|
||||
codegenService.updateCodegen(updateReqVO);
|
||||
// 断言
|
||||
CodegenTableDO dbTable = codegenTableMapper.selectById(table.getId());
|
||||
assertPojoEquals(updateReqVO.getTable(), dbTable);
|
||||
List<CodegenColumnDO> dbColumns = codegenColumnMapper.selectList();
|
||||
assertEquals(2, dbColumns.size());
|
||||
assertPojoEquals(columnVO01, dbColumns.get(0));
|
||||
assertPojoEquals(columnVO02, dbColumns.get(1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSyncCodegenFromDB() {
|
||||
// mock 数据(CodegenTableDO)
|
||||
CodegenTableDO table = randomPojo(CodegenTableDO.class, o -> o.setTableName("t_yunai")
|
||||
.setDataSourceConfigId(1L).setScene(CodegenSceneEnum.ADMIN.getScene()));
|
||||
codegenTableMapper.insert(table);
|
||||
CodegenColumnDO column01 = randomPojo(CodegenColumnDO.class, o -> o.setTableId(table.getId())
|
||||
.setColumnName("id"));
|
||||
codegenColumnMapper.insert(column01);
|
||||
CodegenColumnDO column02 = randomPojo(CodegenColumnDO.class, o -> o.setTableId(table.getId())
|
||||
.setColumnName("name"));
|
||||
codegenColumnMapper.insert(column02);
|
||||
// 准备参数
|
||||
Long tableId = table.getId();
|
||||
// mock 方法(TableInfo)
|
||||
TableInfo tableInfo = mock(TableInfo.class);
|
||||
when(databaseTableService.getTable(eq(1L), eq("t_yunai")))
|
||||
.thenReturn(tableInfo);
|
||||
when(tableInfo.getComment()).thenReturn("芋艿");
|
||||
// mock 方法(TableInfo fields)
|
||||
TableField field01 = mock(TableField.class);
|
||||
when(field01.getComment()).thenReturn("主键");
|
||||
TableField field03 = mock(TableField.class);
|
||||
when(field03.getComment()).thenReturn("分类");
|
||||
List<TableField> fields = Arrays.asList(field01, field03);
|
||||
when(tableInfo.getFields()).thenReturn(fields);
|
||||
when(databaseTableService.getTable(eq(1L), eq("t_yunai")))
|
||||
.thenReturn(tableInfo);
|
||||
// mock 方法(CodegenTableDO)
|
||||
List<CodegenColumnDO> newColumns = randomPojoList(CodegenColumnDO.class);
|
||||
when(codegenBuilder.buildColumns(eq(table.getId()), argThat(tableFields -> {
|
||||
assertEquals(2, tableFields.size());
|
||||
assertSame(tableInfo.getFields(), tableFields);
|
||||
return true;
|
||||
}))).thenReturn(newColumns);
|
||||
|
||||
// 调用
|
||||
codegenService.syncCodegenFromDB(tableId);
|
||||
// 断言
|
||||
List<CodegenColumnDO> dbColumns = codegenColumnMapper.selectList();
|
||||
assertEquals(newColumns.size(), dbColumns.size());
|
||||
assertPojoEquals(newColumns.get(0), dbColumns.get(0));
|
||||
assertPojoEquals(newColumns.get(1), dbColumns.get(1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteCodegen_notExists() {
|
||||
assertServiceException(() -> codegenService.deleteCodegen(randomLongId()),
|
||||
CODEGEN_TABLE_NOT_EXISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteCodegen_success() {
|
||||
// mock 数据
|
||||
CodegenTableDO table = randomPojo(CodegenTableDO.class,
|
||||
o -> o.setScene(CodegenSceneEnum.ADMIN.getScene()));
|
||||
codegenTableMapper.insert(table);
|
||||
CodegenColumnDO column = randomPojo(CodegenColumnDO.class, o -> o.setTableId(table.getId()));
|
||||
codegenColumnMapper.insert(column);
|
||||
// 准备参数
|
||||
Long tableId = table.getId();
|
||||
|
||||
// 调用
|
||||
codegenService.deleteCodegen(tableId);
|
||||
// 断言
|
||||
assertNull(codegenTableMapper.selectById(tableId));
|
||||
assertEquals(0, codegenColumnMapper.selectList().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetCodegenTableList() {
|
||||
// mock 数据
|
||||
CodegenTableDO table01 = randomPojo(CodegenTableDO.class,
|
||||
o -> o.setScene(CodegenSceneEnum.ADMIN.getScene()));
|
||||
codegenTableMapper.insert(table01);
|
||||
CodegenTableDO table02 = randomPojo(CodegenTableDO.class,
|
||||
o -> o.setScene(CodegenSceneEnum.ADMIN.getScene()));
|
||||
codegenTableMapper.insert(table02);
|
||||
// 准备参数
|
||||
Long dataSourceConfigId = table01.getDataSourceConfigId();
|
||||
|
||||
// 调用
|
||||
List<CodegenTableDO> result = codegenService.getCodegenTableList(dataSourceConfigId);
|
||||
// 断言
|
||||
assertEquals(1, result.size());
|
||||
assertPojoEquals(table01, result.get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetCodegenTablePage() {
|
||||
// mock 数据
|
||||
CodegenTableDO tableDO = randomPojo(CodegenTableDO.class, o -> {
|
||||
o.setTableName("t_yunai");
|
||||
o.setTableComment("芋艿");
|
||||
o.setClassName("SystemYunai");
|
||||
o.setCreateTime(buildTime(2021, 3, 10));
|
||||
}).setScene(CodegenSceneEnum.ADMIN.getScene());
|
||||
codegenTableMapper.insert(tableDO);
|
||||
// 测试 tableName 不匹配
|
||||
codegenTableMapper.insert(cloneIgnoreId(tableDO, o -> o.setTableName(randomString())));
|
||||
// 测试 tableComment 不匹配
|
||||
codegenTableMapper.insert(cloneIgnoreId(tableDO, o -> o.setTableComment(randomString())));
|
||||
// 测试 className 不匹配
|
||||
codegenTableMapper.insert(cloneIgnoreId(tableDO, o -> o.setClassName(randomString())));
|
||||
// 测试 createTime 不匹配
|
||||
codegenTableMapper.insert(cloneIgnoreId(tableDO, logDO -> logDO.setCreateTime(buildTime(2021, 4, 10))));
|
||||
// 准备参数
|
||||
CodegenTablePageReqVO reqVO = new CodegenTablePageReqVO();
|
||||
reqVO.setTableName("yunai");
|
||||
reqVO.setTableComment("芋");
|
||||
reqVO.setClassName("Yunai");
|
||||
reqVO.setCreateTime(buildBetweenTime(2021, 3, 1, 2021, 3, 31));
|
||||
|
||||
// 调用
|
||||
PageResult<CodegenTableDO> pageResult = codegenService.getCodegenTablePage(reqVO);
|
||||
// 断言,只查到了一条符合条件的
|
||||
assertEquals(1, pageResult.getTotal());
|
||||
assertEquals(1, pageResult.getList().size());
|
||||
assertPojoEquals(tableDO, pageResult.getList().get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetCodegenTable() {
|
||||
// mock 数据
|
||||
CodegenTableDO tableDO = randomPojo(CodegenTableDO.class, o -> o.setScene(CodegenSceneEnum.ADMIN.getScene()));
|
||||
codegenTableMapper.insert(tableDO);
|
||||
// 准备参数
|
||||
Long id = tableDO.getId();
|
||||
|
||||
// 调用
|
||||
CodegenTableDO result = codegenService.getCodegenTable(id);
|
||||
// 断言
|
||||
assertPojoEquals(tableDO, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetCodegenColumnListByTableId() {
|
||||
// mock 数据
|
||||
CodegenColumnDO column01 = randomPojo(CodegenColumnDO.class);
|
||||
codegenColumnMapper.insert(column01);
|
||||
CodegenColumnDO column02 = randomPojo(CodegenColumnDO.class);
|
||||
codegenColumnMapper.insert(column02);
|
||||
// 准备参数
|
||||
Long tableId = column01.getTableId();
|
||||
|
||||
// 调用
|
||||
List<CodegenColumnDO> result = codegenService.getCodegenColumnListByTableId(tableId);
|
||||
// 断言
|
||||
assertEquals(1, result.size());
|
||||
assertPojoEquals(column01, result.get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGenerationCodes_tableNotExists() {
|
||||
assertServiceException(() -> codegenService.generationCodes(randomLongId()),
|
||||
CODEGEN_TABLE_NOT_EXISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGenerationCodes_columnNotExists() {
|
||||
// mock 数据(CodegenTableDO)
|
||||
CodegenTableDO table = randomPojo(CodegenTableDO.class,
|
||||
o -> o.setScene(CodegenSceneEnum.ADMIN.getScene())
|
||||
.setTemplateType(CodegenTemplateTypeEnum.MASTER_NORMAL.getType()));
|
||||
codegenTableMapper.insert(table);
|
||||
// 准备参数
|
||||
Long tableId = table.getId();
|
||||
|
||||
// 调用,并断言
|
||||
assertServiceException(() -> codegenService.generationCodes(tableId),
|
||||
CODEGEN_COLUMN_NOT_EXISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGenerationCodes_sub_tableNotExists() {
|
||||
// mock 数据(CodegenTableDO)
|
||||
CodegenTableDO table = randomPojo(CodegenTableDO.class,
|
||||
o -> o.setScene(CodegenSceneEnum.ADMIN.getScene())
|
||||
.setTemplateType(CodegenTemplateTypeEnum.MASTER_NORMAL.getType()));
|
||||
codegenTableMapper.insert(table);
|
||||
// mock 数据(CodegenColumnDO)
|
||||
CodegenColumnDO column01 = randomPojo(CodegenColumnDO.class, o -> o.setTableId(table.getId()));
|
||||
codegenColumnMapper.insert(column01);
|
||||
// 准备参数
|
||||
Long tableId = table.getId();
|
||||
|
||||
// 调用,并断言
|
||||
assertServiceException(() -> codegenService.generationCodes(tableId),
|
||||
CODEGEN_MASTER_GENERATION_FAIL_NO_SUB_TABLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGenerationCodes_sub_columnNotExists() {
|
||||
// mock 数据(CodegenTableDO)
|
||||
CodegenTableDO table = randomPojo(CodegenTableDO.class,
|
||||
o -> o.setScene(CodegenSceneEnum.ADMIN.getScene())
|
||||
.setTemplateType(CodegenTemplateTypeEnum.MASTER_NORMAL.getType()));
|
||||
codegenTableMapper.insert(table);
|
||||
// mock 数据(CodegenColumnDO)
|
||||
CodegenColumnDO column01 = randomPojo(CodegenColumnDO.class, o -> o.setTableId(table.getId()));
|
||||
codegenColumnMapper.insert(column01);
|
||||
// mock 数据(sub CodegenTableDO)
|
||||
CodegenTableDO subTable = randomPojo(CodegenTableDO.class,
|
||||
o -> o.setScene(CodegenSceneEnum.ADMIN.getScene())
|
||||
.setTemplateType(CodegenTemplateTypeEnum.SUB.getType())
|
||||
.setMasterTableId(table.getId()));
|
||||
codegenTableMapper.insert(subTable);
|
||||
// 准备参数
|
||||
Long tableId = table.getId();
|
||||
|
||||
// 调用,并断言
|
||||
assertServiceException(() -> codegenService.generationCodes(tableId),
|
||||
CODEGEN_SUB_COLUMN_NOT_EXISTS, subTable.getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGenerationCodes_one_success() {
|
||||
// mock 数据(CodegenTableDO)
|
||||
CodegenTableDO table = randomPojo(CodegenTableDO.class,
|
||||
o -> o.setScene(CodegenSceneEnum.ADMIN.getScene())
|
||||
.setTemplateType(CodegenTemplateTypeEnum.ONE.getType()));
|
||||
codegenTableMapper.insert(table);
|
||||
// mock 数据(CodegenColumnDO)
|
||||
CodegenColumnDO column01 = randomPojo(CodegenColumnDO.class, o -> o.setTableId(table.getId()));
|
||||
codegenColumnMapper.insert(column01);
|
||||
CodegenColumnDO column02 = randomPojo(CodegenColumnDO.class, o -> o.setTableId(table.getId()));
|
||||
codegenColumnMapper.insert(column02);
|
||||
// mock 执行生成
|
||||
Map<String, String> codes = MapUtil.of(randomString(), randomString());
|
||||
when(codegenEngine.execute(eq(table), argThat(columns -> {
|
||||
assertEquals(2, columns.size());
|
||||
assertEquals(column01, columns.get(0));
|
||||
assertEquals(column02, columns.get(1));
|
||||
return true;
|
||||
}), isNull(), isNull())).thenReturn(codes);
|
||||
// 准备参数
|
||||
Long tableId = table.getId();
|
||||
|
||||
// 调用
|
||||
Map<String, String> result = codegenService.generationCodes(tableId);
|
||||
// 断言
|
||||
assertSame(codes, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGenerationCodes_master_success() {
|
||||
// mock 数据(CodegenTableDO)
|
||||
CodegenTableDO table = randomPojo(CodegenTableDO.class,
|
||||
o -> o.setScene(CodegenSceneEnum.ADMIN.getScene())
|
||||
.setTemplateType(CodegenTemplateTypeEnum.MASTER_NORMAL.getType()));
|
||||
codegenTableMapper.insert(table);
|
||||
// mock 数据(CodegenColumnDO)
|
||||
CodegenColumnDO column01 = randomPojo(CodegenColumnDO.class, o -> o.setTableId(table.getId()));
|
||||
codegenColumnMapper.insert(column01);
|
||||
CodegenColumnDO column02 = randomPojo(CodegenColumnDO.class, o -> o.setTableId(table.getId()));
|
||||
codegenColumnMapper.insert(column02);
|
||||
// mock 数据(sub CodegenTableDO)
|
||||
CodegenTableDO subTable = randomPojo(CodegenTableDO.class,
|
||||
o -> o.setScene(CodegenSceneEnum.ADMIN.getScene())
|
||||
.setTemplateType(CodegenTemplateTypeEnum.SUB.getType())
|
||||
.setMasterTableId(table.getId())
|
||||
.setSubJoinColumnId(1024L));
|
||||
codegenTableMapper.insert(subTable);
|
||||
// mock 数据(sub CodegenColumnDO)
|
||||
CodegenColumnDO subColumn01 = randomPojo(CodegenColumnDO.class, o -> o.setId(1024L).setTableId(subTable.getId()));
|
||||
codegenColumnMapper.insert(subColumn01);
|
||||
// mock 执行生成
|
||||
Map<String, String> codes = MapUtil.of(randomString(), randomString());
|
||||
when(codegenEngine.execute(eq(table), argThat(columns -> {
|
||||
assertEquals(2, columns.size());
|
||||
assertEquals(column01, columns.get(0));
|
||||
assertEquals(column02, columns.get(1));
|
||||
return true;
|
||||
}), argThat(tables -> {
|
||||
assertEquals(1, tables.size());
|
||||
assertPojoEquals(subTable, tables.get(0));
|
||||
return true;
|
||||
}), argThat(columns -> {
|
||||
assertEquals(1, columns.size());
|
||||
assertPojoEquals(subColumn01, columns.size());
|
||||
return true;
|
||||
}))).thenReturn(codes);
|
||||
// 准备参数
|
||||
Long tableId = table.getId();
|
||||
|
||||
// 调用
|
||||
Map<String, String> result = codegenService.generationCodes(tableId);
|
||||
// 断言
|
||||
assertSame(codes, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetDatabaseTableList() {
|
||||
// 准备参数
|
||||
Long dataSourceConfigId = randomLongId();
|
||||
String name = randomString();
|
||||
String comment = randomString();
|
||||
// mock 方法
|
||||
TableInfo tableInfo01 = mock(TableInfo.class);
|
||||
when(tableInfo01.getName()).thenReturn("t_yunai");
|
||||
when(tableInfo01.getComment()).thenReturn("芋艿");
|
||||
TableInfo tableInfo02 = mock(TableInfo.class);
|
||||
when(tableInfo02.getName()).thenReturn("t_yunai_02");
|
||||
when(tableInfo02.getComment()).thenReturn("芋艿_02");
|
||||
when(databaseTableService.getTableList(eq(dataSourceConfigId), eq(name), eq(comment)))
|
||||
.thenReturn(ListUtil.toList(tableInfo01, tableInfo02));
|
||||
// mock 数据
|
||||
CodegenTableDO tableDO = randomPojo(CodegenTableDO.class,
|
||||
o -> o.setScene(CodegenSceneEnum.ADMIN.getScene())
|
||||
.setTableName("t_yunai_02")
|
||||
.setDataSourceConfigId(dataSourceConfigId));
|
||||
codegenTableMapper.insert(tableDO);
|
||||
|
||||
// 调用
|
||||
List<DatabaseTableRespVO> result = codegenService.getDatabaseTableList(dataSourceConfigId, name, comment);
|
||||
// 断言
|
||||
assertEquals(1, result.size());
|
||||
assertEquals("t_yunai", result.get(0).getName());
|
||||
assertEquals("芋艿", result.get(0).getComment());
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,89 @@
|
||||
package cn.iocoder.yudao.module.infra.service.codegen.inner;
|
||||
|
||||
import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;
|
||||
import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.CodegenColumnDO;
|
||||
import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.CodegenTableDO;
|
||||
import com.baomidou.mybatisplus.generator.config.po.TableField;
|
||||
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
|
||||
import com.baomidou.mybatisplus.generator.config.rules.IColumnType;
|
||||
import org.apache.ibatis.type.JdbcType;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.InjectMocks;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
public class CodegenBuilderTest extends BaseMockitoUnitTest {
|
||||
|
||||
@InjectMocks
|
||||
private CodegenBuilder codegenBuilder;
|
||||
|
||||
@Test
|
||||
public void testBuildTable() {
|
||||
// 准备参数
|
||||
TableInfo tableInfo = mock(TableInfo.class);
|
||||
// mock 方法
|
||||
when(tableInfo.getName()).thenReturn("system_user");
|
||||
when(tableInfo.getComment()).thenReturn("用户");
|
||||
|
||||
// 调用
|
||||
CodegenTableDO table = codegenBuilder.buildTable(tableInfo);
|
||||
// 断言
|
||||
assertEquals("system_user", table.getTableName());
|
||||
assertEquals("用户", table.getTableComment());
|
||||
assertEquals("system", table.getModuleName());
|
||||
assertEquals("user", table.getBusinessName());
|
||||
assertEquals("User", table.getClassName());
|
||||
assertEquals("用户", table.getClassComment());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBuildColumns() {
|
||||
// 准备参数
|
||||
Long tableId = randomLongId();
|
||||
TableField tableField = mock(TableField.class);
|
||||
List<TableField> tableFields = Collections.singletonList(tableField);
|
||||
// mock 方法
|
||||
TableField.MetaInfo metaInfo = mock(TableField.MetaInfo.class);
|
||||
when(tableField.getMetaInfo()).thenReturn(metaInfo);
|
||||
when(metaInfo.getJdbcType()).thenReturn(JdbcType.BIGINT);
|
||||
when(tableField.getComment()).thenReturn("编号");
|
||||
when(tableField.isKeyFlag()).thenReturn(true);
|
||||
when(tableField.isKeyIdentityFlag()).thenReturn(true);
|
||||
IColumnType columnType = mock(IColumnType.class);
|
||||
when(tableField.getColumnType()).thenReturn(columnType);
|
||||
when(columnType.getType()).thenReturn("Long");
|
||||
when(tableField.getName()).thenReturn("id2");
|
||||
when(tableField.getPropertyName()).thenReturn("id");
|
||||
|
||||
// 调用
|
||||
List<CodegenColumnDO> columns = codegenBuilder.buildColumns(tableId, tableFields);
|
||||
// 断言
|
||||
assertEquals(1, columns.size());
|
||||
CodegenColumnDO column = columns.get(0);
|
||||
assertEquals(tableId, column.getTableId());
|
||||
assertEquals("id2", column.getColumnName());
|
||||
assertEquals("BIGINT", column.getDataType());
|
||||
assertEquals("编号", column.getColumnComment());
|
||||
assertFalse(column.getNullable());
|
||||
assertTrue(column.getPrimaryKey());
|
||||
assertTrue(column.getAutoIncrement());
|
||||
assertEquals(1, column.getOrdinalPosition());
|
||||
assertEquals("Long", column.getJavaType());
|
||||
assertEquals("id", column.getJavaField());
|
||||
assertNull(column.getDictType());
|
||||
assertNotNull(column.getExample());
|
||||
assertFalse(column.getCreateOperation());
|
||||
assertTrue(column.getUpdateOperation());
|
||||
assertFalse(column.getListOperation());
|
||||
assertEquals("=", column.getListOperationCondition());
|
||||
assertTrue(column.getListOperationResult());
|
||||
assertEquals("input", column.getHtmlType());
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,127 @@
|
||||
package cn.iocoder.yudao.module.infra.service.codegen.inner;
|
||||
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
import cn.hutool.core.io.IoUtil;
|
||||
import cn.hutool.core.io.resource.ResourceUtil;
|
||||
import cn.hutool.core.map.MapUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.core.util.ZipUtil;
|
||||
import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
|
||||
import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;
|
||||
import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.CodegenColumnDO;
|
||||
import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.CodegenTableDO;
|
||||
import cn.iocoder.yudao.module.infra.framework.codegen.config.CodegenProperties;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Spy;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
/**
|
||||
* {@link CodegenEngine} 的单元测试抽象基类
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
public abstract class CodegenEngineAbstractTest extends BaseMockitoUnitTest {
|
||||
|
||||
@InjectMocks
|
||||
protected CodegenEngine codegenEngine;
|
||||
|
||||
@Spy
|
||||
protected CodegenProperties codegenProperties = new CodegenProperties()
|
||||
.setBasePackage("cn.iocoder.yudao");
|
||||
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
codegenEngine.initGlobalBindingMap();
|
||||
}
|
||||
|
||||
protected static CodegenTableDO getTable(String name) {
|
||||
String content = ResourceUtil.readUtf8Str("codegen/table/" + name + ".json");
|
||||
return JsonUtils.parseObject(content, "table", CodegenTableDO.class);
|
||||
}
|
||||
|
||||
protected static List<CodegenColumnDO> getColumnList(String name) {
|
||||
String content = ResourceUtil.readUtf8Str("codegen/table/" + name + ".json");
|
||||
List<CodegenColumnDO> list = JsonUtils.parseArray(content, "columns", CodegenColumnDO.class);
|
||||
list.forEach(column -> {
|
||||
if (column.getNullable() == null) {
|
||||
column.setNullable(false);
|
||||
}
|
||||
if (column.getCreateOperation() == null) {
|
||||
column.setCreateOperation(false);
|
||||
}
|
||||
if (column.getUpdateOperation() == null) {
|
||||
column.setUpdateOperation(false);
|
||||
}
|
||||
if (column.getListOperation() == null) {
|
||||
column.setListOperation(false);
|
||||
}
|
||||
if (column.getListOperationResult() == null) {
|
||||
column.setListOperationResult(false);
|
||||
}
|
||||
});
|
||||
return list;
|
||||
}
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
protected static void assertResult(Map<String, String> result, String path) {
|
||||
String assertContent = ResourceUtil.readUtf8Str(path + "/assert.json");
|
||||
List<HashMap> asserts = JsonUtils.parseArray(assertContent, HashMap.class);
|
||||
assertEquals(asserts.size(), result.size());
|
||||
// 校验每个文件
|
||||
asserts.forEach(assertMap -> {
|
||||
String contentPath = (String) assertMap.get("contentPath");
|
||||
String filePath = (String) assertMap.get("filePath");
|
||||
String content = ResourceUtil.readUtf8Str(path + "/" + contentPath);
|
||||
assertEquals(content, result.get(filePath), filePath + ":不匹配");
|
||||
});
|
||||
}
|
||||
|
||||
// ==================== 调试专用 ====================
|
||||
|
||||
/**
|
||||
* 【调试使用】将生成的代码,写入到文件
|
||||
*
|
||||
* @param result 生成的代码
|
||||
* @param path 写入文件的路径
|
||||
*/
|
||||
protected void writeFile(Map<String, String> result, String path) {
|
||||
// 生成压缩包
|
||||
String[] paths = result.keySet().toArray(new String[0]);
|
||||
ByteArrayInputStream[] ins = result.values().stream().map(IoUtil::toUtf8Stream).toArray(ByteArrayInputStream[]::new);
|
||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||
ZipUtil.zip(outputStream, paths, ins);
|
||||
// 写入文件
|
||||
FileUtil.writeBytes(outputStream.toByteArray(), path);
|
||||
}
|
||||
|
||||
/**
|
||||
* 【调试使用】将生成的结果,写入到文件
|
||||
*
|
||||
* @param result 生成的代码
|
||||
* @param basePath 写入文件的路径(绝对路径)
|
||||
*/
|
||||
protected void writeResult(Map<String, String> result, String basePath) {
|
||||
// 写入文件内容
|
||||
List<Map<String, String>> asserts = new ArrayList<>();
|
||||
result.forEach((filePath, fileContent) -> {
|
||||
String lastFilePath = StrUtil.subAfter(filePath, '/', true);
|
||||
String contentPath = StrUtil.subAfter(lastFilePath, '.', true)
|
||||
+ '/' + StrUtil.subBefore(lastFilePath, '.', true);
|
||||
asserts.add(MapUtil.<String, String>builder().put("filePath", filePath)
|
||||
.put("contentPath", contentPath).build());
|
||||
FileUtil.writeUtf8String(fileContent, basePath + "/" + contentPath);
|
||||
});
|
||||
// 写入 assert.json 文件
|
||||
FileUtil.writeUtf8String(JsonUtils.toJsonPrettyString(asserts), basePath +"/assert.json");
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,98 @@
|
||||
package cn.iocoder.yudao.module.infra.service.codegen.inner;
|
||||
|
||||
import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.CodegenColumnDO;
|
||||
import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.CodegenTableDO;
|
||||
import cn.iocoder.yudao.module.infra.enums.codegen.CodegenFrontTypeEnum;
|
||||
import cn.iocoder.yudao.module.infra.enums.codegen.CodegenTemplateTypeEnum;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
// TODO @puhui999:单测需要 fix
|
||||
/**
|
||||
* {@link CodegenEngine} 的 Vue2 + Element UI 单元测试
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Disabled
|
||||
public class CodegenEngineVue2Test extends CodegenEngineAbstractTest {
|
||||
|
||||
@Test
|
||||
public void testExecute_vue2_one() {
|
||||
// 准备参数
|
||||
CodegenTableDO table = getTable("student")
|
||||
.setFrontType(CodegenFrontTypeEnum.VUE2.getType())
|
||||
.setTemplateType(CodegenTemplateTypeEnum.ONE.getType());
|
||||
List<CodegenColumnDO> columns = getColumnList("student");
|
||||
|
||||
// 调用
|
||||
Map<String, String> result = codegenEngine.execute(table, columns, null, null);
|
||||
// 断言
|
||||
assertResult(result, "codegen/vue2_one");
|
||||
// writeResult(result, "/root/ruoyi-vue-pro/yudao-module-infra/yudao-module-infra-biz/src/test/resources/codegen/vue2_one");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExecute_vue2_tree() {
|
||||
// 准备参数
|
||||
CodegenTableDO table = getTable("category")
|
||||
.setFrontType(CodegenFrontTypeEnum.VUE2.getType())
|
||||
.setTemplateType(CodegenTemplateTypeEnum.TREE.getType());
|
||||
List<CodegenColumnDO> columns = getColumnList("category");
|
||||
|
||||
// 调用
|
||||
Map<String, String> result = codegenEngine.execute(table, columns, null, null);
|
||||
// 断言
|
||||
assertResult(result, "codegen/vue2_tree");
|
||||
// writeResult(result, "/root/ruoyi-vue-pro/yudao-module-infra/yudao-module-infra-biz/src/test/resources/codegen/vue2_tree");
|
||||
// writeFile(result, "/Users/yunai/test/demo66.zip");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExecute_vue2_master_normal() {
|
||||
testExecute_vue2_master(CodegenTemplateTypeEnum.MASTER_NORMAL, "codegen/vue2_master_normal");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExecute_vue2_master_erp() {
|
||||
testExecute_vue2_master(CodegenTemplateTypeEnum.MASTER_ERP, "codegen/vue2_master_erp");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExecute_vue2_master_inner() {
|
||||
testExecute_vue2_master(CodegenTemplateTypeEnum.MASTER_INNER, "codegen/vue2_master_inner");
|
||||
}
|
||||
|
||||
private void testExecute_vue2_master(CodegenTemplateTypeEnum templateType,
|
||||
String path) {
|
||||
// 准备参数
|
||||
CodegenTableDO table = getTable("student")
|
||||
.setFrontType(CodegenFrontTypeEnum.VUE2.getType())
|
||||
.setTemplateType(templateType.getType());
|
||||
List<CodegenColumnDO> columns = getColumnList("student");
|
||||
// 准备参数(子表)
|
||||
CodegenTableDO contactTable = getTable("contact")
|
||||
.setTemplateType(CodegenTemplateTypeEnum.SUB.getType())
|
||||
.setFrontType(CodegenFrontTypeEnum.VUE2.getType())
|
||||
.setSubJoinColumnId(100L).setSubJoinMany(true);
|
||||
List<CodegenColumnDO> contactColumns = getColumnList("contact");
|
||||
// 准备参数(班主任)
|
||||
CodegenTableDO teacherTable = getTable("teacher")
|
||||
.setTemplateType(CodegenTemplateTypeEnum.SUB.getType())
|
||||
.setFrontType(CodegenFrontTypeEnum.VUE2.getType())
|
||||
.setSubJoinColumnId(200L).setSubJoinMany(false);
|
||||
List<CodegenColumnDO> teacherColumns = getColumnList("teacher");
|
||||
|
||||
// 调用
|
||||
Map<String, String> result = codegenEngine.execute(table, columns,
|
||||
Arrays.asList(contactTable, teacherTable), Arrays.asList(contactColumns, teacherColumns));
|
||||
// 断言
|
||||
assertResult(result, path);
|
||||
// writeResult(result, "/root/ruoyi-vue-pro/yudao-module-infra/yudao-module-infra-biz/src/test/resources/" + path);
|
||||
// writeFile(result, "/Users/yunai/test/demo11.zip");
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,95 @@
|
||||
package cn.iocoder.yudao.module.infra.service.codegen.inner;
|
||||
|
||||
import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.CodegenColumnDO;
|
||||
import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.CodegenTableDO;
|
||||
import cn.iocoder.yudao.module.infra.enums.codegen.CodegenFrontTypeEnum;
|
||||
import cn.iocoder.yudao.module.infra.enums.codegen.CodegenTemplateTypeEnum;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* {@link CodegenEngine} 的 Vue2 + Element Plus 单元测试
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
public class CodegenEngineVue3Test extends CodegenEngineAbstractTest {
|
||||
|
||||
@Test
|
||||
public void testExecute_vue3_one() {
|
||||
// 准备参数
|
||||
CodegenTableDO table = getTable("student")
|
||||
.setFrontType(CodegenFrontTypeEnum.VUE3.getType())
|
||||
.setTemplateType(CodegenTemplateTypeEnum.ONE.getType());
|
||||
List<CodegenColumnDO> columns = getColumnList("student");
|
||||
|
||||
// 调用
|
||||
Map<String, String> result = codegenEngine.execute(table, columns, null, null);
|
||||
// 断言
|
||||
assertResult(result, "codegen/vue3_one");
|
||||
// writeResult(result, "/root/ruoyi-vue-pro/yudao-module-infra/yudao-module-infra-biz/src/test/resources/codegen/vue3_one");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExecute_vue3_tree() {
|
||||
// 准备参数
|
||||
CodegenTableDO table = getTable("category")
|
||||
.setFrontType(CodegenFrontTypeEnum.VUE3.getType())
|
||||
.setTemplateType(CodegenTemplateTypeEnum.TREE.getType());
|
||||
List<CodegenColumnDO> columns = getColumnList("category");
|
||||
|
||||
// 调用
|
||||
Map<String, String> result = codegenEngine.execute(table, columns, null, null);
|
||||
// 断言
|
||||
assertResult(result, "codegen/vue3_tree");
|
||||
// writeResult(result, "/root/ruoyi-vue-pro/yudao-module-infra/yudao-module-infra-biz/src/test/resources/codegen/vue3_tree");
|
||||
// writeFile(result, "/Users/yunai/test/demo66.zip");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExecute_vue3_master_normal() {
|
||||
testExecute_vue3_master(CodegenTemplateTypeEnum.MASTER_NORMAL, "codegen/vue3_master_normal");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExecute_vue3_master_erp() {
|
||||
testExecute_vue3_master(CodegenTemplateTypeEnum.MASTER_ERP, "codegen/vue3_master_erp");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExecute_vue3_master_inner() {
|
||||
testExecute_vue3_master(CodegenTemplateTypeEnum.MASTER_INNER, "codegen/vue3_master_inner");
|
||||
}
|
||||
|
||||
private void testExecute_vue3_master(CodegenTemplateTypeEnum templateType,
|
||||
String path) {
|
||||
// 准备参数
|
||||
CodegenTableDO table = getTable("student")
|
||||
.setFrontType(CodegenFrontTypeEnum.VUE3.getType())
|
||||
.setTemplateType(templateType.getType());
|
||||
List<CodegenColumnDO> columns = getColumnList("student");
|
||||
// 准备参数(子表)
|
||||
CodegenTableDO contactTable = getTable("contact")
|
||||
.setTemplateType(CodegenTemplateTypeEnum.SUB.getType())
|
||||
.setFrontType(CodegenFrontTypeEnum.VUE3.getType())
|
||||
.setSubJoinColumnId(100L).setSubJoinMany(true);
|
||||
List<CodegenColumnDO> contactColumns = getColumnList("contact");
|
||||
// 准备参数(班主任)
|
||||
CodegenTableDO teacherTable = getTable("teacher")
|
||||
.setTemplateType(CodegenTemplateTypeEnum.SUB.getType())
|
||||
.setFrontType(CodegenFrontTypeEnum.VUE3.getType())
|
||||
.setSubJoinColumnId(200L).setSubJoinMany(false);
|
||||
List<CodegenColumnDO> teacherColumns = getColumnList("teacher");
|
||||
|
||||
// 调用
|
||||
Map<String, String> result = codegenEngine.execute(table, columns,
|
||||
Arrays.asList(contactTable, teacherTable), Arrays.asList(contactColumns, teacherColumns));
|
||||
// 断言
|
||||
assertResult(result, path);
|
||||
// writeResult(result, "/root/ruoyi-vue-pro/yudao-module-infra/yudao-module-infra-biz/src/test/resources/" + path);
|
||||
// writeFile(result, "/Users/yunai/test/demo11.zip");
|
||||
}
|
||||
|
||||
}
|
@ -1,4 +0,0 @@
|
||||
/**
|
||||
* 占位,无其它作用
|
||||
*/
|
||||
package cn.iocoder.yudao.module.infra.service.codegen;
|
@ -0,0 +1,12 @@
|
||||
<?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="cn.iocoder.yudao.module.infra.dal.mysql.demo.InfraStudentMapper">
|
||||
|
||||
<!--
|
||||
一般情况下,尽可能使用 Mapper 进行 CRUD 增删改查即可。
|
||||
无法满足的场景,例如说多表关联查询,才使用 XML 编写 SQL。
|
||||
代码生成器暂时只生成 Mapper XML 文件本身,更多推荐 MybatisX 快速开发插件来生成查询。
|
||||
文档可见:https://www.iocoder.cn/MyBatis/x-plugins/
|
||||
-->
|
||||
|
||||
</mapper>
|
@ -197,11 +197,11 @@ const total = ref(0) // 列表的总页数
|
||||
const queryParams = reactive({
|
||||
pageNo: 1,
|
||||
pageSize: 10,
|
||||
name: null,
|
||||
birthday: null,
|
||||
name: undefined,
|
||||
birthday: undefined,
|
||||
birthday: [],
|
||||
sex: null,
|
||||
enabled: null,
|
||||
sex: undefined,
|
||||
enabled: undefined,
|
||||
createTime: []
|
||||
})
|
||||
const queryFormRef = ref() // 搜索的表单
|
||||
|
@ -192,11 +192,11 @@ const total = ref(0) // 列表的总页数
|
||||
const queryParams = reactive({
|
||||
pageNo: 1,
|
||||
pageSize: 10,
|
||||
name: null,
|
||||
birthday: null,
|
||||
name: undefined,
|
||||
birthday: undefined,
|
||||
birthday: [],
|
||||
sex: null,
|
||||
enabled: null,
|
||||
sex: undefined,
|
||||
enabled: undefined,
|
||||
createTime: []
|
||||
})
|
||||
const queryFormRef = ref() // 搜索的表单
|
||||
|
@ -177,11 +177,11 @@ const total = ref(0) // 列表的总页数
|
||||
const queryParams = reactive({
|
||||
pageNo: 1,
|
||||
pageSize: 10,
|
||||
name: null,
|
||||
birthday: null,
|
||||
name: undefined,
|
||||
birthday: undefined,
|
||||
birthday: [],
|
||||
sex: null,
|
||||
enabled: null,
|
||||
sex: undefined,
|
||||
enabled: undefined,
|
||||
createTime: []
|
||||
})
|
||||
const queryFormRef = ref() // 搜索的表单
|
||||
|
@ -177,11 +177,11 @@ const total = ref(0) // 列表的总页数
|
||||
const queryParams = reactive({
|
||||
pageNo: 1,
|
||||
pageSize: 10,
|
||||
name: null,
|
||||
birthday: null,
|
||||
name: undefined,
|
||||
birthday: undefined,
|
||||
birthday: [],
|
||||
sex: null,
|
||||
enabled: null,
|
||||
sex: undefined,
|
||||
enabled: undefined,
|
||||
createTime: []
|
||||
})
|
||||
const queryFormRef = ref() // 搜索的表单
|
||||
|
@ -106,7 +106,7 @@ const { t } = useI18n() // 国际化
|
||||
const loading = ref(true) // 列表的加载中
|
||||
const list = ref([]) // 列表的数据
|
||||
const queryParams = reactive({
|
||||
name: null
|
||||
name: undefined
|
||||
})
|
||||
const queryFormRef = ref() // 搜索的表单
|
||||
const exportLoading = ref(false) // 导出的加载中
|
||||
|
@ -8,3 +8,5 @@ DELETE FROM "infra_api_error_log";
|
||||
DELETE FROM "infra_file_config";
|
||||
DELETE FROM "infra_test_demo";
|
||||
DELETE FROM "infra_data_source_config";
|
||||
DELETE FROM "infra_codegen_table";
|
||||
DELETE FROM "infra_codegen_column";
|
||||
|
@ -170,3 +170,59 @@ CREATE TABLE IF NOT EXISTS "infra_data_source_config" (
|
||||
"deleted" bit NOT NULL DEFAULT FALSE,
|
||||
PRIMARY KEY ("id")
|
||||
) COMMENT '数据源配置表';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS "infra_codegen_table" (
|
||||
"id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
|
||||
"data_source_config_id" bigint not null,
|
||||
"scene" tinyint not null DEFAULT 1,
|
||||
"table_name" varchar(200) NOT NULL,
|
||||
"table_comment" varchar(500) NOT NULL,
|
||||
"remark" varchar(500) NOT NULL,
|
||||
"module_name" varchar(30) NOT NULL,
|
||||
"business_name" varchar(30) NOT NULL,
|
||||
"class_name" varchar(100) NOT NULL,
|
||||
"class_comment" varchar(50) NOT NULL,
|
||||
"author" varchar(50) NOT NULL,
|
||||
"template_type" tinyint not null DEFAULT 1,
|
||||
"front_type" tinyint not null,
|
||||
"parent_menu_id" bigint not null,
|
||||
"master_table_id" bigint not null,
|
||||
"sub_join_column_id" bigint not null,
|
||||
"sub_join_many" bit not null,
|
||||
"tree_parent_column_id" bigint not null,
|
||||
"tree_name_column_id" bigint not null,
|
||||
"creator" varchar(64) DEFAULT '',
|
||||
"create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updater" varchar(64) DEFAULT '',
|
||||
"update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
"deleted" bit NOT NULL DEFAULT FALSE,
|
||||
PRIMARY KEY ("id")
|
||||
) COMMENT '代码生成表定义表';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS "infra_codegen_column" (
|
||||
"id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
|
||||
"table_id" bigint not null,
|
||||
"column_name" varchar(200) NOT NULL,
|
||||
"data_type" varchar(100) NOT NULL,
|
||||
"column_comment" varchar(500) NOT NULL,
|
||||
"nullable" tinyint not null,
|
||||
"primary_key" tinyint not null,
|
||||
"auto_increment" varchar(5) not null,
|
||||
"ordinal_position" int not null,
|
||||
"java_type" varchar(32) NOT NULL,
|
||||
"java_field" varchar(64) NOT NULL,
|
||||
"dict_type" varchar(200) NOT NULL,
|
||||
"example" varchar(64) NOT NULL,
|
||||
"create_operation" bit not null,
|
||||
"update_operation" bit not null,
|
||||
"list_operation" bit not null,
|
||||
"list_operation_condition" varchar(32) not null,
|
||||
"list_operation_result" bit not null,
|
||||
"html_type" varchar(32) NOT NULL,
|
||||
"creator" varchar(64) DEFAULT '',
|
||||
"create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updater" varchar(64) DEFAULT '',
|
||||
"update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
"deleted" bit NOT NULL DEFAULT FALSE,
|
||||
PRIMARY KEY ("id")
|
||||
) COMMENT '代码生成表字段定义表';
|
@ -14,8 +14,7 @@ import java.util.Set;
|
||||
@Data
|
||||
public class UserSaveReqVO {
|
||||
|
||||
@Schema(description = "用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
@NotNull(message = "用户编号不能为空")
|
||||
@Schema(description = "用户编号", example = "1024")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "用户账号", requiredMode = Schema.RequiredMode.REQUIRED, example = "yudao")
|
||||
|
Loading…
Reference in New Issue
Block a user