Bladeren bron

代码生成:主子表 normal 模式,1 对 1 的 form 生成

YunaiV 1 jaar geleden
bovenliggende
commit
07e71e2ab0

+ 1 - 1
yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3/api/api.ts.vm

@@ -75,7 +75,7 @@ export const get${subSimpleClassName}ListBy${SubJoinColumnName} = async (${subJo
 
 // 获得${subTable.classComment}
 export const get${subSimpleClassName}By${SubJoinColumnName} = async (${subJoinColumn.javaField}) => {
-  return await request.get({ url: `${baseURL}/${subSimpleClassName_strikeCase}/get-by-${subJoinColumn_strikeCase}`, ${subJoinColumn.javaField} })
+  return await request.get({ url: `${baseURL}/${subSimpleClassName_strikeCase}/get-by-${subJoinColumn_strikeCase}?${subJoinColumn.javaField}=` + ${subJoinColumn.javaField} })
 }
   #end
 #end

+ 124 - 0
yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3/views/components/form_sub_normal.vue.vm

@@ -5,6 +5,7 @@
 #set ($subJoinColumn = $subJoinColumns.get($subIndex))##当前 join 字段
 #set ($SubJoinColumnName = $subJoinColumn.javaField.substring(0,1).toUpperCase() + ${subJoinColumn.javaField.substring(1)})##首字母大写
 <template>
+#if ( $subTable.subJoinMany )## 情况一:一对多,table + form
   <el-form
     ref="formRef"
     :model="formData"
@@ -150,6 +151,109 @@
   <el-row justify="center" class="mt-3">
     <el-button @click="handleAdd" round>+ 添加${subTable.classComment}</el-button>
   </el-row>
+#else## 情况二:一对一,form
+  <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}">
+      <UploadFile v-model="formData.${javaField}" />
+    </el-form-item>
+      #elseif($column.htmlType == "editor")## 文本编辑器
+    <el-form-item label="${comment}">
+      <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
+#end
 </template>
 <script setup lang="ts">
 import { getIntDictOptions, getStrDictOptions, getBoolDictOptions, DICT_TYPE } from '@/utils/dict'
@@ -176,19 +280,38 @@ watch(
   async (val) => {
     // 情况一:val 为空,说明是新增,则置空
     if (!val) {
+#if ( $subTable.subJoinMany )
       formData.value = []
+#else
+      formData.value = {
+      #foreach ($column in $subColumns)
+        #if ($column.createOperation || $column.updateOperation)
+          #if ($column.htmlType == "checkbox")
+        $column.javaField: [],
+          #else
+        $column.javaField: undefined,
+          #end
+        #end
+      #end
+      }
+#end
       return;
     }
     // 情况二:val 非空,说明是修改,则加载数据
     try {
       formLoading.value = true
+#if ( $subTable.subJoinMany )
       formData.value = await ${simpleClassName}Api.get${subSimpleClassName}ListBy${SubJoinColumnName}(val)
+#else
+      formData.value = await ${simpleClassName}Api.get${subSimpleClassName}By${SubJoinColumnName}(val)
+#end
     } finally {
       formLoading.value = false
     }
   },
   { immediate: true }
 )
+#if ( $subTable.subJoinMany )
 
 /** 新增按钮操作 */
 const handleAdd = () => {
@@ -211,6 +334,7 @@ const handleAdd = () => {
 const handleDelete = (index) => {
   formData.value.splice(index, 1)
 }
+#end
 
 /** 表单校验 */
 const validate = () => {

+ 51 - 0
yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3/views/form.vue.vm

@@ -102,6 +102,21 @@
     #end
 #end
     </el-form>
+## 特殊:主子表专属逻辑
+#if ( $subTables && $subTables.size() > 0 )
+    <!-- 子表的表单 -->
+    <el-tabs v-model="subTabsName">
+    #foreach ($subTable in $subTables)
+      #set ($index = $foreach.count - 1)
+      #set ($subClassNameVar = $subClassNameVars.get($index))
+      #set ($subSimpleClassName = $subSimpleClassNames.get($index))
+      #set ($subJoinColumn_strikeCase = $subJoinColumn_strikeCases.get($index))
+      <el-tab-pane label="${subTable.classComment}" name="$subClassNameVar">
+        <${subSimpleClassName}Form ref="${subClassNameVar}FormRef" :${subJoinColumn_strikeCase}="formData.id" />
+      </el-tab-pane>
+    #end
+    </el-tabs>
+#end
     <template #footer>
       <el-button @click="submitForm" type="primary" :disabled="formLoading">确 定</el-button>
       <el-button @click="dialogVisible = false">取 消</el-button>
@@ -111,6 +126,10 @@
 <script setup lang="ts">
 import { getIntDictOptions, getStrDictOptions, getBoolDictOptions, DICT_TYPE } from '@/utils/dict'
 import * as ${simpleClassName}Api from '@/api/${table.moduleName}/${classNameVar}'
+## 特殊:主子表专属逻辑
+#foreach ($subSimpleClassName in $subSimpleClassNames)
+import ${subSimpleClassName}Form from './components/${subSimpleClassName}Form.vue'
+#end
 
 const { t } = useI18n() // 国际化
 const message = useMessage() // 消息弹窗
@@ -139,6 +158,15 @@ const formRules = reactive({
 #end
 })
 const formRef = ref() // 表单 Ref
+## 特殊:主子表专属逻辑
+#if ( $subTables && $subTables.size() > 0 )
+
+/** 子表的表单 */
+const subTabsName = ref('$subClassNameVars.get(0)')
+#foreach ($subClassNameVar in $subClassNameVars)
+const ${subClassNameVar}FormRef = ref()
+#end
+#end
 
 /** 打开弹窗 */
 const open = async (type: string, id?: number) => {
@@ -163,10 +191,33 @@ const emit = defineEmits(['success']) // 定义 success 事件,用于操作成
 const submitForm = async () => {
   // 校验表单
   await formRef.value.validate()
+## 特殊:主子表专属逻辑
+#if ( $subTables && $subTables.size() > 0 )
+  // 校验子表单
+  #foreach ($subTable in $subTables)
+  #set ($index = $foreach.count - 1)
+  #set ($subClassNameVar = $subClassNameVars.get($index))
+  try {
+    await ${subClassNameVar}FormRef.value.validate()
+  } catch (e) {
+    subTabsName.value = '${subClassNameVar}'
+    return
+  }
+  #end
+#end
   // 提交请求
   formLoading.value = true
   try {
     const data = formData.value as unknown as ${simpleClassName}Api.${simpleClassName}VO
+## 特殊:主子表专属逻辑
+#if ( $subTables && $subTables.size() > 0 )
+    // 拼接子表的数据
+  #foreach ($subTable in $subTables)
+  #set ($index = $foreach.count - 1)
+  #set ($subClassNameVar = $subClassNameVars.get($index))
+    data.${subClassNameVar}#if ( $subTable.subJoinMany)s#end = ${subClassNameVar}FormRef.value.getData()
+  #end
+#end
     if (formType.value === 'create') {
       await ${simpleClassName}Api.create${simpleClassName}(data)
       message.success(t('common.createSuccess'))

+ 63 - 1
yudao-module-infra/yudao-module-infra-biz/src/test/java/cn/iocoder/yudao/module/infra/service/codegen/inner/CodegenEngineTest.java

@@ -284,7 +284,69 @@ public class CodegenEngineTest extends BaseMockitoUnitTest {
                 .setCreateOperation(false).setUpdateOperation(true).setListOperation(false)
                 .setListOperationResult(true)
                 .setId(200L);
-        List<CodegenColumnDO> addressColumns = Arrays.asList(addressIdColumn, addressStudentIdColumn);
+        CodegenColumnDO addressNameColumn = new CodegenColumnDO().setColumnName("name").setDataType(JdbcType.VARCHAR.name())
+                .setColumnComment("名字").setNullable(false).setPrimaryKey(false)
+                .setOrdinalPosition(3).setJavaType("String").setJavaField("name").setExample("芋头")
+                .setCreateOperation(true).setUpdateOperation(true).setListOperation(true)
+                .setListOperationCondition(CodegenColumnListConditionEnum.LIKE.getCondition()).setListOperationResult(true)
+                .setHtmlType(CodegenColumnHtmlTypeEnum.INPUT.getType());
+        CodegenColumnDO addressAvatarColumn = new CodegenColumnDO().setColumnName("avatar").setDataType(JdbcType.VARCHAR.name())
+                .setColumnComment("头像").setNullable(false).setPrimaryKey(false)
+                .setOrdinalPosition(4).setJavaType("String").setJavaField("avatar").setExample("https://www.iocoder.cn/1.png")
+                .setCreateOperation(true).setUpdateOperation(true).setListOperation(false)
+                .setListOperationResult(true)
+                .setHtmlType(CodegenColumnHtmlTypeEnum.UPLOAD_IMAGE.getType());
+        CodegenColumnDO addressVideoColumn = new CodegenColumnDO().setColumnName("video").setDataType(JdbcType.VARCHAR.name())
+                .setColumnComment("视频").setNullable(false).setPrimaryKey(false)
+                .setOrdinalPosition(5).setJavaType("String").setJavaField("video").setExample("https://www.iocoder.cn/1.mp4")
+                .setCreateOperation(true).setUpdateOperation(true).setListOperation(false)
+                .setListOperationResult(true)
+                .setHtmlType(CodegenColumnHtmlTypeEnum.UPLOAD_FILE.getType());
+        CodegenColumnDO addressDescriptionColumn = new CodegenColumnDO().setColumnName("description").setDataType(JdbcType.VARCHAR.name())
+                .setColumnComment("个人简介").setNullable(false).setPrimaryKey(false)
+                .setOrdinalPosition(6).setJavaType("String").setJavaField("description").setExample("我是介绍")
+                .setCreateOperation(true).setUpdateOperation(true).setListOperation(false)
+                .setListOperationResult(true)
+                .setHtmlType(CodegenColumnHtmlTypeEnum.EDITOR.getType());
+        CodegenColumnDO addressSex1Column = new CodegenColumnDO().setColumnName("sex1").setDataType(JdbcType.VARCHAR.name())
+                .setColumnComment("性别 1").setNullable(false).setPrimaryKey(false)
+                .setOrdinalPosition(7).setJavaType("String").setJavaField("sex1").setExample("男")
+                .setCreateOperation(true).setUpdateOperation(true).setListOperation(true)
+                .setListOperationCondition(CodegenColumnListConditionEnum.EQ.getCondition()).setListOperationResult(true)
+                .setHtmlType(CodegenColumnHtmlTypeEnum.SELECT.getType()).setDictType("system_sex1");
+        CodegenColumnDO addressSex2Column = new CodegenColumnDO().setColumnName("sex2").setDataType(JdbcType.INTEGER.name())
+                .setColumnComment("性别 2").setNullable(false).setPrimaryKey(false)
+                .setOrdinalPosition(8).setJavaType("Integer").setJavaField("sex2").setExample("1")
+                .setCreateOperation(true).setUpdateOperation(true).setListOperation(true)
+                .setListOperationCondition(CodegenColumnListConditionEnum.EQ.getCondition()).setListOperationResult(true)
+                .setHtmlType(CodegenColumnHtmlTypeEnum.CHECKBOX.getType()).setDictType("system_sex2");
+        CodegenColumnDO addressSex3Column = new CodegenColumnDO().setColumnName("sex3").setDataType(JdbcType.BOOLEAN.name())
+                .setColumnComment("性别 3").setNullable(false).setPrimaryKey(false)
+                .setOrdinalPosition(9).setJavaType("Boolean").setJavaField("sex3").setExample("true")
+                .setCreateOperation(true).setUpdateOperation(true).setListOperation(true)
+                .setListOperationResult(true)
+                .setHtmlType(CodegenColumnHtmlTypeEnum.RADIO.getType()).setDictType("system_sex3");
+        CodegenColumnDO addressBirthdayColumn = new CodegenColumnDO().setColumnName("birthday").setDataType(JdbcType.DATE.name())
+                .setColumnComment("出生日期").setNullable(false).setPrimaryKey(false)
+                .setOrdinalPosition(10).setJavaType("LocalDateTime").setJavaField("birthday")
+                .setCreateOperation(true).setUpdateOperation(true).setListOperation(true)
+                .setListOperationCondition(CodegenColumnListConditionEnum.EQ.getCondition()).setListOperationResult(true)
+                .setHtmlType(CodegenColumnHtmlTypeEnum.DATETIME.getType());
+        CodegenColumnDO addressMemoColumn = new CodegenColumnDO().setColumnName("memo").setDataType(JdbcType.VARCHAR.name())
+                .setColumnComment("备注").setNullable(false).setPrimaryKey(false)
+                .setOrdinalPosition(11).setJavaType("String").setJavaField("memo").setExample("我是备注")
+                .setCreateOperation(true).setUpdateOperation(true).setListOperation(false)
+                .setListOperationResult(true)
+                .setHtmlType(CodegenColumnHtmlTypeEnum.TEXTAREA.getType());
+        CodegenColumnDO addressCreateTimeColumn = new CodegenColumnDO().setColumnName("create_time").setDataType(JdbcType.DATE.name())
+                .setColumnComment("创建时间").setNullable(false).setPrimaryKey(false)
+                .setOrdinalPosition(12).setJavaType("LocalDateTime").setJavaField("createTime")
+                .setCreateOperation(false).setUpdateOperation(false).setListOperation(true)
+                .setListOperationCondition(CodegenColumnListConditionEnum.BETWEEN.getCondition()).setListOperationResult(true)
+                .setHtmlType(CodegenColumnHtmlTypeEnum.DATETIME.getType());
+        List<CodegenColumnDO> addressColumns = Arrays.asList(addressIdColumn, addressStudentIdColumn,
+                addressNameColumn, addressAvatarColumn, addressVideoColumn, addressDescriptionColumn,
+                addressSex1Column, addressSex2Column, addressSex3Column, addressBirthdayColumn, addressMemoColumn, addressCreateTimeColumn);
 
         // 调用
         Map<String, String> result = codegenEngine.execute(table, columns,