Skip to content

Commit

Permalink
perf(frontend): mongodb工具箱重构_缩容Shard节点数 #8498
Browse files Browse the repository at this point in the history
  • Loading branch information
3octaves committed Jan 23, 2025
1 parent ff7f06b commit 2d4c365
Show file tree
Hide file tree
Showing 5 changed files with 377 additions and 9 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,334 @@
<!--
* TencentBlueKing is pleased to support the open source community by making 蓝鲸智云-DB管理系统(BlueKing-BK-DBM) available.
*
* Copyright (C) 2017-2023 THL A29 Limited, a Tencent company. All rights reserved.
*
* Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License athttps://opensource.org/licenses/MIT
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for
* the specific language governing permissions and limitations under the License.
-->

<template>
<SmartAction>
<div class="proxy-scale-down-page">
<BkAlert
closable
theme="info"
:title="t('缩容Shard节点数:xxx')" />
<DbForm
ref="form"
class="toolbox-form mt-16"
form-type="vertical"
:model="formData">
<EditableTable
ref="editableTable"
class="mt16 mb16"
:model="formData.tableData"
:rules="rules">
<EditableRow
v-for="(item, index) in formData.tableData"
:key="index">
<ClusterWithRelatedClustersColumn
v-model="item.cluster"
:cluster-types="[ClusterTypes.MONGO_REPLICA_SET, ClusterTypes.MONGO_SHARED_CLUSTER]"
:selected="selected"
@batch-edit="handleClusterBatchEdit" />
<EditableColumn
:label="t('集群类型')"
:width="200">
<EditableBlock
v-model="item.cluster.cluster_type_name"
:placeholder="t('输入集群后自动生成')" />
</EditableColumn>
<EditableColumn
:label="t('当前 Shard 的节点数')"
:width="200">
<EditableBlock :placeholder="t('输入集群后自动生成')">
{{ item.cluster.shard_node_count }}
</EditableBlock>
</EditableColumn>
<EditableColumn
field="target_num"
:label="t('缩容至(节点数)')"
required
:width="200">
<EditableInput
v-model="item.target_num"
:disabled="!item.cluster.id"
:max="item.cluster.shard_node_count"
:min="1"
type="number" />
</EditableColumn>
<OperationColumn
:create-row-method="createRowData"
:table-data="formData.tableData" />
</EditableRow>
</EditableTable>
<IgnoreBiz
v-model="formData.is_ignore_business_access"
v-bk-tooltips="t('如忽略_有连接的情况下也会执行')" />
<TicketPayload v-model="formData" />
</DbForm>
</div>
<template #action>
<BkButton
class="w-88"
:loading="isSubmitting"
theme="primary"
@click="handleSubmit">
{{ t('提交') }}
</BkButton>
<DbPopconfirm
:confirm-handler="handleReset"
:content="t('重置将会清空当前填写的所有内容_请谨慎操作')"
:title="t('确认重置页面')">
<BkButton
class="ml-8 w-88"
:disabled="isSubmitting">
{{ t('重置') }}
</BkButton>
</DbPopconfirm>
</template>
</SmartAction>
</template>

<script setup lang="tsx">
import type { ComponentProps } from 'vue-component-type-helpers';
import { useI18n } from 'vue-i18n';

import MongodbModel from '@services/model/mongodb/mongodb';
import type { Mongodb } from '@services/model/ticket/ticket';

import { useCreateTicket, useTicketDetail } from '@hooks';

import { ClusterTypes, TicketTypes } from '@common/const';

import IgnoreBiz from '@views/db-manage/common/toolbox-field/form-item/ignore-biz/Index.vue';
import TicketPayload, {
createTickePayload,
} from '@views/db-manage/common/toolbox-field/form-item/ticket-payload/Index.vue';
import ClusterColumn from '@views/db-manage/mongodb/common/toolbox-field/cluster-column/Index.vue';
import ClusterWithRelatedClustersColumn from '@views/db-manage/mongodb/common/toolbox-field/cluster-with-related-clusters-column/Index.vue';

