Browse Source

代码生成:完善 Vue3 标准模版的表单

YunaiV 2 years ago
parent
commit
0ff007c783

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

@@ -7,63 +7,64 @@
       label-width="100px"
       v-loading="formLoading"
     >
+#set ($dictMethods = [])## 使用到的 dict 字典方法
 #foreach($column in $columns)
     #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) ## 忽略主键,不用在表单里
+        #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)## 忽略主键,不用在表单里
       <el-form-item label="${comment}" prop="${javaField}">
-        <el-input v-model="form.${javaField}" placeholder="请输入${comment}" />
+        <el-input v-model="formData.${javaField}" placeholder="请输入${comment}" />
       </el-form-item>
         #elseif($column.htmlType == "imageUpload")## 图片上传 TODO 芋艿:待测试
             #set ($hasImageUploadColumn = true)
           <el-form-item label="${comment}">
-            <imageUpload v-model="form.${javaField}"/>
+            <imageUpload v-model="formData.${javaField}"/>
           </el-form-item>
         #elseif($column.htmlType == "fileUpload")## 文件上传 TODO 芋艿:待测试
             #set ($hasFileUploadColumn = true)
           <el-form-item label="${comment}">
-            <fileUpload v-model="form.${javaField}"/>
+            <fileUpload v-model="formData.${javaField}"/>
           </el-form-item>
         #elseif($column.htmlType == "editor")## 文本编辑器 TODO 芋艿:待测试
-            #set ($hasEditorColumn = true)
-          <el-form-item label="${comment}">
-            <editor v-model="form.${javaField}" :min-height="192"/>
-          </el-form-item>
+      <el-form-item label="${comment}">
+        <Editor :model-value="formData.${javaField}" height="150px" />
+      </el-form-item>
         #elseif($column.htmlType == "select")## 下拉框
-          <el-form-item label="${comment}" prop="${javaField}">
-            <el-select v-model="form.${javaField}" placeholder="请选择${comment}">
+      <el-form-item label="${comment}" prop="${javaField}">
+        <el-select v-model="formData.${javaField}" placeholder="请选择${comment}">
                 #if ("" != $dictType)## 有数据字典
-                    #if (!$dictMethods.contains($dictMethod)) ## 如果不存在,则添加到 dictMethods 数组中,后续好 import
-                      #( $dictMethods.add($dictMethod) )
+                    #if (!$dictMethods.contains($dictMethod))## 如果不存在,则添加到 dictMethods 数组中,后续好 import
+                      #set($ignore = $dictMethods.add($dictMethod) )
                     #end
-              <el-option
-                v-for="dict in $dictMethod(DICT_TYPE.$dictType.toUpperCase())"
-                :key="dict.value"
-                :label="dict.label"
-                :value="dict.value"
-              />
+          <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="" />
+          <el-option label="请选择字典生成" value="" />
                 #end
-            </el-select>
-          </el-form-item>
+        </el-select>
+      </el-form-item>
         #elseif($column.htmlType == "checkbox")## 多选框 TODO 芋艿:待测试
-          <el-form-item label="${comment}" prop="${javaField}">
-            <el-checkbox-group v-model="form.${javaField}">
+      <el-form-item label="${comment}" prop="${javaField}">
+        <el-checkbox-group v-model="formData.${javaField}">
                 #if ("" != $dictType)## 有数据字典
-                    #if (!$dictMethods.contains($dictMethod)) ## 如果不存在,则添加到 dictMethods 数组中,后续好 import
-                      #( $dictMethods.add($dictMethod) )
+                    #if (!$dictMethods.contains($dictMethod))## 如果不存在,则添加到 dictMethods 数组中,后续好 import
+                      #set($ignore = $dictMethods.add($dictMethod) )
                     #end
               <el-checkbox
                 v-for="dict in $dictMethod(DICT_TYPE.$dictType.toUpperCase())"
@@ -72,35 +73,36 @@
                 {{dict.label}}
               </el-checkbox>
                 #else##没数据字典
-                  <el-checkbox>请选择字典生成</el-checkbox>
+          <el-checkbox>请选择字典生成</el-checkbox>
                 #end
-            </el-checkbox-group>
-          </el-form-item>
+        </el-checkbox-group>
+      </el-form-item>
         #elseif($column.htmlType == "radio")## 单选框
-          <el-form-item label="${comment}" prop="${javaField}">
-            <el-radio-group v-model="form.${javaField}">
+      <el-form-item label="${comment}" prop="${javaField}">
+        <el-radio-group v-model="formData.${javaField}">
                 #if ("" != $dictType)## 有数据字典
-                    #if (!$dictMethods.contains($dictMethod)) ## 如果不存在,则添加到 dictMethods 数组中,后续好 import
-                      #( $dictMethods.add($dictMethod) )
+                    #if (!$dictMethods.contains($dictMethod))## 如果不存在,则添加到 dictMethods 数组中,后续好 import
+                      #set($ignore = $dictMethods.add($dictMethod) )
                     #end
-                  <el-radio
-                    v-for="dict in $dictMethod(DICT_TYPE.$dictType.toUpperCase())"
-                    :key="dict.value"
-                    :label="dict.value">
-                    {{dict.label}}
-                  </el-radio>
+          <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>
+          <el-radio label="1">请选择字典生成</el-radio>
                 #end
