diff --git a/dbm-ui/frontend/src/components/apply-items/BackendQPSSpec.vue b/dbm-ui/frontend/src/components/apply-items/BackendQPSSpec.vue index c379e5df57..a7b966e21e 100644 --- a/dbm-ui/frontend/src/components/apply-items/BackendQPSSpec.vue +++ b/dbm-ui/frontend/src/components/apply-items/BackendQPSSpec.vue @@ -1,77 +1,171 @@ @@ -80,6 +174,7 @@ import { useI18n } from 'vue-i18n'; import ClusterSpecModel from '@services/model/resource-spec/cluster-sepc'; + import ResourceSpecModel from '@services/model/resource-spec/resourceSpec'; import { getSpecResourceCount } from '@services/source/dbresourceResource'; import { getFilterClusterSpec, @@ -88,8 +183,10 @@ import { ClusterTypes } from '@common/const'; + import SpecSelector from '@components/apply-items/SpecSelector.vue'; + interface ModelValue { - spec_id: number, + spec_id: number | string, capacity: number | string, count: number, future_capacity: number | string, @@ -108,6 +205,7 @@ const { t } = useI18n(); const specRef = ref(); + const specSelectorRef = ref>() const specs = shallowRef([]); const renderSpecs = shallowRef([]); const isLoading = ref(false); @@ -118,9 +216,8 @@ disabled: true, }); - const isTendisCache = computed(() => props.clusterType === ClusterTypes.TWEMPROXY_REDIS_INSTANCE); - const targetCapacityTitle = computed(() => (isTendisCache.value ? t('集群容量需求(内存容量)') : t('集群容量需求(磁盘容量)'))); - const futureCapacityTitle = computed(() => (isTendisCache.value ? t('未来集群容量需求(内存容量)') : t('未来集群容量需求(磁盘容量)'))); + const applyType = ref('auto') + const shardNum = ref(1) const columns = [ { @@ -166,6 +263,39 @@ }, ]; + const clusterShardNum = computed(() => modelValue.value.count * shardNum.value || '') + + const specInfo = computed(() => { + const data = specSelectorRef.value?.getData() + const {count} = modelValue.value + + if (_.isEmpty(data)) { + return { + totalCapcity: '', + qps: '' + } + } + + return { + totalCapcity: count * getSpecCapacity(data.storage_spec), + qps: count * (data.qps.min ?? 0) + } + }) + + const getSpecCapacity = (storageSpec: ResourceSpecModel['storage_spec']) => { + let specCapacity = 0 + for (let i = 0; i < storageSpec.length; i++) { + const storageSpecItem = storageSpec[i] + if (storageSpecItem.mount_point === '/data1') { + return storageSpecItem.size + } + if (storageSpecItem.mount_point === '/data') { + specCapacity = storageSpecItem.size / 2 + } + } + return specCapacity + } + const formatterLabel = (value: string) => `${value}/s`; const resetSlider = () => { @@ -277,7 +407,7 @@ }, 100); watch(() => sliderProps.value, _.debounce(() => { - modelValue.value.spec_id = -1; + modelValue.value.spec_id = ''; if (sliderProps.value[1] > 0) { fetchFilterClusterSpec(); } else { @@ -288,7 +418,7 @@ watch(() => modelValue.value.spec_id, () => { if (modelValue.value.spec_id) { - specRef.value.clearValidate(); + specRef.value?.clearValidate(); } }); @@ -332,8 +462,25 @@ defineExpose({ getData() { - const item = specs.value.find(item => item.spec_id === Number(modelValue.value.spec_id)); - return item ?? {}; + if (applyType.value === 'auto') { + const item = specs.value.find(item => item.spec_id === Number(modelValue.value.spec_id))!; + return { + spec_name: item.spec_name, + machine_pair: item.machine_pair, + cluster_shard_num: item.cluster_shard_num, + cluster_capacity: item.cluster_capacity, + qps: item.qps + }; + } + const item = specSelectorRef.value!.getData()! + const { count } = modelValue.value + return { + spec_name: item.spec_name, + machine_pair: count, + cluster_shard_num: clusterShardNum.value, + cluster_capacity: count * getSpecCapacity(item.storage_spec!), + qps: item.qps + }; }, }); diff --git a/dbm-ui/frontend/src/components/apply-items/SpecSelector.vue b/dbm-ui/frontend/src/components/apply-items/SpecSelector.vue index 6589935989..b0dbbeb74c 100644 --- a/dbm-ui/frontend/src/components/apply-items/SpecSelector.vue +++ b/dbm-ui/frontend/src/components/apply-items/SpecSelector.vue @@ -2,6 +2,7 @@
@@ -29,21 +30,21 @@
- {{ $t('可用主机数') }}: + {{ t('可用主机数') }}: {{ item.count ?? 0 }}
CPU: - ({{ item.cpu.min }} ~ {{ item.cpu.max }}) {{ $t('核') }} + ({{ item.cpu.min }} ~ {{ item.cpu.max }}) {{ t('核') }}
- {{ $t('内存') }}: + {{ t('内存') }}: ({{ item.mem.min }} ~ {{ item.mem.max }}) G
- {{ $t('磁盘') }}: + {{ t('磁盘') }}: {{ $t('每台主机实例数量') }}: + class="info-title text-overflow"> + {{ t('每台主机实例数量') }}: + {{ item.instance_num }}
@@ -71,7 +74,7 @@ @@ -102,10 +105,12 @@ bizId: number | string; cloudId: number | string; showRefresh?: boolean; + clearable?: boolean; } const props = withDefaults(defineProps(), { showRefresh: true, + clearable: true, }); const emits = defineEmits(); @@ -205,6 +210,7 @@ mem: item.mem, storage_spec: item.storage_spec, instance_num: instanceNum && instanceNum > 0 ? instanceNum : undefined, + qps: item.qps, }; } return {}; diff --git a/dbm-ui/frontend/src/components/cluster-spec-plan-selector/Index.vue b/dbm-ui/frontend/src/components/cluster-spec-plan-selector/Index.vue index 96c78a5292..5aeb2f9f0e 100644 --- a/dbm-ui/frontend/src/components/cluster-spec-plan-selector/Index.vue +++ b/dbm-ui/frontend/src/components/cluster-spec-plan-selector/Index.vue @@ -1,50 +1,146 @@ diff --git a/dbm-ui/frontend/src/locales/zh-cn.json b/dbm-ui/frontend/src/locales/zh-cn.json index 69ed83c829..40bcd6bfca 100644 --- a/dbm-ui/frontend/src/locales/zh-cn.json +++ b/dbm-ui/frontend/src/locales/zh-cn.json @@ -3083,5 +3083,12 @@ "变量只能以字母开头": "变量只能以字母开头", "请选择或输入主机": "请选择或输入主机", "表名支持通配符“%”,含通配符的仅支持单个,为空则不克隆表数据": "表名支持通配符“%”,含通配符的仅支持单个,为空则不克隆表数据", + "部署方案选择": "部署方案选择", + "自动推荐方案": "自动推荐方案", + "自定义方案": "自定义方案", + "单机分片数": "单机分片数", + "数量不能为空": "数量不能为空", + "请输入数量": "请输入数量", + "范围n_min_max": "范围 {n}, {min} ~ {max}", "这行勿动!新增翻译请在上一行添加!": "" } diff --git a/dbm-ui/frontend/src/services/types/ticket.ts b/dbm-ui/frontend/src/services/types/ticket.ts index bcf5b7282a..5481048f69 100644 --- a/dbm-ui/frontend/src/services/types/ticket.ts +++ b/dbm-ui/frontend/src/services/types/ticket.ts @@ -259,7 +259,6 @@ export interface MysqlQueryAccountParams { access_dbs: string[]; } - /** * es - 单据详情 */ @@ -340,12 +339,6 @@ export interface ClusterOperationDetails { cluster_id: number; } - - - - - - /** * 大数据实例重启 */ @@ -362,267 +355,268 @@ export interface BigDataRebootDetails { }[]; } - - /** * clusters参数 */ export interface clustersItems { [key: number]: { - alias: string, - bk_biz_id: number, - bk_cloud_id: number, - cluster_type: string, - cluster_type_name: string, - creator: string, - db_module_id: number, - id: number, - immute_domain: string, - major_version: string, - name: string, - phase: string, - region: string, - status: string, - time_zone: string, - updater: string, - }, + alias: string; + bk_biz_id: number; + bk_cloud_id: number; + cluster_type: string; + cluster_type_name: string; + creator: string; + db_module_id: number; + id: number; + immute_domain: string; + major_version: string; + name: string; + phase: string; + region: string; + status: string; + time_zone: string; + updater: string; + }; } /** * MySQL 库表备份 */ export interface MySQLTableBackupDetails { - clusters: clustersItems, + clusters: clustersItems; infos: { - backup_on: string, - cluster_id: number, - db_patterns: [], - ignore_dbs: [], - ignore_tables: [], - table_patterns: [], - force: boolean, - }[], + backup_on: string; + cluster_id: number; + db_patterns: []; + ignore_dbs: []; + ignore_tables: []; + table_patterns: []; + force: boolean; + }[]; } /** * MySQL 主从清档 */ export interface MySQLHATruncateDetails { - clusters: clustersItems, + clusters: clustersItems; infos: { - cluster_id: number, - db_patterns: [], - ignore_dbs: [], - ignore_tables: [], - table_patterns: [], - force: boolean, - truncate_data_type: string, - }[], + cluster_id: number; + db_patterns: []; + ignore_dbs: []; + ignore_tables: []; + table_patterns: []; + force: boolean; + truncate_data_type: string; + }[]; } export interface MysqlIpItem { - bk_biz_id: number, - bk_cloud_id: number, - bk_host_id: number, - ip: string, - port?: number, + bk_biz_id: number; + bk_cloud_id: number; + bk_host_id: number; + ip: string; + port?: number; } /** * MySQL 克隆主从 */ export interface MySQLMigrateDetails { - clusters: clustersItems, + clusters: clustersItems; infos: { - cluster_ids: number[], - new_master: MysqlIpItem, - new_slave: MysqlIpItem, - }[], + cluster_ids: number[]; + new_master: MysqlIpItem; + new_slave: MysqlIpItem; + }[]; } /** * MySQL 主从互换 */ export interface MySQLMasterSlaveDetails { - clusters: clustersItems, + clusters: clustersItems; infos: { - cluster_ids: number[], - master_ip: MysqlIpItem, - slave_ip: MysqlIpItem, - }[], + cluster_ids: number[]; + master_ip: MysqlIpItem; + slave_ip: MysqlIpItem; + }[]; } /** * MySQL 新增 Proxy */ export interface MySQLProxyAddDetails { - clusters: clustersItems, + clusters: clustersItems; infos: { - cluster_ids: number[], - new_proxy: MysqlIpItem, - }[], + cluster_ids: number[]; + new_proxy: MysqlIpItem; + }[]; } /** * MySQL 主故障切换 */ export interface MySQLMasterFailDetails { - clusters: clustersItems, + clusters: clustersItems; infos: { - cluster_ids: number[], - master_ip: MysqlIpItem, - slave_ip: MysqlIpItem, - }[], + cluster_ids: number[]; + master_ip: MysqlIpItem; + slave_ip: MysqlIpItem; + }[]; } /** * MySQL SQL变更执行 */ export interface MySQLImportSQLFileDetails { - uid: string, - path: string, + uid: string; + path: string; backup: { - backup_on: string, - db_patterns: string[], - table_patterns: string[], - }[], - charset: string, - root_id: string, - bk_biz_id: number, - created_by: string, - cluster_ids: number[], - clusters: clustersItems, + backup_on: string; + db_patterns: string[]; + table_patterns: string[]; + }[]; + charset: string; + root_id: string; + bk_biz_id: number; + created_by: string; + cluster_ids: number[]; + clusters: clustersItems; ticket_mode: { - mode: string, - trigger_time: string, - }, - ticket_type: string, + mode: string; + trigger_time: string; + }; + ticket_type: string; execute_objects: { - dbnames: string[], - sql_file: string, - ignore_dbnames: string[] - }[], + dbnames: string[]; + sql_file: string; + ignore_dbnames: string[]; + }[]; execute_db_infos: { - dbnames: string[], - ignore_dbnames: string[] - }[], - execute_sql_files: string[], - grammar_check_info: Record - import_mode: string, - semantic_node_id: string, + dbnames: string[]; + ignore_dbnames: string[]; + }[]; + execute_sql_files: string[]; + grammar_check_info: Record< + string, + { + highrisk_warnings: { + command_type: string; + line: number; + sqltext: string; + warn_info: string; + }[]; + } + >; + import_mode: string; + semantic_node_id: string; } /** * MySQL 闪回 */ export interface MySQLFlashback { - clusters: clustersItems, + clusters: clustersItems; infos: { - cluster_id: number, - databases: [], - databases_ignore: [], - end_time: string, - mysqlbinlog_rollback: string, - recored_file: string, - start_time: string, - tables: [], - tables_ignore: [] - }[], + cluster_id: number; + databases: []; + databases_ignore: []; + end_time: string; + mysqlbinlog_rollback: string; + recored_file: string; + start_time: string; + tables: []; + tables_ignore: []; + }[]; } /** * MySql 定点回档 */ export interface MySQLRollbackDetails { - clusters: clustersItems, + clusters: clustersItems; infos: { - backup_source: string, - backupid: string, - cluster_id: number, - databases: string[], - databases_ignore: string[], - rollback_ip: string, - rollback_time: string, - tables: string[], - tables_ignore: string[], + backup_source: string; + backupid: string; + cluster_id: number; + databases: string[]; + databases_ignore: string[]; + rollback_ip: string; + rollback_time: string; + tables: string[]; + tables_ignore: string[]; backupinfo: { - backup_id: string, - mysql_host: string, - mysql_port: number, - mysql_role: string, - backup_time: string, - backup_type: string, - master_host: string, - master_port: number - }, - }[], + backup_id: string; + mysql_host: string; + mysql_port: number; + mysql_role: string; + backup_time: string; + backup_type: string; + master_host: string; + master_port: number; + }; + }[]; } /** * MySQL SLAVE重建 */ export interface MySQLRestoreSlaveDetails { - clusters: clustersItems, + clusters: clustersItems; infos: { - backup_source: string, - cluster_ids: number[], - new_slave: MysqlIpItem, - old_slave: MysqlIpItem, - }[], + backup_source: string; + cluster_ids: number[]; + new_slave: MysqlIpItem; + old_slave: MysqlIpItem; + }[]; } /** * MySQL 全库备份 */ export interface MySQLFullBackupDetails { - clusters: clustersItems, + clusters: clustersItems; infos: { - backup_type: string, + backup_type: string; clusters: { - backup_local: string, - cluster_id: number, - }[], - file_tag: string, - online: boolean, - } + backup_local: string; + cluster_id: number; + }[]; + file_tag: string; + online: boolean; + }; } /** * MySQL 校验 */ export interface MySQLChecksumDetails { - clusters: clustersItems, + clusters: clustersItems; data_repair: { - is_repair: boolean, - mode: string, - } + is_repair: boolean; + mode: string; + }; infos: { - cluster_id: number, - db_patterns: string[], - ignore_dbs: string[], - ignore_tables: string[], + cluster_id: number; + db_patterns: string[]; + ignore_dbs: string[]; + ignore_tables: string[]; master: { - id: number, - ip: string, - port: number, - }, + id: number; + ip: string; + port: number; + }; slaves: { - id: number, - ip: string, - port: number, - }[], - table_patterns: string[], - }[], - is_sync_non_innodb: boolean, - runtime_hour: number, - timing: string, + id: number; + ip: string; + port: number; + }[]; + table_patterns: string[]; + }[]; + is_sync_non_innodb: boolean; + runtime_hour: number; + timing: string; } /** @@ -705,19 +699,17 @@ export interface SpecInfo { }[]; } - - /** * redis 版本升级 */ export interface RedisVersionUpgrade { - clusters: clustersItems, + clusters: clustersItems; infos: { - cluster_id: number, - current_versions: string[], - node_type: string, - target_version: string - }[], + cluster_id: number; + current_versions: string[]; + node_type: string; + target_version: string; + }[]; } // Spider Checksum @@ -889,15 +881,17 @@ export interface SpiderNodeRebalanceDetails { affinity: string; // 亲和性要求 }; }; + prev_machine_pair: number; + prev_cluster_spec_name: string; }[]; } // spider 定点回档 export interface SpiderRollbackDetails { - cluster_id: number, - clusters: clustersItems, - rollback_type: 'REMOTE_AND_BACKUPID' | 'REMOTE_AND_TIME', - rollback_time: string, + cluster_id: number; + clusters: clustersItems; + rollback_type: 'REMOTE_AND_BACKUPID' | 'REMOTE_AND_TIME'; + rollback_time: string; backupinfo: { backup_begin_time: string; backup_end_time: string; @@ -908,11 +902,11 @@ export interface SpiderRollbackDetails { bk_cloud_id: number; cluster_address: string; cluster_id: number; - }, - databases: string[], - tables: string[], - databases_ignore: string[], - tables_ignore: string[], + }; + databases: string[]; + tables: string[]; + databases_ignore: string[]; + tables_ignore: string[]; } // Spider flashback @@ -1008,8 +1002,6 @@ export interface SpiderPartitionManageDetails { }; } - - export interface MysqlOpenAreaDetails { cluster_id: number; clusters: { @@ -1062,5 +1054,5 @@ export interface MysqlDataMigrateDetails { db_list: string; source_cluster: number; target_clusters: number[]; - }[] + }[]; } diff --git a/dbm-ui/frontend/src/views/spider-manage/apply/Index.vue b/dbm-ui/frontend/src/views/spider-manage/apply/Index.vue index 6785671f3e..7f783e0b64 100644 --- a/dbm-ui/frontend/src/views/spider-manage/apply/Index.vue +++ b/dbm-ui/frontend/src/views/spider-manage/apply/Index.vue @@ -91,11 +91,11 @@ v-model="formdata.details.spider_port" clearable :max="65535" - :min="25000" + :min="3306" style="width: 185px" type="number" /> - {{ t('范围min_max', { min: 25000, max: 65535 }) }} + {{ t('范围n_min_max', { n: 3306, min: 25000, max: 65535 }) }} @@ -172,17 +172,17 @@ cluster_name: '', cluster_alias: '', city_code: '', - db_module_id: 0, + db_module_id: null as null | number, cluster_shard_num: 0, remote_shard_num: 0, disaster_tolerance_level: 'NONE', resource_spec: { spider: { - spec_id: 0, + spec_id: '' as number | '', count: 2, }, backend_group: { - spec_id: 0, + spec_id: '' as number | '', count: 0, capacity: '', future_capacity: '', @@ -202,7 +202,7 @@ const formRef = ref(); const specProxyRef = ref(); - const specBackendRef = ref(); + const specBackendRef = ref>(); const formdata = ref(initData()); const regionItemRef = ref(); @@ -213,7 +213,20 @@ { message: t('以小写英文字母开头_且只能包含英文字母_数字_连字符'), trigger: 'blur', - validator: (val: string) => nameRegx.test(val), + validator: (value: string) => nameRegx.test(value), + }, + ], + 'details.resource_spec.backend_group.count': [ + { + message: t('数量不能为空'), + validator: (value: number) => value > 0, + }, + ], + 'details.spider_port': [ + { + message: t('范围n_min_max', { n: 3306, min: 25000, max: 65535 }), + trigger: 'change', + validator: (value: number) => value === 3306 || (value >= 25000 && value <= 65535), }, ], }; @@ -262,7 +275,7 @@ }, }; - const specInfo = specBackendRef.value.getData(); + const specInfo = specBackendRef.value!.getData(); return { ...details, cluster_shard_num: Number(specInfo.cluster_shard_num), diff --git a/dbm-ui/frontend/src/views/spider-manage/apply/components/ModuleItem.vue b/dbm-ui/frontend/src/views/spider-manage/apply/components/ModuleItem.vue index aecf4908f5..4b79166057 100644 --- a/dbm-ui/frontend/src/views/spider-manage/apply/components/ModuleItem.vue +++ b/dbm-ui/frontend/src/views/spider-manage/apply/components/ModuleItem.vue @@ -83,7 +83,7 @@ } const props = defineProps(); - const moduleId = defineModel({ required: true }); + const moduleId = defineModel({ required: true }); const router = useRouter(); diff --git a/dbm-ui/frontend/src/views/spider-manage/capacity-change/pages/page1/Index.vue b/dbm-ui/frontend/src/views/spider-manage/capacity-change/pages/page1/Index.vue index a4b72c0e4e..0a94a4f45d 100644 --- a/dbm-ui/frontend/src/views/spider-manage/capacity-change/pages/page1/Index.vue +++ b/dbm-ui/frontend/src/views/spider-manage/capacity-change/pages/page1/Index.vue @@ -163,6 +163,7 @@ id: item.id, machinePairCnt: item.machine_pair_cnt, masterDomain: item.master_domain, + remoteShardNum: item.remote_shard_num, }, }); result.push(row); diff --git a/dbm-ui/frontend/src/views/spider-manage/capacity-change/pages/page1/components/RenderData/RenderResourceSpec.vue b/dbm-ui/frontend/src/views/spider-manage/capacity-change/pages/page1/components/RenderData/RenderResourceSpec.vue index 44e5033b1e..d5ed0ac1c7 100644 --- a/dbm-ui/frontend/src/views/spider-manage/capacity-change/pages/page1/components/RenderData/RenderResourceSpec.vue +++ b/dbm-ui/frontend/src/views/spider-manage/capacity-change/pages/page1/components/RenderData/RenderResourceSpec.vue @@ -14,7 +14,7 @@