Commit 0cb951f3344107f01a3c7168a24dd49493bc0914
1 parent
ef9f43e7
fix(codegen): 修复 UniApp Wot 生成代码兼容问题
- 完善日期、浮点数、布尔字典和上传字段生成逻辑 - 修复主子表必填校验和详情按钮类型 - 修复树表查询及生成快照路径问题 - 增加主子表类名、属性名和输出路径碰撞校验 - 补充 normal、inner、ERP 等场景单元测试
Showing
18 changed files
with
453 additions
and
156 deletions
yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/enums/ErrorCodeConstants.java
| ... | ... | @@ -48,6 +48,10 @@ public interface ErrorCodeConstants { |
| 48 | 48 | ErrorCode CODEGEN_MASTER_TABLE_NOT_EXISTS = new ErrorCode(1_001_004_010, "主表(id={})定义不存在,请检查"); |
| 49 | 49 | ErrorCode CODEGEN_SUB_COLUMN_NOT_EXISTS = new ErrorCode(1_001_004_011, "子表的字段(id={})不存在,请检查"); |
| 50 | 50 | ErrorCode CODEGEN_MASTER_GENERATION_FAIL_NO_SUB_TABLE = new ErrorCode(1_001_004_012, "主表生成代码失败,原因:它没有子表"); |
| 51 | + ErrorCode CODEGEN_MASTER_TABLE_NAME_DUPLICATE = new ErrorCode(1_001_004_013, | |
| 52 | + "主子表规范化类名({})重复,请调整主表或子表类名"); | |
| 53 | + ErrorCode CODEGEN_MASTER_TABLE_FIELD_DUPLICATE = new ErrorCode(1_001_004_014, | |
| 54 | + "主子表属性名({})重复,请调整主表字段、子表类名或关联关系"); | |
| 51 | 55 | |
| 52 | 56 | // ========== 文件配置 1-001-006-000 ========== |
| 53 | 57 | ErrorCode FILE_CONFIG_NOT_EXISTS = new ErrorCode(1_001_006_000, "文件配置不存在"); | ... | ... |
yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/service/codegen/inner/CodegenEngine.java
| ... | ... | @@ -48,6 +48,9 @@ import java.util.*; |
| 48 | 48 | |
| 49 | 49 | import static cn.hutool.core.map.MapUtil.getStr; |
| 50 | 50 | import static cn.hutool.core.text.CharSequenceUtil.*; |
| 51 | +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; | |
| 52 | +import static cn.iocoder.yudao.module.infra.enums.ErrorCodeConstants.CODEGEN_MASTER_TABLE_FIELD_DUPLICATE; | |
| 53 | +import static cn.iocoder.yudao.module.infra.enums.ErrorCodeConstants.CODEGEN_MASTER_TABLE_NAME_DUPLICATE; | |
| 51 | 54 | |
| 52 | 55 | /** |
| 53 | 56 | * 代码生成的引擎,用于具体生成代码 |
| ... | ... | @@ -426,16 +429,23 @@ public class CodegenEngine { |
| 426 | 429 | private void generateCode(Map<String, String> result, Map<String, String> generatedSources, String vmPath, |
| 427 | 430 | String filePath, Map<String, Object> bindingMap) { |
| 428 | 431 | filePath = formatFilePath(filePath, bindingMap); |
| 429 | - String source = vmPath + (bindingMap.containsKey("subIndex") ? "[subIndex=" + bindingMap.get("subIndex") + "]" : ""); | |
| 432 | + registerGeneratedSource(generatedSources, filePath, vmPath, bindingMap); | |
| 433 | + String content = templateEngine.getTemplate(vmPath).render(bindingMap); | |
| 434 | + // 格式化代码 | |
| 435 | + content = prettyCode(content, vmPath); | |
| 436 | + result.put(filePath, content); | |
| 437 | + } | |
| 438 | + | |
| 439 | + @VisibleForTesting | |
| 440 | + static void registerGeneratedSource(Map<String, String> generatedSources, String filePath, String vmPath, | |
| 441 | + Map<String, Object> bindingMap) { | |
| 442 | + String source = vmPath | |
| 443 | + + (bindingMap.containsKey("subIndex") ? "[subIndex=" + bindingMap.get("subIndex") + "]" : ""); | |
| 430 | 444 | String previousSource = generatedSources.putIfAbsent(filePath, source); |
| 431 | 445 | if (previousSource != null) { |
| 432 | 446 | throw new IllegalStateException(String.format("生成文件路径重复:%s,来源模板:%s、%s", |
| 433 | 447 | filePath, previousSource, source)); |
| 434 | 448 | } |
| 435 | - String content = templateEngine.getTemplate(vmPath).render(bindingMap); | |
| 436 | - // 格式化代码 | |
| 437 | - content = prettyCode(content, vmPath); | |
| 438 | - result.put(filePath, content); | |
| 439 | 449 | } |
| 440 | 450 | |
| 441 | 451 | private void generateSubCode(CodegenTableDO table, List<CodegenTableDO> subTables, |
| ... | ... | @@ -561,6 +571,14 @@ public class CodegenEngine { |
| 561 | 571 | List<String> subClassNameVars = new ArrayList<>(); |
| 562 | 572 | List<String> simpleClassNameUnderlineCases = new ArrayList<>(); |
| 563 | 573 | List<String> subSimpleClassNameStrikeCases = new ArrayList<>(); |
| 574 | + Set<String> masterSymbols = new HashSet<>(); | |
| 575 | + masterSymbols.add(simpleClassName); | |
| 576 | + boolean mergeSubTableFields = ObjectUtils.equalsAny(table.getTemplateType(), | |
| 577 | + CodegenTemplateTypeEnum.MASTER_NORMAL.getType(), CodegenTemplateTypeEnum.MASTER_INNER.getType()); | |
| 578 | + Set<String> masterFieldSymbols = new HashSet<>(); | |
| 579 | + if (mergeSubTableFields) { | |
| 580 | + columns.forEach(column -> masterFieldSymbols.add(column.getJavaField())); | |
| 581 | + } | |
| 564 | 582 | for (int i = 0; i < subTables.size(); i++) { |
| 565 | 583 | CodegenTableDO subTable = subTables.get(i); |
| 566 | 584 | List<CodegenColumnDO> subColumns = subColumnsList.get(i); |
| ... | ... | @@ -571,9 +589,18 @@ public class CodegenEngine { |
| 571 | 589 | subJoinColumnStrikeCases.add(toSymbolCase(subColumn.getJavaField(), '-')); // 将 DictType 转换成 dict-type |
| 572 | 590 | // className 相关 |
| 573 | 591 | String subSimpleClassName = removePrefix(subTable.getClassName(), upperFirst(subTable.getModuleName())); |
| 592 | + if (!masterSymbols.add(subSimpleClassName)) { | |
| 593 | + throw exception(CODEGEN_MASTER_TABLE_NAME_DUPLICATE, subSimpleClassName); | |
| 594 | + } | |
| 595 | + String subClassNameVar = lowerFirst(subSimpleClassName); | |
| 596 | + String subFieldName = subClassNameVar | |
| 597 | + + (Boolean.TRUE.equals(subTable.getSubJoinMany()) ? "s" : ""); | |
| 598 | + if (mergeSubTableFields && !masterFieldSymbols.add(subFieldName)) { | |
| 599 | + throw exception(CODEGEN_MASTER_TABLE_FIELD_DUPLICATE, subFieldName); | |
| 600 | + } | |
| 574 | 601 | subSimpleClassNames.add(subSimpleClassName); |
| 575 | 602 | simpleClassNameUnderlineCases.add(toUnderlineCase(subSimpleClassName)); // 将 DictType 转换成 dict_type |
| 576 | - subClassNameVars.add(lowerFirst(subSimpleClassName)); // 将 DictType 转换成 dictType,用于变量 | |
| 603 | + subClassNameVars.add(subClassNameVar); // 将 DictType 转换成 dictType,用于变量 | |
| 577 | 604 | subSimpleClassNameStrikeCases.add(toSymbolCase(subSimpleClassName, '-')); // 将 DictType 转换成 dict-type |
| 578 | 605 | } |
| 579 | 606 | bindingMap.put("subPrimaryColumns", subPrimaryColumns); | ... | ... |
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' |
| 4 | 4 | import { http } from '@/http/http' |
| 5 | 5 | |
| 6 | 6 | #set ($primaryJavaType = $primaryColumn.javaType.toLowerCase()) |
| 7 | -#if(${primaryJavaType} == "long" || ${primaryJavaType} == "integer" || ${primaryJavaType} == "short" || ${primaryJavaType} == "double" || ${primaryJavaType} == "bigdecimal" || ${primaryJavaType} == "byte") | |
| 7 | +#if(${primaryJavaType} == "long" || ${primaryJavaType} == "integer" || ${primaryJavaType} == "short" || ${primaryJavaType} == "float" || ${primaryJavaType} == "double" || ${primaryJavaType} == "bigdecimal" || ${primaryJavaType} == "byte") | |
| 8 | 8 | #set ($primaryTsType = "number") |
| 9 | 9 | #else |
| 10 | 10 | #set ($primaryTsType = "string") |
| ... | ... | @@ -20,7 +20,7 @@ export interface ${subSimpleClassName} { |
| 20 | 20 | #if ($column.primaryKey || $column.createOperation || $column.updateOperation || $column.listOperationResult) |
| 21 | 21 | #set ($javaType = $column.javaType.toLowerCase()) |
| 22 | 22 | #set ($optional = $column.nullable || $column.primaryKey || ($table.templateType != 11 && $column.id == $subJoinColumn.id)) |
| 23 | -#if(${javaType} == "long" || ${javaType} == "integer" || ${javaType} == "short" || ${javaType} == "double" || ${javaType} == "bigdecimal" || ${javaType} == "byte") | |
| 23 | +#if(${javaType} == "long" || ${javaType} == "integer" || ${javaType} == "short" || ${javaType} == "float" || ${javaType} == "double" || ${javaType} == "bigdecimal" || ${javaType} == "byte") | |
| 24 | 24 | ${column.javaField}#if($optional)?#end: number |
| 25 | 25 | #elseif(${javaType} == "date" || ${javaType} == "localdate" || ${javaType} == "localdatetime") |
| 26 | 26 | ${column.javaField}#if($optional)?#end: number |
| ... | ... | @@ -40,7 +40,7 @@ export interface ${simpleClassName} { |
| 40 | 40 | #if ($column.primaryKey || $column.createOperation || $column.updateOperation || $column.listOperationResult) |
| 41 | 41 | #set ($javaType = $column.javaType.toLowerCase()) |
| 42 | 42 | #set ($optional = $column.nullable || $column.primaryKey) |
| 43 | -#if(${javaType} == "long" || ${javaType} == "integer" || ${javaType} == "short" || ${javaType} == "double" || ${javaType} == "bigdecimal" || ${javaType} == "byte") | |
| 43 | +#if(${javaType} == "long" || ${javaType} == "integer" || ${javaType} == "short" || ${javaType} == "float" || ${javaType} == "double" || ${javaType} == "bigdecimal" || ${javaType} == "byte") | |
| 44 | 44 | ${column.javaField}#if($optional)?#end: number |
| 45 | 45 | #elseif(${javaType} == "date" || ${javaType} == "localdate" || ${javaType} == "localdatetime") |
| 46 | 46 | ${column.javaField}#if($optional)?#end: number |
| ... | ... | @@ -101,13 +101,13 @@ export function delete${simpleClassName}(id: ${primaryTsType}) { |
| 101 | 101 | #set ($subPrimaryColumn = $subPrimaryColumns.get($index)) |
| 102 | 102 | #set ($subJoinColumn = $subJoinColumns.get($index)) |
| 103 | 103 | #set ($subPrimaryJavaType = $subPrimaryColumn.javaType.toLowerCase()) |
| 104 | -#if(${subPrimaryJavaType} == "long" || ${subPrimaryJavaType} == "integer" || ${subPrimaryJavaType} == "short" || ${subPrimaryJavaType} == "double" || ${subPrimaryJavaType} == "bigdecimal" || ${subPrimaryJavaType} == "byte") | |
| 104 | +#if(${subPrimaryJavaType} == "long" || ${subPrimaryJavaType} == "integer" || ${subPrimaryJavaType} == "short" || ${subPrimaryJavaType} == "float" || ${subPrimaryJavaType} == "double" || ${subPrimaryJavaType} == "bigdecimal" || ${subPrimaryJavaType} == "byte") | |
| 105 | 105 | #set ($subPrimaryTsType = "number") |
| 106 | 106 | #else |
| 107 | 107 | #set ($subPrimaryTsType = "string") |
| 108 | 108 | #end |
| 109 | 109 | #set ($subJoinJavaType = $subJoinColumn.javaType.toLowerCase()) |
| 110 | -#if(${subJoinJavaType} == "long" || ${subJoinJavaType} == "integer" || ${subJoinJavaType} == "short" || ${subJoinJavaType} == "double" || ${subJoinJavaType} == "bigdecimal" || ${subJoinJavaType} == "byte") | |
| 110 | +#if(${subJoinJavaType} == "long" || ${subJoinJavaType} == "integer" || ${subJoinJavaType} == "short" || ${subJoinJavaType} == "float" || ${subJoinJavaType} == "double" || ${subJoinJavaType} == "bigdecimal" || ${subJoinJavaType} == "byte") | |
| 111 | 111 | #set ($subJoinTsType = "number") |
| 112 | 112 | #else |
| 113 | 113 | #set ($subJoinTsType = "string") | ... | ... |
yudao-module-infra/src/main/resources/codegen/vue3_admin_uniapp/components/search-form.vue.vm
| ... | ... | @@ -145,7 +145,7 @@ const formData = reactive({ |
| 145 | 145 | #else |
| 146 | 146 | ${column.javaField}: undefined as number | undefined, |
| 147 | 147 | #end |
| 148 | - #elseif(${javaType} == "long" || ${javaType} == "integer" || ${javaType} == "short" || ${javaType} == "double" || ${javaType} == "bigdecimal" || ${javaType} == "byte") | |
| 148 | + #elseif(${javaType} == "long" || ${javaType} == "integer" || ${javaType} == "short" || ${javaType} == "float" || ${javaType} == "double" || ${javaType} == "bigdecimal" || ${javaType} == "byte") | |
| 149 | 149 | ${column.javaField}: undefined as number | undefined, |
| 150 | 150 | #elseif(${javaType} == "boolean") |
| 151 | 151 | ${column.javaField}: undefined as boolean | undefined, |
| ... | ... | @@ -174,7 +174,7 @@ const placeholder = computed(() => { |
| 174 | 174 | conditions.push(`${comment}:#[[${]]#getDictLabel(DICT_TYPE.${dictType.toUpperCase()}, formData.${javaField})#[[}]]#`) |
| 175 | 175 | } |
| 176 | 176 | #else |
| 177 | - #if(${javaType} == "long" || ${javaType} == "integer" || ${javaType} == "short" || ${javaType} == "double" || ${javaType} == "bigdecimal" || ${javaType} == "byte" || ${javaType} == "boolean") | |
| 177 | + #if(${javaType} == "long" || ${javaType} == "integer" || ${javaType} == "short" || ${javaType} == "float" || ${javaType} == "double" || ${javaType} == "bigdecimal" || ${javaType} == "byte" || ${javaType} == "boolean") | |
| 178 | 178 | if (formData.${javaField} !== undefined) { |
| 179 | 179 | conditions.push(`${comment}:#[[${]]#formData.${javaField}#[[}]]#`) |
| 180 | 180 | } | ... | ... |
yudao-module-infra/src/main/resources/codegen/vue3_admin_uniapp/views/detail/index.vue.vm
| ... | ... | @@ -50,7 +50,7 @@ |
| 50 | 50 | |
| 51 | 51 | <script lang="ts" setup> |
| 52 | 52 | #set ($primaryJavaType = $primaryColumn.javaType.toLowerCase()) |
| 53 | -#if(${primaryJavaType} == "long" || ${primaryJavaType} == "integer" || ${primaryJavaType} == "short" || ${primaryJavaType} == "double" || ${primaryJavaType} == "bigdecimal" || ${primaryJavaType} == "byte") | |
| 53 | +#if(${primaryJavaType} == "long" || ${primaryJavaType} == "integer" || ${primaryJavaType} == "short" || ${primaryJavaType} == "float" || ${primaryJavaType} == "double" || ${primaryJavaType} == "bigdecimal" || ${primaryJavaType} == "byte") | |
| 54 | 54 | #set ($primaryTsType = "number") |
| 55 | 55 | #else |
| 56 | 56 | #set ($primaryTsType = "string") | ... | ... |
yudao-module-infra/src/main/resources/codegen/vue3_admin_uniapp/views/detail_erp.vue.vm
| ... | ... | @@ -101,7 +101,7 @@ |
| 101 | 101 | |
| 102 | 102 | <script lang="ts" setup> |
| 103 | 103 | #set ($primaryJavaType = $primaryColumn.javaType.toLowerCase()) |
| 104 | -#if(${primaryJavaType} == "long" || ${primaryJavaType} == "integer" || ${primaryJavaType} == "short" || ${primaryJavaType} == "double" || ${primaryJavaType} == "bigdecimal" || ${primaryJavaType} == "byte") | |
| 104 | +#if(${primaryJavaType} == "long" || ${primaryJavaType} == "integer" || ${primaryJavaType} == "short" || ${primaryJavaType} == "float" || ${primaryJavaType} == "double" || ${primaryJavaType} == "bigdecimal" || ${primaryJavaType} == "byte") | |
| 105 | 105 | #set ($primaryTsType = "number") |
| 106 | 106 | #else |
| 107 | 107 | #set ($primaryTsType = "string") | ... | ... |
yudao-module-infra/src/main/resources/codegen/vue3_admin_uniapp/views/detail_master.vue.vm
| ... | ... | @@ -94,7 +94,7 @@ |
| 94 | 94 | |
| 95 | 95 | <script lang="ts" setup> |
| 96 | 96 | #set ($primaryJavaType = $primaryColumn.javaType.toLowerCase()) |
| 97 | -#if(${primaryJavaType} == "long" || ${primaryJavaType} == "integer" || ${primaryJavaType} == "short" || ${primaryJavaType} == "double" || ${primaryJavaType} == "bigdecimal" || ${primaryJavaType} == "byte") | |
| 97 | +#if(${primaryJavaType} == "long" || ${primaryJavaType} == "integer" || ${primaryJavaType} == "short" || ${primaryJavaType} == "float" || ${primaryJavaType} == "double" || ${primaryJavaType} == "bigdecimal" || ${primaryJavaType} == "byte") | |
| 98 | 98 | #set ($primaryTsType = "number") |
| 99 | 99 | #else |
| 100 | 100 | #set ($primaryTsType = "string") | ... | ... |
yudao-module-infra/src/main/resources/codegen/vue3_admin_uniapp/views/form/index.vue.vm
| ... | ... | @@ -42,10 +42,14 @@ |
| 42 | 42 | label="${comment}" |
| 43 | 43 | label-width="180rpx" |
| 44 | 44 | prop="${javaField}" |
| 45 | +#if ($javaType == "Boolean") | |
| 46 | + :columns="getBoolDictOptions(DICT_TYPE.${dictType.toUpperCase()})" | |
| 47 | +#else | |
| 45 | 48 | :dict-type="DICT_TYPE.${dictType.toUpperCase()}" |
| 46 | 49 | #if ($javaType == "String") |
| 47 | 50 | dict-kind="str" |
| 48 | 51 | #end |
| 52 | +#end | |
| 49 | 53 | placeholder="请选择${comment}" |
| 50 | 54 | /> |
| 51 | 55 | ## 单选(字典)→ radio-group,适合选项较少 |
| ... | ... | @@ -62,14 +66,14 @@ |
| 62 | 66 | </wd-radio-group> |
| 63 | 67 | </wd-form-item> |
| 64 | 68 | ## 数字类型(无字典) |
| 65 | -#elseif (${javaType.toLowerCase()} == "long" || ${javaType.toLowerCase()} == "integer" || ${javaType.toLowerCase()} == "short" || ${javaType.toLowerCase()} == "double" || ${javaType.toLowerCase()} == "bigdecimal" || ${javaType.toLowerCase()} == "byte") | |
| 69 | +#elseif (${javaType.toLowerCase()} == "long" || ${javaType.toLowerCase()} == "integer" || ${javaType.toLowerCase()} == "short" || ${javaType.toLowerCase()} == "float" || ${javaType.toLowerCase()} == "double" || ${javaType.toLowerCase()} == "bigdecimal" || ${javaType.toLowerCase()} == "byte") | |
| 66 | 70 | <wd-form-item title="${comment}" title-width="180rpx" prop="${javaField}"> |
| 67 | 71 | <wd-input-number |
| 68 | 72 | v-model="formData.${javaField}" |
| 69 | 73 | #if ($column.nullable) |
| 70 | 74 | allow-null |
| 71 | 75 | #end |
| 72 | -#if (${javaType.toLowerCase()} == "double" || ${javaType.toLowerCase()} == "bigdecimal") | |
| 76 | +#if (${javaType.toLowerCase()} == "float" || ${javaType.toLowerCase()} == "double" || ${javaType.toLowerCase()} == "bigdecimal") | |
| 73 | 77 | :precision="2" |
| 74 | 78 | input-type="number" |
| 75 | 79 | #end |
| ... | ... | @@ -104,20 +108,20 @@ |
| 104 | 108 | v-model:visible="${javaField}Visible" |
| 105 | 109 | :model-value="formData.${javaField} || Date.now()" |
| 106 | 110 | type="${pickerType}" |
| 107 | -#if ($pickerType == "datetime") | |
| 108 | 111 | @update:model-value="value => formData.${javaField} = value" |
| 109 | -#else | |
| 110 | - @update:model-value="value => formData.${javaField} = value" | |
| 111 | -#end | |
| 112 | 112 | /> |
| 113 | 113 | ## 文本域 |
| 114 | -#elseif ($column.htmlType == "textarea") | |
| 114 | +#elseif ($column.htmlType == "textarea" || $column.htmlType == "editor") | |
| 115 | 115 | <wd-form-item title="${comment}" title-width="180rpx" prop="${javaField}"> |
| 116 | 116 | <wd-textarea |
| 117 | 117 | v-model="formData.${javaField}" |
| 118 | 118 | clearable |
| 119 | 119 | placeholder="请输入${comment}" |
| 120 | +#if ($column.htmlType == "editor") | |
| 121 | + :maxlength="2000" | |
| 122 | +#else | |
| 120 | 123 | :maxlength="200" |
| 124 | +#end | |
| 121 | 125 | show-word-limit |
| 122 | 126 | /> |
| 123 | 127 | </wd-form-item> |
| ... | ... | @@ -129,7 +133,7 @@ |
| 129 | 133 | ## 文件上传 → yd-upload-file |
| 130 | 134 | #elseif ($column.htmlType == "fileUpload") |
| 131 | 135 | <wd-form-item title="${comment}" title-width="180rpx" prop="${javaField}"> |
| 132 | - <yd-upload-file v-model="formData.${javaField}" directory="${table.moduleName}/${table.businessName}" /> | |
| 136 | + <yd-upload-file v-model="formData.${javaField}" :limit="1" directory="${table.moduleName}/${table.businessName}" /> | |
| 133 | 137 | </wd-form-item> |
| 134 | 138 | ## 默认:文本输入 |
| 135 | 139 | #else |
| ... | ... | @@ -202,10 +206,14 @@ |
| 202 | 206 | v-model="item.${column.javaField}" |
| 203 | 207 | label="${column.columnComment}" |
| 204 | 208 | label-width="180rpx" |
| 209 | +#if ($column.javaType == "Boolean") | |
| 210 | + :columns="getBoolDictOptions(DICT_TYPE.${column.dictType.toUpperCase()})" | |
| 211 | +#else | |
| 205 | 212 | :dict-type="DICT_TYPE.${column.dictType.toUpperCase()}" |
| 206 | 213 | #if ($column.javaType == "String") |
| 207 | 214 | dict-kind="str" |
| 208 | 215 | #end |
| 216 | +#end | |
| 209 | 217 | placeholder="请选择${column.columnComment}" |
| 210 | 218 | /> |
| 211 | 219 | #elseif ($column.htmlType == "radio" && $column.dictType && "" != $column.dictType) |
| ... | ... | @@ -224,14 +232,14 @@ |
| 224 | 232 | <wd-form-item title="${column.columnComment}" title-width="180rpx" center> |
| 225 | 233 | <wd-switch v-model="item.${column.javaField}" /> |
| 226 | 234 | </wd-form-item> |
| 227 | -#elseif ($javaType == "long" || $javaType == "integer" || $javaType == "short" || $javaType == "double" || $javaType == "bigdecimal" || $javaType == "byte") | |
| 235 | +#elseif ($javaType == "long" || $javaType == "integer" || $javaType == "short" || $javaType == "float" || $javaType == "double" || $javaType == "bigdecimal" || $javaType == "byte") | |
| 228 | 236 | <wd-form-item title="${column.columnComment}" title-width="180rpx"> |
| 229 | 237 | <wd-input-number |
| 230 | 238 | v-model="item.${column.javaField}" |
| 231 | 239 | #if($column.nullable) |
| 232 | 240 | allow-null |
| 233 | 241 | #end |
| 234 | -#if ($javaType == "double" || $javaType == "bigdecimal") | |
| 242 | +#if ($javaType == "float" || $javaType == "double" || $javaType == "bigdecimal") | |
| 235 | 243 | :precision="2" |
| 236 | 244 | input-type="number" |
| 237 | 245 | #end |
| ... | ... | @@ -259,15 +267,20 @@ |
| 259 | 267 | v-model:visible="subDateVisible[`${subClassNameVar}s.#[[${]]#index#[[}]]#.${column.javaField}`]" |
| 260 | 268 | :model-value="item.${column.javaField} || Date.now()" |
| 261 | 269 | type="${subPickerType}" |
| 262 | -#if ($javaType == "localdatetime") | |
| 263 | 270 | @update:model-value="value => item.${column.javaField} = value" |
| 264 | -#else | |
| 265 | - @update:model-value="value => item.${column.javaField} = value" | |
| 266 | -#end | |
| 267 | 271 | /> |
| 268 | -#elseif ($column.htmlType == "textarea") | |
| 272 | +#elseif ($column.htmlType == "textarea" || $column.htmlType == "editor") | |
| 269 | 273 | <wd-form-item title="${column.columnComment}" title-width="180rpx"> |
| 270 | - <wd-textarea v-model="item.${column.javaField}" clearable placeholder="请输入${column.columnComment}" /> | |
| 274 | + <wd-textarea | |
| 275 | + v-model="item.${column.javaField}" | |
| 276 | + clearable | |
| 277 | + placeholder="请输入${column.columnComment}" | |
| 278 | +#if ($column.htmlType == "editor") | |
| 279 | + :maxlength="2000" | |
| 280 | +#else | |
| 281 | + :maxlength="200" | |
| 282 | +#end | |
| 283 | + /> | |
| 271 | 284 | </wd-form-item> |
| 272 | 285 | #elseif ($column.htmlType == "imageUpload") |
| 273 | 286 | <wd-form-item title="${column.columnComment}" title-width="180rpx"> |
| ... | ... | @@ -275,7 +288,7 @@ |
| 275 | 288 | </wd-form-item> |
| 276 | 289 | #elseif ($column.htmlType == "fileUpload") |
| 277 | 290 | <wd-form-item title="${column.columnComment}" title-width="180rpx"> |
| 278 | - <yd-upload-file v-model="item.${column.javaField}" directory="${table.moduleName}/${table.businessName}" /> | |
| 291 | + <yd-upload-file v-model="item.${column.javaField}" :limit="1" directory="${table.moduleName}/${table.businessName}" /> | |
| 279 | 292 | </wd-form-item> |
| 280 | 293 | #else |
| 281 | 294 | <wd-form-item title="${column.columnComment}" title-width="180rpx"> |
| ... | ... | @@ -306,10 +319,14 @@ |
| 306 | 319 | v-model="${subClassNameVar}.${column.javaField}" |
| 307 | 320 | label="${column.columnComment}" |
| 308 | 321 | label-width="180rpx" |
| 322 | +#if ($column.javaType == "Boolean") | |
| 323 | + :columns="getBoolDictOptions(DICT_TYPE.${column.dictType.toUpperCase()})" | |
| 324 | +#else | |
| 309 | 325 | :dict-type="DICT_TYPE.${column.dictType.toUpperCase()}" |
| 310 | 326 | #if ($column.javaType == "String") |
| 311 | 327 | dict-kind="str" |
| 312 | 328 | #end |
| 329 | +#end | |
| 313 | 330 | placeholder="请选择${column.columnComment}" |
| 314 | 331 | /> |
| 315 | 332 | #elseif ($column.htmlType == "radio" && $column.dictType && "" != $column.dictType) |
| ... | ... | @@ -328,14 +345,14 @@ |
| 328 | 345 | <wd-form-item title="${column.columnComment}" title-width="180rpx" center> |
| 329 | 346 | <wd-switch v-model="${subClassNameVar}.${column.javaField}" /> |
| 330 | 347 | </wd-form-item> |
| 331 | -#elseif ($javaType == "long" || $javaType == "integer" || $javaType == "short" || $javaType == "double" || $javaType == "bigdecimal" || $javaType == "byte") | |
| 348 | +#elseif ($javaType == "long" || $javaType == "integer" || $javaType == "short" || $javaType == "float" || $javaType == "double" || $javaType == "bigdecimal" || $javaType == "byte") | |
| 332 | 349 | <wd-form-item title="${column.columnComment}" title-width="180rpx"> |
| 333 | 350 | <wd-input-number |
| 334 | 351 | v-model="${subClassNameVar}.${column.javaField}" |
| 335 | 352 | #if($column.nullable) |
| 336 | 353 | allow-null |
| 337 | 354 | #end |
| 338 | -#if ($javaType == "double" || $javaType == "bigdecimal") | |
| 355 | +#if ($javaType == "float" || $javaType == "double" || $javaType == "bigdecimal") | |
| 339 | 356 | :precision="2" |
| 340 | 357 | input-type="number" |
| 341 | 358 | #end |
| ... | ... | @@ -363,15 +380,20 @@ |
| 363 | 380 | v-model:visible="subDateVisible['${subClassNameVar}.${column.javaField}']" |
| 364 | 381 | :model-value="${subClassNameVar}.${column.javaField} || Date.now()" |
| 365 | 382 | type="${subPickerType}" |
| 366 | -#if ($javaType == "localdatetime") | |
| 367 | - @update:model-value="value => ${subClassNameVar}.${column.javaField} = value" | |
| 368 | -#else | |
| 369 | 383 | @update:model-value="value => ${subClassNameVar}.${column.javaField} = value" |
| 370 | -#end | |
| 371 | 384 | /> |
| 372 | -#elseif ($column.htmlType == "textarea") | |
| 385 | +#elseif ($column.htmlType == "textarea" || $column.htmlType == "editor") | |
| 373 | 386 | <wd-form-item title="${column.columnComment}" title-width="180rpx"> |
| 374 | - <wd-textarea v-model="${subClassNameVar}.${column.javaField}" clearable placeholder="请输入${column.columnComment}" /> | |
| 387 | + <wd-textarea | |
| 388 | + v-model="${subClassNameVar}.${column.javaField}" | |
| 389 | + clearable | |
| 390 | + placeholder="请输入${column.columnComment}" | |
| 391 | +#if ($column.htmlType == "editor") | |
| 392 | + :maxlength="2000" | |
| 393 | +#else | |
| 394 | + :maxlength="200" | |
| 395 | +#end | |
| 396 | + /> | |
| 375 | 397 | </wd-form-item> |
| 376 | 398 | #elseif ($column.htmlType == "imageUpload") |
| 377 | 399 | <wd-form-item title="${column.columnComment}" title-width="180rpx"> |
| ... | ... | @@ -379,7 +401,7 @@ |
| 379 | 401 | </wd-form-item> |
| 380 | 402 | #elseif ($column.htmlType == "fileUpload") |
| 381 | 403 | <wd-form-item title="${column.columnComment}" title-width="180rpx"> |
| 382 | - <yd-upload-file v-model="${subClassNameVar}.${column.javaField}" directory="${table.moduleName}/${table.businessName}" /> | |
| 404 | + <yd-upload-file v-model="${subClassNameVar}.${column.javaField}" :limit="1" directory="${table.moduleName}/${table.businessName}" /> | |
| 383 | 405 | </wd-form-item> |
| 384 | 406 | #else |
| 385 | 407 | <wd-form-item title="${column.columnComment}" title-width="180rpx"> |
| ... | ... | @@ -412,7 +434,7 @@ |
| 412 | 434 | <script lang="ts" setup> |
| 413 | 435 | import type { FormInstance } from '@wot-ui/ui/components/wd-form/types' |
| 414 | 436 | #set ($primaryJavaType = $primaryColumn.javaType.toLowerCase()) |
| 415 | -#if(${primaryJavaType} == "long" || ${primaryJavaType} == "integer" || ${primaryJavaType} == "short" || ${primaryJavaType} == "double" || ${primaryJavaType} == "bigdecimal" || ${primaryJavaType} == "byte") | |
| 437 | +#if(${primaryJavaType} == "long" || ${primaryJavaType} == "integer" || ${primaryJavaType} == "short" || ${primaryJavaType} == "float" || ${primaryJavaType} == "double" || ${primaryJavaType} == "bigdecimal" || ${primaryJavaType} == "byte") | |
| 416 | 438 | #set ($primaryTsType = "number") |
| 417 | 439 | #else |
| 418 | 440 | #set ($primaryTsType = "string") |
| ... | ... | @@ -434,7 +456,7 @@ import type { FormInstance } from '@wot-ui/ui/components/wd-form/types' |
| 434 | 456 | #set ($hasGetIntDictOptions = 1) |
| 435 | 457 | #elseif ($column.htmlType == "radio" && $column.javaType == "String") |
| 436 | 458 | #set ($hasGetStrDictOptions = 1) |
| 437 | -#elseif ($column.htmlType == "radio" && $column.javaType == "Boolean") | |
| 459 | +#elseif (($column.htmlType == "select" || $column.htmlType == "radio") && $column.javaType == "Boolean") | |
| 438 | 460 | #set ($hasGetBoolDictOptions = 1) |
| 439 | 461 | #elseif ($column.htmlType == "radio") |
| 440 | 462 | #set ($hasGetDictOptions = 1) |
| ... | ... | @@ -460,7 +482,7 @@ import type { FormInstance } from '@wot-ui/ui/components/wd-form/types' |
| 460 | 482 | #set ($hasGetIntDictOptions = 1) |
| 461 | 483 | #elseif ($column.htmlType == "radio" && $column.javaType == "String") |
| 462 | 484 | #set ($hasGetStrDictOptions = 1) |
| 463 | -#elseif ($column.htmlType == "radio" && $column.javaType == "Boolean") | |
| 485 | +#elseif (($column.htmlType == "select" || $column.htmlType == "radio") && $column.javaType == "Boolean") | |
| 464 | 486 | #set ($hasGetBoolDictOptions = 1) |
| 465 | 487 | #elseif ($column.htmlType == "radio") |
| 466 | 488 | #set ($hasGetDictOptions = 1) |
| ... | ... | @@ -567,7 +589,7 @@ definePage({ |
| 567 | 589 | const toast = useToast() |
| 568 | 590 | const getTitle = computed(() => props.id ? '编辑${table.classComment}' : '新增${table.classComment}') |
| 569 | 591 | const formLoading = ref(false) // 表单提交状态 |
| 570 | -const formData = ref<${simpleClassName}>({ | |
| 592 | +const formData = ref<Partial<${simpleClassName}>>({ | |
| 571 | 593 | #foreach($column in $columns) |
| 572 | 594 | #if (($column.createOperation || $column.updateOperation) || $column.primaryKey) |
| 573 | 595 | #set ($javaType = $column.javaType.toLowerCase()) |
| ... | ... | @@ -577,7 +599,9 @@ const formData = ref<${simpleClassName}>({ |
| 577 | 599 | ${column.javaField}: undefined, |
| 578 | 600 | #elseif($table.templateType == 2 && $column.id == $treeParentColumn.id) |
| 579 | 601 | ${column.javaField}: props.${column.javaField} ?? 0, |
| 580 | -#elseif(${javaType} == "long" || ${javaType} == "integer" || ${javaType} == "short" || ${javaType} == "double" || ${javaType} == "bigdecimal" || ${javaType} == "byte") | |
| 602 | +#elseif(($column.htmlType == "select" || $column.htmlType == "radio") && $column.dictType && "" != $column.dictType) | |
| 603 | + ${column.javaField}: undefined, | |
| 604 | +#elseif(${javaType} == "long" || ${javaType} == "integer" || ${javaType} == "short" || ${javaType} == "float" || ${javaType} == "double" || ${javaType} == "bigdecimal" || ${javaType} == "byte") | |
| 581 | 605 | #if($column.nullable) |
| 582 | 606 | ${column.javaField}: undefined, |
| 583 | 607 | #else |
| ... | ... | @@ -586,7 +610,7 @@ const formData = ref<${simpleClassName}>({ |
| 586 | 610 | #elseif(${javaType} == "boolean") |
| 587 | 611 | ${column.javaField}: false, |
| 588 | 612 | #elseif(${javaType} == "date" || ${javaType} == "localdate" || ${javaType} == "localdatetime") |
| 589 | - ${column.javaField}:#if($column.nullable || $column.primaryKey || $javaFieldLower == "createtime" || $javaFieldLower == "updatetime") undefined#else 0#end, | |
| 613 | + ${column.javaField}: undefined, | |
| 590 | 614 | #else |
| 591 | 615 | ${column.javaField}: '', |
| 592 | 616 | #end |
| ... | ... | @@ -601,9 +625,9 @@ const formData = ref<${simpleClassName}>({ |
| 601 | 625 | #set ($subColumns = $subColumnsList.get($index)) |
| 602 | 626 | #set ($subJoinColumn = $subJoinColumns.get($index)) |
| 603 | 627 | #if ($subTable.subJoinMany) |
| 604 | -const ${subClassNameVar}s = ref<${subSimpleClassName}[]>([]) // ${subTable.classComment}数据 | |
| 628 | +const ${subClassNameVar}s = ref<Partial<${subSimpleClassName}>[]>([]) // ${subTable.classComment}数据 | |
| 605 | 629 | #else |
| 606 | -const ${subClassNameVar} = ref<${subSimpleClassName} | null>(null) // ${subTable.classComment}数据 | |
| 630 | +const ${subClassNameVar} = ref<Partial<${subSimpleClassName}> | null>(null) // ${subTable.classComment}数据 | |
| 607 | 631 | #end |
| 608 | 632 | #end |
| 609 | 633 | #end |
| ... | ... | @@ -646,7 +670,11 @@ function add${subClassNameVar.substring(0,1).toUpperCase()}${subClassNameVar.sub |
| 646 | 670 | #foreach ($column in $subColumns) |
| 647 | 671 | #if (($column.createOperation || $column.updateOperation) && !$column.primaryKey && $column.id != $subJoinColumn.id) |
| 648 | 672 | #set ($javaType = $column.javaType.toLowerCase()) |
| 649 | - ${column.javaField}:#if($column.nullable) undefined#elseif($javaType == "long" || $javaType == "integer" || $javaType == "short" || $javaType == "double" || $javaType == "bigdecimal" || $javaType == "byte" || $javaType == "date" || $javaType == "localdate" || $javaType == "localdatetime") 0#elseif($javaType == "boolean") false#else ''#end, | |
| 673 | +#if((($column.htmlType == "select" || $column.htmlType == "radio") && $column.dictType && "" != $column.dictType) || $javaType == "date" || $javaType == "localdate" || $javaType == "localdatetime") | |
| 674 | + ${column.javaField}: undefined, | |
| 675 | +#else | |
| 676 | + ${column.javaField}:#if($column.nullable) undefined#elseif($javaType == "long" || $javaType == "integer" || $javaType == "short" || $javaType == "float" || $javaType == "double" || $javaType == "bigdecimal" || $javaType == "byte") 0#elseif($javaType == "boolean") false#else ''#end, | |
| 677 | +#end | |
| 650 | 678 | #end |
| 651 | 679 | #end |
| 652 | 680 | }) |
| ... | ... | @@ -664,7 +692,11 @@ function add${subClassNameVar.substring(0,1).toUpperCase()}${subClassNameVar.sub |
| 664 | 692 | #foreach ($column in $subColumns) |
| 665 | 693 | #if (($column.createOperation || $column.updateOperation) && !$column.primaryKey && $column.id != $subJoinColumn.id) |
| 666 | 694 | #set ($javaType = $column.javaType.toLowerCase()) |
| 667 | - ${column.javaField}:#if($column.nullable) undefined#elseif($javaType == "long" || $javaType == "integer" || $javaType == "short" || $javaType == "double" || $javaType == "bigdecimal" || $javaType == "byte" || $javaType == "date" || $javaType == "localdate" || $javaType == "localdatetime") 0#elseif($javaType == "boolean") false#else ''#end, | |
| 695 | +#if((($column.htmlType == "select" || $column.htmlType == "radio") && $column.dictType && "" != $column.dictType) || $javaType == "date" || $javaType == "localdate" || $javaType == "localdatetime") | |
| 696 | + ${column.javaField}: undefined, | |
| 697 | +#else | |
| 698 | + ${column.javaField}:#if($column.nullable) undefined#elseif($javaType == "long" || $javaType == "integer" || $javaType == "short" || $javaType == "float" || $javaType == "double" || $javaType == "bigdecimal" || $javaType == "byte") 0#elseif($javaType == "boolean") false#else ''#end, | |
| 699 | +#end | |
| 668 | 700 | #end |
| 669 | 701 | #end |
| 670 | 702 | } |
| ... | ... | @@ -771,16 +803,16 @@ async function handleSubmit() { |
| 771 | 803 | formLoading.value = true |
| 772 | 804 | try { |
| 773 | 805 | #if ($table.templateType == 10 || $table.templateType == 12) |
| 774 | - const data: ${simpleClassName} = { | |
| 806 | + const data = { | |
| 775 | 807 | ...formData.value, |
| 776 | 808 | #foreach ($subTable in $subTables) |
| 777 | 809 | #set ($index = $foreach.count - 1) |
| 778 | 810 | #set ($subClassNameVar = $subClassNameVars.get($index)) |
| 779 | 811 | ${subClassNameVar}#if($subTable.subJoinMany)s#end: ${subClassNameVar}#if($subTable.subJoinMany)s#end.value, |
| 780 | 812 | #end |
| 781 | - } | |
| 813 | + } as ${simpleClassName} | |
| 782 | 814 | #else |
| 783 | - const data = formData.value | |
| 815 | + const data = formData.value as ${simpleClassName} | |
| 784 | 816 | #end |
| 785 | 817 | if (props.id) { |
| 786 | 818 | await update${simpleClassName}(data) | ... | ... |
yudao-module-infra/src/main/resources/codegen/vue3_admin_uniapp/views/form_sub_erp.vue.vm
| ... | ... | @@ -4,24 +4,28 @@ |
| 4 | 4 | #set ($subPrimaryColumn = $subPrimaryColumns.get($subIndex)) |
| 5 | 5 | #set ($subJoinColumn = $subJoinColumns.get($subIndex)) |
| 6 | 6 | #set ($subPrimaryJavaType = $subPrimaryColumn.javaType.toLowerCase()) |
| 7 | -#if(${subPrimaryJavaType} == "long" || ${subPrimaryJavaType} == "integer" || ${subPrimaryJavaType} == "short" || ${subPrimaryJavaType} == "double" || ${subPrimaryJavaType} == "bigdecimal" || ${subPrimaryJavaType} == "byte") | |
| 7 | +#if(${subPrimaryJavaType} == "long" || ${subPrimaryJavaType} == "integer" || ${subPrimaryJavaType} == "short" || ${subPrimaryJavaType} == "float" || ${subPrimaryJavaType} == "double" || ${subPrimaryJavaType} == "bigdecimal" || ${subPrimaryJavaType} == "byte") | |
| 8 | 8 | #set ($subPrimaryTsType = "number") |
| 9 | 9 | #else |
| 10 | 10 | #set ($subPrimaryTsType = "string") |
| 11 | 11 | #end |
| 12 | 12 | #set ($subJoinJavaType = $subJoinColumn.javaType.toLowerCase()) |
| 13 | -#if(${subJoinJavaType} == "long" || ${subJoinJavaType} == "integer" || ${subJoinJavaType} == "short" || ${subJoinJavaType} == "double" || ${subJoinJavaType} == "bigdecimal" || ${subJoinJavaType} == "byte") | |
| 13 | +#if(${subJoinJavaType} == "long" || ${subJoinJavaType} == "integer" || ${subJoinJavaType} == "short" || ${subJoinJavaType} == "float" || ${subJoinJavaType} == "double" || ${subJoinJavaType} == "bigdecimal" || ${subJoinJavaType} == "byte") | |
| 14 | 14 | #set ($subJoinTsType = "number") |
| 15 | 15 | #else |
| 16 | 16 | #set ($subJoinTsType = "string") |
| 17 | 17 | #end |
| 18 | 18 | #set ($hasDict = 0) |
| 19 | +#set ($hasBoolDict = 0) | |
| 19 | 20 | #set ($hasDate = 0) |
| 20 | 21 | #set ($hasDateTime = 0) |
| 21 | 22 | #foreach ($column in $subColumns) |
| 22 | 23 | #if (($column.createOperation || $column.updateOperation) && !$column.primaryKey && $column.id != $subJoinColumn.id) |
| 23 | 24 | #if (($column.htmlType == "select" || $column.htmlType == "radio") && $column.dictType && "" != $column.dictType) |
| 24 | 25 | #set ($hasDict = 1) |
| 26 | +#if ($column.javaType == "Boolean") | |
| 27 | +#set ($hasBoolDict = 1) | |
| 28 | +#end | |
| 25 | 29 | #end |
| 26 | 30 | #if (${column.javaType.toLowerCase()} == "date" || ${column.javaType.toLowerCase()} == "localdate") |
| 27 | 31 | #set ($hasDate = 1) |
| ... | ... | @@ -48,10 +52,14 @@ |
| 48 | 52 | label="${column.columnComment}" |
| 49 | 53 | label-width="180rpx" |
| 50 | 54 | prop="${column.javaField}" |
| 55 | +#if ($column.javaType == "Boolean") | |
| 56 | + :columns="getBoolDictOptions(DICT_TYPE.${column.dictType.toUpperCase()})" | |
| 57 | +#else | |
| 51 | 58 | :dict-type="DICT_TYPE.${column.dictType.toUpperCase()}" |
| 52 | 59 | #if ($column.javaType == "String") |
| 53 | 60 | dict-kind="str" |
| 54 | 61 | #end |
| 62 | +#end | |
| 55 | 63 | placeholder="请选择${column.columnComment}" |
| 56 | 64 | /> |
| 57 | 65 | #elseif ($javaType == "date" || $javaType == "localdate" || $javaType == "localdatetime") |
| ... | ... | @@ -76,34 +84,39 @@ |
| 76 | 84 | v-model:visible="${column.javaField}Visible" |
| 77 | 85 | :model-value="formData.${column.javaField} || Date.now()" |
| 78 | 86 | type="${pickerType}" |
| 79 | -#if ($javaType == "localdatetime") | |
| 80 | 87 | @update:model-value="value => formData.${column.javaField} = value" |
| 81 | -#else | |
| 82 | - @update:model-value="value => formData.${column.javaField} = value" | |
| 83 | -#end | |
| 84 | 88 | /> |
| 85 | 89 | #else |
| 86 | 90 | <wd-form-item title="${column.columnComment}" title-width="180rpx" prop="${column.javaField}"> |
| 87 | 91 | #if ($javaType == "boolean") |
| 88 | 92 | <wd-switch v-model="formData.${column.javaField}" /> |
| 89 | -#elseif ($javaType == "long" || $javaType == "integer" || $javaType == "short" || $javaType == "double" || $javaType == "bigdecimal" || $javaType == "byte") | |
| 93 | +#elseif ($javaType == "long" || $javaType == "integer" || $javaType == "short" || $javaType == "float" || $javaType == "double" || $javaType == "bigdecimal" || $javaType == "byte") | |
| 90 | 94 | <wd-input-number |
| 91 | 95 | v-model="formData.${column.javaField}" |
| 92 | 96 | #if($column.nullable) |
| 93 | 97 | allow-null |
| 94 | 98 | #end |
| 95 | -#if ($javaType == "double" || $javaType == "bigdecimal") | |
| 99 | +#if ($javaType == "float" || $javaType == "double" || $javaType == "bigdecimal") | |
| 96 | 100 | :precision="2" |
| 97 | 101 | input-type="number" |
| 98 | 102 | #end |
| 99 | 103 | :min="0" |
| 100 | 104 | /> |
| 101 | -#elseif ($column.htmlType == "textarea") | |
| 102 | - <wd-textarea v-model="formData.${column.javaField}" clearable placeholder="请输入${column.columnComment}" /> | |
| 105 | +#elseif ($column.htmlType == "textarea" || $column.htmlType == "editor") | |
| 106 | + <wd-textarea | |
| 107 | + v-model="formData.${column.javaField}" | |
| 108 | + clearable | |
| 109 | + placeholder="请输入${column.columnComment}" | |
| 110 | +#if ($column.htmlType == "editor") | |
| 111 | + :maxlength="2000" | |
| 112 | +#else | |
| 113 | + :maxlength="200" | |
| 114 | +#end | |
| 115 | + /> | |
| 103 | 116 | #elseif ($column.htmlType == "imageUpload") |
| 104 | 117 | <yd-upload-img v-model="formData.${column.javaField}" directory="${table.moduleName}/${table.businessName}" /> |
| 105 | 118 | #elseif ($column.htmlType == "fileUpload") |
| 106 | - <yd-upload-file v-model="formData.${column.javaField}" directory="${table.moduleName}/${table.businessName}" /> | |
| 119 | + <yd-upload-file v-model="formData.${column.javaField}" :limit="1" directory="${table.moduleName}/${table.businessName}" /> | |
| 107 | 120 | #else |
| 108 | 121 | <wd-input v-model="formData.${column.javaField}" clearable placeholder="请输入${column.columnComment}" /> |
| 109 | 122 | #end |
| ... | ... | @@ -130,6 +143,9 @@ import { computed, onMounted, ref } from 'vue' |
| 130 | 143 | import { useToast } from '@wot-ui/ui/components/wd-toast' |
| 131 | 144 | import { create${subSimpleClassName}, get${subSimpleClassName}, update${subSimpleClassName} } from '@/api/${table.moduleName}/${table.businessName}' |
| 132 | 145 | import { delay, navigateBackPlus } from '@/utils' |
| 146 | +#if ($hasBoolDict == 1) | |
| 147 | +import { getBoolDictOptions } from '@/hooks/useDict' | |
| 148 | +#end | |
| 133 | 149 | #if ($hasDict == 1) |
| 134 | 150 | import { DICT_TYPE } from '@/utils/constants' |
| 135 | 151 | #end |
| ... | ... | @@ -159,7 +175,7 @@ definePage({ |
| 159 | 175 | const toast = useToast() |
| 160 | 176 | const getTitle = computed(() => props.id ? '编辑${subTable.classComment}' : '新增${subTable.classComment}') |
| 161 | 177 | const formLoading = ref(false) // 表单提交状态 |
| 162 | -const formData = ref<${subSimpleClassName}>({ | |
| 178 | +const formData = ref<Partial<${subSimpleClassName}>>({ | |
| 163 | 179 | #foreach ($column in $subColumns) |
| 164 | 180 | #if ($column.primaryKey) |
| 165 | 181 | ${column.javaField}: undefined, |
| ... | ... | @@ -167,7 +183,11 @@ const formData = ref<${subSimpleClassName}>({ |
| 167 | 183 | ${column.javaField}: props.${column.javaField}, |
| 168 | 184 | #elseif ($column.createOperation || $column.updateOperation) |
| 169 | 185 | #set ($javaType = $column.javaType.toLowerCase()) |
| 170 | - ${column.javaField}:#if($column.nullable) undefined#elseif($javaType == "long" || $javaType == "integer" || $javaType == "short" || $javaType == "double" || $javaType == "bigdecimal" || $javaType == "byte" || $javaType == "date" || $javaType == "localdate" || $javaType == "localdatetime") 0#elseif($javaType == "boolean") false#else ''#end, | |
| 186 | +#if((($column.htmlType == "select" || $column.htmlType == "radio") && $column.dictType && "" != $column.dictType) || $javaType == "date" || $javaType == "localdate" || $javaType == "localdatetime") | |
| 187 | + ${column.javaField}: undefined, | |
| 188 | +#else | |
| 189 | + ${column.javaField}:#if($column.nullable) undefined#elseif($javaType == "long" || $javaType == "integer" || $javaType == "short" || $javaType == "float" || $javaType == "double" || $javaType == "bigdecimal" || $javaType == "byte") 0#elseif($javaType == "boolean") false#else ''#end, | |
| 190 | +#end | |
| 171 | 191 | #end |
| 172 | 192 | #end |
| 173 | 193 | }) // 表单数据 |
| ... | ... | @@ -206,7 +226,10 @@ async function handleSubmit() { |
| 206 | 226 | } |
| 207 | 227 | formLoading.value = true |
| 208 | 228 | try { |
| 209 | - const data = { ...formData.value, ${subJoinColumn.javaField}: props.${subJoinColumn.javaField} ?? formData.value.${subJoinColumn.javaField} } | |
| 229 | + const data = { | |
| 230 | + ...formData.value, | |
| 231 | + ${subJoinColumn.javaField}: props.${subJoinColumn.javaField} ?? formData.value.${subJoinColumn.javaField}, | |
| 232 | + } as ${subSimpleClassName} | |
| 210 | 233 | if (props.id) { |
| 211 | 234 | await update${subSimpleClassName}(data) |
| 212 | 235 | toast.success('修改成功') | ... | ... |
yudao-module-infra/src/main/resources/codegen/vue3_admin_uniapp/views/index_tree.vue.vm
| ... | ... | @@ -61,7 +61,7 @@ |
| 61 | 61 | |
| 62 | 62 | <script lang="ts" setup> |
| 63 | 63 | #set ($primaryJavaType = $primaryColumn.javaType.toLowerCase()) |
| 64 | -#if(${primaryJavaType} == "long" || ${primaryJavaType} == "integer" || ${primaryJavaType} == "short" || ${primaryJavaType} == "double" || ${primaryJavaType} == "bigdecimal" || ${primaryJavaType} == "byte") | |
| 64 | +#if(${primaryJavaType} == "long" || ${primaryJavaType} == "integer" || ${primaryJavaType} == "short" || ${primaryJavaType} == "float" || ${primaryJavaType} == "double" || ${primaryJavaType} == "bigdecimal" || ${primaryJavaType} == "byte") | |
| 65 | 65 | #set ($primaryTsType = "number") |
| 66 | 66 | #else |
| 67 | 67 | #set ($primaryTsType = "string") | ... | ... |
yudao-module-infra/src/test/java/cn/iocoder/yudao/module/infra/service/codegen/inner/CodegenEngineUniappTest.java
| 1 | 1 | package cn.iocoder.yudao.module.infra.service.codegen.inner; |
| 2 | 2 | |
| 3 | +import cn.iocoder.yudao.framework.common.exception.ServiceException; | |
| 3 | 4 | import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.CodegenColumnDO; |
| 4 | 5 | import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.CodegenTableDO; |
| 5 | 6 | import cn.iocoder.yudao.module.infra.enums.codegen.CodegenFrontTypeEnum; |
| ... | ... | @@ -8,6 +9,7 @@ import com.baomidou.mybatisplus.annotation.DbType; |
| 8 | 9 | import org.junit.jupiter.api.Test; |
| 9 | 10 | |
| 10 | 11 | import java.util.Arrays; |
| 12 | +import java.util.HashMap; | |
| 11 | 13 | import java.util.List; |
| 12 | 14 | import java.util.Map; |
| 13 | 15 | import java.util.Objects; |
| ... | ... | @@ -83,6 +85,8 @@ public class CodegenEngineUniappTest extends CodegenEngineAbstractTest { |
| 83 | 85 | .setFrontType(CodegenFrontTypeEnum.VUE3_ADMIN_UNIAPP_WOT.getType()) |
| 84 | 86 | .setTemplateType(CodegenTemplateTypeEnum.ONE.getType()); |
| 85 | 87 | List<CodegenColumnDO> columns = getColumnList("student"); |
| 88 | + columns.stream().filter(column -> "memo".equals(column.getJavaField())).findFirst().orElseThrow() | |
| 89 | + .setJavaType("Float").setHtmlType("input"); | |
| 86 | 90 | |
| 87 | 91 | // 调用 |
| 88 | 92 | Map<String, String> result = codegenEngine.execute(DbType.MYSQL, table, columns, null, null); |
| ... | ... | @@ -90,7 +94,11 @@ public class CodegenEngineUniappTest extends CodegenEngineAbstractTest { |
| 90 | 94 | String api = result.get("yudao-ui-admin-uniapp/src/api/infra/demo/index.ts"); |
| 91 | 95 | assertTrue(api.contains("birthday: number")); |
| 92 | 96 | assertTrue(api.contains("createTime?: number")); |
| 97 | + assertTrue(api.contains("memo: number")); | |
| 93 | 98 | assertFalse(api.contains("createTime?: Date")); |
| 99 | + String form = result.get("yudao-ui-admin-uniapp/src/pages-infra/demo/form/index.vue"); | |
| 100 | + assertTrue(form.contains("v-model=\"formData.memo\"")); | |
| 101 | + assertTrue(form.contains(":precision=\"2\"")); | |
| 94 | 102 | String detail = result.get("yudao-ui-admin-uniapp/src/pages-infra/demo/detail/index.vue"); |
| 95 | 103 | assertTrue(detail.contains("type=\"danger\"")); |
| 96 | 104 | assertFalse(detail.contains("type=\"error\"")); |
| ... | ... | @@ -150,7 +158,7 @@ public class CodegenEngineUniappTest extends CodegenEngineAbstractTest { |
| 150 | 158 | } |
| 151 | 159 | |
| 152 | 160 | @Test |
| 153 | - public void testExecute_duplicateSubPath() { | |
| 161 | + public void testExecute_duplicateErpSymbol() { | |
| 154 | 162 | // 准备主表 |
| 155 | 163 | CodegenTableDO table = getTable("student") |
| 156 | 164 | .setFrontType(CodegenFrontTypeEnum.VUE3_ADMIN_UNIAPP_WOT.getType()) |
| ... | ... | @@ -169,13 +177,93 @@ public class CodegenEngineUniappTest extends CodegenEngineAbstractTest { |
| 169 | 177 | List<CodegenColumnDO> erpItemColumns = getColumnList("contact"); |
| 170 | 178 | |
| 171 | 179 | // 调用 |
| 172 | - IllegalStateException exception = assertThrows(IllegalStateException.class, | |
| 180 | + ServiceException exception = assertThrows(ServiceException.class, | |
| 173 | 181 | () -> codegenEngine.execute(DbType.MYSQL, table, columns, |
| 174 | 182 | Arrays.asList(crmItemTable, erpItemTable), Arrays.asList(crmItemColumns, erpItemColumns))); |
| 175 | 183 | // 断言 |
| 176 | - assertTrue(exception.getMessage().contains("生成文件路径重复")); | |
| 177 | - assertTrue(exception.getMessage().contains("subIndex=0")); | |
| 178 | - assertTrue(exception.getMessage().contains("subIndex=1")); | |
| 184 | + assertTrue(exception.getMessage().contains("主子表规范化类名(OrderItem)重复")); | |
| 185 | + } | |
| 186 | + | |
| 187 | + @Test | |
| 188 | + public void testExecute_duplicateMasterSymbol() { | |
| 189 | + // 准备主表 | |
| 190 | + CodegenTableDO table = getTable("student") | |
| 191 | + .setFrontType(CodegenFrontTypeEnum.VUE3_ELEMENT_PLUS.getType()) | |
| 192 | + .setTemplateType(CodegenTemplateTypeEnum.MASTER_NORMAL.getType()); | |
| 193 | + List<CodegenColumnDO> columns = getColumnList("student"); | |
| 194 | + // 准备两个规范化名称相同的子表 | |
| 195 | + CodegenTableDO crmItemTable = getTable("contact").setModuleName("crm").setClassName("CrmOrderItem") | |
| 196 | + .setTemplateType(CodegenTemplateTypeEnum.SUB.getType()).setSubJoinColumnId(100L).setSubJoinMany(true); | |
| 197 | + CodegenTableDO erpItemTable = getTable("contact").setModuleName("erp").setClassName("ErpOrderItem") | |
| 198 | + .setTemplateType(CodegenTemplateTypeEnum.SUB.getType()).setSubJoinColumnId(100L).setSubJoinMany(true); | |
| 199 | + List<CodegenColumnDO> crmItemColumns = getColumnList("contact"); | |
| 200 | + List<CodegenColumnDO> erpItemColumns = getColumnList("contact"); | |
| 201 | + | |
| 202 | + // 调用并断言 | |
| 203 | + ServiceException exception = assertThrows(ServiceException.class, | |
| 204 | + () -> codegenEngine.execute(DbType.MYSQL, table, columns, | |
| 205 | + Arrays.asList(crmItemTable, erpItemTable), Arrays.asList(crmItemColumns, erpItemColumns))); | |
| 206 | + assertTrue(exception.getMessage().contains("主子表规范化类名(OrderItem)重复")); | |
| 207 | + } | |
| 208 | + | |
| 209 | + @Test | |
| 210 | + public void testExecute_duplicateMasterFieldNormal() { | |
| 211 | + testExecute_duplicateMasterField(CodegenTemplateTypeEnum.MASTER_NORMAL); | |
| 212 | + } | |
| 213 | + | |
| 214 | + @Test | |
| 215 | + public void testExecute_duplicateMasterFieldInner() { | |
| 216 | + testExecute_duplicateMasterField(CodegenTemplateTypeEnum.MASTER_INNER); | |
| 217 | + } | |
| 218 | + | |
| 219 | + @Test | |
| 220 | + public void testExecute_duplicateMasterFieldWithMainNormal() { | |
| 221 | + testExecute_duplicateMasterFieldWithMain(CodegenTemplateTypeEnum.MASTER_NORMAL); | |
| 222 | + } | |
| 223 | + | |
| 224 | + @Test | |
| 225 | + public void testExecute_duplicateMasterFieldWithMainInner() { | |
| 226 | + testExecute_duplicateMasterFieldWithMain(CodegenTemplateTypeEnum.MASTER_INNER); | |
| 227 | + } | |
| 228 | + | |
| 229 | + @Test | |
| 230 | + public void testExecute_duplicateMasterFieldErp() { | |
| 231 | + // 准备主表 | |
| 232 | + CodegenTableDO table = getTable("student") | |
| 233 | + .setFrontType(CodegenFrontTypeEnum.VUE3_ADMIN_UNIAPP_WOT.getType()) | |
| 234 | + .setTemplateType(CodegenTemplateTypeEnum.MASTER_ERP.getType()); | |
| 235 | + List<CodegenColumnDO> columns = getColumnList("student"); | |
| 236 | + // 准备属性名同为 items 的子表:Item 一对多、Items 一对一 | |
| 237 | + CodegenTableDO crmItemTable = getTable("contact").setModuleName("crm").setClassName("CrmItem") | |
| 238 | + .setTemplateType(CodegenTemplateTypeEnum.SUB.getType()).setSubJoinColumnId(100L).setSubJoinMany(true); | |
| 239 | + CodegenTableDO erpItemsTable = getTable("contact").setModuleName("erp").setClassName("ErpItems") | |
| 240 | + .setTemplateType(CodegenTemplateTypeEnum.SUB.getType()).setSubJoinColumnId(100L).setSubJoinMany(false); | |
| 241 | + | |
| 242 | + // 调用 | |
| 243 | + Map<String, String> result = codegenEngine.execute(DbType.MYSQL, table, columns, | |
| 244 | + Arrays.asList(crmItemTable, erpItemsTable), | |
| 245 | + Arrays.asList(getColumnList("contact"), getColumnList("contact"))); | |
| 246 | + // 断言 | |
| 247 | + assertTrue(result.containsKey("yudao-ui-admin-uniapp/src/pages-infra/demo/item/form/index.vue")); | |
| 248 | + assertTrue(result.containsKey("yudao-ui-admin-uniapp/src/pages-infra/demo/items/form/index.vue")); | |
| 249 | + } | |
| 250 | + | |
| 251 | + @Test | |
| 252 | + public void testRegisterGeneratedSource_duplicatePath() { | |
| 253 | + // 准备参数 | |
| 254 | + Map<String, String> generatedSources = new HashMap<>(); | |
| 255 | + Map<String, Object> bindingMap = new HashMap<>(); | |
| 256 | + bindingMap.put("subIndex", 0); | |
| 257 | + CodegenEngine.registerGeneratedSource(generatedSources, "same.vue", "form_sub.vm", bindingMap); | |
| 258 | + bindingMap.put("subIndex", 1); | |
| 259 | + | |
| 260 | + // 调用 | |
| 261 | + IllegalStateException exception = assertThrows(IllegalStateException.class, | |
| 262 | + () -> CodegenEngine.registerGeneratedSource(generatedSources, "same.vue", "form_sub.vm", bindingMap)); | |
| 263 | + // 断言 | |
| 264 | + assertTrue(exception.getMessage().contains("生成文件路径重复:same.vue")); | |
| 265 | + assertTrue(exception.getMessage().contains("form_sub.vm[subIndex=0]")); | |
| 266 | + assertTrue(exception.getMessage().contains("form_sub.vm[subIndex=1]")); | |
| 179 | 267 | } |
| 180 | 268 | |
| 181 | 269 | @Test |
| ... | ... | @@ -193,6 +281,46 @@ public class CodegenEngineUniappTest extends CodegenEngineAbstractTest { |
| 193 | 281 | testExecute_master(CodegenTemplateTypeEnum.MASTER_ERP, "/vue3_admin_uniapp_master_erp"); |
| 194 | 282 | } |
| 195 | 283 | |
| 284 | + private void testExecute_duplicateMasterField(CodegenTemplateTypeEnum templateType) { | |
| 285 | + // 准备主表 | |
| 286 | + CodegenTableDO table = getTable("student") | |
| 287 | + .setFrontType(CodegenFrontTypeEnum.VUE3_ELEMENT_PLUS.getType()) | |
| 288 | + .setTemplateType(templateType.getType()); | |
| 289 | + List<CodegenColumnDO> columns = getColumnList("student"); | |
| 290 | + // 准备属性名同为 items 的子表:Item 一对多、Items 一对一 | |
| 291 | + CodegenTableDO crmItemTable = getTable("contact").setModuleName("crm").setClassName("CrmItem") | |
| 292 | + .setTemplateType(CodegenTemplateTypeEnum.SUB.getType()).setSubJoinColumnId(100L).setSubJoinMany(true); | |
| 293 | + CodegenTableDO erpItemsTable = getTable("contact").setModuleName("erp").setClassName("ErpItems") | |
| 294 | + .setTemplateType(CodegenTemplateTypeEnum.SUB.getType()).setSubJoinColumnId(100L).setSubJoinMany(false); | |
| 295 | + List<CodegenColumnDO> crmItemColumns = getColumnList("contact"); | |
| 296 | + List<CodegenColumnDO> erpItemsColumns = getColumnList("contact"); | |
| 297 | + | |
| 298 | + // 调用并断言 | |
| 299 | + ServiceException exception = assertThrows(ServiceException.class, | |
| 300 | + () -> codegenEngine.execute(DbType.MYSQL, table, columns, | |
| 301 | + Arrays.asList(crmItemTable, erpItemsTable), Arrays.asList(crmItemColumns, erpItemsColumns))); | |
| 302 | + assertTrue(exception.getMessage().contains("主子表属性名(items)重复")); | |
| 303 | + } | |
| 304 | + | |
| 305 | + private void testExecute_duplicateMasterFieldWithMain(CodegenTemplateTypeEnum templateType) { | |
| 306 | + // 准备主表 | |
| 307 | + CodegenTableDO table = getTable("student") | |
| 308 | + .setFrontType(CodegenFrontTypeEnum.VUE3_ELEMENT_PLUS.getType()) | |
| 309 | + .setTemplateType(templateType.getType()); | |
| 310 | + List<CodegenColumnDO> columns = getColumnList("student"); | |
| 311 | + columns.stream().filter(column -> "memo".equals(column.getJavaField())).findFirst().orElseThrow() | |
| 312 | + .setJavaField("items"); | |
| 313 | + // 准备一对多子表 Item,生成属性名 items | |
| 314 | + CodegenTableDO itemTable = getTable("contact").setModuleName("crm").setClassName("CrmItem") | |
| 315 | + .setTemplateType(CodegenTemplateTypeEnum.SUB.getType()).setSubJoinColumnId(100L).setSubJoinMany(true); | |
| 316 | + | |
| 317 | + // 调用并断言 | |
| 318 | + ServiceException exception = assertThrows(ServiceException.class, | |
| 319 | + () -> codegenEngine.execute(DbType.MYSQL, table, columns, | |
| 320 | + List.of(itemTable), List.of(getColumnList("contact")))); | |
| 321 | + assertTrue(exception.getMessage().contains("主子表属性名(items)重复")); | |
| 322 | + } | |
| 323 | + | |
| 196 | 324 | private void testExecute_master(CodegenTemplateTypeEnum templateType, String path) { |
| 197 | 325 | // 准备主表 |
| 198 | 326 | CodegenTableDO table = getTable("student") |
| ... | ... | @@ -221,13 +349,16 @@ public class CodegenEngineUniappTest extends CodegenEngineAbstractTest { |
| 221 | 349 | String api = result.get("yudao-ui-admin-uniapp/src/api/infra/demo/index.ts"); |
| 222 | 350 | assertTrue(api.contains("studentTeacher?: StudentTeacher | null")); |
| 223 | 351 | String form = result.get("yudao-ui-admin-uniapp/src/pages-infra/demo/form/index.vue"); |
| 224 | - assertTrue(form.contains("ref<StudentTeacher | null>(null)")); | |
| 352 | + assertTrue(form.contains("ref<Partial<StudentTeacher> | null>(null)")); | |
| 225 | 353 | assertTrue(form.contains("studentTeacher.value = studentTeacherData || null")); |
| 226 | 354 | assertTrue(form.contains(":model-value=\"item.birthday || Date.now()\"")); |
| 227 | 355 | assertTrue(form.contains("v-model=\"item.sex\"")); |
| 228 | 356 | assertTrue(form.contains("<yd-upload-img v-model=\"item.avatar\"")); |
| 229 | 357 | assertTrue(form.contains("<yd-upload-file v-model=\"item.video\"")); |
| 230 | - assertTrue(form.contains("<wd-textarea v-model=\"item.description\"")); | |
| 358 | + assertTrue(form.contains("<yd-upload-file v-model=\"item.video\" :limit=\"1\"")); | |
| 359 | + assertTrue(form.contains("v-model=\"item.description\"")); | |
| 360 | + assertTrue(form.contains("v-model=\"item.memo\"")); | |
| 361 | + assertTrue(form.contains("birthday: undefined")); | |
| 231 | 362 | assertTrue(form.contains("function validateSubTables()")); |
| 232 | 363 | } else { |
| 233 | 364 | String contactForm = result.get( |
| ... | ... | @@ -236,7 +367,11 @@ public class CodegenEngineUniappTest extends CodegenEngineAbstractTest { |
| 236 | 367 | assertTrue(contactForm.contains("v-model=\"formData.sex\"")); |
| 237 | 368 | assertTrue(contactForm.contains("<yd-upload-img v-model=\"formData.avatar\"")); |
| 238 | 369 | assertTrue(contactForm.contains("<yd-upload-file v-model=\"formData.video\"")); |
| 239 | - assertTrue(contactForm.contains("<wd-textarea v-model=\"formData.description\"")); | |
| 370 | + assertTrue(contactForm.contains("<yd-upload-file v-model=\"formData.video\" :limit=\"1\"")); | |
| 371 | + assertTrue(contactForm.contains("v-model=\"formData.description\"")); | |
| 372 | + assertTrue(contactForm.contains("v-model=\"formData.memo\"")); | |
| 373 | + assertTrue(contactForm.contains("birthday: undefined")); | |
| 374 | + assertTrue(contactForm.contains(":columns=\"getBoolDictOptions")); | |
| 240 | 375 | } |
| 241 | 376 | } |
| 242 | 377 | ... | ... |
yudao-module-infra/src/test/resources/codegen/vue3_admin_uniapp_master_erp/vue/form/index
| ... | ... | @@ -65,13 +65,15 @@ |
| 65 | 65 | <yd-upload-img v-model="formData.avatar" directory="infra/demo" /> |
| 66 | 66 | </wd-form-item> |
| 67 | 67 | <wd-form-item title="附件" title-width="180rpx" prop="video"> |
| 68 | - <yd-upload-file v-model="formData.video" directory="infra/demo" /> | |
| 68 | + <yd-upload-file v-model="formData.video" :limit="1" directory="infra/demo" /> | |
| 69 | 69 | </wd-form-item> |
| 70 | 70 | <wd-form-item title="备注" title-width="180rpx" prop="memo"> |
| 71 | - <wd-input | |
| 71 | + <wd-textarea | |
| 72 | 72 | v-model="formData.memo" |
| 73 | 73 | clearable |
| 74 | 74 | placeholder="请输入备注" |
| 75 | + :maxlength="2000" | |
| 76 | + show-word-limit | |
| 75 | 77 | /> |
| 76 | 78 | </wd-form-item> |
| 77 | 79 | </wd-cell-group> |
| ... | ... | @@ -120,13 +122,13 @@ definePage({ |
| 120 | 122 | const toast = useToast() |
| 121 | 123 | const getTitle = computed(() => props.id ? '编辑学生' : '新增学生') |
| 122 | 124 | const formLoading = ref(false) // 表单提交状态 |
| 123 | -const formData = ref<Student>({ | |
| 125 | +const formData = ref<Partial<Student>>({ | |
| 124 | 126 | id: undefined, |
| 125 | 127 | name: '', |
| 126 | 128 | description: '', |
| 127 | - birthday: 0, | |
| 128 | - sex: 0, | |
| 129 | - enabled: false, | |
| 129 | + birthday: undefined, | |
| 130 | + sex: undefined, | |
| 131 | + enabled: undefined, | |
| 130 | 132 | avatar: '', |
| 131 | 133 | video: '', |
| 132 | 134 | memo: '', |
| ... | ... | @@ -166,7 +168,7 @@ async function handleSubmit() { |
| 166 | 168 | |
| 167 | 169 | formLoading.value = true |
| 168 | 170 | try { |
| 169 | - const data = formData.value | |
| 171 | + const data = formData.value as Student | |
| 170 | 172 | if (props.id) { |
| 171 | 173 | await updateStudent(data) |
| 172 | 174 | toast.success('修改成功') | ... | ... |
yudao-module-infra/src/test/resources/codegen/vue3_admin_uniapp_master_erp/vue/student-contact/form/index
| ... | ... | @@ -10,7 +10,12 @@ |
| 10 | 10 | <wd-input v-model="formData.name" clearable placeholder="请输入名字" /> |
| 11 | 11 | </wd-form-item> |
| 12 | 12 | <wd-form-item title="简介" title-width="180rpx" prop="description"> |
| 13 | - <wd-textarea v-model="formData.description" clearable placeholder="请输入简介" /> | |
| 13 | + <wd-textarea | |
| 14 | + v-model="formData.description" | |
| 15 | + clearable | |
| 16 | + placeholder="请输入简介" | |
| 17 | + :maxlength="200" | |
| 18 | + /> | |
| 14 | 19 | </wd-form-item> |
| 15 | 20 | <wd-form-item |
| 16 | 21 | title="出生日期" |
| ... | ... | @@ -40,17 +45,22 @@ |
| 40 | 45 | label="是否有效" |
| 41 | 46 | label-width="180rpx" |
| 42 | 47 | prop="enabled" |
| 43 | - :dict-type="DICT_TYPE.INFRA_BOOLEAN_STRING" | |
| 48 | + :columns="getBoolDictOptions(DICT_TYPE.INFRA_BOOLEAN_STRING)" | |
| 44 | 49 | placeholder="请选择是否有效" |
| 45 | 50 | /> |
| 46 | 51 | <wd-form-item title="头像" title-width="180rpx" prop="avatar"> |
| 47 | 52 | <yd-upload-img v-model="formData.avatar" directory="infra/demo" /> |
| 48 | 53 | </wd-form-item> |
| 49 | 54 | <wd-form-item title="附件" title-width="180rpx" prop="video"> |
| 50 | - <yd-upload-file v-model="formData.video" directory="infra/demo" /> | |
| 55 | + <yd-upload-file v-model="formData.video" :limit="1" directory="infra/demo" /> | |
| 51 | 56 | </wd-form-item> |
| 52 | 57 | <wd-form-item title="备注" title-width="180rpx" prop="memo"> |
| 53 | - <wd-input v-model="formData.memo" clearable placeholder="请输入备注" /> | |
| 58 | + <wd-textarea | |
| 59 | + v-model="formData.memo" | |
| 60 | + clearable | |
| 61 | + placeholder="请输入备注" | |
| 62 | + :maxlength="2000" | |
| 63 | + /> | |
| 54 | 64 | </wd-form-item> |
| 55 | 65 | </wd-cell-group> |
| 56 | 66 | </wd-form> |
| ... | ... | @@ -71,6 +81,7 @@ import { computed, onMounted, ref } from 'vue' |
| 71 | 81 | import { useToast } from '@wot-ui/ui/components/wd-toast' |
| 72 | 82 | import { createStudentContact, getStudentContact, updateStudentContact } from '@/api/infra/demo' |
| 73 | 83 | import { delay, navigateBackPlus } from '@/utils' |
| 84 | +import { getBoolDictOptions } from '@/hooks/useDict' | |
| 74 | 85 | import { DICT_TYPE } from '@/utils/constants' |
| 75 | 86 | import { formatDateTime } from '@/utils/date' |
| 76 | 87 | import { createFormSchema } from '@/utils/wot' |
| ... | ... | @@ -87,14 +98,14 @@ definePage({ |
| 87 | 98 | const toast = useToast() |
| 88 | 99 | const getTitle = computed(() => props.id ? '编辑学生联系人' : '新增学生联系人') |
| 89 | 100 | const formLoading = ref(false) // 表单提交状态 |
| 90 | -const formData = ref<StudentContact>({ | |
| 101 | +const formData = ref<Partial<StudentContact>>({ | |
| 91 | 102 | id: undefined, |
| 92 | 103 | studentId: props.studentId, |
| 93 | 104 | name: '', |
| 94 | 105 | description: '', |
| 95 | - birthday: 0, | |
| 96 | - sex: 0, | |
| 97 | - enabled: false, | |
| 106 | + birthday: undefined, | |
| 107 | + sex: undefined, | |
| 108 | + enabled: undefined, | |
| 98 | 109 | avatar: '', |
| 99 | 110 | video: undefined, |
| 100 | 111 | memo: '', |
| ... | ... | @@ -132,7 +143,10 @@ async function handleSubmit() { |
| 132 | 143 | } |
| 133 | 144 | formLoading.value = true |
| 134 | 145 | try { |
| 135 | - const data = { ...formData.value, studentId: props.studentId ?? formData.value.studentId } | |
| 146 | + const data = { | |
| 147 | + ...formData.value, | |
| 148 | + studentId: props.studentId ?? formData.value.studentId, | |
| 149 | + } as StudentContact | |
| 136 | 150 | if (props.id) { |
| 137 | 151 | await updateStudentContact(data) |
| 138 | 152 | toast.success('修改成功') | ... | ... |
yudao-module-infra/src/test/resources/codegen/vue3_admin_uniapp_master_erp/vue/student-teacher/form/index
| ... | ... | @@ -10,7 +10,12 @@ |
| 10 | 10 | <wd-input v-model="formData.name" clearable placeholder="请输入名字" /> |
| 11 | 11 | </wd-form-item> |
| 12 | 12 | <wd-form-item title="简介" title-width="180rpx" prop="description"> |
| 13 | - <wd-textarea v-model="formData.description" clearable placeholder="请输入简介" /> | |
| 13 | + <wd-textarea | |
| 14 | + v-model="formData.description" | |
| 15 | + clearable | |
| 16 | + placeholder="请输入简介" | |
| 17 | + :maxlength="200" | |
| 18 | + /> | |
| 14 | 19 | </wd-form-item> |
| 15 | 20 | <wd-form-item |
| 16 | 21 | title="出生日期" |
| ... | ... | @@ -40,17 +45,22 @@ |
| 40 | 45 | label="是否有效" |
| 41 | 46 | label-width="180rpx" |
| 42 | 47 | prop="enabled" |
| 43 | - :dict-type="DICT_TYPE.INFRA_BOOLEAN_STRING" | |
| 48 | + :columns="getBoolDictOptions(DICT_TYPE.INFRA_BOOLEAN_STRING)" | |
| 44 | 49 | placeholder="请选择是否有效" |
| 45 | 50 | /> |
| 46 | 51 | <wd-form-item title="头像" title-width="180rpx" prop="avatar"> |
| 47 | 52 | <yd-upload-img v-model="formData.avatar" directory="infra/demo" /> |
| 48 | 53 | </wd-form-item> |
| 49 | 54 | <wd-form-item title="附件" title-width="180rpx" prop="video"> |
| 50 | - <yd-upload-file v-model="formData.video" directory="infra/demo" /> | |
| 55 | + <yd-upload-file v-model="formData.video" :limit="1" directory="infra/demo" /> | |
| 51 | 56 | </wd-form-item> |
| 52 | 57 | <wd-form-item title="备注" title-width="180rpx" prop="memo"> |
| 53 | - <wd-input v-model="formData.memo" clearable placeholder="请输入备注" /> | |
| 58 | + <wd-textarea | |
| 59 | + v-model="formData.memo" | |
| 60 | + clearable | |
| 61 | + placeholder="请输入备注" | |
| 62 | + :maxlength="2000" | |
| 63 | + /> | |
| 54 | 64 | </wd-form-item> |
| 55 | 65 | </wd-cell-group> |
| 56 | 66 | </wd-form> |
| ... | ... | @@ -71,6 +81,7 @@ import { computed, onMounted, ref } from 'vue' |
| 71 | 81 | import { useToast } from '@wot-ui/ui/components/wd-toast' |
| 72 | 82 | import { createStudentTeacher, getStudentTeacher, updateStudentTeacher } from '@/api/infra/demo' |
| 73 | 83 | import { delay, navigateBackPlus } from '@/utils' |
| 84 | +import { getBoolDictOptions } from '@/hooks/useDict' | |
| 74 | 85 | import { DICT_TYPE } from '@/utils/constants' |
| 75 | 86 | import { formatDateTime } from '@/utils/date' |
| 76 | 87 | import { createFormSchema } from '@/utils/wot' |
| ... | ... | @@ -87,14 +98,14 @@ definePage({ |
| 87 | 98 | const toast = useToast() |
| 88 | 99 | const getTitle = computed(() => props.id ? '编辑学生班主任' : '新增学生班主任') |
| 89 | 100 | const formLoading = ref(false) // 表单提交状态 |
| 90 | -const formData = ref<StudentTeacher>({ | |
| 101 | +const formData = ref<Partial<StudentTeacher>>({ | |
| 91 | 102 | id: undefined, |
| 92 | 103 | studentId: props.studentId, |
| 93 | 104 | name: '', |
| 94 | 105 | description: '', |
| 95 | - birthday: 0, | |
| 96 | - sex: 0, | |
| 97 | - enabled: false, | |
| 106 | + birthday: undefined, | |
| 107 | + sex: undefined, | |
| 108 | + enabled: undefined, | |
| 98 | 109 | avatar: '', |
| 99 | 110 | video: undefined, |
| 100 | 111 | memo: '', |
| ... | ... | @@ -132,7 +143,10 @@ async function handleSubmit() { |
| 132 | 143 | } |
| 133 | 144 | formLoading.value = true |
| 134 | 145 | try { |
| 135 | - const data = { ...formData.value, studentId: props.studentId ?? formData.value.studentId } | |
| 146 | + const data = { | |
| 147 | + ...formData.value, | |
| 148 | + studentId: props.studentId ?? formData.value.studentId, | |
| 149 | + } as StudentTeacher | |
| 136 | 150 | if (props.id) { |
| 137 | 151 | await updateStudentTeacher(data) |
| 138 | 152 | toast.success('修改成功') | ... | ... |
yudao-module-infra/src/test/resources/codegen/vue3_admin_uniapp_master_inner/vue/form/index
| ... | ... | @@ -65,13 +65,15 @@ |
| 65 | 65 | <yd-upload-img v-model="formData.avatar" directory="infra/demo" /> |
| 66 | 66 | </wd-form-item> |
| 67 | 67 | <wd-form-item title="附件" title-width="180rpx" prop="video"> |
| 68 | - <yd-upload-file v-model="formData.video" directory="infra/demo" /> | |
| 68 | + <yd-upload-file v-model="formData.video" :limit="1" directory="infra/demo" /> | |
| 69 | 69 | </wd-form-item> |
| 70 | 70 | <wd-form-item title="备注" title-width="180rpx" prop="memo"> |
| 71 | - <wd-input | |
| 71 | + <wd-textarea | |
| 72 | 72 | v-model="formData.memo" |
| 73 | 73 | clearable |
| 74 | 74 | placeholder="请输入备注" |
| 75 | + :maxlength="2000" | |
| 76 | + show-word-limit | |
| 75 | 77 | /> |
| 76 | 78 | </wd-form-item> |
| 77 | 79 | </wd-cell-group> |
| ... | ... | @@ -102,7 +104,12 @@ |
| 102 | 104 | <wd-input v-model="item.name" clearable placeholder="请输入名字" /> |
| 103 | 105 | </wd-form-item> |
| 104 | 106 | <wd-form-item title="简介" title-width="180rpx"> |
| 105 | - <wd-textarea v-model="item.description" clearable placeholder="请输入简介" /> | |
| 107 | + <wd-textarea | |
| 108 | + v-model="item.description" | |
| 109 | + clearable | |
| 110 | + placeholder="请输入简介" | |
| 111 | + :maxlength="200" | |
| 112 | + /> | |
| 106 | 113 | </wd-form-item> |
| 107 | 114 | <wd-form-item |
| 108 | 115 | title="出生日期" |
| ... | ... | @@ -140,10 +147,15 @@ |
| 140 | 147 | <yd-upload-img v-model="item.avatar" directory="infra/demo" /> |
| 141 | 148 | </wd-form-item> |
| 142 | 149 | <wd-form-item title="附件" title-width="180rpx"> |
| 143 | - <yd-upload-file v-model="item.video" directory="infra/demo" /> | |
| 150 | + <yd-upload-file v-model="item.video" :limit="1" directory="infra/demo" /> | |
| 144 | 151 | </wd-form-item> |
| 145 | 152 | <wd-form-item title="备注" title-width="180rpx"> |
| 146 | - <wd-input v-model="item.memo" clearable placeholder="请输入备注" /> | |
| 153 | + <wd-textarea | |
| 154 | + v-model="item.memo" | |
| 155 | + clearable | |
| 156 | + placeholder="请输入备注" | |
| 157 | + :maxlength="2000" | |
| 158 | + /> | |
| 147 | 159 | </wd-form-item> |
| 148 | 160 | </view> |
| 149 | 161 | </view> |
| ... | ... | @@ -170,7 +182,12 @@ |
| 170 | 182 | <wd-input v-model="studentTeacher.name" clearable placeholder="请输入名字" /> |
| 171 | 183 | </wd-form-item> |
| 172 | 184 | <wd-form-item title="简介" title-width="180rpx"> |
| 173 | - <wd-textarea v-model="studentTeacher.description" clearable placeholder="请输入简介" /> | |
| 185 | + <wd-textarea | |
| 186 | + v-model="studentTeacher.description" | |
| 187 | + clearable | |
| 188 | + placeholder="请输入简介" | |
| 189 | + :maxlength="200" | |
| 190 | + /> | |
| 174 | 191 | </wd-form-item> |
| 175 | 192 | <wd-form-item |
| 176 | 193 | title="出生日期" |
| ... | ... | @@ -208,10 +225,15 @@ |
| 208 | 225 | <yd-upload-img v-model="studentTeacher.avatar" directory="infra/demo" /> |
| 209 | 226 | </wd-form-item> |
| 210 | 227 | <wd-form-item title="附件" title-width="180rpx"> |
| 211 | - <yd-upload-file v-model="studentTeacher.video" directory="infra/demo" /> | |
| 228 | + <yd-upload-file v-model="studentTeacher.video" :limit="1" directory="infra/demo" /> | |
| 212 | 229 | </wd-form-item> |
| 213 | 230 | <wd-form-item title="备注" title-width="180rpx"> |
| 214 | - <wd-input v-model="studentTeacher.memo" clearable placeholder="请输入备注" /> | |
| 231 | + <wd-textarea | |
| 232 | + v-model="studentTeacher.memo" | |
| 233 | + clearable | |
| 234 | + placeholder="请输入备注" | |
| 235 | + :maxlength="2000" | |
| 236 | + /> | |
| 215 | 237 | </wd-form-item> |
| 216 | 238 | </view> |
| 217 | 239 | </view> |
| ... | ... | @@ -267,19 +289,19 @@ definePage({ |
| 267 | 289 | const toast = useToast() |
| 268 | 290 | const getTitle = computed(() => props.id ? '编辑学生' : '新增学生') |
| 269 | 291 | const formLoading = ref(false) // 表单提交状态 |
| 270 | -const formData = ref<Student>({ | |
| 292 | +const formData = ref<Partial<Student>>({ | |
| 271 | 293 | id: undefined, |
| 272 | 294 | name: '', |
| 273 | 295 | description: '', |
| 274 | - birthday: 0, | |
| 275 | - sex: 0, | |
| 276 | - enabled: false, | |
| 296 | + birthday: undefined, | |
| 297 | + sex: undefined, | |
| 298 | + enabled: undefined, | |
| 277 | 299 | avatar: '', |
| 278 | 300 | video: '', |
| 279 | 301 | memo: '', |
| 280 | 302 | }) // 表单数据 |
| 281 | -const studentContacts = ref<StudentContact[]>([]) // 学生联系人数据 | |
| 282 | -const studentTeacher = ref<StudentTeacher | null>(null) // 学生班主任数据 | |
| 303 | +const studentContacts = ref<Partial<StudentContact>[]>([]) // 学生联系人数据 | |
| 304 | +const studentTeacher = ref<Partial<StudentTeacher> | null>(null) // 学生班主任数据 | |
| 283 | 305 | const birthdayVisible = ref(false) // 出生日期选择器状态 |
| 284 | 306 | const subDateVisible = ref<Record<string, boolean>>({}) // 子表日期选择器状态 |
| 285 | 307 | const formSchema = createFormSchema({ |
| ... | ... | @@ -299,9 +321,9 @@ function addStudentContact() { |
| 299 | 321 | studentContacts.value.push({ |
| 300 | 322 | name: '', |
| 301 | 323 | description: '', |
| 302 | - birthday: 0, | |
| 303 | - sex: 0, | |
| 304 | - enabled: false, | |
| 324 | + birthday: undefined, | |
| 325 | + sex: undefined, | |
| 326 | + enabled: undefined, | |
| 305 | 327 | avatar: '', |
| 306 | 328 | video: undefined, |
| 307 | 329 | memo: '', |
| ... | ... | @@ -318,9 +340,9 @@ function addStudentTeacher() { |
| 318 | 340 | studentTeacher.value = { |
| 319 | 341 | name: '', |
| 320 | 342 | description: '', |
| 321 | - birthday: 0, | |
| 322 | - sex: 0, | |
| 323 | - enabled: false, | |
| 343 | + birthday: undefined, | |
| 344 | + sex: undefined, | |
| 345 | + enabled: undefined, | |
| 324 | 346 | avatar: '', |
| 325 | 347 | video: undefined, |
| 326 | 348 | memo: '', |
| ... | ... | @@ -429,11 +451,11 @@ async function handleSubmit() { |
| 429 | 451 | |
| 430 | 452 | formLoading.value = true |
| 431 | 453 | try { |
| 432 | - const data: Student = { | |
| 454 | + const data = { | |
| 433 | 455 | ...formData.value, |
| 434 | 456 | studentContacts: studentContacts.value, |
| 435 | 457 | studentTeacher: studentTeacher.value, |
| 436 | - } | |
| 458 | + } as Student | |
| 437 | 459 | if (props.id) { |
| 438 | 460 | await updateStudent(data) |
| 439 | 461 | toast.success('修改成功') | ... | ... |
yudao-module-infra/src/test/resources/codegen/vue3_admin_uniapp_master_normal/vue/form/index
| ... | ... | @@ -65,13 +65,15 @@ |
| 65 | 65 | <yd-upload-img v-model="formData.avatar" directory="infra/demo" /> |
| 66 | 66 | </wd-form-item> |
| 67 | 67 | <wd-form-item title="附件" title-width="180rpx" prop="video"> |
| 68 | - <yd-upload-file v-model="formData.video" directory="infra/demo" /> | |
| 68 | + <yd-upload-file v-model="formData.video" :limit="1" directory="infra/demo" /> | |
| 69 | 69 | </wd-form-item> |
| 70 | 70 | <wd-form-item title="备注" title-width="180rpx" prop="memo"> |
| 71 | - <wd-input | |
| 71 | + <wd-textarea | |
| 72 | 72 | v-model="formData.memo" |
| 73 | 73 | clearable |
| 74 | 74 | placeholder="请输入备注" |
| 75 | + :maxlength="2000" | |
| 76 | + show-word-limit | |
| 75 | 77 | /> |
| 76 | 78 | </wd-form-item> |
| 77 | 79 | </wd-cell-group> |
| ... | ... | @@ -102,7 +104,12 @@ |
| 102 | 104 | <wd-input v-model="item.name" clearable placeholder="请输入名字" /> |
| 103 | 105 | </wd-form-item> |
| 104 | 106 | <wd-form-item title="简介" title-width="180rpx"> |
| 105 | - <wd-textarea v-model="item.description" clearable placeholder="请输入简介" /> | |
| 107 | + <wd-textarea | |
| 108 | + v-model="item.description" | |
| 109 | + clearable | |
| 110 | + placeholder="请输入简介" | |
| 111 | + :maxlength="200" | |
| 112 | + /> | |
| 106 | 113 | </wd-form-item> |
| 107 | 114 | <wd-form-item |
| 108 | 115 | title="出生日期" |
| ... | ... | @@ -140,10 +147,15 @@ |
| 140 | 147 | <yd-upload-img v-model="item.avatar" directory="infra/demo" /> |
| 141 | 148 | </wd-form-item> |
| 142 | 149 | <wd-form-item title="附件" title-width="180rpx"> |
| 143 | - <yd-upload-file v-model="item.video" directory="infra/demo" /> | |
| 150 | + <yd-upload-file v-model="item.video" :limit="1" directory="infra/demo" /> | |
| 144 | 151 | </wd-form-item> |
| 145 | 152 | <wd-form-item title="备注" title-width="180rpx"> |
| 146 | - <wd-input v-model="item.memo" clearable placeholder="请输入备注" /> | |
| 153 | + <wd-textarea | |
| 154 | + v-model="item.memo" | |
| 155 | + clearable | |
| 156 | + placeholder="请输入备注" | |
| 157 | + :maxlength="2000" | |
| 158 | + /> | |
| 147 | 159 | </wd-form-item> |
| 148 | 160 | </view> |
| 149 | 161 | </view> |
| ... | ... | @@ -170,7 +182,12 @@ |
| 170 | 182 | <wd-input v-model="studentTeacher.name" clearable placeholder="请输入名字" /> |
| 171 | 183 | </wd-form-item> |
| 172 | 184 | <wd-form-item title="简介" title-width="180rpx"> |
| 173 | - <wd-textarea v-model="studentTeacher.description" clearable placeholder="请输入简介" /> | |
| 185 | + <wd-textarea | |
| 186 | + v-model="studentTeacher.description" | |
| 187 | + clearable | |
| 188 | + placeholder="请输入简介" | |
| 189 | + :maxlength="200" | |
| 190 | + /> | |
| 174 | 191 | </wd-form-item> |
| 175 | 192 | <wd-form-item |
| 176 | 193 | title="出生日期" |
| ... | ... | @@ -208,10 +225,15 @@ |
| 208 | 225 | <yd-upload-img v-model="studentTeacher.avatar" directory="infra/demo" /> |
| 209 | 226 | </wd-form-item> |
| 210 | 227 | <wd-form-item title="附件" title-width="180rpx"> |
| 211 | - <yd-upload-file v-model="studentTeacher.video" directory="infra/demo" /> | |
| 228 | + <yd-upload-file v-model="studentTeacher.video" :limit="1" directory="infra/demo" /> | |
| 212 | 229 | </wd-form-item> |
| 213 | 230 | <wd-form-item title="备注" title-width="180rpx"> |
| 214 | - <wd-input v-model="studentTeacher.memo" clearable placeholder="请输入备注" /> | |
| 231 | + <wd-textarea | |
| 232 | + v-model="studentTeacher.memo" | |
| 233 | + clearable | |
| 234 | + placeholder="请输入备注" | |
| 235 | + :maxlength="2000" | |
| 236 | + /> | |
| 215 | 237 | </wd-form-item> |
| 216 | 238 | </view> |
| 217 | 239 | </view> |
| ... | ... | @@ -267,19 +289,19 @@ definePage({ |
| 267 | 289 | const toast = useToast() |
| 268 | 290 | const getTitle = computed(() => props.id ? '编辑学生' : '新增学生') |
| 269 | 291 | const formLoading = ref(false) // 表单提交状态 |
| 270 | -const formData = ref<Student>({ | |
| 292 | +const formData = ref<Partial<Student>>({ | |
| 271 | 293 | id: undefined, |
| 272 | 294 | name: '', |
| 273 | 295 | description: '', |
| 274 | - birthday: 0, | |
| 275 | - sex: 0, | |
| 276 | - enabled: false, | |
| 296 | + birthday: undefined, | |
| 297 | + sex: undefined, | |
| 298 | + enabled: undefined, | |
| 277 | 299 | avatar: '', |
| 278 | 300 | video: '', |
| 279 | 301 | memo: '', |
| 280 | 302 | }) // 表单数据 |
| 281 | -const studentContacts = ref<StudentContact[]>([]) // 学生联系人数据 | |
| 282 | -const studentTeacher = ref<StudentTeacher | null>(null) // 学生班主任数据 | |
| 303 | +const studentContacts = ref<Partial<StudentContact>[]>([]) // 学生联系人数据 | |
| 304 | +const studentTeacher = ref<Partial<StudentTeacher> | null>(null) // 学生班主任数据 | |
| 283 | 305 | const birthdayVisible = ref(false) // 出生日期选择器状态 |
| 284 | 306 | const subDateVisible = ref<Record<string, boolean>>({}) // 子表日期选择器状态 |
| 285 | 307 | const formSchema = createFormSchema({ |
| ... | ... | @@ -299,9 +321,9 @@ function addStudentContact() { |
| 299 | 321 | studentContacts.value.push({ |
| 300 | 322 | name: '', |
| 301 | 323 | description: '', |
| 302 | - birthday: 0, | |
| 303 | - sex: 0, | |
| 304 | - enabled: false, | |
| 324 | + birthday: undefined, | |
| 325 | + sex: undefined, | |
| 326 | + enabled: undefined, | |
| 305 | 327 | avatar: '', |
| 306 | 328 | video: undefined, |
| 307 | 329 | memo: '', |
| ... | ... | @@ -318,9 +340,9 @@ function addStudentTeacher() { |
| 318 | 340 | studentTeacher.value = { |
| 319 | 341 | name: '', |
| 320 | 342 | description: '', |
| 321 | - birthday: 0, | |
| 322 | - sex: 0, | |
| 323 | - enabled: false, | |
| 343 | + birthday: undefined, | |
| 344 | + sex: undefined, | |
| 345 | + enabled: undefined, | |
| 324 | 346 | avatar: '', |
| 325 | 347 | video: undefined, |
| 326 | 348 | memo: '', |
| ... | ... | @@ -429,11 +451,11 @@ async function handleSubmit() { |
| 429 | 451 | |
| 430 | 452 | formLoading.value = true |
| 431 | 453 | try { |
| 432 | - const data: Student = { | |
| 454 | + const data = { | |
| 433 | 455 | ...formData.value, |
| 434 | 456 | studentContacts: studentContacts.value, |
| 435 | 457 | studentTeacher: studentTeacher.value, |
| 436 | - } | |
| 458 | + } as Student | |
| 437 | 459 | if (props.id) { |
| 438 | 460 | await updateStudent(data) |
| 439 | 461 | toast.success('修改成功') | ... | ... |
yudao-module-infra/src/test/resources/codegen/vue3_admin_uniapp_one/vue/form/index
| ... | ... | @@ -65,13 +65,15 @@ |
| 65 | 65 | <yd-upload-img v-model="formData.avatar" directory="infra/demo" /> |
| 66 | 66 | </wd-form-item> |
| 67 | 67 | <wd-form-item title="附件" title-width="180rpx" prop="video"> |
| 68 | - <yd-upload-file v-model="formData.video" directory="infra/demo" /> | |
| 68 | + <yd-upload-file v-model="formData.video" :limit="1" directory="infra/demo" /> | |
| 69 | 69 | </wd-form-item> |
| 70 | 70 | <wd-form-item title="备注" title-width="180rpx" prop="memo"> |
| 71 | - <wd-input | |
| 71 | + <wd-textarea | |
| 72 | 72 | v-model="formData.memo" |
| 73 | 73 | clearable |
| 74 | 74 | placeholder="请输入备注" |
| 75 | + :maxlength="2000" | |
| 76 | + show-word-limit | |
| 75 | 77 | /> |
| 76 | 78 | </wd-form-item> |
| 77 | 79 | </wd-cell-group> |
| ... | ... | @@ -120,13 +122,13 @@ definePage({ |
| 120 | 122 | const toast = useToast() |
| 121 | 123 | const getTitle = computed(() => props.id ? '编辑学生' : '新增学生') |
| 122 | 124 | const formLoading = ref(false) // 表单提交状态 |
| 123 | -const formData = ref<Student>({ | |
| 125 | +const formData = ref<Partial<Student>>({ | |
| 124 | 126 | id: undefined, |
| 125 | 127 | name: '', |
| 126 | 128 | description: '', |
| 127 | - birthday: 0, | |
| 128 | - sex: 0, | |
| 129 | - enabled: false, | |
| 129 | + birthday: undefined, | |
| 130 | + sex: undefined, | |
| 131 | + enabled: undefined, | |
| 130 | 132 | avatar: '', |
| 131 | 133 | video: '', |
| 132 | 134 | memo: '', |
| ... | ... | @@ -166,7 +168,7 @@ async function handleSubmit() { |
| 166 | 168 | |
| 167 | 169 | formLoading.value = true |
| 168 | 170 | try { |
| 169 | - const data = formData.value | |
| 171 | + const data = formData.value as Student | |
| 170 | 172 | if (props.id) { |
| 171 | 173 | await updateStudent(data) |
| 172 | 174 | toast.success('修改成功') | ... | ... |
yudao-module-infra/src/test/resources/codegen/vue3_admin_uniapp_tree/vue/form/index
| ... | ... | @@ -71,7 +71,7 @@ definePage({ |
| 71 | 71 | const toast = useToast() |
| 72 | 72 | const getTitle = computed(() => props.id ? '编辑分类' : '新增分类') |
| 73 | 73 | const formLoading = ref(false) // 表单提交状态 |
| 74 | -const formData = ref<Category>({ | |
| 74 | +const formData = ref<Partial<Category>>({ | |
| 75 | 75 | id: undefined, |
| 76 | 76 | name: '', |
| 77 | 77 | parentId: props.parentId ?? 0, |
| ... | ... | @@ -105,7 +105,7 @@ async function handleSubmit() { |
| 105 | 105 | |
| 106 | 106 | formLoading.value = true |
| 107 | 107 | try { |
| 108 | - const data = formData.value | |
| 108 | + const data = formData.value as Category | |
| 109 | 109 | if (props.id) { |
| 110 | 110 | await updateCategory(data) |
| 111 | 111 | toast.success('修改成功') | ... | ... |