-            </el-radio-group>
-          </el-form-item>
+        </el-radio-group>
+      </el-form-item>
         #elseif($column.htmlType == "datetime")## 时间框 TODO 芋艿:待测试
           <el-form-item label="${comment}" prop="${javaField}">
-            <el-date-picker clearable v-model="form.${javaField}" type="date" value-format="timestamp" placeholder="选择${comment}" />
+            <el-date-picker clearable v-model="formData.${javaField}" type="date" value-format="timestamp" placeholder="选择${comment}" />
           </el-form-item>
         #elseif($column.htmlType == "textarea")## 文本框 TODO 芋艿:待测试
           <el-form-item label="${comment}" prop="${javaField}">
-            <el-input v-model="form.${javaField}" type="textarea" placeholder="请输入内容" />
+            <el-input v-model="formData.${javaField}" type="textarea" placeholder="请输入${comment}" />
           </el-form-item>
         #end
     #end
@@ -114,3 +116,115 @@
     </template>
   </Dialog>
 </template>
+<script setup lang="ts">
+#if ($dictMethods.size() > 0)
+import { DICT_TYPE#foreach ($dictMethod in $dictMethods), ${dictMethod}#end } from '@/utils/dict'
+#end
+import * as ${simpleClassName}Api from '@/api/${table.moduleName}/${classNameVar}'
+
+const { t } = useI18n() // 国际化
+const message = useMessage() // 消息弹窗
+
+const modelVisible = ref(false) // 弹窗的是否展示
+const modelTitle = ref('') // 弹窗的标题
+const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
+const formType = ref('') // 表单的类型:create - 新增;update - 修改
+const formData = ref({
+#set ($listOperationLastIndex = -1)## 求最后一个需要 , 的地方
+#foreach ($column in $columns)
+    #if ($column.createOperation || $column.updateOperation)
+        #set ($listOperationLastIndex = $foreach.index)
+    #end
+#end
+#foreach ($column in $columns)
+    #if ($column.createOperation || $column.updateOperation)
+        #if ($column.htmlType == "checkbox")
+  $column.javaField: []#if($foreach.index < $listOperationLastIndex),#end
+        #else
+  $column.javaField: undefined#if($foreach.index < $listOperationLastIndex),#end
+        #end
+    #end
+#end
+})
+const formRules = reactive({
+#set ($listOperationLastIndex = -1)## 求最后一个需要 , 的地方
+#foreach ($column in $columns)
+    #if (($column.createOperation || $column.updateOperation) && !$column.nullable && !${column.primaryKey})## 创建或者更新操作 && 要求非空 && 非主键
+        #set ($listOperationLastIndex = $foreach.index)
+    #end
+#end
+#foreach ($column in $columns)
+    #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 }]#if($foreach.index < $listOperationLastIndex),#end
+    #end
+#end
+})
+const formRef = ref() // 表单 Ref
+
+/** 打开弹窗 */
+const openModal = async (type: string, id?: number) => {
+  modelVisible.value = true
+  modelTitle.value = t('action.' + type)
+  formType.value = type
+  resetForm()
+  // 修改时,设置数据
+  if (id) {
+    formLoading.value = true
+    try {
+      formData.value = await ${simpleClassName}Api.get${simpleClassName}(id)
+    } finally {
+      formLoading.value = false
+    }
+  }
+}
+defineExpose({ openModal }) // 提供 openModal 方法,用于打开弹窗
+
+/** 提交表单 */
+const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
+const submitForm = async () => {
+  // 校验表单
+  if (!formRef) return
+  const valid = await formRef.value.validate()
+  if (!valid) return
+  // 提交请求
+  formLoading.value = true
+  try {
+    const data = formData.value as unknown as ${simpleClassName}Api.${simpleClassName}VO
+    if (formType.value === 'create') {
+      await ${simpleClassName}Api.create${simpleClassName}(data)
+      message.success(t('common.createSuccess'))
+    } else {
+      await ${simpleClassName}Api.update${simpleClassName}(data)
+      message.success(t('common.updateSuccess'))
+    }
+    modelVisible.value = false
+    // 发送操作成功的事件
+    emit('success')
+  } finally {
+    formLoading.value = false
+  }
+}
+
+/** 重置表单 */
+const resetForm = () => {
+  formData.value = {
+#set ($listOperationLastIndex = -1)## 求最后一个需要 , 的地方
+#foreach ($column in $columns)
+  #if ($column.createOperation || $column.updateOperation)
+      #set ($listOperationLastIndex = $foreach.index)
+  #end
+#end
+#foreach ($column in $columns)
+  #if ($column.createOperation || $column.updateOperation)
+      #if ($column.htmlType == "checkbox")
+    $column.javaField: []#if($foreach.index < $listOperationLastIndex),#end
+      #else
+    $column.javaField: undefined#if($foreach.index < $listOperationLastIndex),#end
+      #end
+  #end
+#end
+  }
+  formRef.value?.resetFields()
+}
+</script>

+ 1 - 1
yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3/views/index.vue.vm

@@ -92,7 +92,7 @@
       <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>
-        #if ($permissionPrefix <= 14)
+        #if ($permissionPrefix.length() < 15)
         <el-button type="primary" @click="openModal('create')" v-hasPermi="['${permissionPrefix}:create']">
         #else
         <el-button