diff --git a/apps/web-antd/src/api/infra/codegen/index.ts b/apps/web-antd/src/api/infra/codegen/index.ts index 1c2d97ba..4fe35b04 100644 --- a/apps/web-antd/src/api/infra/codegen/index.ts +++ b/apps/web-antd/src/api/infra/codegen/index.ts @@ -148,3 +148,10 @@ export function deleteCodegenTable(tableId: number) { params: { tableId }, }); } + +/** 批量删除代码生成表定义 */ +export function deleteCodegenTableList(tableIds: number[]) { + return requestClient.delete( + `/infra/codegen/delete-list?tableIds=${tableIds.join(',')}`, + ); +} diff --git a/apps/web-antd/src/api/infra/config/index.ts b/apps/web-antd/src/api/infra/config/index.ts index 3911e01c..521e957a 100644 --- a/apps/web-antd/src/api/infra/config/index.ts +++ b/apps/web-antd/src/api/infra/config/index.ts @@ -54,6 +54,11 @@ export function deleteConfig(id: number) { return requestClient.delete(`/infra/config/delete?id=${id}`); } +/** 批量删除参数 */ +export function deleteConfigList(ids: number[]) { + return requestClient.delete(`/infra/config/delete-list?ids=${ids.join(',')}`); +} + /** 导出参数 */ export function exportConfig(params: any) { return requestClient.download('/infra/config/export', { diff --git a/apps/web-antd/src/api/infra/file-config/index.ts b/apps/web-antd/src/api/infra/file-config/index.ts index a16cf2bc..20a0ab3f 100644 --- a/apps/web-antd/src/api/infra/file-config/index.ts +++ b/apps/web-antd/src/api/infra/file-config/index.ts @@ -69,6 +69,13 @@ export function deleteFileConfig(id: number) { return requestClient.delete(`/infra/file-config/delete?id=${id}`); } +/** 批量删除文件配置 */ +export function deleteFileConfigList(ids: number[]) { + return requestClient.delete( + `/infra/file-config/delete-list?ids=${ids.join(',')}`, + ); +} + /** 测试文件配置 */ export function testFileConfig(id: number) { return requestClient.get(`/infra/file-config/test?id=${id}`); diff --git a/apps/web-antd/src/api/infra/file/index.ts b/apps/web-antd/src/api/infra/file/index.ts index a399db67..edf06933 100644 --- a/apps/web-antd/src/api/infra/file/index.ts +++ b/apps/web-antd/src/api/infra/file/index.ts @@ -45,6 +45,11 @@ export function deleteFile(id: number) { return requestClient.delete(`/infra/file/delete?id=${id}`); } +/** 批量删除文件 */ +export function deleteFileList(ids: number[]) { + return requestClient.delete(`/infra/file/delete-list?ids=${ids.join(',')}`); +} + /** 获取文件预签名地址 */ export function getFilePresignedUrl(name: string, directory?: string) { return requestClient.get( diff --git a/apps/web-antd/src/api/infra/job/index.ts b/apps/web-antd/src/api/infra/job/index.ts index bacdbc4a..05f6a727 100644 --- a/apps/web-antd/src/api/infra/job/index.ts +++ b/apps/web-antd/src/api/infra/job/index.ts @@ -46,6 +46,11 @@ export function deleteJob(id: number) { return requestClient.delete(`/infra/job/delete?id=${id}`); } +/** 批量删除定时任务调度 */ +export function deleteJobList(ids: number[]) { + return requestClient.delete(`/infra/job/delete-list?ids=${ids.join(',')}`); +} + /** 导出定时任务调度 */ export function exportJob(params: any) { return requestClient.download('/infra/job/export-excel', { params }); diff --git a/apps/web-antd/src/views/infra/codegen/data.ts b/apps/web-antd/src/views/infra/codegen/data.ts index a2b50d9c..928f2700 100644 --- a/apps/web-antd/src/views/infra/codegen/data.ts +++ b/apps/web-antd/src/views/infra/codegen/data.ts @@ -394,6 +394,7 @@ export function useGridColumns( getDataSourceConfigName?: (dataSourceConfigId: number) => string | undefined, ): VxeTableGridOptions['columns'] { return [ + { type: 'checkbox', width: 40 }, { field: 'dataSourceConfigId', title: '数据源', diff --git a/apps/web-antd/src/views/infra/codegen/index.vue b/apps/web-antd/src/views/infra/codegen/index.vue index 467b84fb..1e113ace 100644 --- a/apps/web-antd/src/views/infra/codegen/index.vue +++ b/apps/web-antd/src/views/infra/codegen/index.vue @@ -7,12 +7,14 @@ import { ref } from 'vue'; import { useRouter } from 'vue-router'; import { DocAlert, Page, useVbenModal } from '@vben/common-ui'; +import { isEmpty } from '@vben/utils'; import { message } from 'ant-design-vue'; import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table'; import { deleteCodegenTable, + deleteCodegenTableList, downloadCodegen, getCodegenTablePage, syncCodegenFromDB, @@ -82,6 +84,31 @@ async function handleDelete(row: InfraCodegenApi.CodegenTable) { } } +const checkedIds = ref([]); +function handleRowCheckboxChange({ + records, +}: { + records: InfraCodegenApi.CodegenTable[]; +}) { + checkedIds.value = records.map((item) => item.id); +} + +/** 批量删除代码生成配置 */ +async function handleDeleteBatch() { + const hideLoading = message.loading({ + content: $t('ui.actionMessage.deleting'), + duration: 0, + key: 'action_process_msg', + }); + try { + await deleteCodegenTableList(checkedIds.value); + message.success($t('ui.actionMessage.deleteSuccess')); + onRefresh(); + } finally { + hideLoading(); + } +} + /** 同步数据库 */ async function handleSync(row: InfraCodegenApi.CodegenTable) { const hideLoading = message.loading({ @@ -145,12 +172,17 @@ const [Grid, gridApi] = useVbenVxeGrid({ }, rowConfig: { keyField: 'id', + isHover: true, }, toolbarConfig: { refresh: { code: 'query' }, search: true, }, } as VxeTableGridOptions, + gridEvents: { + checkboxAll: handleRowCheckboxChange, + checkboxChange: handleRowCheckboxChange, + }, }); /** 获取数据源配置列表 */ @@ -196,6 +228,15 @@ initDataSourceConfig(); auth: ['infra:codegen:create'], onClick: handleImport, }, + { + label: '批量删除', + type: 'primary', + danger: true, + disabled: isEmpty(checkedIds), + icon: ACTION_ICON.DELETE, + auth: ['infra:codegen:delete'], + onClick: handleDeleteBatch, + }, ]" /> diff --git a/apps/web-antd/src/views/infra/config/data.ts b/apps/web-antd/src/views/infra/config/data.ts index ae886c47..612b00ce 100644 --- a/apps/web-antd/src/views/infra/config/data.ts +++ b/apps/web-antd/src/views/infra/config/data.ts @@ -119,6 +119,7 @@ export function useGridFormSchema(): VbenFormSchema[] { /** 列表的字段 */ export function useGridColumns(): VxeTableGridOptions['columns'] { return [ + { type: 'checkbox', width: 40 }, { field: 'id', title: '参数主键', diff --git a/apps/web-antd/src/views/infra/config/index.vue b/apps/web-antd/src/views/infra/config/index.vue index 9d4d6d0c..b1950e6a 100644 --- a/apps/web-antd/src/views/infra/config/index.vue +++ b/apps/web-antd/src/views/infra/config/index.vue @@ -2,13 +2,20 @@ import type { VxeTableGridOptions } from '#/adapter/vxe-table'; import type { InfraConfigApi } from '#/api/infra/config'; +import { ref } from 'vue'; + import { Page, useVbenModal } from '@vben/common-ui'; -import { downloadFileFromBlobPart } from '@vben/utils'; +import { downloadFileFromBlobPart, isEmpty } from '@vben/utils'; import { message } from 'ant-design-vue'; import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table'; -import { deleteConfig, exportConfig, getConfigPage } from '#/api/infra/config'; +import { + deleteConfig, + deleteConfigList, + exportConfig, + getConfigPage, +} from '#/api/infra/config'; import { $t } from '#/locales'; import { useGridColumns, useGridFormSchema } from './data'; @@ -59,6 +66,31 @@ async function handleDelete(row: InfraConfigApi.Config) { } } +const checkedIds = ref([]); +function handleRowCheckboxChange({ + records, +}: { + records: InfraConfigApi.Config[]; +}) { + checkedIds.value = records.map((item) => item.id as number); +} + +/** 批量删除参数 */ +async function handleDeleteBatch() { + const hideLoading = message.loading({ + content: $t('ui.actionMessage.deleting'), + duration: 0, + key: 'action_process_msg', + }); + try { + await deleteConfigList(checkedIds.value); + message.success($t('ui.actionMessage.deleteSuccess')); + onRefresh(); + } finally { + hideLoading(); + } +} + const [Grid, gridApi] = useVbenVxeGrid({ formOptions: { schema: useGridFormSchema(), @@ -80,12 +112,17 @@ const [Grid, gridApi] = useVbenVxeGrid({ }, rowConfig: { keyField: 'id', + isHover: true, }, toolbarConfig: { refresh: { code: 'query' }, search: true, }, } as VxeTableGridOptions, + gridEvents: { + checkboxAll: handleRowCheckboxChange, + checkboxChange: handleRowCheckboxChange, + }, }); @@ -110,6 +147,15 @@ const [Grid, gridApi] = useVbenVxeGrid({ auth: ['infra:config:export'], onClick: handleExport, }, + { + label: '批量删除', + type: 'primary', + danger: true, + disabled: isEmpty(checkedIds), + icon: ACTION_ICON.DELETE, + auth: ['infra:config:delete'], + onClick: handleDeleteBatch, + }, ]" /> diff --git a/apps/web-antd/src/views/infra/file/data.ts b/apps/web-antd/src/views/infra/file/data.ts index 3b9eecb1..53293955 100644 --- a/apps/web-antd/src/views/infra/file/data.ts +++ b/apps/web-antd/src/views/infra/file/data.ts @@ -54,6 +54,7 @@ export function useGridFormSchema(): VbenFormSchema[] { /** 列表的字段 */ export function useGridColumns(): VxeTableGridOptions['columns'] { return [ + { type: 'checkbox', width: 40 }, { field: 'name', title: '文件名', diff --git a/apps/web-antd/src/views/infra/file/index.vue b/apps/web-antd/src/views/infra/file/index.vue index 6d55c409..b9df5e8a 100644 --- a/apps/web-antd/src/views/infra/file/index.vue +++ b/apps/web-antd/src/views/infra/file/index.vue @@ -2,14 +2,16 @@ import type { VxeTableGridOptions } from '#/adapter/vxe-table'; import type { InfraFileApi } from '#/api/infra/file'; +import { ref } from 'vue'; + import { Page, useVbenModal } from '@vben/common-ui'; -import { openWindow } from '@vben/utils'; +import { isEmpty, openWindow } from '@vben/utils'; import { useClipboard } from '@vueuse/core'; import { Button, Image, message } from 'ant-design-vue'; import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table'; -import { deleteFile, getFilePage } from '#/api/infra/file'; +import { deleteFile, deleteFileList, getFilePage } from '#/api/infra/file'; import { $t } from '#/locales'; import { useGridColumns, useGridFormSchema } from './data'; @@ -64,6 +66,31 @@ async function handleDelete(row: InfraFileApi.File) { } } +const checkedIds = ref([]); +function handleRowCheckboxChange({ + records, +}: { + records: InfraFileApi.File[]; +}) { + checkedIds.value = records.map((item) => item.id as number); +} + +/** 批量删除文件 */ +async function handleDeleteBatch() { + const hideLoading = message.loading({ + content: $t('ui.actionMessage.deleting'), + duration: 0, + key: 'action_process_msg', + }); + try { + await deleteFileList(checkedIds.value); + message.success($t('ui.actionMessage.deleteSuccess')); + onRefresh(); + } finally { + hideLoading(); + } +} + const [Grid, gridApi] = useVbenVxeGrid({ formOptions: { schema: useGridFormSchema(), @@ -85,12 +112,17 @@ const [Grid, gridApi] = useVbenVxeGrid({ }, rowConfig: { keyField: 'id', + isHover: true, }, toolbarConfig: { refresh: { code: 'query' }, search: true, }, } as VxeTableGridOptions, + gridEvents: { + checkboxAll: handleRowCheckboxChange, + checkboxChange: handleRowCheckboxChange, + }, }); @@ -108,6 +140,15 @@ const [Grid, gridApi] = useVbenVxeGrid({ auth: ['infra:file:create'], onClick: handleUpload, }, + { + label: '批量删除', + type: 'primary', + danger: true, + disabled: isEmpty(checkedIds), + icon: ACTION_ICON.DELETE, + auth: ['infra:file:delete'], + onClick: handleDeleteBatch, + }, ]" /> diff --git a/apps/web-antd/src/views/infra/fileConfig/data.ts b/apps/web-antd/src/views/infra/fileConfig/data.ts index 84d1178e..58cc4cd9 100644 --- a/apps/web-antd/src/views/infra/fileConfig/data.ts +++ b/apps/web-antd/src/views/infra/fileConfig/data.ts @@ -262,6 +262,7 @@ export function useGridFormSchema(): VbenFormSchema[] { /** 列表的字段 */ export function useGridColumns(): VxeTableGridOptions['columns'] { return [ + { type: 'checkbox', width: 40 }, { field: 'id', title: '编号', diff --git a/apps/web-antd/src/views/infra/fileConfig/index.vue b/apps/web-antd/src/views/infra/fileConfig/index.vue index 9f0c5332..06418759 100644 --- a/apps/web-antd/src/views/infra/fileConfig/index.vue +++ b/apps/web-antd/src/views/infra/fileConfig/index.vue @@ -2,14 +2,17 @@ import type { VxeTableGridOptions } from '#/adapter/vxe-table'; import type { InfraFileConfigApi } from '#/api/infra/file-config'; +import { ref } from 'vue'; + import { confirm, Page, useVbenModal } from '@vben/common-ui'; -import { openWindow } from '@vben/utils'; +import { isEmpty, openWindow } from '@vben/utils'; import { message } from 'ant-design-vue'; import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table'; import { deleteFileConfig, + deleteFileConfigList, getFileConfigPage, testFileConfig, updateFileConfigMaster, @@ -97,6 +100,31 @@ async function handleDelete(row: InfraFileConfigApi.FileConfig) { } } +const checkedIds = ref([]); +function handleRowCheckboxChange({ + records, +}: { + records: InfraFileConfigApi.FileConfig[]; +}) { + checkedIds.value = records.map((item) => item.id as number); +} + +/** 批量删除文件配置 */ +async function handleDeleteBatch() { + const hideLoading = message.loading({ + content: $t('ui.actionMessage.deleting'), + duration: 0, + key: 'action_process_msg', + }); + try { + await deleteFileConfigList(checkedIds.value); + message.success($t('ui.actionMessage.deleteSuccess')); + onRefresh(); + } finally { + hideLoading(); + } +} + const [Grid, gridApi] = useVbenVxeGrid({ formOptions: { schema: useGridFormSchema(), @@ -118,12 +146,17 @@ const [Grid, gridApi] = useVbenVxeGrid({ }, rowConfig: { keyField: 'id', + isHover: true, }, toolbarConfig: { refresh: { code: 'query' }, search: true, }, } as VxeTableGridOptions, + gridEvents: { + checkboxAll: handleRowCheckboxChange, + checkboxChange: handleRowCheckboxChange, + }, }); @@ -141,6 +174,15 @@ const [Grid, gridApi] = useVbenVxeGrid({ auth: ['infra:file-config:create'], onClick: handleCreate, }, + { + label: '批量删除', + type: 'primary', + danger: true, + disabled: isEmpty(checkedIds), + icon: ACTION_ICON.DELETE, + auth: ['infra:file-config:delete'], + onClick: handleDeleteBatch, + }, ]" /> diff --git a/apps/web-antd/src/views/infra/job/data.ts b/apps/web-antd/src/views/infra/job/data.ts index 982ee9f9..0f1e663d 100644 --- a/apps/web-antd/src/views/infra/job/data.ts +++ b/apps/web-antd/src/views/infra/job/data.ts @@ -129,6 +129,7 @@ export function useGridFormSchema(): VbenFormSchema[] { /** 表格列配置 */ export function useGridColumns(): VxeTableGridOptions['columns'] { return [ + { type: 'checkbox', width: 40 }, { field: 'id', title: '任务编号', diff --git a/apps/web-antd/src/views/infra/job/index.vue b/apps/web-antd/src/views/infra/job/index.vue index 8830573b..c3b63002 100644 --- a/apps/web-antd/src/views/infra/job/index.vue +++ b/apps/web-antd/src/views/infra/job/index.vue @@ -2,16 +2,18 @@ import type { VxeTableGridOptions } from '#/adapter/vxe-table'; import type { InfraJobApi } from '#/api/infra/job'; +import { ref } from 'vue'; import { useRouter } from 'vue-router'; import { confirm, DocAlert, Page, useVbenModal } from '@vben/common-ui'; -import { downloadFileFromBlobPart } from '@vben/utils'; +import { downloadFileFromBlobPart, isEmpty } from '@vben/utils'; import { message } from 'ant-design-vue'; import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table'; import { deleteJob, + deleteJobList, exportJob, getJobPage, runJob, @@ -114,6 +116,27 @@ async function handleDelete(row: InfraJobApi.Job) { } } +const checkedIds = ref([]); +function handleRowCheckboxChange({ records }: { records: InfraJobApi.Job[] }) { + checkedIds.value = records.map((item) => item.id as number); +} + +/** 批量删除任务 */ +async function handleDeleteBatch() { + const hideLoading = message.loading({ + content: $t('ui.actionMessage.deleting'), + duration: 0, + key: 'action_process_msg', + }); + try { + await deleteJobList(checkedIds.value); + message.success($t('ui.actionMessage.deleteSuccess')); + onRefresh(); + } finally { + hideLoading(); + } +} + const [Grid, gridApi] = useVbenVxeGrid({ formOptions: { schema: useGridFormSchema(), @@ -135,12 +158,17 @@ const [Grid, gridApi] = useVbenVxeGrid({ }, rowConfig: { keyField: 'id', + isHover: true, }, toolbarConfig: { refresh: { code: 'query' }, search: true, }, } as VxeTableGridOptions, + gridEvents: { + checkboxAll: handleRowCheckboxChange, + checkboxChange: handleRowCheckboxChange, + }, }); @@ -177,7 +205,16 @@ const [Grid, gridApi] = useVbenVxeGrid({ type: 'primary', icon: 'lucide:history', auth: ['infra:job:export'], - onClick: handleExport, + onClick: handleLog, + }, + { + label: '批量删除', + type: 'primary', + danger: true, + disabled: isEmpty(checkedIds), + icon: ACTION_ICON.DELETE, + auth: ['infra:job:delete'], + onClick: handleDeleteBatch, }, ]" />