Commit 01bdb33696344439a349750f83db48d31b6e26fc

Authored by zhijiantianya@gmail.com
1 parent 90842542

代码生成器:进一步完善 erp 生成模版

yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/codegen/inner/CodegenEngine.java
@@ -337,7 +337,7 @@ public class CodegenEngine { @@ -337,7 +337,7 @@ public class CodegenEngine {
337 String subSimpleClassName = removePrefix(subTable.getClassName(), upperFirst(subTable.getModuleName())); 337 String subSimpleClassName = removePrefix(subTable.getClassName(), upperFirst(subTable.getModuleName()));
338 subSimpleClassNames.add(subSimpleClassName); 338 subSimpleClassNames.add(subSimpleClassName);
339 subClassNameVars.add(lowerFirst(subSimpleClassName)); // 将 DictType 转换成 dictType,用于变量 339 subClassNameVars.add(lowerFirst(subSimpleClassName)); // 将 DictType 转换成 dictType,用于变量
340 - subSimpleClassNameStrikeCases.add(toSymbolCase(simpleClassName, '-')); // 将 DictType 转换成 dict-type 340 + subSimpleClassNameStrikeCases.add(toSymbolCase(subSimpleClassName, '-')); // 将 DictType 转换成 dict-type
341 } 341 }
342 bindingMap.put("subPrimaryColumns", subPrimaryColumns); 342 bindingMap.put("subPrimaryColumns", subPrimaryColumns);
343 bindingMap.put("subJoinColumns", subJoinColumns); 343 bindingMap.put("subJoinColumns", subJoinColumns);
yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/controller/controller.vm
@@ -15,6 +15,7 @@ import javax.servlet.http.*; @@ -15,6 +15,7 @@ import javax.servlet.http.*;
15 import java.util.*; 15 import java.util.*;
16 import java.io.IOException; 16 import java.io.IOException;
17 17
  18 +import ${PageParamClassName};