export interface IDataRow {
cluster: {
id: number;
master_domain: string;
related_clusters: {
id: number;
domain: string;
}[];
cluster_type: string;
cluster_type_name: string;
shard_node_count: number;
machine_instance_num: number;
shard_num: number;
};
target_num: number;
}

const createRowData = (values = {} as Partial<IDataRow>) => ({
cluster: Object.assign(
{
id: 0,
master_domain: '',
related_clusters: [] as IDataRow['cluster']['related_clusters'],
cluster_type: '',
cluster_type_name: '',
shard_node_count: 0,
machine_instance_num: 0,
shard_num: 0,
},
values.cluster,
),
target_num: values.target_num || 0,
});

const createDefaultFormData = () => ({
tableData: [createRowData()],
is_ignore_business_access: false,
...createTickePayload(),
});

const { t } = useI18n();

useTicketDetail<Mongodb.ReduceShardNodes>(TicketTypes.MONGODB_REDUCE_SHARD_NODES, {
onSuccess(ticketDetail) {
const { details, remark } = ticketDetail;
const { infos, clusters, is_safe: isSafe } = details;
formData.tableData = infos.map((item) => {
const clusterItem = clusters[item.cluster_ids[0]];
return createRowData({
cluster: {
master_domain: clusterItem.immute_domain,
} as IDataRow['cluster'],
target_num: item.current_shard_nodes_num - item.reduce_shard_nodes,
});
});
Object.assign(formData, {
is_ignore_business_access: !isSafe,
remark,
});
},
});

const { run: createTicketRun, loading: isSubmitting } = useCreateTicket<{
infos: {
cluster_ids: number[];
current_shard_nodes_num: number; // 当前shard节点数
reduce_shard_nodes: number; // 当前 - 缩容至
shard_num: number; // 分片数
machine_instance_num: number; // 单机部署实例
}[];
is_safe: boolean;
}>(TicketTypes.MONGODB_REDUCE_SHARD_NODES);

const formRef = useTemplateRef('form');
const editableTableRef = useTemplateRef('editableTable');

const rules = {
'cluster.master_domain': [
{
validator: (value: string) => {
if (value) {
return domainList.value.filter((domain) => domain === value).length === 1;
}
return true;
},
trigger: 'change',
message: t('目标集群重复'),
},
],
target_num: [
{
validator: (value: number, rowData: IDataRow) => value < Number(rowData.cluster.shard_node_count),
trigger: 'change',
message: t('必须小于当前节点数'),
},
{
validator: (value: number) => value >= 3,
trigger: 'change',
message: t('不能少于n台', { n: 3 }),
},
],
};

const formData = reactive(createDefaultFormData());

const selected = computed(() => {
const selectedClusters: ComponentProps<typeof ClusterColumn>['selected'] = {
[ClusterTypes.MONGO_REPLICA_SET]: [],
[ClusterTypes.MONGO_SHARED_CLUSTER]: [],
};
formData.tableData.forEach((tableRow) => {
const { id, cluster_type: clusterType, master_domain: masterDomain } = tableRow.cluster;
if (id) {
selectedClusters[clusterType as keyof typeof selectedClusters].push({
id,
master_domain: masterDomain,
});
}
});
return selectedClusters;
});

const clusterMemo = computed(() =>
Object.fromEntries(
Object.values(selected.value).flatMap((clusters) =>
clusters.filter((cluster) => cluster.master_domain).map((cluster) => [cluster.master_domain, true]),
),
),
);

const domainList = computed(() =>
formData.tableData.flatMap((tableRow) => {
if (tableRow.cluster.master_domain) {
return [
tableRow.cluster.master_domain,
...tableRow.cluster.related_clusters.map((relatedItem) => relatedItem.domain),
];
}
return [];
}),
);

