diff --git a/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/enums/ErrorCodeConstants.java b/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/enums/ErrorCodeConstants.java index 7cf23c8..94b89a2 100644 --- a/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/enums/ErrorCodeConstants.java +++ b/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/enums/ErrorCodeConstants.java @@ -48,6 +48,10 @@ public interface ErrorCodeConstants { ErrorCode CODEGEN_MASTER_TABLE_NOT_EXISTS = new ErrorCode(1_001_004_010, "主表(id={})定义不存在,请检查"); ErrorCode CODEGEN_SUB_COLUMN_NOT_EXISTS = new ErrorCode(1_001_004_011, "子表的字段(id={})不存在,请检查"); ErrorCode CODEGEN_MASTER_GENERATION_FAIL_NO_SUB_TABLE = new ErrorCode(1_001_004_012, "主表生成代码失败,原因:它没有子表"); + ErrorCode CODEGEN_MASTER_TABLE_NAME_DUPLICATE = new ErrorCode(1_001_004_013, + "主子表规范化类名({})重复,请调整主表或子表类名"); + ErrorCode CODEGEN_MASTER_TABLE_FIELD_DUPLICATE = new ErrorCode(1_001_004_014, + "主子表属性名({})重复,请调整主表字段、子表类名或关联关系"); // ========== 文件配置 1-001-006-000 ========== ErrorCode FILE_CONFIG_NOT_EXISTS = new ErrorCode(1_001_006_000, "文件配置不存在"); diff --git a/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/service/codegen/inner/CodegenEngine.java b/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/service/codegen/inner/CodegenEngine.java index 9a1f530..8bf14ba 100644 --- a/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/service/codegen/inner/CodegenEngine.java +++ b/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/service/codegen/inner/CodegenEngine.java @@ -48,6 +48,9 @@ import java.util.*; import static cn.hutool.core.map.MapUtil.getStr; import static cn.hutool.core.text.CharSequenceUtil.*; +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.module.infra.enums.ErrorCodeConstants.CODEGEN_MASTER_TABLE_FIELD_DUPLICATE; +import static cn.iocoder.yudao.module.infra.enums.ErrorCodeConstants.CODEGEN_MASTER_TABLE_NAME_DUPLICATE; /** * 代码生成的引擎,用于具体生成代码 @@ -426,16 +429,23 @@ public class CodegenEngine { private void generateCode(Map result, Map generatedSources, String vmPath, String filePath, Map bindingMap) { filePath = formatFilePath(filePath, bindingMap); - String source = vmPath + (bindingMap.containsKey("subIndex") ? "[subIndex=" + bindingMap.get("subIndex") + "]" : ""); + registerGeneratedSource(generatedSources, filePath, vmPath, bindingMap); + String content = templateEngine.getTemplate(vmPath).render(bindingMap); + // 格式化代码 + content = prettyCode(content, vmPath); + result.put(filePath, content); + } + + @VisibleForTesting + static void registerGeneratedSource(Map generatedSources, String filePath, String vmPath, + Map bindingMap) { + String source = vmPath + + (bindingMap.containsKey("subIndex") ? "[subIndex=" + bindingMap.get("subIndex") + "]" : ""); String previousSource = generatedSources.putIfAbsent(filePath, source); if (previousSource != null) { throw new IllegalStateException(String.format("生成文件路径重复:%s,来源模板:%s、%s", filePath, previousSource, source)); } - String content = templateEngine.getTemplate(vmPath).render(bindingMap); - // 格式化代码 - content = prettyCode(content, vmPath); - result.put(filePath, content); } private void generateSubCode(CodegenTableDO table, List subTables, @@ -561,6 +571,14 @@ public class CodegenEngine { List subClassNameVars = new ArrayList<>(); List simpleClassNameUnderlineCases = new ArrayList<>(); List subSimpleClassNameStrikeCases = new ArrayList<>(); + Set masterSymbols = new HashSet<>(); + masterSymbols.add(simpleClassName); + boolean mergeSubTableFields = ObjectUtils.equalsAny(table.getTemplateType(), + CodegenTemplateTypeEnum.MASTER_NORMAL.getType(), CodegenTemplateTypeEnum.MASTER_INNER.getType()); + Set masterFieldSymbols = new HashSet<>(); + if (mergeSubTableFields) { + columns.forEach(column -> masterFieldSymbols.add(column.getJavaField())); + } for (int i = 0; i < subTables.size(); i++) { CodegenTableDO subTable = subTables.get(i); List subColumns = subColumnsList.get(i); @@ -571,9 +589,18 @@ public class CodegenEngine { subJoinColumnStrikeCases.add(toSymbolCase(subColumn.getJavaField(), '-')); // 将 DictType 转换成 dict-type // className 相关 String subSimpleClassName = removePrefix(subTable.getClassName(), upperFirst(subTable.getModuleName())); + if (!masterSymbols.add(subSimpleClassName)) { + throw exception(CODEGEN_MASTER_TABLE_NAME_DUPLICATE, subSimpleClassName); + } + String subClassNameVar = lowerFirst(subSimpleClassName); + String subFieldName = subClassNameVar + + (Boolean.TRUE.equals(subTable.getSubJoinMany()) ? "s" : ""); + if (mergeSubTableFields && !masterFieldSymbols.add(subFieldName)) { + throw exception(CODEGEN_MASTER_TABLE_FIELD_DUPLICATE, subFieldName); + } subSimpleClassNames.add(subSimpleClassName); simpleClassNameUnderlineCases.add(toUnderlineCase(subSimpleClassName)); // 将 DictType 转换成 dict_type - subClassNameVars.add(lowerFirst(subSimpleClassName)); // 将 DictType 转换成 dictType,用于变量 + subClassNameVars.add(subClassNameVar); // 将 DictType 转换成 dictType,用于变量 subSimpleClassNameStrikeCases.add(toSymbolCase(subSimpleClassName, '-')); // 将 DictType 转换成 dict-type } bindingMap.put("subPrimaryColumns", subPrimaryColumns); diff --git a/yudao-module-infra/src/main/resources/codegen/vue3_admin_uniapp/api/api.ts.vm b/yudao-module-infra/src/main/resources/codegen/vue3_admin_uniapp/api/api.ts.vm index 209b540..9285223 100644 --- a/yudao-module-infra/src/main/resources/codegen/vue3_admin_uniapp/api/api.ts.vm +++ b/yudao-module-infra/src/main/resources/codegen/vue3_admin_uniapp/api/api.ts.vm @@ -4,7 +4,7 @@ import type { PageParam, PageResult } from '@/http/types' import { http } from '@/http/http' #set ($primaryJavaType = $primaryColumn.javaType.toLowerCase()) -#if(${primaryJavaType} == "long" || ${primaryJavaType} == "integer" || ${primaryJavaType} == "short" || ${primaryJavaType} == "double" || ${primaryJavaType} == "bigdecimal" || ${primaryJavaType} == "byte") +#if(${primaryJavaType} == "long" || ${primaryJavaType} == "integer" || ${primaryJavaType} == "short" || ${primaryJavaType} == "float" || ${primaryJavaType} == "double" || ${primaryJavaType} == "bigdecimal" || ${primaryJavaType} == "byte") #set ($primaryTsType = "number") #else #set ($primaryTsType = "string") @@ -20,7 +20,7 @@ export interface ${subSimpleClassName} { #if ($column.primaryKey || $column.createOperation || $column.updateOperation || $column.listOperationResult) #set ($javaType = $column.javaType.toLowerCase()) #set ($optional = $column.nullable || $column.primaryKey || ($table.templateType != 11 && $column.id == $subJoinColumn.id)) -#if(${javaType} == "long" || ${javaType} == "integer" || ${javaType} == "short" || ${javaType} == "double" || ${javaType} == "bigdecimal" || ${javaType} == "byte") +#if(${javaType} == "long" || ${javaType} == "integer" || ${javaType} == "short" || ${javaType} == "float" || ${javaType} == "double" || ${javaType} == "bigdecimal" || ${javaType} == "byte") ${column.javaField}#if($optional)?#end: number #elseif(${javaType} == "date" || ${javaType} == "localdate" || ${javaType} == "localdatetime") ${column.javaField}#if($optional)?#end: number @@ -40,7 +40,7 @@ export interface ${simpleClassName} { #if ($column.primaryKey || $column.createOperation || $column.updateOperation || $column.listOperationResult) #set ($javaType = $column.javaType.toLowerCase()) #set ($optional = $column.nullable || $column.primaryKey) -#if(${javaType} == "long" || ${javaType} == "integer" || ${javaType} == "short" || ${javaType} == "double" || ${javaType} == "bigdecimal" || ${javaType} == "byte") +#if(${javaType} == "long" || ${javaType} == "integer" || ${javaType} == "short" || ${javaType} == "float" || ${javaType} == "double" || ${javaType} == "bigdecimal" || ${javaType} == "byte") ${column.javaField}#if($optional)?#end: number #elseif(${javaType} == "date" || ${javaType} == "localdate" || ${javaType} == "localdatetime") ${column.javaField}#if($optional)?#end: number @@ -101,13 +101,13 @@ export function delete${simpleClassName}(id: ${primaryTsType}) { #set ($subPrimaryColumn = $subPrimaryColumns.get($index)) #set ($subJoinColumn = $subJoinColumns.get($index)) #set ($subPrimaryJavaType = $subPrimaryColumn.javaType.toLowerCase()) -#if(${subPrimaryJavaType} == "long" || ${subPrimaryJavaType} == "integer" || ${subPrimaryJavaType} == "short" || ${subPrimaryJavaType} == "double" || ${subPrimaryJavaType} == "bigdecimal" || ${subPrimaryJavaType} == "byte") +#if(${subPrimaryJavaType} == "long" || ${subPrimaryJavaType} == "integer" || ${subPrimaryJavaType} == "short" || ${subPrimaryJavaType} == "float" || ${subPrimaryJavaType} == "double" || ${subPrimaryJavaType} == "bigdecimal" || ${subPrimaryJavaType} == "byte") #set ($subPrimaryTsType = "number") #else #set ($subPrimaryTsType = "string") #end #set ($subJoinJavaType = $subJoinColumn.javaType.toLowerCase()) -#if(${subJoinJavaType} == "long" || ${subJoinJavaType} == "integer" || ${subJoinJavaType} == "short" || ${subJoinJavaType} == "double" || ${subJoinJavaType} == "bigdecimal" || ${subJoinJavaType} == "byte") +#if(${subJoinJavaType} == "long" || ${subJoinJavaType} == "integer" || ${subJoinJavaType} == "short" || ${subJoinJavaType} == "float" || ${subJoinJavaType} == "double" || ${subJoinJavaType} == "bigdecimal" || ${subJoinJavaType} == "byte") #set ($subJoinTsType = "number") #else #set ($subJoinTsType = "string") diff --git a/yudao-module-infra/src/main/resources/codegen/vue3_admin_uniapp/components/search-form.vue.vm b/yudao-module-infra/src/main/resources/codegen/vue3_admin_uniapp/components/search-form.vue.vm index 0aa06fd..483af6b 100644 --- a/yudao-module-infra/src/main/resources/codegen/vue3_admin_uniapp/components/search-form.vue.vm +++ b/yudao-module-infra/src/main/resources/codegen/vue3_admin_uniapp/components/search-form.vue.vm @@ -145,7 +145,7 @@ const formData = reactive({ #else ${column.javaField}: undefined as number | undefined, #end - #elseif(${javaType} == "long" || ${javaType} == "integer" || ${javaType} == "short" || ${javaType} == "double" || ${javaType} == "bigdecimal" || ${javaType} == "byte") + #elseif(${javaType} == "long" || ${javaType} == "integer" || ${javaType} == "short" || ${javaType} == "float" || ${javaType} == "double" || ${javaType} == "bigdecimal" || ${javaType} == "byte") ${column.javaField}: undefined as number | undefined, #elseif(${javaType} == "boolean") ${column.javaField}: undefined as boolean | undefined, @@ -174,7 +174,7 @@ const placeholder = computed(() => { conditions.push(`${comment}:#[[${]]#getDictLabel(DICT_TYPE.${dictType.toUpperCase()}, formData.${javaField})#[[}]]#`) } #else - #if(${javaType} == "long" || ${javaType} == "integer" || ${javaType} == "short" || ${javaType} == "double" || ${javaType} == "bigdecimal" || ${javaType} == "byte" || ${javaType} == "boolean") + #if(${javaType} == "long" || ${javaType} == "integer" || ${javaType} == "short" || ${javaType} == "float" || ${javaType} == "double" || ${javaType} == "bigdecimal" || ${javaType} == "byte" || ${javaType} == "boolean") if (formData.${javaField} !== undefined) { conditions.push(`${comment}:#[[${]]#formData.${javaField}#[[}]]#`) } diff --git a/yudao-module-infra/src/main/resources/codegen/vue3_admin_uniapp/views/detail/index.vue.vm b/yudao-module-infra/src/main/resources/codegen/vue3_admin_uniapp/views/detail/index.vue.vm index c861eea..817ab5e 100644 --- a/yudao-module-infra/src/main/resources/codegen/vue3_admin_uniapp/views/detail/index.vue.vm +++ b/yudao-module-infra/src/main/resources/codegen/vue3_admin_uniapp/views/detail/index.vue.vm @@ -50,7 +50,7 @@