18 import ${PageResultClassName}; 19 import ${PageResultClassName};
19 import ${CommonResultClassName}; 20 import ${CommonResultClassName};
20 import static ${CommonResultClassName}.success; 21 import static ${CommonResultClassName}.success;
@@ -175,7 +176,7 @@ public class ${sceneEnum.prefixClass}${table.className}Controller { @@ -175,7 +176,7 @@ public class ${sceneEnum.prefixClass}${table.className}Controller {
175 #if ($sceneEnum.scene == 1) 176 #if ($sceneEnum.scene == 1)
176 @PreAuthorize("@ss.hasPermission('${permissionPrefix}:update')") 177 @PreAuthorize("@ss.hasPermission('${permissionPrefix}:update')")
177 #end 178 #end
178 - public CommonResult<Booealn> update${subSimpleClassName}(@Valid @RequestBody ${subTable.className}DO ${subClassNameVar}) { 179 + public CommonResult<Boolean> update${subSimpleClassName}(@Valid @RequestBody ${subTable.className}DO ${subClassNameVar}) {
179 ${classNameVar}Service.update${subSimpleClassName}(${subClassNameVar}); 180 ${classNameVar}Service.update${subSimpleClassName}(${subClassNameVar});
180 return success(true); 181 return success(true);
181 } 182 }
@@ -186,8 +187,8 @@ public class ${sceneEnum.prefixClass}${table.className}Controller { @@ -186,8 +187,8 @@ public class ${sceneEnum.prefixClass}${table.className}Controller {
186 #if ($sceneEnum.scene == 1) 187 #if ($sceneEnum.scene == 1)
187 @PreAuthorize("@ss.hasPermission('${permissionPrefix}:delete')") 188 @PreAuthorize("@ss.hasPermission('${permissionPrefix}:delete')")
188 #end 189 #end
189 - public CommonResult<Booealn> delete${subSimpleClassName}(@RequestParam("id") ${subPrimaryColumn.javaType} id) {  
190 - ${classNameVar}Service.delete${subSimpleClassName}(${subClassNameVar}); 190 + public CommonResult<Boolean> delete${subSimpleClassName}(@RequestParam("id") ${subPrimaryColumn.javaType} id) {
  191 + ${classNameVar}Service.delete${subSimpleClassName}(id);
191 return success(true); 192 return success(true);
192 } 193 }
193 194
yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/controller/vo/baseVO.vm
@@ -42,7 +42,9 @@ public class ${sceneEnum.prefixClass}${table.className}BaseVO { @@ -42,7 +42,9 @@ public class ${sceneEnum.prefixClass}${table.className}BaseVO {
42 42
43 #end 43 #end
44 #end 44 #end
45 -## 特殊:主子表专属逻辑 45 +## 特殊:主子表专属逻辑(非 ERP 模式)
  46 +#if ( $subTables && $subTables.size() > 0 && $table.templateType != 11 )
  47 +
46 #foreach ($subTable in $subTables) 48 #foreach ($subTable in $subTables)
47 #set ($index = $foreach.count - 1) 49 #set ($index = $foreach.count - 1)
48 #if ( $subTable.subJoinMany) 50 #if ( $subTable.subJoinMany)
@@ -53,4 +55,5 @@ public class ${sceneEnum.prefixClass}${table.className}BaseVO { @@ -53,4 +55,5 @@ public class ${sceneEnum.prefixClass}${table.className}BaseVO {
53 55
54 #end 56 #end
55 #end 57 #end
  58 +#end
56 } 59 }
57 \ No newline at end of file 60 \ No newline at end of file
yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/service/service.vm
@@ -9,6 +9,7 @@ import ${basePackage}.module.${table.moduleName}.dal.dataobject.${table.business @@ -9,6 +9,7 @@ import ${basePackage}.module.${table.moduleName}.dal.dataobject.${table.business
9 import ${basePackage}.module.${subTable.moduleName}.dal.dataobject.${subTable.businessName}.${subTable.className}DO; 9 import ${basePackage}.module.${subTable.moduleName}.dal.dataobject.${subTable.businessName}.${subTable.className}DO;
10 #end 10 #end
11 import ${PageResultClassName}; 11 import ${PageResultClassName};
  12 +import ${PageParamClassName};
12 13
13 /** 14 /**
14 * ${table.classComment} Service 接口 15 * ${table.classComment} Service 接口
@@ -83,7 +84,7 @@ public interface ${table.className}Service { @@ -83,7 +84,7 @@ public interface ${table.className}Service {
83 * @param ${subJoinColumn.javaField} ${subJoinColumn.columnComment} 84 * @param ${subJoinColumn.javaField} ${subJoinColumn.columnComment}
84 * @return ${subTable.classComment}分页 85 * @return ${subTable.classComment}分页
85 */ 86 */
86 - PageResult<${subTable.className}DO> get${subSimpleClassName}Page(PageParam pageReqVO, ${subJoinColumn.javaType} ${subJoinColumn.javaField}) 87 + PageResult<${subTable.className}DO> get${subSimpleClassName}Page(PageParam pageReqVO, ${subJoinColumn.javaType} ${subJoinColumn.javaField});
87 88
88 ## 情况二:非 MASTER_ERP 时,需要列表查询子表 89 ## 情况二:非 MASTER_ERP 时,需要列表查询子表
89 #else 90 #else
yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/service/serviceImpl.vm
@@ -13,6 +13,7 @@ import ${basePackage}.module.${table.moduleName}.dal.dataobject.${table.business @@ -13,6 +13,7 @@ import ${basePackage}.module.${table.moduleName}.dal.dataobject.${table.business
13 import ${basePackage}.module.${subTable.moduleName}.dal.dataobject.${subTable.businessName}.${subTable.className}DO; 13 import ${basePackage}.module.${subTable.moduleName}.dal.dataobject.${subTable.businessName}.${subTable.className}DO;
14 #end 14 #end
15 import ${PageResultClassName}; 15 import ${PageResultClassName};
  16 +import ${PageParamClassName};
16 17
17 import ${basePackage}.module.${table.moduleName}.convert.${table.businessName}.${table.className}Convert; 18 import ${basePackage}.module.${table.moduleName}.convert.${table.businessName}.${table.className}Convert;
18 import ${basePackage}.module.${table.moduleName}.dal.mysql.${table.businessName}.${table.className}Mapper; 19 import ${basePackage}.module.${table.moduleName}.dal.mysql.${table.businessName}.${table.className}Mapper;
@@ -44,16 +45,16 @@ public class ${table.className}ServiceImpl implements ${table.className}Service @@ -44,16 +45,16 @@ public class ${table.className}ServiceImpl implements ${table.className}Service
44 #end 45 #end
45 46
46 @Override 47 @Override
47 -## 特殊:主子表专属逻辑  
48 -#if ( $subTables && $subTables.size() > 0 ) 48 +## 特殊:主子表专属逻辑(非 ERP 模式)
  49 +#if ( $subTables && $subTables.size() > 0 && $table.templateType != 11 )
49 @Transactional(rollbackFor = Exception.class) 50 @Transactional(rollbackFor = Exception.class)
50 #end 51 #end
51 public ${primaryColumn.javaType} create${simpleClassName}(${sceneEnum.prefixClass}${table.className}CreateReqVO createReqVO) { 52 public ${primaryColumn.javaType} create${simpleClassName}(${sceneEnum.prefixClass}${table.className}CreateReqVO createReqVO) {
52 // 插入 53 // 插入
53 ${table.className}DO ${classNameVar} = ${table.className}Convert.INSTANCE.convert(createReqVO); 54 ${table.className}DO ${classNameVar} = ${table.className}Convert.INSTANCE.convert(createReqVO);
54 ${classNameVar}Mapper.insert(${classNameVar}); 55 ${classNameVar}Mapper.insert(${classNameVar});
55 -## 特殊:主子表专属逻辑  
56 -#if ( $subTables && $subTables.size() > 0) 56 +## 特殊:主子表专属逻辑(非 ERP 模式)
  57 +#if ( $subTables && $subTables.size() > 0 && $table.templateType != 11 )
57 58
58 // 插入子表 59 // 插入子表
59 #foreach ($subTable in $subTables) 60 #foreach ($subTable in $subTables)
@@ -73,8 +74,8 @@ public class ${table.className}ServiceImpl implements ${table.className}Service @@ -73,8 +74,8 @@ public class ${table.className}ServiceImpl implements ${table.className}Service
73 } 74 }
74 75
75 @Override 76 @Override
76 -## 特殊:主子表专属逻辑  
77 -#if ( $subTables && $subTables.size() > 0) 77 +## 特殊:主子表专属逻辑(非 ERP 模式)
  78 +#if ( $subTables && $subTables.size() > 0 && $table.templateType != 11 )
78 @Transactional(rollbackFor = Exception.class) 79 @Transactional(rollbackFor = Exception.class)
79 #end 80 #end
80 public void update${simpleClassName}(${sceneEnum.prefixClass}${table.className}UpdateReqVO updateReqVO) { 81 public void update${simpleClassName}(${sceneEnum.prefixClass}${table.className}UpdateReqVO updateReqVO) {
@@ -83,8 +84,8 @@ public class ${table.className}ServiceImpl implements ${table.className}Service @@ -83,8 +84,8 @@ public class ${table.className}ServiceImpl implements ${table.className}Service
83 // 更新 84 // 更新
84 ${table.className}DO updateObj = ${table.className}Convert.INSTANCE.convert(updateReqVO); 85 ${table.className}DO updateObj = ${table.className}Convert.INSTANCE.convert(updateReqVO);
85 ${classNameVar}Mapper.updateById(updateObj); 86 ${classNameVar}Mapper.updateById(updateObj);
86 -## 特殊:主子表专属逻辑  
87 -#if ( $subTables && $subTables.size() > 0) 87 +## 特殊:主子表专属逻辑(非 ERP 模式)
  88 +#if ( $subTables && $subTables.size() > 0 && $table.templateType != 11)
88 89
89 // 更新子表 90 // 更新子表
90 #foreach ($subTable in $subTables) 91 #foreach ($subTable in $subTables)
@@ -182,13 +183,13 @@ public class ${table.className}ServiceImpl implements ${table.className}Service @@ -182,13 +183,13 @@ public class ${table.className}ServiceImpl implements ${table.className}Service
182 ## 情况一:MASTER_ERP 时,支持单个的新增、修改、删除操作 183 ## 情况一:MASTER_ERP 时,支持单个的新增、修改、删除操作
183 #if ( $table.templateType == 11 ) 184 #if ( $table.templateType == 11 )
184 @Override 185 @Override
185 - public ${subPrimaryColumn.javaType} create${subSimpleClassName}(@Valid ${subTable.className}DO ${subClassNameVar}) { 186 + public ${subPrimaryColumn.javaType} create${subSimpleClassName}(${subTable.className}DO ${subClassNameVar}) {
186 ${subClassNameVars.get($index)}Mapper.insert(${subClassNameVar}); 187 ${subClassNameVars.get($index)}Mapper.insert(${subClassNameVar});
187 return ${subClassNameVar}.getId(); 188 return ${subClassNameVar}.getId();
188 } 189 }
189 190
190 @Override 191 @Override
191 - public void update${subSimpleClassName}(@Valid ${subTable.className}DO ${subClassNameVar}) { 192 + public void update${subSimpleClassName}(${subTable.className}DO ${subClassNameVar}) {
192 ${subClassNameVars.get($index)}Mapper.updateById(${subClassNameVar}); 193 ${subClassNameVars.get($index)}Mapper.updateById(${subClassNameVar});
193 } 194 }
194 195
@@ -230,10 +231,10 @@ public class ${table.className}ServiceImpl implements ${table.className}Service @@ -230,10 +231,10 @@ public class ${table.className}ServiceImpl implements ${table.className}Service
230 } 231 }
231 232
232 #end 233 #end
  234 +#end
233 private void delete${subSimpleClassName}By${SubJoinColumnName}(${primaryColumn.javaType} ${subJoinColumn.javaField}) { 235 private void delete${subSimpleClassName}By${SubJoinColumnName}(${primaryColumn.javaType} ${subJoinColumn.javaField}) {
234 ${subClassNameVars.get($index)}Mapper.deleteBy${SubJoinColumnName}(${subJoinColumn.javaField}); 236 ${subClassNameVars.get($index)}Mapper.deleteBy${SubJoinColumnName}(${subJoinColumn.javaField});
235 } 237 }
236 238
237 #end 239 #end
238 -#end  
239 } 240 }
240 \ No newline at end of file 241 \ No newline at end of file
yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3/views/components/_column.vm deleted
1 -## 提供给 baseVO、createVO、updateVO 生成字段  
2 - @Schema(description = "${column.columnComment}"#if (!${column.nullable}), requiredMode = Schema.RequiredMode.REQUIRED#end#if ("$!column.example" != ""), example = "${column.example}"#end)  
3 -#if (!${column.nullable})## 判断 @NotEmpty 和 @NotNull 注解  
4 -#if (${column.javaType} == 'String')  
5 - @NotEmpty(message = "${column.columnComment}不能为空")  
6 -#else  
7 - @NotNull(message = "${column.columnComment}不能为空")  
8 -#end  
9 -#end  
10 -#if (${column.javaType} == "LocalDateTime")## 时间类型  
11 - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)  
12 -#end  
13 - private ${column.javaType} ${column.javaField};  
yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3/views/components/form_sub_erp.vue.vm
  1 +#set ($subColumns = $subColumnsList.get($subIndex))##当前字段数组
  2 +#set ($subSimpleClassName = $subSimpleClassNames.get($subIndex))
  3 +#set ($subJoinColumn = $subJoinColumns.get($subIndex))##当前 join 字段
  4 +<template>
  5 + <Dialog :title="dialogTitle" v-model="dialogVisible">
  6 + <el-form
  7 + ref="formRef"
  8 + :model="formData"
  9 + :rules="formRules"
  10 + label-width="100px"
  11 + v-loading="formLoading"
  12 + >
  13 +#foreach($column in $subColumns)
  14 + #if ($column.createOperation || $column.updateOperation)
  15 + #set ($dictType = $column.dictType)
  16 + #set ($javaField = $column.javaField)
  17 + #set ($javaType = $column.javaType)
  18 + #set ($AttrName = $column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
  19 + #set ($comment = $column.columnComment)
  20 + #set ($dictMethod = "getDictOptions")## 计算使用哪个 dict 字典方法
  21 + #if ($javaType == "Integer" || $javaType == "Long" || $javaType == "Byte" || $javaType == "Short")
  22 + #set ($dictMethod = "getIntDictOptions")
  23 + #elseif ($javaType == "String")
  24 + #set ($dictMethod = "getStrDictOptions")
  25 + #elseif ($javaType == "Boolean")
  26 + #set ($dictMethod = "getBoolDictOptions")
  27 + #end
  28 + #if ($column.htmlType == "input" && !$column.primaryKey)## 忽略主键,不用在表单里 TODO 芋艿:这里要忽略下 join 字段;
  29 + <el-form-item label="${comment}" prop="${javaField}">
  30 + <el-input v-model="formData.${javaField}" placeholder="请输入${comment}" />
  31 + </el-form-item>
  32 + #elseif($column.htmlType == "imageUpload")## 图片上传
  33 + <el-form-item label="${comment}">
  34 + <UploadImg v-model="formData.${javaField}" />
  35 + </el-form-item>
  36 + #elseif($column.htmlType == "fileUpload")## 文件上传
  37 + <el-form-item label="${comment}" prop="${javaField}">
  38 + <UploadFile v-model="formData.${javaField}" />
  39 + </el-form-item>
  40 + #elseif($column.htmlType == "editor")## 文本编辑器
  41 + <el-form-item label="${comment}" prop="${javaField}">
  42 + <Editor v-model="formData.${javaField}" height="150px" />
  43 + </el-form-item>
  44 + #elseif($column.htmlType == "select")## 下拉框
  45 + <el-form-item label="${comment}" prop="${javaField}">
  46 + <el-select v-model="formData.${javaField}" placeholder="请选择${comment}">
  47 + #if ("" != $dictType)## 有数据字典
  48 + <el-option
  49 + v-for="dict in $dictMethod(DICT_TYPE.$dictType.toUpperCase())"
  50 + :key="dict.value"
  51 + :label="dict.label"
  52 + :value="dict.value"
  53 + />
  54 + #else##没数据字典
  55 + <el-option label="请选择字典生成" value="" />
  56 + #end
  57 + </el-select>
  58 + </el-form-item>
  59 + #elseif($column.htmlType == "checkbox")## 多选框
  60 + <el-form-item label="${comment}" prop="${javaField}">
  61 + <el-checkbox-group v-model="formData.${javaField}">
  62 + #if ("" != $dictType)## 有数据字典
  63 + <el-checkbox
  64 + v-for="dict in $dictMethod(DICT_TYPE.$dictType.toUpperCase())"
  65 + :key="dict.value"
  66 + :label="dict.value"
  67 + >
  68 + {{ dict.label }}
  69 + </el-checkbox>
  70 + #else##没数据字典
  71 + <el-checkbox>请选择字典生成</el-checkbox>
  72 + #end
  73 + </el-checkbox-group>
  74 + </el-form-item>
  75 + #elseif($column.htmlType == "radio")## 单选框
  76 + <el-form-item label="${comment}" prop="${javaField}">
  77 + <el-radio-group v-model="formData.${javaField}">
  78 + #if ("" != $dictType)## 有数据字典
  79 + <el-radio
  80 + v-for="dict in $dictMethod(DICT_TYPE.$dictType.toUpperCase())"
  81 + :key="dict.value"
  82 + :label="dict.value"
  83 + >
  84 + {{ dict.label }}
  85 + </el-radio>
  86 + #else##没数据字典
  87 + <el-radio label="1">请选择字典生成</el-radio>
  88 + #end
  89 + </el-radio-group>
  90 + </el-form-item>
  91 + #elseif($column.htmlType == "datetime")## 时间框
  92 + <el-form-item label="${comment}" prop="${javaField}">
  93 + <el-date-picker
  94 + v-model="formData.${javaField}"
  95 + type="date"
  96 + value-format="x"
  97 + placeholder="选择${comment}"
  98 + />
  99 + </el-form-item>
  100 + #elseif($column.htmlType == "textarea")## 文本框
  101 + <el-form-item label="${comment}" prop="${javaField}">
  102 + <el-input v-model="formData.${javaField}" type="textarea" placeholder="请输入${comment}" />
  103 + </el-form-item>
  104 + #end
  105 + #end
  106 +#end
  107 + </el-form>
  108 + <template #footer>
  109 + <el-button @click="submitForm" type="primary" :disabled="formLoading">确 定</el-button>
  110 + <el-button @click="dialogVisible = false">取 消</el-button>
  111 + </template>
  112 + </Dialog>
  113 +</template>
  114 +<script setup lang="ts">
  115 +import { getIntDictOptions, getStrDictOptions, getBoolDictOptions, DICT_TYPE } from '@/utils/dict'
  116 +import * as ${simpleClassName}Api from '@/api/${table.moduleName}/${table.businessName}'
  117 +
  118 +const { t } = useI18n() // 国际化
  119 +const message = useMessage() // 消息弹窗
  120 +
  121 +const dialogVisible = ref(false) // 弹窗的是否展示
  122 +const dialogTitle = ref('') // 弹窗的标题
  123 +const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
  124 +const formType = ref('') // 表单的类型:create - 新增;update - 修改
  125 +const formData = ref({
  126 +#foreach ($column in $subColumns)
  127 + #if ($column.createOperation || $column.updateOperation)
  128 + #if ($column.htmlType == "checkbox")
  129 + $column.javaField: [],
  130 + #else
  131 + $column.javaField: undefined,
  132 + #end
  133 + #end
  134 +#end
  135 +})
  136 +const formRules = reactive({
  137 +#foreach ($column in $subColumns)
  138 + #if (($column.createOperation || $column.updateOperation) && !$column.nullable && !${column.primaryKey})## 创建或者更新操作 && 要求非空 && 非主键
  139 + #set($comment=$column.columnComment)
  140 + $column.javaField: [{ required: true, message: '${comment}不能为空', trigger: #if($column.htmlType == 'select')'change'#else'blur'#end }],
  141 + #end
  142 +#end
  143 +})
  144 +const formRef = ref() // 表单 Ref
  145 +
  146 +/** 打开弹窗 */
  147 +const open = async (type: string, id?: number, ${subJoinColumn.javaField}: number) => {
  148 + dialogVisible.value = true
  149 + dialogTitle.value = t('action.' + type)
  150 + formType.value = type
  151 + resetForm()
  152 + formData.${subJoinColumn.javaField} = ${subJoinColumn.javaField}
  153 + // 修改时,设置数据
  154 + if (id) {
  155 + formLoading.value = true
  156 + try {
  157 + formData.value = await ${simpleClassName}Api.get${subSimpleClassName}(id)
  158 + } finally {
  159 + formLoading.value = false
  160 + }
  161 + }
  162 +}
  163 +defineExpose({ open }) // 提供 open 方法,用于打开弹窗
  164 +
  165 +/** 提交表单 */
  166 +const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
  167 +const submitForm = async () => {
  168 + // 校验表单
  169 + await formRef.value.validate()
  170 + // 提交请求
  171 + formLoading.value = true
  172 + try {
  173 + const data = formData.value
  174 + if (formType.value === 'create') {
  175 + await ${simpleClassName}Api.create${subSimpleClassName}(data)
  176 + message.success(t('common.createSuccess'))
  177 + } else {
  178 + await ${simpleClassName}Api.update${subSimpleClassName}(data)
  179 + message.success(t('common.updateSuccess'))
  180 + }
  181 + dialogVisible.value = false
  182 + // 发送操作成功的事件
  183 + emit('success')
  184 + } finally {
  185 + formLoading.value = false
  186 + }
  187 +}
  188 +
  189 +/** 重置表单 */
  190 +const resetForm = () => {
  191 + formData.value = {
  192 +#foreach ($column in $subColumns)
  193 + #if ($column.createOperation || $column.updateOperation)
  194 + #if ($column.htmlType == "checkbox")
  195 + $column.javaField: [],
  196 + #else
  197 + $column.javaField: undefined,
  198 + #end
  199 + #end
  200 +#end
  201 + }
  202 + formRef.value?.resetFields()
  203 +}
  204 +</script>
0 \ No newline at end of file 205 \ No newline at end of file
yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3/views/components/form_sub_inner.vue.vm
1 ## 主表的 normal 和 inner 使用相同的 form 表单 1 ## 主表的 normal 和 inner 使用相同的 form 表单
2 -#parse("codegen/vue3/views/components/form_sub_inner.vue.vm")  
3 \ No newline at end of file 2 \ No newline at end of file
  3 +#parse("codegen/vue3/views/components/form_sub_normal.vue.vm")
4 \ No newline at end of file 4 \ No newline at end of file
yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3/views/components/list_sub_erp.vue.vm
@@ -7,6 +7,14 @@ @@ -7,6 +7,14 @@
7 <template> 7 <template>
8 <!-- 列表 --> 8 <!-- 列表 -->
9 <ContentWrap> 9 <ContentWrap>
  10 + <el-button
  11 + type="primary"
  12 + plain
  13 + @click="openForm('create')"
  14 + v-hasPermi="['${permissionPrefix}:create']"
  15 + >
  16 + <Icon icon="ep:plus" class="mr-5px" /> 新增
  17 + </el-button>
10 <el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true"> 18 <el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
11 #foreach($column in $subColumns) 19 #foreach($column in $subColumns)
12 #if ($column.listOperationResult) 20 #if ($column.listOperationResult)
@@ -66,27 +74,56 @@ @@ -66,27 +74,56 @@
66 /> 74 />
67 #end 75 #end
68 </ContentWrap> 76 </ContentWrap>
  77 +
  78 + <!-- 表单弹窗:添加/修改 -->
  79 + <${subSimpleClassName}Form ref="formRef" @success="getList" />
69 </template> 80 </template>
70 81
71 <script setup lang="ts"> 82 <script setup lang="ts">
72 import { getIntDictOptions, getStrDictOptions, getBoolDictOptions, DICT_TYPE } from '@/utils/dict' 83 import { getIntDictOptions, getStrDictOptions, getBoolDictOptions, DICT_TYPE } from '@/utils/dict'
73 import * as ${simpleClassName}Api from '@/api/${table.moduleName}/${table.businessName}' 84 import * as ${simpleClassName}Api from '@/api/${table.moduleName}/${table.businessName}'
  85 +import ${subSimpleClassName}Form from './${subSimpleClassName}Form.vue'
  86 +
  87 +const { t } = useI18n() // 国际化
  88 +const message = useMessage() // 消息弹窗
  89 +
74 const props = defineProps<{ 90 const props = defineProps<{
75 ${subJoinColumn.javaField}: undefined // ${subJoinColumn.columnComment}(主表的关联字段) 91 ${subJoinColumn.javaField}: undefined // ${subJoinColumn.columnComment}(主表的关联字段)
76 }>() 92 }>()
77 -const loading = ref(true) // 列表的加载中 93 +const loading = ref(false) // 列表的加载中
78 const list = ref([]) // 列表的数据 94 const list = ref([]) // 列表的数据
  95 +#if ($table.templateType == 11)
  96 +const total = ref(0) // 列表的总页数
  97 +const queryParams = reactive({
  98 + pageNo: 1,
  99 + pageSize: 10,
  100 + ${subJoinColumn.javaField}: undefined
  101 +})
  102 +
  103 +/** 监听主表的关联字段的变化,加载对应的子表数据 */
  104 +watch(
  105 + () => props.${subJoinColumn.javaField},
  106 + (val) => {
  107 + queryParams.${subJoinColumn.javaField} = val
  108 + handleQuery()
  109 + },
  110 + { immediate: false }
  111 +)
  112 +#end
79 113
80 /** 查询列表 */ 114 /** 查询列表 */
81 const getList = async () => { 115 const getList = async () => {
82 loading.value = true 116 loading.value = true
83 try { 117 try {
84 #if ($table.templateType == 11) 118 #if ($table.templateType == 11)
  119 + const data = await ${simpleClassName}Api.get${subSimpleClassName}Page(queryParams)
  120 + list.value = data.list
  121 + total.value = data.total
85 #else 122 #else
86 #if ( $subTable.subJoinMany ) 123 #if ( $subTable.subJoinMany )
87 - list.value = await ${simpleClassName}Api.get${subSimpleClassName}ListBy${SubJoinColumnName}(${subJoinColumn.javaField}.props) 124 + list.value = await ${simpleClassName}Api.get${subSimpleClassName}ListBy${SubJoinColumnName}(props.${subJoinColumn.javaField})
88 #else 125 #else
89 - const data = await ${simpleClassName}Api.get${subSimpleClassName}By${SubJoinColumnName}(${subJoinColumn.javaField}.props) 126 + const data = await ${simpleClassName}Api.get${subSimpleClassName}By${SubJoinColumnName}(props.${subJoinColumn.javaField})
90 if (!data) { 127 if (!data) {
91 return 128 return
92 } 129 }
@@ -98,8 +135,41 @@ const getList = async () =&gt; { @@ -98,8 +135,41 @@ const getList = async () =&gt; {
98 } 135 }
99 } 136 }
100 137
  138 +/** 搜索按钮操作 */
  139 +const handleQuery = () => {
  140 + queryParams.pageNo = 1
  141 + getList()
  142 +}
  143 +#if ($table.templateType == 11)
  144 +
  145 +/** 添加/修改操作 */
  146 +const formRef = ref()
  147 +const openForm = (type: string, id?: number) => {
  148 + if (!props.${subJoinColumn.javaField}) {
  149 + message.error('请选择一个${table.classComment}')
  150 + return
  151 + }
  152 + formRef.value.open(type, id, props.${subJoinColumn.javaField})
  153 +}
  154 +
  155 +/** 删除按钮操作 */
  156 +const handleDelete = async (id: number) => {
  157 + try {
  158 + // 删除的二次确认
  159 + await message.delConfirm()
  160 + // 发起删除
  161 + await ${simpleClassName}Api.delete${subSimpleClassName}(id)
  162 + message.success(t('common.delSuccess'))
  163 + // 刷新列表
  164 + await getList()
  165 + } catch {}
  166 +}
  167 +#end
  168 +#if ($table.templateType != 11)
  169 +
101 /** 初始化 **/ 170 /** 初始化 **/
102 onMounted(() => { 171 onMounted(() => {
103 getList() 172 getList()
104 }) 173 })
  174 +#end
105 </script> 175 </script>
106 \ No newline at end of file 176 \ No newline at end of file
yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3/views/index.vue.vm
  1 +#set ($subTable = $subTables.get($subIndex))##当前表
  2 +#set ($subColumns = $subColumnsList.get($subIndex))##当前字段数组
  3 +#set ($subJoinColumn = $subJoinColumns.get($subIndex))##当前 join 字段
  4 +#set ($subSimpleClassName = $subSimpleClassNames.get($subIndex))
  5 +#set ($subJoinColumn = $subJoinColumns.get($subIndex))##当前 join 字段
  6 +#set ($SubJoinColumnName = $subJoinColumn.javaField.substring(0,1).toUpperCase() + ${subJoinColumn.javaField.substring(1)})##首字母大写
1 <template> 7 <template>
2 - <ContentWrap>  
3 - <!-- 搜索工作栏 -->  
4 - <el-form  
5 - class="-mb-15px"  
6 - :model="queryParams"  
7 - ref="queryFormRef"  
8 - :inline="true"  
9 - label-width="68px"  
10 - >  
11 - #foreach($column in $columns)  
12 - #if ($column.listOperation)  
13 - #set ($dictType = $column.dictType)  
14 - #set ($javaField = $column.javaField)  
15 - #set ($javaType = $column.javaType)  
16 - #set ($AttrName = $column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})  
17 - #set ($comment = $column.columnComment)  
18 - #set ($dictMethod = "getDictOptions")## 计算使用哪个 dict 字典方法  
19 - #if ($javaType == "Integer" || $javaType == "Long" || $javaType == "Byte" || $javaType == "Short")  
20 - #set ($dictMethod = "getIntDictOptions")  
21 - #elseif ($javaType == "String")  
22 - #set ($dictMethod = "getStrDictOptions")  
23 - #elseif ($javaType == "Boolean")  
24 - #set ($dictMethod = "getBoolDictOptions")  
25 - #end  
26 - #if ($column.htmlType == "input")  
27 - <el-form-item label="${comment}" prop="${javaField}">  
28 - <el-input  
29 - v-model="queryParams.${javaField}"  
30 - placeholder="请输入${comment}"  
31 - clearable  
32 - @keyup.enter="handleQuery"  
33 - class="!w-240px"  
34 - />  
35 - </el-form-item>  
36 - #elseif ($column.htmlType == "select" || $column.htmlType == "radio")  
37 - <el-form-item label="${comment}" prop="${javaField}">  
38 - <el-select  
39 - v-model="queryParams.${javaField}"  
40 - placeholder="请选择${comment}"  
41 - clearable  
42 - class="!w-240px"  
43 - >  
44 - #if ("" != $dictType)## 设置了 dictType 数据字典的情况  
45 - <el-option  
46 - v-for="dict in $dictMethod(DICT_TYPE.$dictType.toUpperCase())"  
47 - :key="dict.value"  
48 - :label="dict.label"  
49 - :value="dict.value"  
50 - />  
51 - #else## 未设置 dictType 数据字典的情况  
52 - <el-option label="请选择字典生成" value="" />  
53 - #end  
54 - </el-select>  
55 - </el-form-item>  
56 - #elseif($column.htmlType == "datetime")  
57 - #if ($column.listOperationCondition != "BETWEEN")## 非范围  
58 - <el-form-item label="${comment}" prop="${javaField}">  
59 - <el-date-picker  
60 - v-model="queryParams.${javaField}"  
61 - value-format="YYYY-MM-DD"  
62 - type="date"  
63 - placeholder="选择${comment}"  
64 - clearable  
65 - class="!w-240px"  
66 - />  
67 - </el-form-item>  
68 - #else## 范围  
69 - <el-form-item label="${comment}" prop="${javaField}">  
70 - <el-date-picker  
71 - v-model="queryParams.${javaField}"  
72 - value-format="YYYY-MM-DD HH:mm:ss"  
73 - type="daterange"  
74 - start-placeholder="开始日期"  
75 - end-placeholder="结束日期"  
76 - :default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"  
77 - class="!w-240px"  
78 - />  
79 - </el-form-item>  
80 - #end  
81 - #end  
82 - #end  
83 - #end  
84 - <el-form-item>  
85 - <el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>  
86 - <el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>  
87 - <el-button  
88 - type="primary"  
89 - plain  
90 - @click="openForm('create')"  
91 - v-hasPermi="['${permissionPrefix}:create']"  
92 - >  
93 - <Icon icon="ep:plus" class="mr-5px" /> 新增  
94 - </el-button>  
95 - <el-button  
96 - type="success"  
97 - plain  
98 - @click="handleExport"  
99 - :loading="exportLoading"  
100 - v-hasPermi="['${permissionPrefix}:export']"  
101 - >  
102 - <Icon icon="ep:download" class="mr-5px" /> 导出  
103 - </el-button>  
104 - </el-form-item>  
105 - </el-form>  
106 - </ContentWrap>  
107 -  
108 <!-- 列表 --> 8 <!-- 列表 -->
109 <ContentWrap> 9 <ContentWrap>
  10 + <el-button
  11 + type="primary"
  12 + plain
  13 + @click="openForm('create')"
  14 + v-hasPermi="['${permissionPrefix}:create']"
  15 + >
  16 + <Icon icon="ep:plus" class="mr-5px" /> 新增
  17 + </el-button>
110 <el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true"> 18 <el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
111 - #foreach($column in $columns) 19 + #foreach($column in $subColumns)
112 #if ($column.listOperationResult) 20 #if ($column.listOperationResult)
113 #set ($dictType=$column.dictType) 21 #set ($dictType=$column.dictType)
114 #set ($javaField = $column.javaField) 22 #set ($javaField = $column.javaField)
@@ -133,6 +41,7 @@ @@ -133,6 +41,7 @@
133 #end 41 #end
134 #end 42 #end
135 #end 43 #end
  44 + #if ($table.templateType == 11)
136 <el-table-column label="操作" align="center"> 45 <el-table-column label="操作" align="center">
137 <template #default="scope"> 46 <template #default="scope">
138 <el-button 47 <el-button
@@ -153,7 +62,9 @@ @@ -153,7 +62,9 @@
153 </el-button> 62 </el-button>
154 </template> 63 </template>
155 </el-table-column> 64 </el-table-column>
  65 + #end
156 </el-table> 66 </el-table>
  67 + #if ($table.templateType == 11)
157 <!-- 分页 --> 68 <!-- 分页 -->
158 <Pagination 69 <Pagination
159 :total="total" 70 :total="total"
@@ -161,51 +72,64 @@ @@ -161,51 +72,64 @@
161 v-model:limit="queryParams.pageSize" 72 v-model:limit="queryParams.pageSize"
162 @pagination="getList" 73 @pagination="getList"
163 /> 74 />
  75 + #end
164 </ContentWrap> 76 </ContentWrap>
165 77
166 - <!-- 表单弹窗:添加/修改 -->  
167 - <${simpleClassName}Form ref="formRef" @success="getList" /> 78 + <!-- 表单弹窗:添加/修改 -->
  79 + <${subSimpleClassName}Form ref="formRef" @success="getList" />
168 </template> 80 </template>
169 81
170 <script setup lang="ts"> 82 <script setup lang="ts">
171 import { getIntDictOptions, getStrDictOptions, getBoolDictOptions, DICT_TYPE } from '@/utils/dict' 83 import { getIntDictOptions, getStrDictOptions, getBoolDictOptions, DICT_TYPE } from '@/utils/dict'
172 -import { dateFormatter } from '@/utils/formatTime'  
173 -import download from '@/utils/download'  
174 import * as ${simpleClassName}Api from '@/api/${table.moduleName}/${table.businessName}' 84 import * as ${simpleClassName}Api from '@/api/${table.moduleName}/${table.businessName}'
175 -import ${simpleClassName}Form from './${simpleClassName}Form.vue'  
176 -  
177 -defineOptions({ name: '${table.className}' }) 85 +import ${subSimpleClassName}Form from './${subSimpleClassName}Form.vue'
178 86
179 -const message = useMessage() // 消息弹窗  
180 const { t } = useI18n() // 国际化 87 const { t } = useI18n() // 国际化
  88 +const message = useMessage() // 消息弹窗
181 89
182 -const loading = ref(true) // 列表的加载中  
183 -const total = ref(0) // 列表的总页数 90 +const props = defineProps<{
  91 + ${subJoinColumn.javaField}: undefined // ${subJoinColumn.columnComment}(主表的关联字段)
  92 +}>()
  93 +const loading = ref(false) // 列表的加载中
184 const list = ref([]) // 列表的数据 94 const list = ref([]) // 列表的数据
  95 +#if ($table.templateType == 11)
  96 +const total = ref(0) // 列表的总页数
185 const queryParams = reactive({ 97 const queryParams = reactive({
186 pageNo: 1, 98 pageNo: 1,
187 pageSize: 10, 99 pageSize: 10,
188 - #foreach ($column in $columns)  
189 - #if ($column.listOperation)  
190 - #if ($column.listOperationCondition != 'BETWEEN')  
191 - $column.javaField: null,  
192 - #end  
193 - #if ($column.htmlType == "datetime" || $column.listOperationCondition == "BETWEEN")  
194 - $column.javaField: [],  
195 - #end  
196 - #end  
197 - #end 100 + ${subJoinColumn.javaField}: undefined
198 }) 101 })
199 -const queryFormRef = ref() // 搜索的表单  
200 -const exportLoading = ref(false) // 导出的加载中 102 +
  103 +/** 监听主表的关联字段的变化,加载对应的子表数据 */
  104 +watch(
  105 + () => props.${subJoinColumn.javaField},
  106 + (val) => {
  107 + queryParams.${subJoinColumn.javaField} = val
  108 + handleQuery()
  109 + },
  110 + { immediate: false }
  111 +)
  112 +#end
201 113
202 /** 查询列表 */ 114 /** 查询列表 */
203 const getList = async () => { 115 const getList = async () => {
204 loading.value = true 116 loading.value = true
205 try { 117 try {
206 - const data = await ${simpleClassName}Api.get${simpleClassName}Page(queryParams) 118 +#if ($table.templateType == 11)
  119 + const data = await ${simpleClassName}Api.get${subSimpleClassName}Page(queryParams)
207 list.value = data.list 120 list.value = data.list
208 total.value = data.total 121 total.value = data.total
  122 +#else
  123 + #if ( $subTable.subJoinMany )
  124 + list.value = await ${simpleClassName}Api.get${subSimpleClassName}ListBy${SubJoinColumnName}(props.${subJoinColumn.javaField})
  125 + #else
  126 + const data = await ${simpleClassName}Api.get${subSimpleClassName}By${SubJoinColumnName}(props.${subJoinColumn.javaField})
  127 + if (!data) {
  128 + return
  129 + }
  130 + list.value.push(data)
  131 + #end
  132 +#end
209 } finally { 133 } finally {
210 loading.value = false 134 loading.value = false
211 } 135 }
@@ -216,17 +140,16 @@ const handleQuery = () =&gt; { @@ -216,17 +140,16 @@ const handleQuery = () =&gt; {
216 queryParams.pageNo = 1 140 queryParams.pageNo = 1
217 getList() 141 getList()
218 } 142 }
219 -  
220 -/** 重置按钮操作 */  
221 -const resetQuery = () => {  
222 - queryFormRef.value.resetFields()  
223 - handleQuery()  
224 -} 143 +#if ($table.templateType == 11)
225 144
226 /** 添加/修改操作 */ 145 /** 添加/修改操作 */
227 const formRef = ref() 146 const formRef = ref()
228 const openForm = (type: string, id?: number) => { 147 const openForm = (type: string, id?: number) => {
229 - formRef.value.open(type, id) 148 + if (!props.${subJoinColumn.javaField}) {
  149 + message.error('请选择一个${table.classComment}')
  150 + return
  151 + }
  152 + formRef.value.open(type, id, props.${subJoinColumn.javaField})
230 } 153 }
231 154
232 /** 删除按钮操作 */ 155 /** 删除按钮操作 */
@@ -235,30 +158,18 @@ const handleDelete = async (id: number) =&gt; { @@ -235,30 +158,18 @@ const handleDelete = async (id: number) =&gt; {
235 // 删除的二次确认 158 // 删除的二次确认
236 await message.delConfirm() 159 await message.delConfirm()
237 // 发起删除 160 // 发起删除
238 - await ${simpleClassName}Api.delete${simpleClassName}(id) 161 + await ${simpleClassName}Api.delete${subSimpleClassName}(id)
239 message.success(t('common.delSuccess')) 162 message.success(t('common.delSuccess'))
240 // 刷新列表 163 // 刷新列表
241 await getList() 164 await getList()
242 } catch {} 165 } catch {}
243 } 166 }
244 -  
245 -/** 导出按钮操作 */  
246 -const handleExport = async () => {  
247 - try {  
248 - // 导出的二次确认  
249 - await message.exportConfirm()  
250 - // 发起导出  
251 - exportLoading.value = true  
252 - const data = await ${simpleClassName}Api.export${simpleClassName}(queryParams)  
253 - download.excel(data, '${table.classComment}.xls')  
254 - } catch {  
255 - } finally {  
256 - exportLoading.value = false  
257 - }  
258 -} 167 +#end
  168 +#if ($table.templateType != 11)
259 169
260 /** 初始化 **/ 170 /** 初始化 **/
261 onMounted(() => { 171 onMounted(() => {
262 getList() 172 getList()
263 }) 173 })
  174 +#end
264 </script> 175 </script>
265 \ No newline at end of file 176 \ No newline at end of file
yudao-module-infra/yudao-module-infra-biz/src/test/java/cn/iocoder/yudao/module/infra/service/codegen/inner/CodegenEngineTest.java
@@ -469,7 +469,8 @@ public class CodegenEngineTest extends BaseMockitoUnitTest { @@ -469,7 +469,8 @@ public class CodegenEngineTest extends BaseMockitoUnitTest {
469 .setTableName("infra_demo12_student").setTableComment("学生表") 469 .setTableName("infra_demo12_student").setTableComment("学生表")
470 .setModuleName("infra").setBusinessName("demo12").setClassName("InfraDemo12Student") 470 .setModuleName("infra").setBusinessName("demo12").setClassName("InfraDemo12Student")
471 .setClassComment("学生").setAuthor("芋道源码") 471 .setClassComment("学生").setAuthor("芋道源码")
472 - .setTemplateType(CodegenTemplateTypeEnum.MASTER_INNER.getType()) 472 +// .setTemplateType(CodegenTemplateTypeEnum.MASTER_INNER.getType())
  473 + .setTemplateType(CodegenTemplateTypeEnum.MASTER_ERP.getType())
473 .setFrontType(CodegenFrontTypeEnum.VUE3.getType()); 474 .setFrontType(CodegenFrontTypeEnum.VUE3.getType());
474 CodegenColumnDO idColumn = new CodegenColumnDO().setColumnName("id").setDataType(JdbcType.BIGINT.name()) 475 CodegenColumnDO idColumn = new CodegenColumnDO().setColumnName("id").setDataType(JdbcType.BIGINT.name())
475 .setId(100L) 476 .setId(100L)