const handleClusterBatchEdit = (clusterList: MongodbModel[]) => {
const newList: IDataRow[] = [];
clusterList.forEach((item) => {
if (!clusterMemo.value[item.master_domain]) {
newList.push(
createRowData({
cluster: {
id: item.id,
master_domain: item.master_domain,
related_clusters: [],
cluster_type: item.cluster_type,
cluster_type_name: item.cluster_type_name,
shard_node_count: item.shard_node_count,
machine_instance_num: item.machine_instance_num,
shard_num: item.shard_num,
},
}),
);
}
});
formData.tableData = [...(formData.tableData[0].cluster.master_domain ? formData.tableData : []), ...newList];
window.changeConfirm = true;
};

const handleSubmit = async () => {
await formRef.value!.validate();
const validateResult = await editableTableRef.value!.validate();
if (validateResult) {
createTicketRun({
details: {
is_safe: !formData.is_ignore_business_access,
infos: formData.tableData.map((tableRow) => {
const cluster = tableRow.cluster as Required<IDataRow['cluster']>;
const targerNum = tableRow.target_num;
return {
cluster_ids:
cluster.cluster_type === ClusterTypes.MONGO_REPLICA_SET
? [cluster.id, ...cluster.related_clusters.map((relatedItem) => relatedItem.id)]
: [cluster.id],
reduce_shard_nodes: cluster.shard_node_count - targerNum, // 当前 - 缩容至
current_shard_nodes_num: cluster.shard_node_count, // 当前shard节点数
shard_num: cluster.shard_num, // 分片数
machine_instance_num: cluster.machine_instance_num, // 单机部署实例
};
}),
},
remark: formData.remark,
});
}
};

const handleReset = () => {
Object.assign(formData, createDefaultFormData());
window.changeConfirm = false;
};
</script>

<style lang="less" scoped>
.proxy-scale-down-page {
padding-bottom: 20px;

.page-action-box {
display: flex;
align-items: center;
margin-top: 16px;

.safe-action {
margin-left: auto;

.safe-action-text {
padding-bottom: 2px;
border-bottom: 1px dashed #979ba5;
}
}
}
}
</style>
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<!--
* TencentBlueKing is pleased to support the open source community by making 蓝鲸智云-DB管理系统(BlueKing-BK-DBM) available.
*
* Copyright (C) 2017-2023 THL A29 Limited, a Tencent company. All rights reserved.
*
* Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License athttps://opensource.org/licenses/MIT
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for
* the specific language governing permissions and limitations under the License.
-->

<template>
<Component :is="components[page]" />
</template>
<script setup lang="ts">
import { useRoute } from 'vue-router';

import Page2 from '@views/db-manage/common/create-ticket-success/Index.vue';

import Page1 from './Create.vue';

const route = useRoute();

const components = {
create: Page1,
success: Page2,
};

const page = computed(() => (route.params.page as keyof typeof components) || 'create');
</script>
17 changes: 9 additions & 8 deletions dbm-ui/frontend/src/views/db-manage/mongodb/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,15 @@ export const mongoToolboxChildrenRoutes: RouteRecordRaw[] = [
// component: () => import('@views/db-manage/mongodb/shard-scale-up/Index.vue'),
// },
createRouteItem(TicketTypes.MONGODB_ADD_SHARD_NODES, t('扩容Shard节点数')),
{
name: 'MongoShardScaleDown',
path: 'shard-scale-down/:page?',
meta: {
navName: t('缩容Shard节点数'),
},
component: () => import('@views/db-manage/mongodb/shard-scale-down/Index.vue'),
},
// {
// name: 'MongoShardScaleDown',
// path: 'shard-scale-down/:page?',
// meta: {
// navName: t('缩容Shard节点数'),
// },
// component: () => import('@views/db-manage/mongodb/shard-scale-down/Index.vue'),
// },
createRouteItem(TicketTypes.MONGODB_REDUCE_SHARD_NODES, t('缩容Shard节点数')),
// {
// name: 'MongoCapacityChange',
// path: 'capacity-change/:page?',
Expand Down
Loading

0 comments on commit 2d4c365

Please sign in to comment.