Skip to content

Commit 9c3f808

Browse files
committed
perf(frontend): redis工具箱重构_迁移 #8840
1 parent 2af9cea commit 9c3f808

File tree

12 files changed

+1766
-38
lines changed

12 files changed

+1766
-38
lines changed

dbm-ui/frontend/src/components/instance-selector/Index.vue

+1
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@
129129
master_domain: string;
130130
immute_domain: string;
131131
cluster_type: string;
132+
major_version: string;
132133
}[];
133134
related_instances: {
134135
cluster_id: number;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<!--
2+
* TencentBlueKing is pleased to support the open source community by making 蓝鲸智云-DB管理系统(BlueKing-BK-DBM) available.
3+
*
4+
* Copyright (C) 2017-2023 THL A29 Limited, a Tencent company. All rights reserved.
5+
*
6+
* Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License athttps://opensource.org/licenses/MIT
8+
*
9+
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
10+
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for
11+
* the specific language governing permissions and limitations under the License.
12+
-->
13+
14+
<template>
15+
<Component :is="components[page]" />
16+
</template>
17+
<script setup lang="ts">
18+
import { useRoute } from 'vue-router';
19+
20+
import Page2 from '@views/db-manage/common/create-ticket-success/Index.vue';
21+
22+
import Page1 from './create/Index.vue';
23+
24+
const route = useRoute();
25+
26+
const components = {
27+
create: Page1,
28+
success: Page2,
29+
};
30+
31+
const page = computed(() => (route.params.page as keyof typeof components) || 'create');
32+
</script>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,298 @@
1+
<!--
2+
* TencentBlueKing is pleased to support the open source community by making 蓝鲸智云-DB管理系统(BlueKing-BK-DBM) available.
3+
*
4+
* Copyright (C) 2017-2023 THL A29 Limited, a Tencent company. All rights reserved.
5+
*
6+
* Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License athttps://opensource.org/licenses/MIT
8+
*
9+
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
10+
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for
11+
* the specific language governing permissions and limitations under the License.
12+
-->
13+
14+
<template>
15+
<SmartAction>
16+
<div class="redis-migrate">
17+
<BkAlert
18+
closable
19+
theme="info"
20+
:title="
21+
t(
22+
'集群架构:将集群的部分实例迁移到新机器,迁移保持规格、版本不变;主从架构:主从实例成对迁移到新机器上,可选择部分实例迁移,也可整机所有实例一起迁移。',
23+
)
24+
" />
25+
<DbForm
26+
class="toolbox-form mt-16 mb-24"
27+
form-type="vertical"
28+
:model="formData">
29+
<BkFormItem
30+
:label="t('升级类型')"
31+
property="updateType"
32+
required>
33+
<CardCheckbox
34+
v-model="formData.architectureType"
35+
:desc="t('如 TendisCache 等,迁移过程保持规格、版本不变')"
36+
icon="cluster"
37+
:title="t('集群架构')"
38+
true-value="cluster" />
39+
<CardCheckbox
40+
v-model="formData.architectureType"
41+
class="ml-8"
42+
:desc="t('支持部分或整机所有实例成对迁移至新主机,版本规格可变')"
43+
:disabled-tooltips="t('单节点仅支持原地升级')"
44+
icon="gaokeyong"
45+
:title="t('主从架构')"
46+
true-value="masterSlave" />
47+
</BkFormItem>
48+
<BkFormItem
49+
:label="t('迁移类型')"
50+
property="updateType"
51+
required>
52+
<CardCheckbox
53+
v-model="formData.migrateType"
54+
:desc="t('只迁移目标实例')"
55+
icon="fill-1"
56+
:title="t('实例迁移')"
57+
true-value="instance" />
58+
<CardCheckbox
59+
v-model="formData.migrateType"
60+
class="ml-8"
61+
:desc="t('主机关联的所有实例一并迁移')"
62+
:disabled="formData.architectureType === 'cluster'"
63+
icon="host"
64+
:title="t('整机迁移')"
65+
true-value="machine" />
66+
</BkFormItem>
67+
<Component
68+
:is="currentTable"
69+
ref="currentTable" />
70+
<TicketPayload v-model="formData" />
71+
</DbForm>
72+
</div>
73+
<template #action>
74+
<BkButton
75+
class="w-88"
76+
:loading="isSubmitting"
77+
theme="primary"
78+
@click="handleSubmit">
79+
{{ t('提交') }}
80+
</BkButton>
81+
<DbPopconfirm
82+
:confirm-handler="handleReset"
83+
:content="t('重置将会清空当前填写的所有内容_请谨慎操作')"
84+
:title="t('确认重置页面')">
85+
<BkButton
86+
class="ml8 w-88"
87+
:disabled="isSubmitting">
88+
{{ t('重置') }}
89+
</BkButton>
90+
</DbPopconfirm>
91+
</template>
92+
</SmartAction>
93+
</template>
94+
95+
<script setup lang="tsx">
96+
import { BkFormItem } from 'bkui-vue/lib/form';
97+
import { useI18n } from 'vue-i18n';
98+
99+
import { type Redis } from '@services/model/ticket/ticket';
100+
101+
import { useCreateTicket, useTicketDetail } from '@hooks';
102+
103+
import { TicketTypes } from '@common/const';
104+
105+
import CardCheckbox from '@components/db-card-checkbox/CardCheckbox.vue';
106+
107+
import TicketPayload, {
108+
createTickePayload,
109+
} from '@views/db-manage/common/toolbox-field/form-item/ticket-payload/Index.vue';
110+
111+
import RenderClusterInstance from './components/cluseter-instance/Index.vue';
112+
import RenderMasterInstance from './components/master-slave-instance/Index.vue';
113+
import RenderMasterSlaveHost from './components/master-slave-machine/Index.vue';
114+
115+
const { t } = useI18n();
116+
const router = useRouter();
117+
118+
const currentTableRef = useTemplateRef('currentTable');
119+
120+
// 单据克隆
121+
useTicketDetail<Redis.MigrateCluster>(TicketTypes.REDIS_CLUSTER_INS_MIGRATE, {
122+
onSuccess(cloneData) {
123+
currentTableRef.value!.setTableByTicketClone(cloneData);
124+
formData.remark = cloneData.remark;
125+
window.changeConfirm = true;
126+
},
127+
});
128+
129+
// 单据克隆
130+
useTicketDetail<Redis.MigrateSingle>(TicketTypes.REDIS_SINGLE_INS_MIGRATE, {
131+
onSuccess(cloneData) {
132+
formData.architectureType = 'masterSlave';
133+
const isDomain = cloneData.details.infos[0].display_info.migrate_type === 'domain';
134+
135+
nextTick(() => {
136+
if (!isDomain) {
137+
formData.migrateType = 'machine';
138+
}
139+
});
140+
setTimeout(() => {
141+
currentTableRef.value!.setTableByTicketClone(cloneData);
142+
formData.remark = cloneData.remark;
143+
window.changeConfirm = true;
144+
});
145+
},
146+
});
147+
148+
const { run: createClusterTicketRun, loading: isClusterSubmitting } = useCreateTicket<{
149+
infos: {
150+
cluster_id: number;
151+
resource_spec: {
152+
backend_group: {
153+
spec_id: number;
154+
count: number;
155+
};
156+
};
157+
old_nodes: {
158+
master: {
159+
bk_host_id: number;
160+
ip: string;
161+
port: number;
162+
bk_cloud_id: number;
163+
bk_biz_id: number;
164+
}[];
165+
slave: {
166+
bk_host_id: number;
167+
ip: string;
168+
port: number;
169+
bk_cloud_id: number;
170+
bk_biz_id: number;
171+
}[];
172+
};
173+
display_info: {
174+
instance: string;
175+
db_version: string[];
176+
};
177+
}[];
178+
}>(TicketTypes.REDIS_CLUSTER_INS_MIGRATE);
179+
180+
const { run: createSingleTicketRun, loading: isSingleSubmitting } = useCreateTicket<{
181+
infos: {
182+
cluster_id: number;
183+
resource_spec: {
184+
backend_group: {
185+
spec_id: number;
186+
count: number;
187+
};
188+
};
189+
db_version: string;
190+
old_nodes: {
191+
master: {
192+
bk_host_id: number;
193+
ip: string;
194+
port: number;
195+
bk_cloud_id: number;
196+
bk_biz_id: number;
197+
}[];
198+
slave: {
199+
bk_host_id: number;
200+
ip: string;
201+
port: number;
202+
bk_cloud_id: number;
203+
bk_biz_id: number;
204+
}[];
205+
};
206+
display_info: {
207+
migrate_type: string; // domain | machine
208+
ip: string;
209+
domain: string;
210+
};
211+
}[];
212+
}>(TicketTypes.REDIS_SINGLE_INS_MIGRATE, {
213+
onSuccess(ticketId: number) {
214+
router.push({
215+
name: TicketTypes.REDIS_CLUSTER_INS_MIGRATE,
216+
params: {
217+
page: 'success',
218+
},
219+
query: {
220+
ticketId,
221+
},
222+
});
223+
},
224+
});
225+
226+
const initFormData = () => ({
227+
architectureType: 'cluster', // cluster | masterSlave
228+
migrateType: 'instance', // instance | machine
229+
...createTickePayload(),
230+
});
231+
232+
const formData = reactive(initFormData());
233+
234+
const renderKey = computed(() => `${formData.architectureType}-${formData.migrateType}`);
235+
236+
const currentTable = computed(() => {
237+
const [architectureType, migrateType] = renderKey.value.split('-');
238+
if (architectureType === 'cluster') {
239+
return RenderClusterInstance;
240+
}
241+
242+
if (migrateType === 'instance') {
243+
return RenderMasterInstance;
244+
}
245+
246+
return RenderMasterSlaveHost;
247+
});
248+
249+
const isSubmitting = computed(() => isClusterSubmitting.value || isSingleSubmitting.value);
250+
251+
watch(
252+
() => formData.architectureType,
253+
() => {
254+
formData.migrateType = 'instance';
255+
},
256+
);
257+
258+
watch(renderKey, () => {
259+
currentTable.value;
260+
});
261+
262+
const handleSubmit = async () => {
263+
const runMap = {
264+
cluster: createClusterTicketRun,
265+
masterSlave: createSingleTicketRun,
266+
};
267+
268+
const infos = await currentTableRef.value!.getValue();
269+
if (infos.length > 0) {
270+
runMap[formData.architectureType as keyof typeof runMap]({
271+
details: {
272+
infos,
273+
},
274+
remark: formData.remark,
275+
});
276+
}
277+
};
278+
279+
const handleReset = () => {
280+
currentTableRef.value!.resetTable();
281+
};
282+
</script>
283+
284+
<style lang="less" scoped>
285+
.redis-migrate {
286+
padding-bottom: 20px;
287+
288+
.card-checkbox {
289+
width: 400px;
290+
}
291+
292+
.page-action-box {
293+
display: flex;
294+
align-items: center;
295+
margin-top: 16px;
296+
}
297+
}
298+
</style>

0 commit comments

Comments
 (0)