Kaynağa Gözat

perf: 优化 vue3 代码生成模板,增加批量删除功能

puhui999 5 ay önce
ebeveyn
işleme
6a5d343036

+ 67 - 16
yudao-module-infra/src/main/resources/codegen/vue3/api/api.ts.vm

@@ -1,19 +1,56 @@
 import request from '@/config/axios'
+import type { Dayjs } from 'dayjs';
 #set ($baseURL = "/${table.moduleName}/${simpleClassName_strikeCase}")
 
-// ${table.classComment} VO
-export interface ${simpleClassName}VO {
-#foreach ($column in $columns)
-#if ($column.createOperation || $column.updateOperation)
-#if(${column.javaType.toLowerCase()} == "long" || ${column.javaType.toLowerCase()} == "integer" || ${column.javaType.toLowerCase()} == "short" || ${column.javaType.toLowerCase()} == "double" || ${column.javaType.toLowerCase()} == "bigdecimal")
-  ${column.javaField}: number // ${column.columnComment}
-#elseif(${column.javaType.toLowerCase()} == "date" || ${column.javaType.toLowerCase()} == "localdate" || ${column.javaType.toLowerCase()} == "localdatetime")
-  ${column.javaField}: Date // ${column.columnComment}
-#else
-  ${column.javaField}: ${column.javaType.toLowerCase()} // ${column.columnComment}
-#end
-#end
+## 特殊:主子表专属逻辑
+#foreach ($subTable in $subTables)
+  #set ($index = $foreach.count - 1)
+  #set ($subSimpleClassName = $subSimpleClassNames.get($index))
+  #set ($subColumns = $subColumnsList.get($index))##当前字段数组
+/** ${subTable.classComment}信息 */
+export interface ${subSimpleClassName} {
+  #foreach ($column in $subColumns)
+    #if ($column.createOperation || $column.updateOperation)
+      #if(${column.javaType.toLowerCase()} == "long" || ${column.javaType.toLowerCase()} == "integer" || ${column.javaType.toLowerCase()} == "short" || ${column.javaType.toLowerCase()} == "double" || ${column.javaType.toLowerCase()} == "bigdecimal")
+          ${column.javaField}#if($column.updateOperation && !$column.primaryKey && !$column.nullable)?#end: number; // ${column.columnComment}
+      #elseif(${column.javaType.toLowerCase()} == "date" || ${column.javaType.toLowerCase()} == "localdate" || ${column.javaType.toLowerCase()} == "localdatetime")
+          ${column.javaField}#if($column.updateOperation && !$column.primaryKey && !$column.nullable)?#end: string | Dayjs; // ${column.columnComment}
+      #else
+          ${column.javaField}#if($column.updateOperation && !$column.primaryKey && !$column.nullable)?#end: ${column.javaType.toLowerCase()}; // ${column.columnComment}
+      #end
+    #end
+  #end
+}
+
 #end
+/** ${table.classComment}信息 */
+export interface ${simpleClassName} {
+  #foreach ($column in $columns)
+    #if ($column.createOperation || $column.updateOperation)
+      #if(${column.javaType.toLowerCase()} == "long" || ${column.javaType.toLowerCase()} == "integer" || ${column.javaType.toLowerCase()} == "short" || ${column.javaType.toLowerCase()} == "double" || ${column.javaType.toLowerCase()} == "bigdecimal")
+          ${column.javaField}#if($column.updateOperation && !$column.primaryKey && !$column.nullable)?#end: number; // ${column.columnComment}
+      #elseif(${column.javaType.toLowerCase()} == "date" || ${column.javaType.toLowerCase()} == "localdate" || ${column.javaType.toLowerCase()} == "localdatetime")
+          ${column.javaField}#if($column.updateOperation && !$column.primaryKey && !$column.nullable)?#end: string | Dayjs; // ${column.columnComment}
+      #else
+          ${column.javaField}#if($column.updateOperation && !$column.primaryKey && !$column.nullable)?#end: ${column.javaType.toLowerCase()}; // ${column.columnComment}
+      #end
+    #end
+  #end
+  #if ( $table.templateType == 2 )
+    children?: ${simpleClassName}[];
+  #end
+  ## 特殊:主子表专属逻辑
+  #if ( $table.templateType == 10 || $table.templateType == 12 )
+    #foreach ($subTable in $subTables)
+      #set ($index = $foreach.count - 1)
+      #set ($subSimpleClassName = $subSimpleClassNames.get($index))
+      #if ( $subTable.subJoinMany )
+          ${subSimpleClassName.toLowerCase()}s?: ${subSimpleClassName}[]
+      #else
+          ${subSimpleClassName.toLowerCase()}?: ${subSimpleClassName}
+      #end
+    #end
+  #end
 }
 
 // ${table.classComment} API
@@ -36,12 +73,12 @@ export const ${simpleClassName}Api = {
   },
 
   // 新增${table.classComment}
-  create${simpleClassName}: async (data: ${simpleClassName}VO) => {
+  create${simpleClassName}: async (data: ${simpleClassName}) => {
     return await request.post({ url: `${baseURL}/create`, data })
   },
 
   // 修改${table.classComment}
-  update${simpleClassName}: async (data: ${simpleClassName}VO) => {
+  update${simpleClassName}: async (data: ${simpleClassName}) => {
     return await request.put({ url: `${baseURL}/update`, data })
   },
 
@@ -50,6 +87,13 @@ export const ${simpleClassName}Api = {
     return await request.delete({ url: `${baseURL}/delete?id=` + id })
   },
 
+#if ( $table.templateType != 2 && $deleteBatchEnable)
+  /** 批量删除${table.classComment} */
+  delete${simpleClassName}List: async (ids: number[]) => {
+    return await request.delete({ url: `${baseURL}/delete-list?ids=${ids.join(',')}` })
+  },
+#end
+
   // 导出${table.classComment} Excel
   export${simpleClassName}: async (params) => {
     return await request.download({ url: `${baseURL}/export-excel`, params })
@@ -92,12 +136,12 @@ export const ${simpleClassName}Api = {
 ## 特殊:MASTER_ERP 时,支持单个的新增、修改、删除操作
 #if ( $table.templateType == 11 )
   // 新增${subTable.classComment}
-  create${subSimpleClassName}: async (data) => {
+  create${subSimpleClassName}: async (data: ${subSimpleClassName}) => {
     return await request.post({ url: `${baseURL}/${subSimpleClassName_strikeCase}/create`, data })
   },
 
   // 修改${subTable.classComment}
-  update${subSimpleClassName}: async (data) => {
+  update${subSimpleClassName}: async (data: ${subSimpleClassName}) => {
     return await request.put({ url: `${baseURL}/${subSimpleClassName_strikeCase}/update`, data })
   },
 
@@ -106,6 +150,13 @@ export const ${simpleClassName}Api = {
     return await request.delete({ url: `${baseURL}/${subSimpleClassName_strikeCase}/delete?id=` + id })
   },
 
+  #if ($deleteBatchEnable)
+  /** 批量删除${subTable.classComment} */
+  delete${subSimpleClassName}List: async (ids: number[]) => {
+    return await request.delete({ url: `${baseURL}/${subSimpleClassName_strikeCase}/delete-list?ids=${ids.join(',')}` })
+  },
+  #end
+
   // 获得${subTable.classComment}
   get${subSimpleClassName}: async (id: number) => {
     return await request.get({ url: `${baseURL}/${subSimpleClassName_strikeCase}/get?id=` + id })

+ 4 - 4
yudao-module-infra/src/main/resources/codegen/vue3/views/components/form_sub_erp.vue.vm

@@ -113,7 +113,7 @@
 </template>
 <script setup lang="ts">
 import { getIntDictOptions, getStrDictOptions, getBoolDictOptions, DICT_TYPE } from '@/utils/dict'
-import { ${simpleClassName}Api } from '@/api/${table.moduleName}/${table.businessName}'
+import { ${simpleClassName}Api, ${subSimpleClassName} } from '@/api/${table.moduleName}/${table.businessName}'
 
 const { t } = useI18n() // 国际化
 const message = useMessage() // 消息弹窗
@@ -144,12 +144,12 @@ const formRules = reactive({
 const formRef = ref() // 表单 Ref
 
 /** 打开弹窗 */
-const open = async (type: string, id?: number, ${subJoinColumn.javaField}: number) => {
+const open = async (type: string, id?: number, ${subJoinColumn.javaField}?: number) => {
   dialogVisible.value = true
   dialogTitle.value = t('action.' + type)
   formType.value = type
   resetForm()
-  formData.value.${subJoinColumn.javaField} = ${subJoinColumn.javaField}
+  formData.value.${subJoinColumn.javaField} = ${subJoinColumn.javaField}  as any
   // 修改时,设置数据
   if (id) {
     formLoading.value = true
@@ -170,7 +170,7 @@ const submitForm = async () => {
   // 提交请求
   formLoading.value = true
   try {
-    const data = formData.value
+    const data = formData.value as unknown as  ${subSimpleClassName}
     if (formType.value === 'create') {
       await ${simpleClassName}Api.create${subSimpleClassName}(data)
       message.success(t('common.createSuccess'))

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

@@ -266,10 +266,10 @@ import { getIntDictOptions, getStrDictOptions, getBoolDictOptions, DICT_TYPE } f
 import { ${simpleClassName}Api } from '@/api/${table.moduleName}/${table.businessName}'
 
 const props = defineProps<{
-  ${subJoinColumn.javaField}: undefined // ${subJoinColumn.columnComment}(主表的关联字段)
+  ${subJoinColumn.javaField}: number // ${subJoinColumn.columnComment}(主表的关联字段)
 }>()
 const formLoading = ref(false) // 表单的加载中
-const formData = ref([])
+const formData = ref<any#if ( $subTable.subJoinMany )[]#end>(#if ( $subTable.subJoinMany )[]#else{}#end)
 const formRules = reactive({
 #foreach ($column in $subColumns)
     #if (($column.createOperation || $column.updateOperation) && !$column.nullable && !${column.primaryKey})## 创建或者更新操作 && 要求非空 && 非主键
@@ -336,7 +336,7 @@ const handleAdd = () => {
   #end
 #end
   }
-  row.${subJoinColumn.javaField} = props.${subJoinColumn.javaField}
+  row.${subJoinColumn.javaField} = props.${subJoinColumn.javaField} as any
   formData.value.push(row)
 }
 

+ 49 - 4
yudao-module-infra/src/main/resources/codegen/vue3/views/components/list_sub_erp.vue.vm

@@ -16,8 +16,31 @@
     >
       <Icon icon="ep:plus" class="mr-5px" /> 新增
     </el-button>
+    #if ($deleteBatchEnable)
+      <el-button
+          type="danger"
+          plain
+          :disabled="isEmpty(checkedIds)"
+          @click="handleDeleteBatch"
+          v-hasPermi="['${permissionPrefix}:delete']"
+      >
+        <Icon icon="ep:delete" class="mr-5px" /> 批量删除
+      </el-button>
+    #end
 #end
-    <el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
+    <el-table
+        row-key="id"
+        v-loading="loading"
+        :data="list"
+        :stripe="true"
+        :show-overflow-tooltip="true"
+        #if ($table.templateType == 11 && $deleteBatchEnable)
+        @selection-change="handleRowCheckboxChange"
+        #end
+    >
+        #if ($table.templateType == 11 && $deleteBatchEnable)
+          <el-table-column type="selection" width="55" />
+        #end
       #foreach($column in $subColumns)
       #if ($column.listOperationResult)
         #set ($dictType=$column.dictType)
@@ -85,14 +108,18 @@
 <script setup lang="ts">
 import { getIntDictOptions, getStrDictOptions, getBoolDictOptions, DICT_TYPE } from '@/utils/dict'
 import { dateFormatter } from '@/utils/formatTime'
-import { ${simpleClassName}Api } from '@/api/${table.moduleName}/${table.businessName}'
+#if ($deleteBatchEnable)
+import { isEmpty } from '@/utils/is'
+#end
+import { ${simpleClassName}Api, ${subSimpleClassName} } from '@/api/${table.moduleName}/${table.businessName}'
 #if ($table.templateType == 11)
 import ${subSimpleClassName}Form from './${subSimpleClassName}Form.vue'
 #end
 
+#if ($table.templateType == 11)
 const { t } = useI18n() // 国际化
 const message = useMessage() // 消息弹窗
-
+#end
 const props = defineProps<{
   ${subJoinColumn.javaField}?: number // ${subJoinColumn.columnComment}(主表的关联字段)
 }>()
@@ -144,12 +171,12 @@ const getList = async () => {
   }
 }
 
+#if ($table.templateType == 11)
 /** 搜索按钮操作 */
 const handleQuery = () => {
   queryParams.pageNo = 1
   getList()
 }
-#if ($table.templateType == 11)
 
 /** 添加/修改操作 */
 const formRef = ref()
@@ -173,6 +200,24 @@ const handleDelete = async (id: number) => {
     await getList()
   } catch {}
 }
+
+#if ($table.templateType == 11 && $deleteBatchEnable)
+/** 批量删除${subTable.classComment} */
+const handleDeleteBatch = async () => {
+  try {
+    // 删除的二次确认
+    await message.delConfirm()
+    await ${simpleClassName}Api.delete${subSimpleClassName}List(checkedIds.value);
+    message.success(t('common.delSuccess'))
+    await getList();
+  } catch {}
+}
+
+const checkedIds = ref<number[]>([])
+const handleRowCheckboxChange = (records: ${subSimpleClassName}[]) => {
+  checkedIds.value = records.map((item) => item.id);
+}
+#end
 #end
 #if ($table.templateType != 11)
 

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

@@ -139,7 +139,7 @@
 </template>
 <script setup lang="ts">
 import { getIntDictOptions, getStrDictOptions, getBoolDictOptions, DICT_TYPE } from '@/utils/dict'
-import { ${simpleClassName}Api, ${simpleClassName}VO } from '@/api/${table.moduleName}/${table.businessName}'
+import { ${simpleClassName}Api, ${simpleClassName} } from '@/api/${table.moduleName}/${table.businessName}'
 ## 特殊:树表专属逻辑
 #if ( $table.templateType == 2 )
 import { defaultProps, handleTree } from '@/utils/tree'
@@ -243,7 +243,7 @@ const submitForm = async () => {
   // 提交请求
   formLoading.value = true
   try {
-    const data = formData.value as unknown as ${simpleClassName}VO
+    const data = formData.value as unknown as ${simpleClassName}
 ## 特殊:主子表专属逻辑
 #if ( $table.templateType == 10 || $table.templateType == 12 )
 #if ( $subTables && $subTables.size() > 0 )

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

@@ -107,6 +107,17 @@
           <Icon icon="ep:sort" class="mr-5px" /> 展开/折叠
         </el-button>
 #end
+      #if ($table.templateType != 2 && $deleteBatchEnable)
+        <el-button
+            type="danger"
+            plain
+            :disabled="isEmpty(checkedIds)"
+            @click="handleDeleteBatch"
+            v-hasPermi="['${table.moduleName}:${simpleClassName_strikeCase}:delete']"
+        >
+          <Icon icon="ep:delete" class="mr-5px" /> 批量删除
+        </el-button>
+      #end
       </el-form-item>
     </el-form>
   </ContentWrap>
@@ -116,12 +127,16 @@
 ## 特殊:主子表专属逻辑
 #if ( $table.templateType == 11 && $subTables && $subTables.size() > 0 )
     <el-table
+      row-key="id"
       v-loading="loading"
       :data="list"
       :stripe="true"
       :show-overflow-tooltip="true"
       highlight-current-row
       @current-change="handleCurrentChange"
+      #if ($deleteBatchEnable)
+      @selection-change="handleRowCheckboxChange"
+      #end
     >
 ## 特殊:树表专属逻辑
 #elseif ( $table.templateType == 2 )
@@ -135,7 +150,19 @@
       v-if="refreshTable"
     >
 #else
-    <el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
+    <el-table
+        row-key="id"
+        v-loading="loading"
+        :data="list"
+        :stripe="true"
+        :show-overflow-tooltip="true"
+        #if ($deleteBatchEnable)
+        @selection-change="handleRowCheckboxChange"
+        #end
+    >
+#end
+#if ($table.templateType != 2 && $deleteBatchEnable)
+    <el-table-column type="selection" width="55" />
 #end
 ## 特殊:主子表专属逻辑
 #if ( $table.templateType == 12 && $subTables && $subTables.size() > 0 )
@@ -234,13 +261,14 @@
 
 <script setup lang="ts">
 import { getIntDictOptions, getStrDictOptions, getBoolDictOptions, DICT_TYPE } from '@/utils/dict'
+import { isEmpty } from '@/utils/is'
 import { dateFormatter } from '@/utils/formatTime'
 ## 特殊:树表专属逻辑
 #if ( $table.templateType == 2 )
 import { handleTree } from '@/utils/tree'
 #end
 import download from '@/utils/download'
-import { ${simpleClassName}Api, ${simpleClassName}VO } from '@/api/${table.moduleName}/${table.businessName}'
+import { ${simpleClassName}Api, ${simpleClassName} } from '@/api/${table.moduleName}/${table.businessName}'
 import ${simpleClassName}Form from './${simpleClassName}Form.vue'
 ## 特殊:主子表专属逻辑
 #if ( $table.templateType != 10 )
@@ -256,7 +284,7 @@ const message = useMessage() // 消息弹窗
 const { t } = useI18n() // 国际化
 
 const loading = ref(true) // 列表的加载中
-const list = ref<${simpleClassName}VO[]>([]) // 列表的数据
+const list = ref<${simpleClassName}[]>([]) // 列表的数据
 ## 特殊:树表专属逻辑(树不需要分页接口)
 #if ( $table.templateType != 2 )
 const total = ref(0) // 列表的总页数
@@ -330,6 +358,24 @@ const handleDelete = async (id: number) => {
   } catch {}
 }
 
+#if ($table.templateType != 2 && $deleteBatchEnable)
+/** 批量删除${table.classComment} */
+const handleDeleteBatch = async () => {
+  try {
+    // 删除的二次确认
+    await message.delConfirm()
+    await ${simpleClassName}Api.delete${simpleClassName}List(checkedIds.value);
+    message.success(t('common.delSuccess'))
+    await getList();
+  } catch {}
+}
+
+const checkedIds = ref<number[]>([])
+const handleRowCheckboxChange = (records: ${simpleClassName}[]) => {
+  checkedIds.value = records.map((item) => item.id);
+}
+#end
+
 /** 导出按钮操作 */
 const handleExport = async () => {
   try {

+ 3 - 3
yudao-module-infra/src/main/resources/codegen/vue3_vben5_antd/general/views/index.vue.vm

@@ -30,7 +30,7 @@ import { handleTree,isEmpty } from '@vben/utils'
 import { get${simpleClassName}List, delete${simpleClassName}, export${simpleClassName} } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
 #else## 标准表接口
 import { isEmpty } from '@vben/utils';
-import { get${simpleClassName}Page, delete${simpleClassName},#if ($deleteBatchEnable) delete${simpleClassName}ListByIds,#end export${simpleClassName} } from '#/api/${table.moduleName}/${table.businessName}';
+import { get${simpleClassName}Page, delete${simpleClassName},#if ($deleteBatchEnable) delete${simpleClassName}List,#end export${simpleClassName} } from '#/api/${table.moduleName}/${table.businessName}';
 #end
 import { downloadFileFromBlobPart } from '@vben/utils';
 
@@ -157,7 +157,7 @@ async function onDelete(row: ${simpleClassName}Api.${simpleClassName}) {
     hideLoading();
   }
 }
-
+// TODO @puhui999: 改成和 schema 模式一样
 #if ($table.templateType != 2 && $deleteBatchEnable)
 /** 批量删除${table.classComment} */
 async function onDeleteBatch() {
@@ -167,7 +167,7 @@ async function onDeleteBatch() {
     key: 'action_process_msg',
   });
   try {
-    await delete${simpleClassName}ListByIds(checkedIds.value);
+    await delete${simpleClassName}List(checkedIds.value);
     message.success( $t('ui.actionMessage.deleteSuccess') );
     await getList();
   } finally {

+ 2 - 2
yudao-module-infra/src/main/resources/codegen/vue3_vben5_antd/general/views/modules/list_sub_erp.vue.vm

@@ -29,7 +29,7 @@
 #end
 
 #if ($table.templateType == 11) ## erp
-    import { delete${subSimpleClassName},#if ($deleteBatchEnable) delete${subSimpleClassName}ListByIds,#end get${subSimpleClassName}Page } from '#/api/${table.moduleName}/${table.businessName}';
+    import { delete${subSimpleClassName},#if ($deleteBatchEnable) delete${subSimpleClassName}List,#end get${subSimpleClassName}Page } from '#/api/${table.moduleName}/${table.businessName}';
     import { isEmpty } from '@vben/utils';
   #else
   #if ($subTable.subJoinMany) ## 一对多
@@ -91,7 +91,7 @@ async function onDeleteBatch() {
     key: 'action_process_msg',
   });
   try {
-    await delete${subSimpleClassName}ListByIds(checkedIds.value);
+    await delete${subSimpleClassName}List(checkedIds.value);
     message.success( $t('ui.actionMessage.deleteSuccess') );
     await getList();
   } finally {

+ 3 - 2
yudao-module-infra/src/main/resources/codegen/vue3_vben5_antd/schema/views/index.vue.vm

@@ -21,7 +21,7 @@ import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
 #if (${table.templateType} == 2)## 树表接口
 import { get${simpleClassName}List, delete${simpleClassName}, export${simpleClassName} } from '#/api/${table.moduleName}/${table.businessName}';
 #else## 标准表接口
-import { get${simpleClassName}Page, delete${simpleClassName},#if ($deleteBatchEnable) delete${simpleClassName}ListByIds,#end export${simpleClassName} } from '#/api/${table.moduleName}/${table.businessName}';
+import { get${simpleClassName}Page, delete${simpleClassName},#if ($deleteBatchEnable) delete${simpleClassName}List,#end export${simpleClassName} } from '#/api/${table.moduleName}/${table.businessName}';
 #end
 import { downloadFileFromBlobPart, isEmpty } from '@vben/utils';
 
@@ -101,7 +101,8 @@ async function handleDeleteBatch() {
     key: 'action_key_msg',
   });
   try {
-    await delete${simpleClassName}ListByIds(checkedIds.value);
+    // TODO @puhui999: 移除所有模板中的 List
+    await delete${simpleClassName}List(checkedIds.value);
     message.success({
       content: $t('ui.actionMessage.deleteSuccess'),
       key: 'action_key_msg',

+ 2 - 2
yudao-module-infra/src/main/resources/codegen/vue3_vben5_antd/schema/views/modules/list_sub_erp.vue.vm

@@ -19,7 +19,7 @@ import { $t } from '#/locales';
 import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
 
 #if ($table.templateType == 11) ## erp
-import { delete${subSimpleClassName},#if ($deleteBatchEnable) delete${subSimpleClassName}ListByIds,#end get${subSimpleClassName}Page } from '#/api/${table.moduleName}/${table.businessName}';
+import { delete${subSimpleClassName},#if ($deleteBatchEnable) delete${subSimpleClassName}List,#end get${subSimpleClassName}Page } from '#/api/${table.moduleName}/${table.businessName}';
 import { use${subSimpleClassName}GridFormSchema, use${subSimpleClassName}GridColumns } from '../data';
 import { isEmpty } from '@vben/utils';
 #else
@@ -81,7 +81,7 @@ async function handleDeleteBatch() {
     key: 'action_key_msg',
   });
   try {
-    await delete${subSimpleClassName}ListByIds(checkedIds.value);
+    await delete${subSimpleClassName}List(checkedIds.value);
     message.success({
       content: $t('ui.actionMessage.deleteSuccess', [row.id]),
       key: 'action_key_msg',