From 01bdb33696344439a349750f83db48d31b6e26fc Mon Sep 17 00:00:00 2001 From: "zhijiantianya@gmail.com" <zhijiantianya@gmail.com> Date: Mon, 13 Nov 2023 20:35:03 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E7=94=9F=E6=88=90=E5=99=A8?= =?UTF-8?q?=EF=BC=9A=E8=BF=9B=E4=B8=80=E6=AD=A5=E5=AE=8C=E5=96=84=20erp=20?= =?UTF-8?q?=E7=94=9F=E6=88=90=E6=A8=A1=E7=89=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/codegen/inner/CodegenEngine.java | 2 +- .../codegen/java/controller/controller.vm | 7 +- .../codegen/java/controller/vo/baseVO.vm | 5 +- .../resources/codegen/java/service/service.vm | 3 +- .../codegen/java/service/serviceImpl.vm | 23 +- .../codegen/vue3/views/components/_column.vm | 13 -- .../vue3/views/components/form_sub_erp.vue.vm | 204 ++++++++++++++++ .../views/components/form_sub_inner.vue.vm | 2 +- .../vue3/views/components/list_sub_erp.vue.vm | 76 +++++- .../resources/codegen/vue3/views/index.vue.vm | 217 ++++++------------ .../codegen/inner/CodegenEngineTest.java | 3 +- 11 files changed, 367 insertions(+), 188 deletions(-) delete mode 100644 yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3/views/components/_column.vm diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/codegen/inner/CodegenEngine.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/codegen/inner/CodegenEngine.java index e43aa723f..a37cb5691 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/codegen/inner/CodegenEngine.java +++ b/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 { String subSimpleClassName = removePrefix(subTable.getClassName(), upperFirst(subTable.getModuleName())); subSimpleClassNames.add(subSimpleClassName); subClassNameVars.add(lowerFirst(subSimpleClassName)); // 将 DictType 转换成 dictType,用于变量 - subSimpleClassNameStrikeCases.add(toSymbolCase(simpleClassName, '-')); // 将 DictType 转换成 dict-type + subSimpleClassNameStrikeCases.add(toSymbolCase(subSimpleClassName, '-')); // 将 DictType 转换成 dict-type } bindingMap.put("subPrimaryColumns", subPrimaryColumns); bindingMap.put("subJoinColumns", subJoinColumns); diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/controller/controller.vm b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/controller/controller.vm index c864f22be..eb89ffcf3 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/controller/controller.vm +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/controller/controller.vm @@ -15,6 +15,7 @@ import javax.servlet.http.*; import java.util.*; import java.io.IOException; +import ${PageParamClassName}; import ${PageResultClassName}; import ${CommonResultClassName}; import static ${CommonResultClassName}.success; @@ -175,7 +176,7 @@ public class ${sceneEnum.prefixClass}${table.className}Controller { #if ($sceneEnum.scene == 1) @PreAuthorize("@ss.hasPermission('${permissionPrefix}:update')") #end - public CommonResult<Booealn> update${subSimpleClassName}(@Valid @RequestBody ${subTable.className}DO ${subClassNameVar}) { + public CommonResult<Boolean> update${subSimpleClassName}(@Valid @RequestBody ${subTable.className}DO ${subClassNameVar}) { ${classNameVar}Service.update${subSimpleClassName}(${subClassNameVar}); return success(true); } @@ -186,8 +187,8 @@ public class ${sceneEnum.prefixClass}${table.className}Controller { #if ($sceneEnum.scene == 1) @PreAuthorize("@ss.hasPermission('${permissionPrefix}:delete')") #end - public CommonResult<Booealn> delete${subSimpleClassName}(@RequestParam("id") ${subPrimaryColumn.javaType} id) { - ${classNameVar}Service.delete${subSimpleClassName}(${subClassNameVar}); + public CommonResult<Boolean> delete${subSimpleClassName}(@RequestParam("id") ${subPrimaryColumn.javaType} id) { + ${classNameVar}Service.delete${subSimpleClassName}(id); return success(true); } diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/controller/vo/baseVO.vm b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/controller/vo/baseVO.vm index b02c7bc0f..f56d854d7 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/controller/vo/baseVO.vm +++ b/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 { #end #end -## 特殊:主子表专属逻辑 +## 特殊:主子表专属逻辑(非 ERP 模式) +#if ( $subTables && $subTables.size() > 0 && $table.templateType != 11 ) + #foreach ($subTable in $subTables) #set ($index = $foreach.count - 1) #if ( $subTable.subJoinMany) @@ -53,4 +55,5 @@ public class ${sceneEnum.prefixClass}${table.className}BaseVO { #end #end +#end } \ No newline at end of file diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/service/service.vm b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/service/service.vm index 6f95ac164..0fd6f8514 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/service/service.vm +++ b/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 import ${basePackage}.module.${subTable.moduleName}.dal.dataobject.${subTable.businessName}.${subTable.className}DO; #end import ${PageResultClassName}; +import ${PageParamClassName}; /** * ${table.classComment} Service 接口 @@ -83,7 +84,7 @@ public interface ${table.className}Service { * @param ${subJoinColumn.javaField} ${subJoinColumn.columnComment} * @return ${subTable.classComment}分页 */ - PageResult<${subTable.className}DO> get${subSimpleClassName}Page(PageParam pageReqVO, ${subJoinColumn.javaType} ${subJoinColumn.javaField}) + PageResult<${subTable.className}DO> get${subSimpleClassName}Page(PageParam pageReqVO, ${subJoinColumn.javaType} ${subJoinColumn.javaField}); ## 情况二:非 MASTER_ERP 时,需要列表查询子表 #else diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/service/serviceImpl.vm b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/service/serviceImpl.vm index 9fb3769fc..2cb4d4792 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/service/serviceImpl.vm +++ b/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 import ${basePackage}.module.${subTable.moduleName}.dal.dataobject.${subTable.businessName}.${subTable.className}DO; #end import ${PageResultClassName}; +import ${PageParamClassName}; import ${basePackage}.module.${table.moduleName}.convert.${table.businessName}.${table.className}Convert; 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 #end @Override -## 特殊:主子表专属逻辑 -#if ( $subTables && $subTables.size() > 0 ) +## 特殊:主子表专属逻辑(非 ERP 模式) +#if ( $subTables && $subTables.size() > 0 && $table.templateType != 11 ) @Transactional(rollbackFor = Exception.class) #end public ${primaryColumn.javaType} create${simpleClassName}(${sceneEnum.prefixClass}${table.className}CreateReqVO createReqVO) { // 插入 ${table.className}DO ${classNameVar} = ${table.className}Convert.INSTANCE.convert(createReqVO); ${classNameVar}Mapper.insert(${classNameVar}); -## 特殊:主子表专属逻辑 -#if ( $subTables && $subTables.size() > 0) +## 特殊:主子表专属逻辑(非 ERP 模式) +#if ( $subTables && $subTables.size() > 0 && $table.templateType != 11 ) // 插入子表 #foreach ($subTable in $subTables) @@ -73,8 +74,8 @@ public class ${table.className}ServiceImpl implements ${table.className}Service } @Override -## 特殊:主子表专属逻辑 -#if ( $subTables && $subTables.size() > 0) +## 特殊:主子表专属逻辑(非 ERP 模式) +#if ( $subTables && $subTables.size() > 0 && $table.templateType != 11 ) @Transactional(rollbackFor = Exception.class) #end public void update${simpleClassName}(${sceneEnum.prefixClass}${table.className}UpdateReqVO updateReqVO) { @@ -83,8 +84,8 @@ public class ${table.className}ServiceImpl implements ${table.className}Service // 更新 ${table.className}DO updateObj = ${table.className}Convert.INSTANCE.convert(updateReqVO); ${classNameVar}Mapper.updateById(updateObj); -## 特殊:主子表专属逻辑 -#if ( $subTables && $subTables.size() > 0) +## 特殊:主子表专属逻辑(非 ERP 模式) +#if ( $subTables && $subTables.size() > 0 && $table.templateType != 11) // 更新子表 #foreach ($subTable in $subTables) @@ -182,13 +183,13 @@ public class ${table.className}ServiceImpl implements ${table.className}Service ## 情况一:MASTER_ERP 时,支持单个的新增、修改、删除操作 #if ( $table.templateType == 11 ) @Override - public ${subPrimaryColumn.javaType} create${subSimpleClassName}(@Valid ${subTable.className}DO ${subClassNameVar}) { + public ${subPrimaryColumn.javaType} create${subSimpleClassName}(${subTable.className}DO ${subClassNameVar}) { ${subClassNameVars.get($index)}Mapper.insert(${subClassNameVar}); return ${subClassNameVar}.getId(); } @Override - public void update${subSimpleClassName}(@Valid ${subTable.className}DO ${subClassNameVar}) { + public void update${subSimpleClassName}(${subTable.className}DO ${subClassNameVar}) { ${subClassNameVars.get($index)}Mapper.updateById(${subClassNameVar}); } @@ -230,10 +231,10 @@ public class ${table.className}ServiceImpl implements ${table.className}Service } #end +#end private void delete${subSimpleClassName}By${SubJoinColumnName}(${primaryColumn.javaType} ${subJoinColumn.javaField}) { ${subClassNameVars.get($index)}Mapper.deleteBy${SubJoinColumnName}(${subJoinColumn.javaField}); } -#end #end } \ No newline at end of file diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3/views/components/_column.vm b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3/views/components/_column.vm deleted file mode 100644 index 57a6ef123..000000000 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3/views/components/_column.vm +++ /dev/null @@ -1,13 +0,0 @@ -## 提供给 baseVO、createVO、updateVO 生成字段 - @Schema(description = "${column.columnComment}"#if (!${column.nullable}), requiredMode = Schema.RequiredMode.REQUIRED#end#if ("$!column.example" != ""), example = "${column.example}"#end) -#if (!${column.nullable})## 判断 @NotEmpty 和 @NotNull 注解 -#if (${column.javaType} == 'String') - @NotEmpty(message = "${column.columnComment}不能为空") -#else - @NotNull(message = "${column.columnComment}不能为空") -#end -#end -#if (${column.javaType} == "LocalDateTime")## 时间类型 - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) -#end - private ${column.javaType} ${column.javaField}; diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3/views/components/form_sub_erp.vue.vm b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3/views/components/form_sub_erp.vue.vm index e69de29bb..36d800734 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3/views/components/form_sub_erp.vue.vm +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3/views/components/form_sub_erp.vue.vm @@ -0,0 +1,204 @@ +#set ($subColumns = $subColumnsList.get($subIndex))##当前字段数组 +#set ($subSimpleClassName = $subSimpleClassNames.get($subIndex)) +#set ($subJoinColumn = $subJoinColumns.get($subIndex))##当前 join 字段 +<template> + <Dialog :title="dialogTitle" v-model="dialogVisible"> + <el-form + ref="formRef" + :model="formData" + :rules="formRules" + label-width="100px" + v-loading="formLoading" + > +#foreach($column in $subColumns) + #if ($column.createOperation || $column.updateOperation) + #set ($dictType = $column.dictType) + #set ($javaField = $column.javaField) + #set ($javaType = $column.javaType) + #set ($AttrName = $column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)}) + #set ($comment = $column.columnComment) + #set ($dictMethod = "getDictOptions")## 计算使用哪个 dict 字典方法 + #if ($javaType == "Integer" || $javaType == "Long" || $javaType == "Byte" || $javaType == "Short") + #set ($dictMethod = "getIntDictOptions") + #elseif ($javaType == "String") + #set ($dictMethod = "getStrDictOptions") + #elseif ($javaType == "Boolean") + #set ($dictMethod = "getBoolDictOptions") + #end + #if ($column.htmlType == "input" && !$column.primaryKey)## 忽略主键,不用在表单里 TODO 芋艿:这里要忽略下 join 字段; + <el-form-item label="${comment}" prop="${javaField}"> + <el-input v-model="formData.${javaField}" placeholder="请输入${comment}" /> + </el-form-item> + #elseif($column.htmlType == "imageUpload")## 图片上传 + <el-form-item label="${comment}"> + <UploadImg v-model="formData.${javaField}" /> + </el-form-item> + #elseif($column.htmlType == "fileUpload")## 文件上传 + <el-form-item label="${comment}" prop="${javaField}"> + <UploadFile v-model="formData.${javaField}" /> + </el-form-item> + #elseif($column.htmlType == "editor")## 文本编辑器 + <el-form-item label="${comment}" prop="${javaField}"> + <Editor v-model="formData.${javaField}" height="150px" /> + </el-form-item> + #elseif($column.htmlType == "select")## 下拉框 + <el-form-item label="${comment}" prop="${javaField}"> + <el-select v-model="formData.${javaField}" placeholder="请选择${comment}"> + #if ("" != $dictType)## 有数据字典 + <el-option + v-for="dict in $dictMethod(DICT_TYPE.$dictType.toUpperCase())" + :key="dict.value" + :label="dict.label" + :value="dict.value" + /> + #else##没数据字典 + <el-option label="请选择字典生成" value="" /> + #end + </el-select> + </el-form-item> + #elseif($column.htmlType == "checkbox")## 多选框 + <el-form-item label="${comment}" prop="${javaField}"> + <el-checkbox-group v-model="formData.${javaField}"> + #if ("" != $dictType)## 有数据字典 + <el-checkbox + v-for="dict in $dictMethod(DICT_TYPE.$dictType.toUpperCase())" + :key="dict.value" + :label="dict.value" + > + {{ dict.label }} + </el-checkbox> + #else##没数据字典 + <el-checkbox>请选择字典生成</el-checkbox> + #end + </el-checkbox-group> + </el-form-item> + #elseif($column.htmlType == "radio")## 单选框 + <el-form-item label="${comment}" prop="${javaField}"> + <el-radio-group v-model="formData.${javaField}"> + #if ("" != $dictType)## 有数据字典 + <el-radio + v-for="dict in $dictMethod(DICT_TYPE.$dictType.toUpperCase())" + :key="dict.value" + :label="dict.value" + > + {{ dict.label }} + </el-radio> + #else##没数据字典 + <el-radio label="1">请选择字典生成</el-radio> + #end + </el-radio-group> + </el-form-item> + #elseif($column.htmlType == "datetime")## 时间框 + <el-form-item label="${comment}" prop="${javaField}"> + <el-date-picker + v-model="formData.${javaField}" + type="date" + value-format="x" + placeholder="选择${comment}" + /> + </el-form-item> + #elseif($column.htmlType == "textarea")## 文本框 + <el-form-item label="${comment}" prop="${javaField}"> + <el-input v-model="formData.${javaField}" type="textarea" placeholder="请输入${comment}" /> + </el-form-item> + #end + #end +#end + </el-form> + <template #footer> + <el-button @click="submitForm" type="primary" :disabled="formLoading">确 定</el-button> + <el-button @click="dialogVisible = false">取 消</el-button> + </template> + </Dialog> +</template> +<script setup lang="ts"> +import { getIntDictOptions, getStrDictOptions, getBoolDictOptions, DICT_TYPE } from '@/utils/dict' +import * as ${simpleClassName}Api from '@/api/${table.moduleName}/${table.businessName}' + +const { t } = useI18n() // 国际化 +const message = useMessage() // 消息弹窗 + +const dialogVisible = ref(false) // 弹窗的是否展示 +const dialogTitle = ref('') // 弹窗的标题 +const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用 +const formType = ref('') // 表单的类型:create - 新增;update - 修改 +const formData = ref({ +#foreach ($column in $subColumns) + #if ($column.createOperation || $column.updateOperation) + #if ($column.htmlType == "checkbox") + $column.javaField: [], + #else + $column.javaField: undefined, + #end + #end +#end +}) +const formRules = reactive({ +#foreach ($column in $subColumns) + #if (($column.createOperation || $column.updateOperation) && !$column.nullable && !${column.primaryKey})## 创建或者更新操作 && 要求非空 && 非主键 + #set($comment=$column.columnComment) + $column.javaField: [{ required: true, message: '${comment}不能为空', trigger: #if($column.htmlType == 'select')'change'#else'blur'#end }], + #end +#end +}) +const formRef = ref() // 表单 Ref + +/** 打开弹窗 */ +const open = async (type: string, id?: number, ${subJoinColumn.javaField}: number) => { + dialogVisible.value = true + dialogTitle.value = t('action.' + type) + formType.value = type + resetForm() + formData.${subJoinColumn.javaField} = ${subJoinColumn.javaField} + // 修改时,设置数据 + if (id) { + formLoading.value = true + try { + formData.value = await ${simpleClassName}Api.get${subSimpleClassName}(id) + } finally { + formLoading.value = false + } + } +} +defineExpose({ open }) // 提供 open 方法,用于打开弹窗 + +/** 提交表单 */ +const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调 +const submitForm = async () => { + // 校验表单 + await formRef.value.validate() + // 提交请求 + formLoading.value = true + try { + const data = formData.value + if (formType.value === 'create') { + await ${simpleClassName}Api.create${subSimpleClassName}(data) + message.success(t('common.createSuccess')) + } else { + await ${simpleClassName}Api.update${subSimpleClassName}(data) + message.success(t('common.updateSuccess')) + } + dialogVisible.value = false + // 发送操作成功的事件 + emit('success') + } finally { + formLoading.value = false + } +} + +/** 重置表单 */ +const resetForm = () => { + formData.value = { +#foreach ($column in $subColumns) + #if ($column.createOperation || $column.updateOperation) + #if ($column.htmlType == "checkbox") + $column.javaField: [], + #else + $column.javaField: undefined, + #end + #end +#end + } + formRef.value?.resetFields() +} +</script> \ No newline at end of file diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3/views/components/form_sub_inner.vue.vm b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3/views/components/form_sub_inner.vue.vm index cffb5f491..d8542c3d5 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3/views/components/form_sub_inner.vue.vm +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3/views/components/form_sub_inner.vue.vm @@ -1,2 +1,2 @@ ## 主表的 normal 和 inner 使用相同的 form 表单 -#parse("codegen/vue3/views/components/form_sub_inner.vue.vm") \ No newline at end of file +#parse("codegen/vue3/views/components/form_sub_normal.vue.vm") \ No newline at end of file diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3/views/components/list_sub_erp.vue.vm b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3/views/components/list_sub_erp.vue.vm index 860927736..1fb79dbf6 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3/views/components/list_sub_erp.vue.vm +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3/views/components/list_sub_erp.vue.vm @@ -7,6 +7,14 @@ <template> <!-- 列表 --> <ContentWrap> + <el-button + type="primary" + plain + @click="openForm('create')" + v-hasPermi="['${permissionPrefix}:create']" + > + <Icon icon="ep:plus" class="mr-5px" /> 新增 + </el-button> <el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true"> #foreach($column in $subColumns) #if ($column.listOperationResult) @@ -66,27 +74,56 @@ /> #end </ContentWrap> + + <!-- 表单弹窗:添加/修改 --> + <${subSimpleClassName}Form ref="formRef" @success="getList" /> </template> <script setup lang="ts"> import { getIntDictOptions, getStrDictOptions, getBoolDictOptions, DICT_TYPE } from '@/utils/dict' import * as ${simpleClassName}Api from '@/api/${table.moduleName}/${table.businessName}' +import ${subSimpleClassName}Form from './${subSimpleClassName}Form.vue' + +const { t } = useI18n() // 国际化 +const message = useMessage() // 消息弹窗 + const props = defineProps<{ ${subJoinColumn.javaField}: undefined // ${subJoinColumn.columnComment}(主表的关联字段) }>() -const loading = ref(true) // 列表的加载中 +const loading = ref(false) // 列表的加载中 const list = ref([]) // 列表的数据 +#if ($table.templateType == 11) +const total = ref(0) // 列表的总页数 +const queryParams = reactive({ + pageNo: 1, + pageSize: 10, + ${subJoinColumn.javaField}: undefined +}) + +/** 监听主表的关联字段的变化,加载对应的子表数据 */ +watch( + () => props.${subJoinColumn.javaField}, + (val) => { + queryParams.${subJoinColumn.javaField} = val + handleQuery() + }, + { immediate: false } +) +#end /** 查询列表 */ const getList = async () => { loading.value = true try { #if ($table.templateType == 11) + const data = await ${simpleClassName}Api.get${subSimpleClassName}Page(queryParams) + list.value = data.list + total.value = data.total #else #if ( $subTable.subJoinMany ) - list.value = await ${simpleClassName}Api.get${subSimpleClassName}ListBy${SubJoinColumnName}(${subJoinColumn.javaField}.props) + list.value = await ${simpleClassName}Api.get${subSimpleClassName}ListBy${SubJoinColumnName}(props.${subJoinColumn.javaField}) #else - const data = await ${simpleClassName}Api.get${subSimpleClassName}By${SubJoinColumnName}(${subJoinColumn.javaField}.props) + const data = await ${simpleClassName}Api.get${subSimpleClassName}By${SubJoinColumnName}(props.${subJoinColumn.javaField}) if (!data) { return } @@ -98,8 +135,41 @@ const getList = async () => { } } +/** 搜索按钮操作 */ +const handleQuery = () => { + queryParams.pageNo = 1 + getList() +} +#if ($table.templateType == 11) + +/** 添加/修改操作 */ +const formRef = ref() +const openForm = (type: string, id?: number) => { + if (!props.${subJoinColumn.javaField}) { + message.error('请选择一个${table.classComment}') + return + } + formRef.value.open(type, id, props.${subJoinColumn.javaField}) +} + +/** 删除按钮操作 */ +const handleDelete = async (id: number) => { + try { + // 删除的二次确认 + await message.delConfirm() + // 发起删除 + await ${simpleClassName}Api.delete${subSimpleClassName}(id) + message.success(t('common.delSuccess')) + // 刷新列表 + await getList() + } catch {} +} +#end +#if ($table.templateType != 11) + /** 初始化 **/ onMounted(() => { getList() }) +#end </script> \ No newline at end of file diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3/views/index.vue.vm b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3/views/index.vue.vm index e080082ab..1fb79dbf6 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3/views/index.vue.vm +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3/views/index.vue.vm @@ -1,114 +1,22 @@ +#set ($subTable = $subTables.get($subIndex))##当前表 +#set ($subColumns = $subColumnsList.get($subIndex))##当前字段数组 +#set ($subJoinColumn = $subJoinColumns.get($subIndex))##当前 join 字段 +#set ($subSimpleClassName = $subSimpleClassNames.get($subIndex)) +#set ($subJoinColumn = $subJoinColumns.get($subIndex))##当前 join 字段 +#set ($SubJoinColumnName = $subJoinColumn.javaField.substring(0,1).toUpperCase() + ${subJoinColumn.javaField.substring(1)})##首字母大写 <template> - <ContentWrap> - <!-- 搜索工作栏 --> - <el-form - class="-mb-15px" - :model="queryParams" - ref="queryFormRef" - :inline="true" - label-width="68px" - > - #foreach($column in $columns) - #if ($column.listOperation) - #set ($dictType = $column.dictType) - #set ($javaField = $column.javaField) - #set ($javaType = $column.javaType) - #set ($AttrName = $column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)}) - #set ($comment = $column.columnComment) - #set ($dictMethod = "getDictOptions")## 计算使用哪个 dict 字典方法 - #if ($javaType == "Integer" || $javaType == "Long" || $javaType == "Byte" || $javaType == "Short") - #set ($dictMethod = "getIntDictOptions") - #elseif ($javaType == "String") - #set ($dictMethod = "getStrDictOptions") - #elseif ($javaType == "Boolean") - #set ($dictMethod = "getBoolDictOptions") - #end - #if ($column.htmlType == "input") - <el-form-item label="${comment}" prop="${javaField}"> - <el-input - v-model="queryParams.${javaField}" - placeholder="请输入${comment}" - clearable - @keyup.enter="handleQuery" - class="!w-240px" - /> - </el-form-item> - #elseif ($column.htmlType == "select" || $column.htmlType == "radio") - <el-form-item label="${comment}" prop="${javaField}"> - <el-select - v-model="queryParams.${javaField}" - placeholder="请选择${comment}" - clearable - class="!w-240px" - > - #if ("" != $dictType)## 设置了 dictType 数据字典的情况 - <el-option - v-for="dict in $dictMethod(DICT_TYPE.$dictType.toUpperCase())" - :key="dict.value" - :label="dict.label" - :value="dict.value" - /> - #else## 未设置 dictType 数据字典的情况 - <el-option label="请选择字典生成" value="" /> - #end - </el-select> - </el-form-item> - #elseif($column.htmlType == "datetime") - #if ($column.listOperationCondition != "BETWEEN")## 非范围 - <el-form-item label="${comment}" prop="${javaField}"> - <el-date-picker - v-model="queryParams.${javaField}" - value-format="YYYY-MM-DD" - type="date" - placeholder="选择${comment}" - clearable - class="!w-240px" - /> - </el-form-item> - #else## 范围 - <el-form-item label="${comment}" prop="${javaField}"> - <el-date-picker - v-model="queryParams.${javaField}" - value-format="YYYY-MM-DD HH:mm:ss" - type="daterange" - start-placeholder="开始日期" - end-placeholder="结束日期" - :default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]" - class="!w-240px" - /> - </el-form-item> - #end - #end - #end - #end - <el-form-item> - <el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button> - <el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button> - <el-button - type="primary" - plain - @click="openForm('create')" - v-hasPermi="['${permissionPrefix}:create']" - > - <Icon icon="ep:plus" class="mr-5px" /> 新增 - </el-button> - <el-button - type="success" - plain - @click="handleExport" - :loading="exportLoading" - v-hasPermi="['${permissionPrefix}:export']" - > - <Icon icon="ep:download" class="mr-5px" /> 导出 - </el-button> - </el-form-item> - </el-form> - </ContentWrap> - <!-- 列表 --> <ContentWrap> + <el-button + type="primary" + plain + @click="openForm('create')" + v-hasPermi="['${permissionPrefix}:create']" + > + <Icon icon="ep:plus" class="mr-5px" /> 新增 + </el-button> <el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true"> - #foreach($column in $columns) + #foreach($column in $subColumns) #if ($column.listOperationResult) #set ($dictType=$column.dictType) #set ($javaField = $column.javaField) @@ -133,6 +41,7 @@ #end #end #end + #if ($table.templateType == 11) <el-table-column label="操作" align="center"> <template #default="scope"> <el-button @@ -153,7 +62,9 @@ </el-button> </template> </el-table-column> + #end </el-table> + #if ($table.templateType == 11) <!-- 分页 --> <Pagination :total="total" @@ -161,51 +72,64 @@ v-model:limit="queryParams.pageSize" @pagination="getList" /> + #end </ContentWrap> - <!-- 表单弹窗:添加/修改 --> - <${simpleClassName}Form ref="formRef" @success="getList" /> + <!-- 表单弹窗:添加/修改 --> + <${subSimpleClassName}Form ref="formRef" @success="getList" /> </template> <script setup lang="ts"> import { getIntDictOptions, getStrDictOptions, getBoolDictOptions, DICT_TYPE } from '@/utils/dict' -import { dateFormatter } from '@/utils/formatTime' -import download from '@/utils/download' import * as ${simpleClassName}Api from '@/api/${table.moduleName}/${table.businessName}' -import ${simpleClassName}Form from './${simpleClassName}Form.vue' +import ${subSimpleClassName}Form from './${subSimpleClassName}Form.vue' -defineOptions({ name: '${table.className}' }) - -const message = useMessage() // 消息弹窗 const { t } = useI18n() // 国际化 +const message = useMessage() // 消息弹窗 -const loading = ref(true) // 列表的加载中 -const total = ref(0) // 列表的总页数 +const props = defineProps<{ + ${subJoinColumn.javaField}: undefined // ${subJoinColumn.columnComment}(主表的关联字段) +}>() +const loading = ref(false) // 列表的加载中 const list = ref([]) // 列表的数据 +#if ($table.templateType == 11) +const total = ref(0) // 列表的总页数 const queryParams = reactive({ pageNo: 1, pageSize: 10, - #foreach ($column in $columns) - #if ($column.listOperation) - #if ($column.listOperationCondition != 'BETWEEN') - $column.javaField: null, - #end - #if ($column.htmlType == "datetime" || $column.listOperationCondition == "BETWEEN") - $column.javaField: [], - #end - #end - #end + ${subJoinColumn.javaField}: undefined }) -const queryFormRef = ref() // 搜索的表单 -const exportLoading = ref(false) // 导出的加载中 + +/** 监听主表的关联字段的变化,加载对应的子表数据 */ +watch( + () => props.${subJoinColumn.javaField}, + (val) => { + queryParams.${subJoinColumn.javaField} = val + handleQuery() + }, + { immediate: false } +) +#end /** 查询列表 */ const getList = async () => { loading.value = true try { - const data = await ${simpleClassName}Api.get${simpleClassName}Page(queryParams) +#if ($table.templateType == 11) + const data = await ${simpleClassName}Api.get${subSimpleClassName}Page(queryParams) list.value = data.list total.value = data.total +#else + #if ( $subTable.subJoinMany ) + list.value = await ${simpleClassName}Api.get${subSimpleClassName}ListBy${SubJoinColumnName}(props.${subJoinColumn.javaField}) + #else + const data = await ${simpleClassName}Api.get${subSimpleClassName}By${SubJoinColumnName}(props.${subJoinColumn.javaField}) + if (!data) { + return + } + list.value.push(data) + #end +#end } finally { loading.value = false } @@ -216,17 +140,16 @@ const handleQuery = () => { queryParams.pageNo = 1 getList() } - -/** 重置按钮操作 */ -const resetQuery = () => { - queryFormRef.value.resetFields() - handleQuery() -} +#if ($table.templateType == 11) /** 添加/修改操作 */ const formRef = ref() const openForm = (type: string, id?: number) => { - formRef.value.open(type, id) + if (!props.${subJoinColumn.javaField}) { + message.error('请选择一个${table.classComment}') + return + } + formRef.value.open(type, id, props.${subJoinColumn.javaField}) } /** 删除按钮操作 */ @@ -235,30 +158,18 @@ const handleDelete = async (id: number) => { // 删除的二次确认 await message.delConfirm() // 发起删除 - await ${simpleClassName}Api.delete${simpleClassName}(id) + await ${simpleClassName}Api.delete${subSimpleClassName}(id) message.success(t('common.delSuccess')) // 刷新列表 await getList() } catch {} } - -/** 导出按钮操作 */ -const handleExport = async () => { - try { - // 导出的二次确认 - await message.exportConfirm() - // 发起导出 - exportLoading.value = true - const data = await ${simpleClassName}Api.export${simpleClassName}(queryParams) - download.excel(data, '${table.classComment}.xls') - } catch { - } finally { - exportLoading.value = false - } -} +#end +#if ($table.templateType != 11) /** 初始化 **/ onMounted(() => { getList() }) +#end </script> \ No newline at end of file diff --git a/yudao-module-infra/yudao-module-infra-biz/src/test/java/cn/iocoder/yudao/module/infra/service/codegen/inner/CodegenEngineTest.java b/yudao-module-infra/yudao-module-infra-biz/src/test/java/cn/iocoder/yudao/module/infra/service/codegen/inner/CodegenEngineTest.java index 1ebaceed4..ae2676b87 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/test/java/cn/iocoder/yudao/module/infra/service/codegen/inner/CodegenEngineTest.java +++ b/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 { .setTableName("infra_demo12_student").setTableComment("学生表") .setModuleName("infra").setBusinessName("demo12").setClassName("InfraDemo12Student") .setClassComment("学生").setAuthor("芋道源码") - .setTemplateType(CodegenTemplateTypeEnum.MASTER_INNER.getType()) +// .setTemplateType(CodegenTemplateTypeEnum.MASTER_INNER.getType()) + .setTemplateType(CodegenTemplateTypeEnum.MASTER_ERP.getType()) .setFrontType(CodegenFrontTypeEnum.VUE3.getType()); CodegenColumnDO idColumn = new CodegenColumnDO().setColumnName("id").setDataType(JdbcType.BIGINT.name()) .setId(100L)