From d93c1e6e3bd4a82cc1c3acc5d4286067f07ec1f3 Mon Sep 17 00:00:00 2001 From: GONGONGONG <506419689@qq.com> Date: Thu, 28 Dec 2023 16:53:58 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 6 +- .../components/common/header-render-mixins.ts | 1 + frontend/src/store/modules/agent.ts | 4 +- frontend/src/store/modules/plugin-new.ts | 1 + frontend/src/views/agent/agent-list.vue | 80 +++++++++---- .../views/plugin/plugin-list/plugin-list.vue | 109 ++++++++++++------ 6 files changed, 140 insertions(+), 61 deletions(-) diff --git a/.gitignore b/.gitignore index cd5b58fe3..936953f8f 100644 --- a/.gitignore +++ b/.gitignore @@ -188,4 +188,8 @@ build.yml ## Helm support-files/**/private_values.yaml support-files/**/*.tgz -.codecc \ No newline at end of file +.codecc +.idea +.vscode + +pre-*-bkcodeai diff --git a/frontend/src/components/common/header-render-mixins.ts b/frontend/src/components/common/header-render-mixins.ts index a6d6de71a..87f4dd36b 100644 --- a/frontend/src/components/common/header-render-mixins.ts +++ b/frontend/src/components/common/header-render-mixins.ts @@ -49,6 +49,7 @@ export default class TableHeaderRenderMixin extends Vue { width: item?.width, align: item?.align, filterList, + checkAll: !!item?.showCheckAll, showSearch: !!item?.showSearch, }, on: { diff --git a/frontend/src/store/modules/agent.ts b/frontend/src/store/modules/agent.ts index 05a793000..c8dca4d6a 100644 --- a/frontend/src/store/modules/agent.ts +++ b/frontend/src/store/modules/agent.ts @@ -170,8 +170,8 @@ export default class AgentStore extends VuexModule { * @param {*} params */ @Action - public async getFilterCondition(category = 'host') { - let data: ISearchItem[] = await getFilterCondition({ category }).catch(() => []); + public async getFilterCondition(param) { + let data: ISearchItem[] = await getFilterCondition(param).catch(() => []); data = data.map((item) => { if (item.children && item.children.length) { item.multiable = true; diff --git a/frontend/src/store/modules/plugin-new.ts b/frontend/src/store/modules/plugin-new.ts index c51a8960a..7b07acaf9 100644 --- a/frontend/src/store/modules/plugin-new.ts +++ b/frontend/src/store/modules/plugin-new.ts @@ -187,6 +187,7 @@ export default class PluginStore extends VuexModule { }); } if (item.id === 'bk_cloud_id') { + item.showCheckAll = true; item.showSearch = true; item.width = 180; item.align = 'right'; diff --git a/frontend/src/views/agent/agent-list.vue b/frontend/src/views/agent/agent-list.vue index 6931194be..99209d6c3 100644 --- a/frontend/src/views/agent/agent-list.vue +++ b/frontend/src/views/agent/agent-list.vue @@ -645,6 +645,7 @@ export default class AgentList extends Mixins(pollMixin, TableHeaderMixins, auth sort_type: '', }; private loading = true; + private loadingDelay = false; // 重新拉去过虑条件之后可能需要重置搜素框里的数据 private searchInputKey = 0; // 跨页全选loading private checkLoading = false; @@ -1011,6 +1012,47 @@ export default class AgentList extends Mixins(pollMixin, TableHeaderMixins, auth this.agentTable.doLayout(); }); } + /** + * 业务变更 + */ + @Watch('selectedBiz') + private handleBizChange(newValue: number[]) { + if (newValue.length !== 1) { + // topo未选择时 清空biz不会触发 cascade组件change事件 + if (this.search.topo.length) { + this.topoSelect.clearData(); + return false; + } + } else { + const bizIdKey = newValue.join(''); + if (Object.prototype.hasOwnProperty.call(this.topoBizFormat, bizIdKey) + && this.topoBizFormat[bizIdKey].needLoad) { + this.topoRemotehandler(this.topoBizFormat[bizIdKey], null); + } + } + this.loadingDelay = true; + this.loading = true; + this.getFilterCondition().then(() => { + const copyValue: ISearchItem[] = []; + this.searchSelectValue.forEach((item) => { + const already = this.filterData.find(opt => opt.id === item.id); + if (already) { + if (already.children?.length) { + copyValue.push({ + ...item, + values: item.values?.filter(opt => already.children?.find(child => child.id === opt.id)), + }); + } else { + copyValue.push(item); + } + } + }); + this.handleSearchSelectChange(copyValue); + this.loadingDelay = false; + this.table.pagination.current = 1; + this.initAgentListDebounce(); + }); + } private created() { this.initRouterQuery(); @@ -1021,6 +1063,19 @@ export default class AgentList extends Mixins(pollMixin, TableHeaderMixins, auth this.handleInit(); } + private async getFilterCondition() { + const param = { category: 'host' }; + if (this.selectedBiz.length) { + Object.assign(param, { bk_biz_ids: this.selectedBiz }); + } + const optSearchKeys = ['version', 'bk_cloud_id']; + const data = await AgentStore.getFilterCondition(param); + this.filterData.splice(0, this.filterData.length, ...data.map(item => (optSearchKeys.includes(item.id) + ? ({ ...item, showCheckAll: true, showSearch: true }) + : item))); + return data; + } + private async handleInit() { this.initCustomColStatus(); const { cloud, agentNum } = this.$route.params; @@ -1038,8 +1093,7 @@ export default class AgentList extends Mixins(pollMixin, TableHeaderMixins, auth // this.search.biz = this.bk_biz_id.length ? [...this.bk_biz_id] : this.selectedBiz; const searchParams: ISearchItem[] = []; const { cloud } = this.$route.params; - AgentStore.getFilterCondition().then((data) => { - this.filterData = data; + this.getFilterCondition().then((data) => { if (cloud) { searchParams.push({ name: this.filter.bk_cloud_id.name, @@ -1147,6 +1201,7 @@ export default class AgentList extends Mixins(pollMixin, TableHeaderMixins, auth * @param {Boolean} spreadChecked 是否是跨页操作 */ private async initAgentList(spreadChecked = false) { + if (this.loadingDelay) return; this.loading = true; if (!spreadChecked) { this.isSelectedAllPages = false; @@ -1349,27 +1404,6 @@ export default class AgentList extends Mixins(pollMixin, TableHeaderMixins, auth return Object.assign(params, this.getCommonCondition()); } - /** - * 业务变更 - */ - @Watch('selectedBiz') - private handleBizChange(newValue: number[]) { - if (newValue.length !== 1) { - // topo未选择时 清空biz不会触发 cascade组件change事件 - if (this.search.topo.length) { - this.topoSelect.clearData(); - return false; - } - } else { - const bizIdKey = newValue.join(''); - if (Object.prototype.hasOwnProperty.call(this.topoBizFormat, bizIdKey) - && this.topoBizFormat[bizIdKey].needLoad) { - this.topoRemotehandler(this.topoBizFormat[bizIdKey], null); - } - } - this.table.pagination.current = 1; - this.initAgentListDebounce(); - } /** * 拉取拓扑 */ diff --git a/frontend/src/views/plugin/plugin-list/plugin-list.vue b/frontend/src/views/plugin/plugin-list/plugin-list.vue index 6f25e7ef6..a84f3d65a 100644 --- a/frontend/src/views/plugin/plugin-list/plugin-list.vue +++ b/frontend/src/views/plugin/plugin-list/plugin-list.vue @@ -120,6 +120,7 @@ export default class PluginList extends Mixins(HeaderFilterMixins) { @Prop({ type: String, default: '' }) private readonly pluginName!: string; private loading = true; + private loadingDelay = false; // 重新拉去过滤条件之后可能需要重置搜素框里的数据 private tableLoading = false; private selectionLoading = false; private tableList: IPluginList[] = []; @@ -191,11 +192,39 @@ export default class PluginList extends Mixins(HeaderFilterMixins) { this.handleSearch(params); } @Watch('selectedBiz') - public handleBizSelect() { - this.getStrategyTopo(); - this.pagination.current = 1; - const params = this.getCommonParams(); - this.handleSearch(params); + public async handleBizSelect() { + this.tableLoading = true; + this.loadingDelay = true; + this.getPluginFilter().then(async () => { + await this.getStrategyTopo(); + await this.getFilterData(); + + const copyValue: ISearchItem[] = []; + this.searchSelectValue.forEach((item) => { + const already = this.filterData.find(opt => opt.id === item.id); + if (already) { + if (already.children?.length) { + copyValue.push({ + ...item, + values: item.values?.filter(opt => already.children?.find(child => child.id === opt.id)), + }); + } else { + copyValue.push(item); + } + } + }); + this.handleSearchSelectChange(copyValue); + + setTimeout(() => { + this.loadingDelay = false; + this.pagination.current = 1; + const params = this.getCommonParams(); + this.handleSearch(params); + }); + }) + .finally(() => { + this.loadingDelay = false; + }); } private async created() { @@ -228,36 +257,35 @@ export default class PluginList extends Mixins(HeaderFilterMixins) { if (initValue.length) { this.searchSelectValue.push(...initValue); } - Promise.all([this.getPluginFilter(), this.getStrategyTopo()]).then(([len, children]) => { - this.filterData.splice(len, 0, { - id: 'source_id', - name: window.i18n.t('部署策略'), - multiable: true, - children, - }); - }); - const params = this.hasOldRouteParams ? initParams as ISearchParams : this.getCommonParams(); - if (this.$route.params.policyId) { - // 修正部署策略接口未加载完毕的错误筛选条件 - const sourceConditions = params.conditions.find(item => item.key === 'source_id'); - if (sourceConditions) { - sourceConditions.value = [this.$route.params.policyId]; + this.getPluginFilter().then(async () => { + await this.getStrategyTopo(); + const params = this.hasOldRouteParams ? initParams as ISearchParams : this.getCommonParams(); + if (this.$route.params.policyId) { + // 修正部署策略接口未加载完毕的错误筛选条件 + const sourceConditions = params.conditions.find(item => item.key === 'source_id'); + if (sourceConditions) { + sourceConditions.value = [this.$route.params.policyId]; + } } - } - const promiseList: Promise[] = [ - this.getFilterData(), - this.getHostList(params), - ]; - await Promise.all(promiseList); - this.loading = false; + const promiseList: Promise[] = [ + this.getFilterData(), + this.getHostList(params), + ]; + await Promise.all(promiseList); + this.loading = false; + }); } // 拉取筛选条件 并 插入插件名称项 public async getFilterData() { + const param = { category: 'plugin_host' }; + if (this.selectedBiz.length) { + Object.assign(param, { bk_biz_ids: this.selectedBiz }); + } const [ data, { list: data2 }, - ] = await Promise.all([PluginStore.getFilterList(), PluginStore.pluginPkgList({ simple_all: true })]); + ] = await Promise.all([PluginStore.getFilterList(param), PluginStore.pluginPkgList({ simple_all: true })]); this.mixisPluginName = data.filter(item => item.children && !item.children.length).map(item => item.id); const list = data.filter(item => !item.children || item.children.length); if (data2.length) { @@ -304,15 +332,22 @@ export default class PluginList extends Mixins(HeaderFilterMixins) { if (inputValues.length) { this.searchSelectValue.splice(this.searchSelectValue.length, 0, ...inputValues); } + this.hasOldRouteParams = false; } this.filterData.splice(0, 0, ...list); return Promise.resolve(true); } public async getPluginFilter() { - const data = await PluginStore.getFilterList({ category: 'plugin_version' }); + const param = { category: 'plugin_version' }; + if (this.selectedBiz.length) { + Object.assign(param, { bk_biz_ids: this.selectedBiz }); + } + const data = await PluginStore.getFilterList(param); const statusName: string[] = []; const statusReg = /_status/; data.forEach((item) => { + item.showCheckAll = true; + item.showSearch = true; if (!statusReg.test(item.id)) { const statusItem = data.find(child => child.id === `${item.id}_status`); this.pluginStatusMap[item.id] = statusItem?.children?.map(item => item.id) || []; @@ -324,11 +359,12 @@ export default class PluginList extends Mixins(HeaderFilterMixins) { } }); const filters = data.filter(item => !statusReg.test(item.id)); - this.filterData.splice(this.filterData.length, 0, ...filters); + this.filterData.splice(0, this.filterData.length, ...filters); return filters.length; } public async getHostList(params: ISearchParams) { + if (this.loadingDelay) return; const data: IHostData = await PluginStore.getHostList(params); const { list, total } = data; this.tableList = list; @@ -348,14 +384,17 @@ export default class PluginList extends Mixins(HeaderFilterMixins) { } return list; }, []); + const sourceItem = { + id: 'source_id', + name: window.i18n.t('部署策略'), + multiable: true, + children, + }; const index = this.filterData.findIndex(item => item.id === 'source_id'); if (index > -1) { - this.filterData.splice(index, 1, { - id: 'source_id', - name: window.i18n.t('部署策略'), - multiable: true, - children, - }); + this.filterData.splice(index, 1, sourceItem); + } else { + this.filterData.splice(0, 0, sourceItem); } return children; }