Commit 01a55b93c2dc9019d85ea5548ba82d26c32476e5

Authored by YunaiV
1 parent f5ea270b

代码生成:增加更全的 tree 场景下的新增/修改校验

yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/codegen/inner/CodegenEngine.java
... ... @@ -324,10 +324,14 @@ public class CodegenEngine {
324 324  
325 325 // 特殊:树表专属逻辑
326 326 if (CodegenTemplateTypeEnum.isTree(table.getTemplateType())) {
327   - bindingMap.put("treeParentColumn", CollUtil.findOne(columns,
328   - column -> Objects.equals(column.getId(), table.getTreeParentColumnId())));
329   - bindingMap.put("treeNameColumn", CollUtil.findOne(columns,
330   - column -> Objects.equals(column.getId(), table.getTreeNameColumnId())));
  327 + CodegenColumnDO treeParentColumn = CollUtil.findOne(columns,
  328 + column -> Objects.equals(column.getId(), table.getTreeParentColumnId()));
  329 + bindingMap.put("treeParentColumn", treeParentColumn);
  330 + bindingMap.put("treeParentColumn_javaField_underlineCase", toUnderlineCase(treeParentColumn.getJavaField()));
  331 + CodegenColumnDO treeNameColumn = CollUtil.findOne(columns,
  332 + column -> Objects.equals(column.getId(), table.getTreeNameColumnId()));
  333 + bindingMap.put("treeNameColumn", treeNameColumn);
  334 + bindingMap.put("treeNameColumn_javaField_underlineCase", toUnderlineCase(treeNameColumn.getJavaField()));
331 335 }
332 336  
333 337 // 特殊:主子表专属逻辑
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/dal/do.vm
... ... @@ -28,6 +28,11 @@ import ${BaseDOClassName};
28 28 @AllArgsConstructor
29 29 public class ${table.className}DO extends BaseDO {
30 30  
  31 +## 特殊:树表专属逻辑
  32 +#if ( $table.templateType == 2 )
  33 + public static final Long ${treeParentColumn_javaField_underlineCase.toUpperCase()}_ROOT = 0L;
  34 +
  35 +#end
31 36 #foreach ($column in $columns)
32 37 #if (!${baseDOFields.contains(${column.javaField})})##排除 BaseDO 的字段
33 38 /**
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/dal/mapper.vm
... ... @@ -68,9 +68,14 @@ public interface ${table.className}Mapper extends BaseMapperX<${table.className}
68 68  
69 69 ## 特殊:树表专属逻辑
70 70 #if ( $table.templateType == 2 )
71   -#set ($ParentJavaField = $treeParentColumn.javaField.substring(0,1).toUpperCase() + ${treeParentColumn.javaField.substring(1)})##首字母大写
72   - default Long selectCountBy${ParentJavaField}(${treeParentColumn.javaType} ${treeParentColumn.javaField}) {
73   - return selectCount(${table.className}DO::get${ParentJavaField}, ${treeParentColumn.javaField});
  71 +#set ($TreeParentJavaField = $treeParentColumn.javaField.substring(0,1).toUpperCase() + ${treeParentColumn.javaField.substring(1)})##首字母大写
  72 +#set ($TreeNameJavaField = $treeNameColumn.javaField.substring(0,1).toUpperCase() + ${treeNameColumn.javaField.substring(1)})##首字母大写
  73 + default ${table.className}DO selectBy${TreeParentJavaField}And${TreeNameJavaField}(Long ${treeParentColumn.javaField}, String ${treeNameColumn.javaField}) {
  74 + return selectOne(${table.className}DO::get${TreeParentJavaField}, ${treeParentColumn.javaField}, ${table.className}DO::get${TreeNameJavaField}, ${treeNameColumn.javaField});
  75 + }
  76 +
  77 + default Long selectCountBy${TreeParentJavaField}(${treeParentColumn.javaType} ${treeParentColumn.javaField}) {
  78 + return selectCount(${table.className}DO::get${TreeParentJavaField}, ${treeParentColumn.javaField});
74 79 }
75 80  
76 81 #end
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/enums/errorcode.vm
... ... @@ -4,4 +4,7 @@ ErrorCode ${simpleClassName_underlineCase.toUpperCase()}_NOT_EXISTS = new ErrorC
4 4 ## 特殊:树表专属逻辑
5 5 #if ( $table.templateType == 2 )
6 6 ErrorCode ${simpleClassName_underlineCase.toUpperCase()}_EXITS_CHILDREN = new ErrorCode(TODO 补充编号, "存在存在子${table.classComment},无法删除");
  7 +ErrorCode ${simpleClassName_underlineCase.toUpperCase()}_PARENT_NOT_EXITS = new ErrorCode(TODO 补充编号,"父级${table.classComment}不存在");
  8 +ErrorCode ${simpleClassName_underlineCase.toUpperCase()}_PARENT_ERROR = new ErrorCode(TODO 补充编号, "不能设置自己为父${table.classComment}");
  9 +ErrorCode ${simpleClassName_underlineCase.toUpperCase()}_${treeNameColumn_javaField_underlineCase.toUpperCase()}_DUPLICATE = new ErrorCode(TODO 补充编号, "已经存在该${treeNameColumn.columnComment}的${table.classComment}");
7 10 #end
8 11 \ No newline at end of file
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/service/serviceImpl.vm
... ... @@ -50,6 +50,16 @@ public class ${table.className}ServiceImpl implements ${table.className}Service
50 50 @Transactional(rollbackFor = Exception.class)
51 51 #end
52 52 public ${primaryColumn.javaType} create${simpleClassName}(${sceneEnum.prefixClass}${table.className}SaveReqVO createReqVO) {
  53 +## 特殊:树表专属逻辑
  54 +#if ( $table.templateType == 2 )
  55 +#set ($TreeParentJavaField = $treeParentColumn.javaField.substring(0,1).toUpperCase() + ${treeParentColumn.javaField.substring(1)})##首字母大写
  56 +#set ($TreeNameJavaField = $treeNameColumn.javaField.substring(0,1).toUpperCase() + ${treeNameColumn.javaField.substring(1)})##首字母大写
  57 + // 校验${treeParentColumn.columnComment}的有效性
  58 + validateParent${simpleClassName}(null, createReqVO.get${TreeParentJavaField}());
  59 + // 校验${treeNameColumn.columnComment}的唯一性
  60 + validate${simpleClassName}${TreeNameJavaField}Unique(null, createReqVO.get${TreeParentJavaField}(), createReqVO.get${TreeNameJavaField}());
  61 +
  62 +#end
53 63 // 插入
54 64 ${table.className}DO ${classNameVar} = BeanUtils.toBean(createReqVO, ${table.className}DO.class);
55 65 ${classNameVar}Mapper.insert(${classNameVar});
... ... @@ -81,6 +91,16 @@ public class ${table.className}ServiceImpl implements ${table.className}Service
81 91 public void update${simpleClassName}(${sceneEnum.prefixClass}${table.className}SaveReqVO updateReqVO) {
82 92 // 校验存在
83 93 validate${simpleClassName}Exists(updateReqVO.getId());
  94 +## 特殊:树表专属逻辑
  95 +#if ( $table.templateType == 2 )
  96 +#set ($TreeParentJavaField = $treeParentColumn.javaField.substring(0,1).toUpperCase() + ${treeParentColumn.javaField.substring(1)})##首字母大写
  97 +#set ($TreeNameJavaField = $treeNameColumn.javaField.substring(0,1).toUpperCase() + ${treeNameColumn.javaField.substring(1)})##首字母大写
  98 + // 校验${treeParentColumn.columnComment}的有效性
  99 + validateParent${simpleClassName}(updateReqVO.getId(), updateReqVO.get${TreeParentJavaField}());
  100 + // 校验${treeNameColumn.columnComment}的唯一性
  101 + validate${simpleClassName}${TreeNameJavaField}Unique(updateReqVO.getId(), updateReqVO.get${TreeParentJavaField}(), updateReqVO.get${TreeNameJavaField}());
  102 +
  103 +#end
84 104 // 更新
85 105 ${table.className}DO updateObj = BeanUtils.toBean(updateReqVO, ${table.className}DO.class);
86 106 ${classNameVar}Mapper.updateById(updateObj);
... ... @@ -140,6 +160,59 @@ public class ${table.className}ServiceImpl implements ${table.className}Service
140 160 }
141 161 }
142 162  
  163 +## 特殊:树表专属逻辑
  164 +#if ( $table.templateType == 2 )
  165 +#set ($TreeParentJavaField = $treeParentColumn.javaField.substring(0,1).toUpperCase() + ${treeParentColumn.javaField.substring(1)})##首字母大写
  166 +#set ($TreeNameJavaField = $treeNameColumn.javaField.substring(0,1).toUpperCase() + ${treeNameColumn.javaField.substring(1)})##首字母大写
  167 + private void validateParent${simpleClassName}(Long id, Long ${treeParentColumn.javaField}) {
  168 + if (${treeParentColumn.javaField} == null || ${simpleClassName}DO.${treeParentColumn_javaField_underlineCase.toUpperCase()}_ROOT.equals(${treeParentColumn.javaField})) {
  169 + return;
  170 + }
  171 + // 1. 不能设置自己为父${table.classComment}
  172 + if (Objects.equals(id, ${treeParentColumn.javaField})) {
  173 + throw exception(${simpleClassName_underlineCase.toUpperCase()}_PARENT_ERROR);
  174 + }
  175 + // 2. 父${table.classComment}不存在
  176 + ${simpleClassName}DO parent${simpleClassName} = ${classNameVar}Mapper.selectById(${treeParentColumn.javaField});
  177 + if (parent${simpleClassName} == null) {
  178 + throw exception(${simpleClassName_underlineCase.toUpperCase()}_PARENT_NOT_EXITS);
  179 + }
  180 + // 3. 递归校验父${table.classComment},如果父${table.classComment}是自己的子${table.classComment},则报错,避免形成环路
  181 + if (id == null) { // id 为空,说明新增,不需要考虑环路
  182 + return;
  183 + }
  184 + for (int i = 0; i < Short.MAX_VALUE; i++) {
  185 + // 3.1 校验环路
  186 + ${treeParentColumn.javaField} = parent${simpleClassName}.get${TreeParentJavaField}();
  187 + if (Objects.equals(id, ${treeParentColumn.javaField})) {
  188 + throw exception(${simpleClassName_underlineCase.toUpperCase()}_PARENT_IS_CHILD);
  189 + }
  190 + // 3.2 继续递归下一级父${table.classComment}
  191 + if (${treeParentColumn.javaField} == null || ${simpleClassName}DO.${treeParentColumn_javaField_underlineCase.toUpperCase()}_ROOT.equals(${treeParentColumn.javaField})) {
  192 + break;
  193 + }
  194 + parent${simpleClassName} = ${classNameVar}Mapper.selectById(${treeParentColumn.javaField});
  195 + if (parent${simpleClassName} == null) {
  196 + break;
  197 + }
  198 + }
  199 + }
  200 +
  201 + private void validate${simpleClassName}${TreeNameJavaField}Unique(Long id, Long ${treeParentColumn.javaField}, String ${treeNameColumn.javaField}) {
  202 + ${simpleClassName}DO ${classNameVar} = ${classNameVar}Mapper.selectBy${TreeParentJavaField}And${TreeNameJavaField}(${treeParentColumn.javaField}, ${treeNameColumn.javaField});
  203 + if (${classNameVar} == null) {
  204 + return;
  205 + }
  206 + // 如果 id 为空,说明不用比较是否为相同 id 的${table.classComment}
  207 + if (id == null) {
  208 + throw exception(${simpleClassName_underlineCase.toUpperCase()}_${treeNameColumn_javaField_underlineCase.toUpperCase()}_DUPLICATE);
  209 + }
  210 + if (ObjectUtil.notEqual(${classNameVar}.getId(), id)) {
  211 + throw exception(${simpleClassName_underlineCase.toUpperCase()}_${treeNameColumn_javaField_underlineCase.toUpperCase()}_DUPLICATE);
  212 + }
  213 + }
  214 +
  215 +#end
143 216 @Override
144 217 public ${table.className}DO get${simpleClassName}(${primaryColumn.javaType} id) {
145 218 return ${classNameVar}Mapper.selectById(id);
... ...
yudao-module-infra/yudao-module-infra-biz/src/test/java/cn/iocoder/yudao/module/infra/service/codegen/inner/CodegenEngineTest.java
... ... @@ -51,8 +51,7 @@ public class CodegenEngineTest extends BaseMockitoUnitTest {
51 51 .setClassComment("学生").setAuthor("芋道源码")
52 52 .setTemplateType(CodegenTemplateTypeEnum.TREE.getType())
53 53 .setFrontType(CodegenFrontTypeEnum.VUE3.getType())
54   - .setTreeParentColumnId(22L).setTreeNameColumnId(11L)
55   - ;
  54 + .setTreeParentColumnId(22L).setTreeNameColumnId(11L);
56 55 CodegenColumnDO idColumn = new CodegenColumnDO().setColumnName("id").setDataType(JdbcType.BIGINT.name())
57 56 .setColumnComment("编号").setNullable(false).setPrimaryKey(true).setAutoIncrement(true)
58 57 .setJavaType("Long").setJavaField("id").setExample("1024")
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/dept/DeptServiceImpl.java
... ... @@ -141,7 +141,7 @@ public class DeptServiceImpl implements DeptService {
141 141 if (dept == null) {
142 142 return;
143 143 }
144   - // 如果 id 为空,说明不用比较是否为相同 id 的岗位
  144 + // 如果 id 为空,说明不用比较是否为相同 id 的部门
145 145 if (id == null) {
146 146 throw exception(DEPT_NAME_DUPLICATE);
147 147 }
... ...