From 549056a42d1f131779d700316c248b93b5b759d2 Mon Sep 17 00:00:00 2001 From: LH_R Date: Fri, 25 Apr 2025 16:33:21 +0800 Subject: [PATCH] feat(ui): IPAM - ipSearch and subnetList add batch action group --- .../views/ipam/modules/ipSearch/index.vue | 274 +++++++++++++----- .../views/ipam/modules/subnetList/index.vue | 274 +++++++++++++----- 2 files changed, 402 insertions(+), 146 deletions(-) diff --git a/cmdb-ui/src/modules/cmdb/views/ipam/modules/ipSearch/index.vue b/cmdb-ui/src/modules/cmdb/views/ipam/modules/ipSearch/index.vue index fe71354..9ca4375 100644 --- a/cmdb-ui/src/modules/cmdb/views/ipam/modules/ipSearch/index.vue +++ b/cmdb-ui/src/modules/cmdb/views/ipam/modules/ipSearch/index.vue @@ -1,79 +1,82 @@ @@ -90,7 +99,7 @@ import _ from 'lodash' import { mapState } from 'vuex' import ExcelJS from 'exceljs' import FileSaver from 'file-saver' -import { searchCI, deleteCI } from '@/modules/cmdb/api/ci' +import { searchCI, deleteCI, updateCI } from '@/modules/cmdb/api/ci' import { getSubscribeAttributes } from '@/modules/cmdb/api/preference' import { getCITypeAttributesById } from '@/modules/cmdb/api/CITypeAttr' import { getCITableColumns } from '@/modules/cmdb/utils/helper' @@ -100,6 +109,7 @@ import CITable from '@/modules/cmdb/components/ciTable/index.vue' import BatchDownload from '@/modules/cmdb/components/batchDownload/batchDownload.vue' import CIDetailDrawer from '@/modules/cmdb/views/ci/modules/ciDetailDrawer.vue' import EditAttrsPopover from '@/modules/cmdb/views/ci/modules/editAttrsPopover.vue' +import CreateInstanceForm from '@/modules/cmdb/views/ci/modules/CreateInstanceForm' export default { name: 'IPSearch', @@ -108,7 +118,8 @@ export default { CITable, BatchDownload, CIDetailDrawer, - EditAttrsPopover + EditAttrsPopover, + CreateInstanceForm }, props: { addressCIType: { @@ -122,6 +133,7 @@ export default { pageSize: 50, pageSizeOptions: ['50', '100', '200'], loading: false, + loadTip: '', sortByTable: undefined, instanceList: [], @@ -130,6 +142,7 @@ export default { preferenceAttrList: [], attrList: [], attributes: {}, + selectedRowKeys: [], } }, computed: { @@ -275,7 +288,7 @@ export default { }) }, - handleExport() { + openBatchDownload() { this.$refs.batchDownload.open({ preferenceAttrList: this.preferenceAttrList, ciTypeName: this.$t('cmdb.ipam.ipSearch') || '', @@ -336,6 +349,7 @@ export default { FileSaver.saveAs(file, `${filename}.xlsx`) }) + this.selectedRowKeys = [] this.$refs.xTable.getVxetableRef().clearCheckboxRow() this.$refs.xTable.getVxetableRef().clearCheckboxReserve() }, @@ -361,6 +375,120 @@ export default { }, }) }, + + onSelectChange(records) { + this.selectedRowKeys = records.map((i) => i.ci_id || i._id) + }, + + batchDelete() { + this.$confirm({ + title: this.$t('warning'), + content: this.$t('confirmDelete'), + onOk: () => { + this.batchDeleteAsync() + }, + }) + }, + + async batchDeleteAsync() { + let successNum = 0 + let errorNum = 0 + this.loading = true + this.loadTip = this.$t('cmdb.ci.batchDeleting') + + const floor = Math.ceil(this.selectedRowKeys.length / 6) + for (let i = 0; i < floor; i++) { + const itemList = this.selectedRowKeys.slice(6 * i, 6 * i + 6) + const promises = itemList.map((x) => deleteCI(x, false)) + await Promise.allSettled(promises) + .then((res) => { + res.forEach((r) => { + if (r.status === 'fulfilled') { + successNum += 1 + } else { + errorNum += 1 + } + }) + }) + .finally(() => { + this.loadTip = this.$t('cmdb.ci.batchDeleting2', { + total: this.selectedRowKeys.length, + successNum: successNum, + errorNum: errorNum, + }) + }) + } + + this.loading = false + this.loadTip = '' + this.selectedRowKeys = [] + this.$refs.xTable.getVxetableRef().clearCheckboxRow() + this.$refs.xTable.getVxetableRef().clearCheckboxReserve() + this.$nextTick(() => { + this.page = 1 + this.getTableData() + }) + }, + + batchUpdate(values) { + this.$confirm({ + title: this.$t('warning'), + content: this.$t('cmdb.ci.batchUpdateConfirm'), + onOk: () => { + this.batchUpdateAsync(values) + }, + }) + }, + + async batchUpdateAsync(values) { + let successNum = 0 + let errorNum = 0 + this.loading = true + this.loadTip = this.$t('cmdb.ci.batchUpdateInProgress') + '...' + + const payload = {} + Object.keys(values).forEach((key) => { + if (values[key] === undefined || values[key] === null) { + payload[key] = null + } else { + payload[key] = values[key] + } + }) + this.$refs.create.visible = false + const key = 'updatable' + let errorMsg = '' + + for (let i = 0; i < this.selectedRowKeys.length; i++) { + await updateCI(this.selectedRowKeys[i], payload, false) + .then(() => { + successNum += 1 + }) + .catch((error) => { + errorMsg = errorMsg + '\n' + `${this.selectedRowKeys[i]}:${error.response?.data?.message ?? ''}` + this.$notification.warning({ + key, + message: this.$t('warning'), + description: errorMsg, + duration: 0, + style: { whiteSpace: 'break-spaces', overflow: 'auto', maxHeight: this.windowHeight - 80 + 'px' }, + }) + errorNum += 1 + }) + .finally(() => { + this.loadTip = this.$t('cmdb.ci.batchUpdateInProgress2', { + total: this.selectedRowKeys.length, + successNum: successNum, + errorNum: errorNum, + }) + }) + } + this.loading = false + this.loadTip = '' + this.selectedRowKeys = [] + this.$refs.xTable.getVxetableRef().clearCheckboxRow() + this.$refs.xTable.getVxetableRef().clearCheckboxReserve() + this.getTableData() + }, } } diff --git a/cmdb-ui/src/modules/cmdb/views/ipam/modules/subnetList/index.vue b/cmdb-ui/src/modules/cmdb/views/ipam/modules/subnetList/index.vue index fd89ae4..325556d 100644 --- a/cmdb-ui/src/modules/cmdb/views/ipam/modules/subnetList/index.vue +++ b/cmdb-ui/src/modules/cmdb/views/ipam/modules/subnetList/index.vue @@ -1,79 +1,82 @@ @@ -90,7 +99,7 @@ import _ from 'lodash' import { mapState } from 'vuex' import ExcelJS from 'exceljs' import FileSaver from 'file-saver' -import { searchCI, deleteCI } from '@/modules/cmdb/api/ci' +import { searchCI, deleteCI, updateCI } from '@/modules/cmdb/api/ci' import { getSubscribeAttributes } from '@/modules/cmdb/api/preference' import { getCITypeAttributesById } from '@/modules/cmdb/api/CITypeAttr' import { getCITableColumns } from '@/modules/cmdb/utils/helper' @@ -100,6 +109,7 @@ import CITable from '@/modules/cmdb/components/ciTable/index.vue' import BatchDownload from '@/modules/cmdb/components/batchDownload/batchDownload.vue' import CIDetailDrawer from '@/modules/cmdb/views/ci/modules/ciDetailDrawer.vue' import EditAttrsPopover from '@/modules/cmdb/views/ci/modules/editAttrsPopover.vue' +import CreateInstanceForm from '@/modules/cmdb/views/ci/modules/CreateInstanceForm' export default { name: 'SubnetList', @@ -108,7 +118,8 @@ export default { CITable, BatchDownload, CIDetailDrawer, - EditAttrsPopover + EditAttrsPopover, + CreateInstanceForm }, props: { subnetCIType: { @@ -122,6 +133,7 @@ export default { pageSize: 50, pageSizeOptions: ['50', '100', '200'], loading: false, + loadTip: '', sortByTable: undefined, instanceList: [], @@ -130,6 +142,7 @@ export default { preferenceAttrList: [], attrList: [], attributes: {}, + selectedRowKeys: [], } }, computed: { @@ -275,7 +288,7 @@ export default { }) }, - handleExport() { + openBatchDownload() { this.$refs.batchDownload.open({ preferenceAttrList: this.preferenceAttrList, ciTypeName: this.$t('cmdb.ipam.subnetList') || '', @@ -336,6 +349,7 @@ export default { FileSaver.saveAs(file, `${filename}.xlsx`) }) + this.selectedRowKeys = [] this.$refs.xTable.getVxetableRef().clearCheckboxRow() this.$refs.xTable.getVxetableRef().clearCheckboxReserve() }, @@ -362,6 +376,120 @@ export default { }, }) }, + + onSelectChange(records) { + this.selectedRowKeys = records.map((i) => i.ci_id || i._id) + }, + + batchDelete() { + this.$confirm({ + title: this.$t('warning'), + content: this.$t('confirmDelete'), + onOk: () => { + this.batchDeleteAsync() + }, + }) + }, + + async batchDeleteAsync() { + let successNum = 0 + let errorNum = 0 + this.loading = true + this.loadTip = this.$t('cmdb.ci.batchDeleting') + + const floor = Math.ceil(this.selectedRowKeys.length / 6) + for (let i = 0; i < floor; i++) { + const itemList = this.selectedRowKeys.slice(6 * i, 6 * i + 6) + const promises = itemList.map((x) => deleteCI(x, false)) + await Promise.allSettled(promises) + .then((res) => { + res.forEach((r) => { + if (r.status === 'fulfilled') { + successNum += 1 + } else { + errorNum += 1 + } + }) + }) + .finally(() => { + this.loadTip = this.$t('cmdb.ci.batchDeleting2', { + total: this.selectedRowKeys.length, + successNum: successNum, + errorNum: errorNum, + }) + }) + } + + this.loading = false + this.loadTip = '' + this.selectedRowKeys = [] + this.$refs.xTable.getVxetableRef().clearCheckboxRow() + this.$refs.xTable.getVxetableRef().clearCheckboxReserve() + this.$nextTick(() => { + this.page = 1 + this.getTableData() + }) + }, + + batchUpdate(values) { + this.$confirm({ + title: this.$t('warning'), + content: this.$t('cmdb.ci.batchUpdateConfirm'), + onOk: () => { + this.batchUpdateAsync(values) + }, + }) + }, + + async batchUpdateAsync(values) { + let successNum = 0 + let errorNum = 0 + this.loading = true + this.loadTip = this.$t('cmdb.ci.batchUpdateInProgress') + '...' + + const payload = {} + Object.keys(values).forEach((key) => { + if (values[key] === undefined || values[key] === null) { + payload[key] = null + } else { + payload[key] = values[key] + } + }) + this.$refs.create.visible = false + const key = 'updatable' + let errorMsg = '' + + for (let i = 0; i < this.selectedRowKeys.length; i++) { + await updateCI(this.selectedRowKeys[i], payload, false) + .then(() => { + successNum += 1 + }) + .catch((error) => { + errorMsg = errorMsg + '\n' + `${this.selectedRowKeys[i]}:${error.response?.data?.message ?? ''}` + this.$notification.warning({ + key, + message: this.$t('warning'), + description: errorMsg, + duration: 0, + style: { whiteSpace: 'break-spaces', overflow: 'auto', maxHeight: this.windowHeight - 80 + 'px' }, + }) + errorNum += 1 + }) + .finally(() => { + this.loadTip = this.$t('cmdb.ci.batchUpdateInProgress2', { + total: this.selectedRowKeys.length, + successNum: successNum, + errorNum: errorNum, + }) + }) + } + this.loading = false + this.loadTip = '' + this.selectedRowKeys = [] + this.$refs.xTable.getVxetableRef().clearCheckboxRow() + this.$refs.xTable.getVxetableRef().clearCheckboxReserve() + this.getTableData() + }, } }