From d8aec7424a5b24a9fee402a00d9bb024f485a4a4 Mon Sep 17 00:00:00 2001 From: 3octaves <873551943@qq.com> Date: Thu, 26 Sep 2024 12:02:05 +0800 Subject: [PATCH] =?UTF-8?q?fix(frontend):=20mongo=E9=AA=8C=E6=94=B6?= =?UTF-8?q?=E9=97=AE=E9=A2=98=E4=BF=AE=E5=A4=8D=20#6052?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/common/const/clusterTypeInfos.ts | 2 +- .../src/components/cluster-selector/Index.vue | 4 +- .../components/instance-selector/Index.vue | 2 + .../components/mongo/table/Index.vue | 29 ++- .../components/mongo/table/useTableData.ts | 7 +- .../columns/role-host-select/Index.vue | 2 +- .../render-table/columns/tag-input/index.vue | 8 + dbm-ui/frontend/src/locales/zh-cn.json | 33 ++- .../services/model/mongodb/mongodb-detail.ts | 38 +++ .../src/services/model/mongodb/mongodb.ts | 53 ++++ .../frontend/src/services/source/mongodb.ts | 29 ++- .../cluster-details/common/graphData.ts | 26 +- .../cluster-details/common/useRenderGraph.tsx | 2 + .../components/mongo/CreateRule.vue | 4 +- .../capacity-change/pages/page1/Index.vue | 93 +++---- .../page1/components/ChooseDeployPlan.vue | 13 +- .../pages/page1/components/Index.vue | 1 - .../mongodb/components/AccessEntry.vue | 154 +++++++++++ .../components/CapacityChange.vue | 21 +- .../mongodb/components/MongoConfigSpec.vue | 19 +- .../mongodb/components/edit-field/DbName.vue | 98 ++++++- .../components/edit-field/TableName.vue | 93 ++++++- .../clusters-with-selector/Index.vue | 18 +- .../clusters-with-selector/Input.vue | 2 +- .../mongodb/db-backup/pages/page1/Index.vue | 81 +++--- .../mongodb/db-clear/pages/page1/Index.vue | 77 +++--- .../pages/page1/components/RenderData/Row.vue | 41 ++- .../mongodb/db-replace/pages/page1/Index.vue | 240 +++++++++++++----- .../pages/page1/components/HostName.vue | 200 +++++++++++++++ .../db-replace/pages/page1/components/Row.vue | 26 +- .../db-structure/pages/page1/Index.vue | 106 ++++---- .../page1/components/RenderTargetSpec.vue | 7 +- .../components/render-db-table/Index.vue | 1 - .../page1/components/render-db-table/Row.vue | 53 +++- .../render-target-cluster/Index.vue | 7 +- .../render-table/RenderBackupFile.vue | 31 ++- .../render-table/Row.vue | 15 +- .../db-table-backup/pages/page1/Index.vue | 87 +++---- .../components/RenderData/RenderHost.vue | 12 +- .../pages/page1/components/RenderData/Row.vue | 40 ++- .../detail/components/BaseInfo.vue | 4 +- .../mongodb/mongodb-instance/detail/index.vue | 4 +- .../proxy-scale-down/pages/page1/Index.vue | 72 +++--- .../pages/page1/components/Index.vue | 10 +- .../pages/page1/components/RenderIpSelect.vue | 31 +-- .../page1/components/RenderTargetNumber.vue | 38 ++- .../pages/page1/components/Row.vue | 47 ++-- .../proxy-scale-up/pages/page1/Index.vue | 65 ++--- .../pages/page1/components/Index.vue | 2 +- .../page1/components/RenderTargetNumber.vue | 8 +- .../pages/page1/components/Row.vue | 9 +- .../mongodb/replica-set-apply/Index.vue | 32 +-- .../components/DomainTable.vue | 45 ++-- .../components/detail/Index.vue | 85 ++++++- .../components/list/Index.vue | 96 ++++++- .../script-execute/steps/step1/Index.vue | 67 +++-- .../components/sql-file/editor/Index.vue | 2 +- .../shard-scale-down/pages/page1/Index.vue | 64 ++--- .../pages/page1/components/Row.vue | 12 +- .../shard-scale-up/pages/page1/Index.vue | 70 +++-- .../page1/components/RenderTargetNumber.vue | 1 - .../mongodb/shared-cluster-apply/Index.vue | 16 +- .../components/detail/Index.vue | 29 ++- .../components/list/Index.vue | 43 ++-- .../list/components/render-shard/Index.vue | 231 +++++++++++++++++ .../render-shard/components/RenderRow.vue | 139 ++++++++++ .../demand-factory/mongodb/DbBackup.vue | 17 +- .../demand-factory/mongodb/DbStruct.vue | 6 +- .../demand-factory/mongodb/DbTableBackup.vue | 15 +- .../mongodb/DetailsMongoDBReplicaSet.vue | 10 +- .../demand-factory/mongodb/ProxyScaleDown.vue | 48 +--- .../demand-factory/mongodb/ProxyScaleUp.vue | 42 +-- 72 files changed, 2257 insertions(+), 878 deletions(-) create mode 100644 dbm-ui/frontend/src/views/db-manage/mongodb/components/AccessEntry.vue rename dbm-ui/frontend/src/views/db-manage/mongodb/{shared-cluster-list/components => }/components/CapacityChange.vue (90%) create mode 100644 dbm-ui/frontend/src/views/db-manage/mongodb/db-replace/pages/page1/components/HostName.vue create mode 100644 dbm-ui/frontend/src/views/db-manage/mongodb/shared-cluster-list/components/list/components/render-shard/Index.vue create mode 100644 dbm-ui/frontend/src/views/db-manage/mongodb/shared-cluster-list/components/list/components/render-shard/components/RenderRow.vue diff --git a/dbm-ui/frontend/src/common/const/clusterTypeInfos.ts b/dbm-ui/frontend/src/common/const/clusterTypeInfos.ts index 85d7eedf73..98d47d3e3c 100644 --- a/dbm-ui/frontend/src/common/const/clusterTypeInfos.ts +++ b/dbm-ui/frontend/src/common/const/clusterTypeInfos.ts @@ -254,7 +254,7 @@ const mongodb: InfoType = { }, [ClusterTypes.MONGO_SHARED_CLUSTER]: { id: ClusterTypes.MONGO_SHARED_CLUSTER, - name: t('Mongo分片集'), + name: t('Mongo 分片集群'), dbType: DBTypes.MONGODB, moduleId: 'mongodb', machineList: [ diff --git a/dbm-ui/frontend/src/components/cluster-selector/Index.vue b/dbm-ui/frontend/src/components/cluster-selector/Index.vue index f13fcf3ae4..df14d0af41 100644 --- a/dbm-ui/frontend/src/components/cluster-selector/Index.vue +++ b/dbm-ui/frontend/src/components/cluster-selector/Index.vue @@ -315,7 +315,7 @@ }, [ClusterTypes.MONGO_REPLICA_SET]: { id: ClusterTypes.MONGO_REPLICA_SET, - name: t('集群选择'), + name: t('副本集'), disabledRowConfig: [ { handler: (data: T) => data.isOffline, @@ -329,7 +329,7 @@ }, [ClusterTypes.MONGO_SHARED_CLUSTER]: { id: ClusterTypes.MONGO_SHARED_CLUSTER, - name: t('集群选择'), + name: t('分片集群'), disabledRowConfig: [ { handler: (data: T) => data.isOffline, diff --git a/dbm-ui/frontend/src/components/instance-selector/Index.vue b/dbm-ui/frontend/src/components/instance-selector/Index.vue index 0cec145441..6458af4364 100644 --- a/dbm-ui/frontend/src/components/instance-selector/Index.vue +++ b/dbm-ui/frontend/src/components/instance-selector/Index.vue @@ -50,6 +50,7 @@ :is-remote-pagination="activePanelObj?.tableConfig?.isRemotePagination" :last-values="lastValues" :manual-config="activePanelObj?.manualConfig" + :multiple="activePanelObj?.tableConfig?.multiple" :role-filter-list="activePanelObj?.tableConfig?.roleFilterList" :status-filter="activePanelObj?.tableConfig?.statusFilter" :table-setting="tableSettings" @@ -146,6 +147,7 @@ spec_config?: TendbclusterMachineModel['spec_config']; spec_id?: number; role: string; + shard?: string; } export type InstanceSelectorValues = Record; diff --git a/dbm-ui/frontend/src/components/instance-selector/components/mongo/table/Index.vue b/dbm-ui/frontend/src/components/instance-selector/components/mongo/table/Index.vue index c606c1eb99..9d1e524f67 100644 --- a/dbm-ui/frontend/src/components/instance-selector/components/mongo/table/Index.vue +++ b/dbm-ui/frontend/src/components/instance-selector/components/mongo/table/Index.vue @@ -39,6 +39,8 @@ import type { Ref } from 'vue'; import { useI18n } from 'vue-i18n'; + import { ClusterTypes } from '@common/const'; + import DbStatus from '@components/db-status/index.vue'; import type { InstanceSelectorValues, @@ -65,7 +67,7 @@ manualTableData?: DataRow[]; isRemotePagination?: TableConfigType['isRemotePagination'], firsrColumn?: TableConfigType['firsrColumn'], - roleFilterList?: TableConfigType['roleFilterList'], + // roleFilterList?: TableConfigType['roleFilterList'], disabledRowConfig?: TableConfigType['disabledRowConfig'], multiple: boolean, getTableList: NonNullable, @@ -96,6 +98,7 @@ const checkedMap = shallowRef({} as DataRow); + const initRole = computed(() => props.firsrColumn?.role); const selectClusterId = computed(() => props.clusterId); const firstColumnFieldId = computed(() => (props.firsrColumn?.field || 'instance_address') as keyof IValue); const mainSelectDisable = computed(() => (props.disabledRowConfig @@ -111,7 +114,7 @@ fetchResources, handleChangePage, handeChangeLimit, - } = useTableData(selectClusterId); + } = useTableData(selectClusterId, initRole); const renderManualData = computed(() => { if (searchValue.value === '') { @@ -194,11 +197,31 @@ label: props.firsrColumn?.label ? firstLetterToUpper(props.firsrColumn.label) : t('实例'), field: props.firsrColumn?.field ? props.firsrColumn.field : 'instance_address', }, + // { + // label: t('角色'), + // field: 'role', + // showOverflowTooltip: true, + // filter: props.roleFilterList, + // }, { label: t('角色'), field: 'role', + minWidth: 160, showOverflowTooltip: true, - filter: props.roleFilterList, + rowspan: ({ row }: { row: DataRow }) => { + if (row.machine_type === 'mongodb') { + const rowSpan = tableData.value.filter((item) => item.master_domain === row.master_domain && item.machine_type === row.machine_type && item.shard === row.shard).length; + return rowSpan > 1 ? rowSpan : 1; + } + const rowSpan = tableData.value.filter((item) => item.master_domain === row.master_domain && item.machine_type === row.machine_type).length; + return rowSpan > 1 ? rowSpan : 1; + }, + render: ({ row }: { row: DataRow }) => { + if (row.cluster_type === ClusterTypes.MONGO_SHARED_CLUSTER && row.machine_type === 'mongodb') { + return row.shard + } + return row.machine_type + } }, { label: t('实例状态'), diff --git a/dbm-ui/frontend/src/components/instance-selector/components/mongo/table/useTableData.ts b/dbm-ui/frontend/src/components/instance-selector/components/mongo/table/useTableData.ts index 623c341ddf..0f6c343eae 100644 --- a/dbm-ui/frontend/src/components/instance-selector/components/mongo/table/useTableData.ts +++ b/dbm-ui/frontend/src/components/instance-selector/components/mongo/table/useTableData.ts @@ -19,7 +19,7 @@ import { useGlobalBizs } from '@stores'; /** * 处理集群列表数据 */ -export function useTableData(clusterId?: Ref) { +export function useTableData(clusterId?: Ref, role?: Ref) { const { currentBizId } = useGlobalBizs(); const currentInstance = getCurrentInstance() as ComponentInternalInstance & { proxy: { @@ -72,6 +72,11 @@ export function useTableData(clusterId?: Ref) { cluster_id: clusterId.value, }); } + if (role?.value) { + Object.assign(params, { + role: role.value, + }); + } return params; }; diff --git a/dbm-ui/frontend/src/components/render-table/columns/role-host-select/Index.vue b/dbm-ui/frontend/src/components/render-table/columns/role-host-select/Index.vue index 7a31dd1f2b..8f8391663c 100644 --- a/dbm-ui/frontend/src/components/render-table/columns/role-host-select/Index.vue +++ b/dbm-ui/frontend/src/components/render-table/columns/role-host-select/Index.vue @@ -79,7 +79,7 @@ clusterId: number; hostSelectType?: string; }; - clusterType: ClusterTypes | 'TendbClusterHost'; + clusterType: ClusterTypes | 'TendbClusterHost' | 'mongoCluster'; tabListConfig: ComponentProps['tabListConfig']; selectedNodeList?: IValue[]; count?: number; diff --git a/dbm-ui/frontend/src/components/render-table/columns/tag-input/index.vue b/dbm-ui/frontend/src/components/render-table/columns/tag-input/index.vue index 365c32d91a..cd754dca9c 100644 --- a/dbm-ui/frontend/src/components/render-table/columns/tag-input/index.vue +++ b/dbm-ui/frontend/src/components/render-table/columns/tag-input/index.vue @@ -30,6 +30,7 @@ :max-data="single ? 1 : -1" :paste-fn="tagInputPasteFn" :placeholder="placeholder" + @blur="handleBlur" @change="handleChange" @focus="handleFocus" />
{ isFocus.value = true; + emits('focus'); + }; + + const handleBlur = () => { + emits('blur'); }; onMounted(() => { diff --git a/dbm-ui/frontend/src/locales/zh-cn.json b/dbm-ui/frontend/src/locales/zh-cn.json index 3339a9d9ab..88f5b6ff09 100644 --- a/dbm-ui/frontend/src/locales/zh-cn.json +++ b/dbm-ui/frontend/src/locales/zh-cn.json @@ -2597,9 +2597,9 @@ "每台主机oplog容量占比": "每台主机oplog容量占比", "预计容量nG": "预计容量 {0} G", "所需主机数量": "所需主机数量", - "主从节点数": "主从节点数", + "Shard 节点数": "Shard 节点数", "部署副本集数量": "部署副本集数量", - "每台主机部署副本集数量": "每台主机部署副本集数量", + "每组主机部署副本集数量": "每组主机部署副本集数量", "共需n台": "共需 {0} 台", "计算规则": "计算规则", "集群ID重复": "集群ID重复", @@ -2690,7 +2690,7 @@ "保留索引": "保留索引", "删除索引": "删除索引", "索引处理": "索引处理", - "备份文件保存时间": "备份文件保存时间", + "备份保存时间": "备份保存时间", "备份方式": "备份方式", "当前Shard节点规格": "当前 Shard 节点规格", "当前Shard节点数": "当前 Shard 节点数", @@ -2718,7 +2718,6 @@ "目标集群与构造设置": "目标集群与构造设置", "备份文件": "备份文件", "该操作将会修改对应DB的数据,请谨慎操作": "该操作将会修改对应 DB 的数据,请谨慎操作!", - "是否开启 Oplog": "是否开启 Oplog", "确认清档n个副本集集群": "确认清档 {n} 个副本集集群?", "确认执行变更脚本任务": "确认执行变更脚本任务?", "集群上的数据将会全部构造至指定的新机器": "集群上的数据将会全部构造至指定的新机器", @@ -3567,5 +3566,31 @@ "匹配的规则": "匹配的规则", "域名不能为空": "域名不能为空", "请选择或直接输入账号,Enter完成输入": "请选择或直接输入账号,Enter完成输入", + "Mongo 分片集群": "Mongo 分片集群", + "不允许输入系统库和特殊库,如admin、config、local": "不允许输入系统库和特殊库,如admin、config、local", + "DB名、表名不允许为空,忽略DB名、忽略表名要么同时为空, 要么同时不为空": "DB名、表名不允许为空,忽略DB名、忽略表名要么同时为空, 要么同时不为空", + "支持通配符 *(指代任意长度字符串)": "支持通配符 *(指代任意长度字符串)", + "库表名支持数字、字母、中划线、下划线,最大64字符": "库表名支持数字、字母、中划线、下划线,最大64字符", + "请输入表名称,支持通配符“*”": "请输入表名称,支持通配符“*”", + "请输入DB 名称,支持通配符“*”": "请输入DB 名称,支持通配符“*”", + "连接字符串": "连接字符串", + "连接字符串(CLB)": "连接字符串(CLB)", + "复制xxx": "复制{0}", + "是否备份 Oplog": "是否备份 Oplog", + "缩容接入层:减加集群的Proxy数量,但集群Proxy数量不能少于2": "缩容接入层:减加集群的Proxy数量,但集群Proxy数量不能少于2", + "Mongo 主机": "Mongo 主机", + "机器类型": "机器类型", + "Proxy数量不足,至少 2 台": "Proxy数量不足,至少 2 台", + "忽略DB名、忽略表名要么同时为空, 要么同时不为空": "忽略DB名、忽略表名要么同时为空, 要么同时不为空", + "至多n台": "至多n台", + "同一个副本集,一次只能替换一个节点": "同一个副本集,一次只能替换一个节点", + "同一个分片集群,config一次只能替换一个节点": "同一个分片集群,config一次只能替换一个节点", + "config一次只能替换一个节点": "config一次只能替换一个节点", + "同一个shard,同时只能替换一个节点": "同一个shard,同时只能替换一个节点", + "扩容数量(台)": "扩容数量(台)", + "缩容数量(台)": "缩容数量(台)", + "ShardSvr 名称": "ShardSvr 名称", + "回档至指定时间": "回档至指定时间", + "待替换的主机 ": "待替换的主机", "这行勿动!新增翻译请在上一行添加!": "" } diff --git a/dbm-ui/frontend/src/services/model/mongodb/mongodb-detail.ts b/dbm-ui/frontend/src/services/model/mongodb/mongodb-detail.ts index a0fe5bd058..603f2124b8 100644 --- a/dbm-ui/frontend/src/services/model/mongodb/mongodb-detail.ts +++ b/dbm-ui/frontend/src/services/model/mongodb/mongodb-detail.ts @@ -11,6 +11,8 @@ * the specific language governing permissions and limitations under the License. */ +import type { ClusterListEntry } from '@services/types'; + import { TicketTypes } from '@common/const'; import { utcDisplayTime } from '@utils'; @@ -73,6 +75,7 @@ export default class MongodbDetail { bk_cloud_name: string; cluster_access_port: number; cluster_alias: string; + cluster_entry: ClusterListEntry[]; cluster_entry_details: { cluster_entry_type: string; role: string; @@ -217,6 +220,7 @@ export default class MongodbDetail { this.bk_cloud_name = payload.bk_cloud_name; this.cluster_alias = payload.cluster_alias; this.cluster_access_port = payload.cluster_access_port; + this.cluster_entry = payload.cluster_entry || []; this.cluster_entry_details = payload.cluster_entry_details; this.cluster_id = payload.cluster_id; this.cluster_name = payload.cluster_name; @@ -338,4 +342,38 @@ export default class MongodbDetail { get createAtDisplay() { return utcDisplayTime(this.create_at); } + + get isMongoReplicaSet() { + return this.cluster_type === 'MongoReplicaSet'; + } + + get entryDomain() { + if (this.isMongoReplicaSet) { + const domainList = this.cluster_entry.reduce((prevDomainList, entryItem) => { + if (!entryItem.entry.includes('backup')) { + return prevDomainList.concat(`${entryItem.entry}:${this.cluster_access_port}`); + } + return prevDomainList; + }, []); + return domainList.join(','); + } + return `${this.master_domain}:${this.cluster_access_port}`; + } + + get entryAccess() { + if (this.isMongoReplicaSet) { + return `mongodb://{username}:{password}@${this.entryDomain}/?replicaSet=${this.cluster_name}&authSource=admin`; + } + return `mongodb://{username}:{password}@${this.entryDomain}/?authSource=admin`; + } + + get entryAccessClb() { + if (!this.isMongoReplicaSet) { + const clbItem = this.cluster_entry.find((entryItem) => entryItem.cluster_entry_type === 'clbDns'); + if (clbItem) { + return `mongodb://{username}:{password}@${clbItem.entry}:${this.cluster_access_port}/?authSource=admin`; + } + } + return ''; + } } diff --git a/dbm-ui/frontend/src/services/model/mongodb/mongodb.ts b/dbm-ui/frontend/src/services/model/mongodb/mongodb.ts index 28d5a12fda..2cbcf5d575 100644 --- a/dbm-ui/frontend/src/services/model/mongodb/mongodb.ts +++ b/dbm-ui/frontend/src/services/model/mongodb/mongodb.ts @@ -14,6 +14,8 @@ import dayjs from 'dayjs'; import { uniq } from 'lodash'; +import type { ClusterListEntry } from '@services/types'; + import { PipelineStatus, TicketTypes } from '@common/const'; import { utcDisplayTime } from '@utils'; @@ -81,6 +83,7 @@ export default class Mongodb { bk_cloud_name: string; cluster_access_port: number; cluster_alias: string; + cluster_entry: ClusterListEntry[]; cluster_name: string; cluster_stats: Record<'used' | 'total' | 'in_use', number>; cluster_time_zone: string; @@ -114,6 +117,7 @@ export default class Mongodb { phase_name: string; region: string; replicaset_machine_num: number; + seg_range: Record; slave_domain: string; shard_node_count: number; // 分片节点数 shard_num: number; // 分片数 @@ -135,6 +139,7 @@ export default class Mongodb { this.db_module_name = payload.db_module_name; this.cluster_access_port = payload.cluster_access_port; this.cluster_alias = payload.cluster_alias; + this.cluster_entry = payload.cluster_entry || []; this.disaster_tolerance_level = payload.disaster_tolerance_level; this.cluster_name = payload.cluster_name; this.cluster_stats = payload.cluster_stats || {}; @@ -158,6 +163,7 @@ export default class Mongodb { this.phase_name = payload.phase_name; this.region = payload.region; this.replicaset_machine_num = payload.replicaset_machine_num; + this.seg_range = payload.seg_range; this.slave_domain = payload.slave_domain; this.shard_node_count = payload.shard_node_count; this.shard_num = payload.shard_num; @@ -313,4 +319,51 @@ export default class Mongodb { get updateAtDisplay() { return utcDisplayTime(this.update_at); } + + get entryDomain() { + if (this.isMongoReplicaSet) { + const domainList = this.cluster_entry.reduce((prevDomainList, entryItem) => { + if (!entryItem.entry.includes('backup')) { + return prevDomainList.concat(`${entryItem.entry}:${this.cluster_access_port}`); + } + return prevDomainList; + }, []); + return domainList.join(','); + } + return `${this.master_domain}:${this.cluster_access_port}`; + } + + get entryAccess() { + if (this.isMongoReplicaSet) { + return `mongodb://{username}:{password}@${this.entryDomain}/?replicaSet=${this.cluster_name}&authSource=admin`; + } + return `mongodb://{username}:{password}@${this.entryDomain}/?authSource=admin`; + } + + get entryAccessClb() { + if (!this.isMongoReplicaSet) { + const clbItem = this.cluster_entry.find((entryItem) => entryItem.cluster_entry_type === 'clbDns'); + if (clbItem) { + return `mongodb://{username}:{password}@${clbItem.entry}:${this.cluster_access_port}/?authSource=admin`; + } + } + return ''; + } + + get shardList() { + return Object.entries(this.seg_range).reduce< + { + shardName: string; + instanceList: string[]; + }[] + >((prevList, [shardName, instanceList]) => { + if (!shardName.endsWith('conf')) { + return prevList.concat({ + shardName, + instanceList, + }); + } + return prevList; + }, []); + } } diff --git a/dbm-ui/frontend/src/services/source/mongodb.ts b/dbm-ui/frontend/src/services/source/mongodb.ts index 21757cc471..2d74e075c1 100644 --- a/dbm-ui/frontend/src/services/source/mongodb.ts +++ b/dbm-ui/frontend/src/services/source/mongodb.ts @@ -24,7 +24,7 @@ import http from '../http'; const { currentBizId } = useGlobalBizs(); -const path = `/apis/mongodb/bizs/${currentBizId}/mongodb_resources`; +const getRootPath = () => `/apis/mongodb/bizs/${window.PROJECT_CONFIG.BIZ_ID}/mongodb_resources`; interface RelatedCluster { cluster_id: number; @@ -72,7 +72,7 @@ export function getMongoList(params: { limit?: number; offset?: number; }) { - return http.get>(`${path}/`, params).then((data) => ({ + return http.get>(`${getRootPath()}/`, params).then((data) => ({ ...data, results: data.results.map((item) => new MongodbModel(item)), })); @@ -97,7 +97,7 @@ export function getMongoTopoList(params: { offset?: number; }) { return http - .get>(`${path}/`, params) + .get>(`${getRootPath()}/`, params) .then((data) => data.results.map((item) => new MongodbModel(item))); } @@ -105,21 +105,23 @@ export function getMongoTopoList(params: { * 查询Mongo集群详情 */ export function getMongoClusterDetails(params: { cluster_id: number }) { - return http.get(`${path}/${params.cluster_id}/`).then((data) => new MongodbDetailModel(data)); + return http + .get(`${getRootPath()}/${params.cluster_id}/`) + .then((data) => new MongodbDetailModel(data)); } /** * 查询Mongo拓扑图 */ export function getMongoClustersTopoGraph(params: { cluster_id: number }) { - return http.get(`${path}/${params.cluster_id}/get_topo_graph/`); + return http.get(`${getRootPath()}/${params.cluster_id}/get_topo_graph/`); } /** * 获取Mongo集群 table 信息 */ export function getMongoTableFields(params: { limit?: number; offset?: number }) { - return http.get(`${path}/get_table_fields/`, params); + return http.get(`${getRootPath()}/get_table_fields/`, params); } /** @@ -138,7 +140,7 @@ export function getMongoInstancesList(params: { offset?: number; extra?: number; }) { - return http.get>(`${path}/list_instances/`, params).then((data) => ({ + return http.get>(`${getRootPath()}/list_instances/`, params).then((data) => ({ ...data, results: data.results.map((item) => new MongodbInstanceModel(item)), })); @@ -147,7 +149,7 @@ export function getMongoInstancesList(params: { /** * 查询Mongo集群实例详情 */ -export function getMongoInstanceDetail(params: { +export function retrieveMongoInstanceDetail(params: { instance_address: string; cluster_id?: number; ip?: string; @@ -156,7 +158,7 @@ export function getMongoInstanceDetail(params: { offset?: number; }) { return http - .get(`${path}/retrieve_instance/`, params) + .get(`${getRootPath()}/retrieve_instance/`, params) .then((data) => new MongodbInstanceDetailModel(data)); } @@ -164,7 +166,7 @@ export function getMongoInstanceDetail(params: { * 获取Mongo角色列表 */ export function getMongoRoleList(params: { limit?: number; offset?: number }) { - return http.get(`${path}/get_instance_role/`, params); + return http.get(`${getRootPath()}/get_instance_role/`, params); } /** @@ -174,6 +176,7 @@ export function getMongodbMachineList(params: { bk_host_id?: number; ip?: string; machine_type?: string; + cluster_type?: string; bk_os_name?: string; bk_cloud_id?: number; bk_agent_id?: string; @@ -182,21 +185,21 @@ export function getMongodbMachineList(params: { limit?: number; offset?: number; }) { - return http.get(`${path}/list_machines/`, params); + return http.get(`${getRootPath()}/list_machines/`, params); } /** * 导出Mongo集群数据为 excel 文件 */ export function exportMongodbClusterToExcel(params: { cluster_ids?: number[] }) { - return http.post(`${path}/export_cluster/`, params, { responseType: 'blob' }); + return http.post(`${getRootPath()}/export_cluster/`, params, { responseType: 'blob' }); } /** * 导出Mongo实例数据为 excel 文件 */ export function exportMongodbInstanceToExcel(params: { bk_host_ids?: number[] }) { - return http.post(`${path}/export_instance/`, params, { responseType: 'blob' }); + return http.post(`${getRootPath()}/export_instance/`, params, { responseType: 'blob' }); } /** diff --git a/dbm-ui/frontend/src/views/db-manage/common/cluster-details/common/graphData.ts b/dbm-ui/frontend/src/views/db-manage/common/cluster-details/common/graphData.ts index 5fa3031502..ce5c692231 100644 --- a/dbm-ui/frontend/src/views/db-manage/common/cluster-details/common/graphData.ts +++ b/dbm-ui/frontend/src/views/db-manage/common/cluster-details/common/graphData.ts @@ -91,6 +91,11 @@ export const nodeTypes = { TENDBCLUSTER_SLAVE: 'spider_slave', TENDBCLUSTER_CONTROLLER: 'controller_group', TENDBCLUSTER_MNT: 'spider_mnt', + MONGODB_M1: 'mongodb::m1', + MONGODB_M2: 'mongodb::m2', + MONGODB_BACKUP: 'mongodb::backup', + MONGODB_MONGOS: 'mongos', + MONGODB_CONFIG: 'mongo_config::m1', }; // 特殊逻辑:控制节点水平对齐 @@ -102,6 +107,8 @@ const sameSources = [ nodeTypes.PULSAR_BROKER, nodeTypes.TENDBCLUSTER_REMOTE_MASTER, nodeTypes.TENDBCLUSTER_MASTER, + nodeTypes.MONGODB_M1, + nodeTypes.MONGODB_MONGOS, ]; const sameTargets = [ nodeTypes.SLAVE, @@ -111,6 +118,8 @@ const sameTargets = [ nodeTypes.PULSAR_ZOOKEEPER, nodeTypes.TENDBCLUSTER_REMOTE_SLAVE, nodeTypes.TENDBCLUSTER_SLAVE, + nodeTypes.MONGODB_M2, + nodeTypes.MONGODB_CONFIG, ]; export class GraphData { @@ -150,15 +159,15 @@ export class GraphData { belong: '', // 节点所属组 ID })); } else { - const rootGroups = this.getRootGroups(data); + const rootGroups = this.getRootGroups(data, dbType); const groups = this.getGroups(data, rootGroups); const groupLines = this.getGroupLines(data); this.calcRootLocations(rootGroups); const [firstRoot] = rootGroups; this.calcNodeLocations(firstRoot, groups, groupLines); - // es hdfs 集群特殊逻辑 - if (([ClusterTypes.ES, ClusterTypes.HDFS] as string[]).includes(this.clusterType)) { + // es hdfs mongo 集群特殊逻辑 + if (([ClusterTypes.ES, ClusterTypes.HDFS, ClusterTypes.MONGODB] as string[]).includes(this.clusterType)) { this.calcHorizontalAlignLocations(groups); } else if (this.clusterType === ClusterTypes.TENDBCLUSTER) { this.calcSpiderNodeLocations(rootGroups, groups); @@ -171,7 +180,6 @@ export class GraphData { ); this.calcLines(lines, locations); } - this.graphData = { locations, lines, @@ -185,7 +193,7 @@ export class GraphData { * @param data 集群拓扑数据 * @returns 访问入口 groups */ - getRootGroups(data: ResourceTopo): GraphNode[] { + getRootGroups(data: ResourceTopo, dbType: string): GraphNode[] { const { node_id: nodeId, nodes, groups, lines } = data; const rootLines = lines.filter( (line) => @@ -242,6 +250,10 @@ export class GraphData { }; }) .filter((item) => item !== null) as GraphNode[]; + + if (dbType === DBTypes.MONGODB) { + return [roots[0]]; + } // 排序根节点 roots.sort((a) => (a.children.find((node) => node.id === nodeId) ? -1 : 0)); return roots; @@ -477,7 +489,7 @@ export class GraphData { } /** - * 单独处理 es master、cold、hot || hdfs hournal、zookeeper、datanode 节点水平排列 + * 单独处理 es master、cold、hot || hdfs hournal、zookeeper、datanode || mongo分片 节点水平排列 * @param nodes 节点列表 */ calcHorizontalAlignLocations(nodes: GraphNode[] = []) { @@ -489,7 +501,7 @@ export class GraphData { nodeTypes.HDFS_MASTER_HOURNALNODE, nodeTypes.HDFS_MASTER_ZOOKEEPER, ]; - const targetNodes = nodes.filter((node) => targetNodeIds.includes(node.id)); + const targetNodes = nodes.filter((node) => targetNodeIds.includes(node.id) || node.id.includes('分片')); const [referenceNode] = targetNodes; const moveNodes = targetNodes.slice(1); diff --git a/dbm-ui/frontend/src/views/db-manage/common/cluster-details/common/useRenderGraph.tsx b/dbm-ui/frontend/src/views/db-manage/common/cluster-details/common/useRenderGraph.tsx index d9aa1bd4ef..d76cc353fb 100644 --- a/dbm-ui/frontend/src/views/db-manage/common/cluster-details/common/useRenderGraph.tsx +++ b/dbm-ui/frontend/src/views/db-manage/common/cluster-details/common/useRenderGraph.tsx @@ -18,6 +18,7 @@ import type { VNode } from 'vue'; import { retrieveEsInstance } from '@services/source/es'; import { retrieveHdfsInstance } from '@services/source/hdfs'; import { retrieveKafkaInstance } from '@services/source/kafka'; +import { retrieveMongoInstanceDetail } from '@services/source/mongodb'; import { retrievePulsarInstance } from '@services/source/pulsar'; import { retrieveRedisInstance } from '@services/source/redis'; import { retrieveRiakInstance } from '@services/source/riak'; @@ -167,6 +168,7 @@ const apiMap: Record Promise> = { tendbha: retrieveTendbhaInstance, tendbcluster: getTendbclusterInstanceDetail, riak: retrieveRiakInstance, + mongodb: retrieveMongoInstanceDetail, }; const entryTagMap: Record = { diff --git a/dbm-ui/frontend/src/views/db-manage/common/permission/components/mongo/CreateRule.vue b/dbm-ui/frontend/src/views/db-manage/common/permission/components/mongo/CreateRule.vue index c9908f6e4a..5fcaafc303 100644 --- a/dbm-ui/frontend/src/views/db-manage/common/permission/components/mongo/CreateRule.vue +++ b/dbm-ui/frontend/src/views/db-manage/common/permission/components/mongo/CreateRule.vue @@ -335,8 +335,8 @@ .check-all { position: relative; - width: 48px; - margin-right: 48px; + width: 50px; + margin-right: 50px; :deep(.bk-checkbox-label) { font-weight: bold; diff --git a/dbm-ui/frontend/src/views/db-manage/mongodb/capacity-change/pages/page1/Index.vue b/dbm-ui/frontend/src/views/db-manage/mongodb/capacity-change/pages/page1/Index.vue index 5ce8304869..38f9c3a94d 100644 --- a/dbm-ui/frontend/src/views/db-manage/mongodb/capacity-change/pages/page1/Index.vue +++ b/dbm-ui/frontend/src/views/db-manage/mongodb/capacity-change/pages/page1/Index.vue @@ -54,14 +54,15 @@ + + diff --git a/dbm-ui/frontend/src/views/db-manage/mongodb/shared-cluster-list/components/components/CapacityChange.vue b/dbm-ui/frontend/src/views/db-manage/mongodb/components/CapacityChange.vue similarity index 90% rename from dbm-ui/frontend/src/views/db-manage/mongodb/shared-cluster-list/components/components/CapacityChange.vue rename to dbm-ui/frontend/src/views/db-manage/mongodb/components/CapacityChange.vue index 9c994285bb..c84ace185b 100644 --- a/dbm-ui/frontend/src/views/db-manage/mongodb/shared-cluster-list/components/components/CapacityChange.vue +++ b/dbm-ui/frontend/src/views/db-manage/mongodb/components/CapacityChange.vue @@ -30,6 +30,7 @@ v-model="specInfo" :biz-id="data.bizId" :cloud-id="data.cloudId" + :cluster-type="clusterType" :is-apply="false" :origin-spec-id="originSpecId" :properties="{ @@ -45,16 +46,16 @@ + + diff --git a/dbm-ui/frontend/src/views/db-manage/mongodb/components/edit-field/TableName.vue b/dbm-ui/frontend/src/views/db-manage/mongodb/components/edit-field/TableName.vue index c1ddd91ebc..23d56bf87f 100644 --- a/dbm-ui/frontend/src/views/db-manage/mongodb/components/edit-field/TableName.vue +++ b/dbm-ui/frontend/src/views/db-manage/mongodb/components/edit-field/TableName.vue @@ -15,18 +15,44 @@ + @blur="handleBlur" + @change="handleChange" + @focus="handleFocus"> + + + + diff --git a/dbm-ui/frontend/src/views/db-manage/mongodb/components/edit-field/clusters-with-selector/Index.vue b/dbm-ui/frontend/src/views/db-manage/mongodb/components/edit-field/clusters-with-selector/Index.vue index a4305552c9..5745b56210 100644 --- a/dbm-ui/frontend/src/views/db-manage/mongodb/components/edit-field/clusters-with-selector/Index.vue +++ b/dbm-ui/frontend/src/views/db-manage/mongodb/components/edit-field/clusters-with-selector/Index.vue @@ -146,14 +146,14 @@ .render-host-box { position: relative; - :deep(.is-error) { - .error-icon { - top: auto; - top: 50%; - right: auto; - left: 50%; - transform: translate(-50%, -50%); - } - } + // :deep(.is-error) { + // .error-icon { + // top: auto; + // top: 50%; + // right: auto; + // left: 50%; + // transform: translate(-50%, -50%); + // } + // } } diff --git a/dbm-ui/frontend/src/views/db-manage/mongodb/components/edit-field/clusters-with-selector/Input.vue b/dbm-ui/frontend/src/views/db-manage/mongodb/components/edit-field/clusters-with-selector/Input.vue index 5b1f33b84d..235fe1549c 100644 --- a/dbm-ui/frontend/src/views/db-manage/mongodb/components/edit-field/clusters-with-selector/Input.vue +++ b/dbm-ui/frontend/src/views/db-manage/mongodb/components/edit-field/clusters-with-selector/Input.vue @@ -376,7 +376,7 @@ .input-error { position: absolute; top: 50%; - left: 50%; + right: 28px; z-index: 99; padding-bottom: 3px; font-size: 14px; diff --git a/dbm-ui/frontend/src/views/db-manage/mongodb/db-backup/pages/page1/Index.vue b/dbm-ui/frontend/src/views/db-manage/mongodb/db-backup/pages/page1/Index.vue index 09950c6523..9cee7869b5 100644 --- a/dbm-ui/frontend/src/views/db-manage/mongodb/db-backup/pages/page1/Index.vue +++ b/dbm-ui/frontend/src/views/db-manage/mongodb/db-backup/pages/page1/Index.vue @@ -37,21 +37,27 @@ :model="formData" style="margin-top: 16px"> - {{ t('常规备份(25天)') }} + {{ t('25天') }} + + + {{ t('6个月') }} + + + {{ t('1年') }} - {{ t('长期备份(3年)') }} + {{ t('3年') }} @@ -95,7 +102,6 @@ + + diff --git a/dbm-ui/frontend/src/views/db-manage/mongodb/db-replace/pages/page1/components/Row.vue b/dbm-ui/frontend/src/views/db-manage/mongodb/db-replace/pages/page1/components/Row.vue index 0eda8e1b8c..eb3ecca849 100644 --- a/dbm-ui/frontend/src/views/db-manage/mongodb/db-replace/pages/page1/components/Row.vue +++ b/dbm-ui/frontend/src/views/db-manage/mongodb/db-replace/pages/page1/components/Row.vue @@ -16,12 +16,14 @@ @@ -61,10 +63,11 @@ import { useGlobalBizs } from '@stores'; + import { ClusterTypes } from '@common/const'; + import OperateColumn from '@components/render-table/columns/operate-column/index.vue'; import RenderText from '@components/render-table/columns/text-plain/index.vue'; - import RenderHost from '@views/db-manage/mongodb/components/edit-field/HostName.vue'; import type { SpecInfo } from '@views/db-manage/mongodb/components/edit-field/spec-select/components/Panel.vue'; import type { IListItem } from '@views/db-manage/mongodb/components/edit-field/spec-select/components/Select.vue'; import RenderTargetSpec from '@views/db-manage/mongodb/components/edit-field/spec-select/Index.vue'; @@ -72,6 +75,8 @@ import { random } from '@utils'; + import RenderHost from './HostName.vue'; + export interface IDataRow { rowKey: string; isLoading: boolean; @@ -80,6 +85,7 @@ clusterType: string; role: string; machineType: string; + shard: string; cluster: { domain: string; isStart: boolean; @@ -99,6 +105,7 @@ clusterId: 0, clusterType: '', machineType: '', + shard: '', role: '', relatedClusters: [], cluster: { @@ -108,11 +115,11 @@ rowSpan: 1, }, }); - - + diff --git a/dbm-ui/frontend/src/views/db-manage/mongodb/db-table-backup/pages/page1/Index.vue b/dbm-ui/frontend/src/views/db-manage/mongodb/db-table-backup/pages/page1/Index.vue index bf7ce8d82e..fc2bf02b40 100644 --- a/dbm-ui/frontend/src/views/db-manage/mongodb/db-table-backup/pages/page1/Index.vue +++ b/dbm-ui/frontend/src/views/db-manage/mongodb/db-table-backup/pages/page1/Index.vue @@ -66,16 +66,22 @@ :model="formData" style="margin-top: 16px"> - {{ t('常规备份(25天)') }} + {{ t('25天') }} + + + {{ t('6个月') }} + + + {{ t('1年') }} - {{ t('长期备份(3年)') }} + {{ t('3年') }} @@ -108,7 +114,6 @@ - + + + diff --git a/dbm-ui/frontend/src/views/db-manage/mongodb/shared-cluster-list/components/list/components/render-shard/components/RenderRow.vue b/dbm-ui/frontend/src/views/db-manage/mongodb/shared-cluster-list/components/list/components/render-shard/components/RenderRow.vue new file mode 100644 index 0000000000..16e4ff29db --- /dev/null +++ b/dbm-ui/frontend/src/views/db-manage/mongodb/shared-cluster-list/components/list/components/render-shard/components/RenderRow.vue @@ -0,0 +1,139 @@ + + + + + + + diff --git a/dbm-ui/frontend/src/views/tickets/common/components/demand-factory/mongodb/DbBackup.vue b/dbm-ui/frontend/src/views/tickets/common/components/demand-factory/mongodb/DbBackup.vue index b166179605..491d9c356d 100644 --- a/dbm-ui/frontend/src/views/tickets/common/components/demand-factory/mongodb/DbBackup.vue +++ b/dbm-ui/frontend/src/views/tickets/common/components/demand-factory/mongodb/DbBackup.vue @@ -18,11 +18,11 @@ :data="dataList" />
- {{ t('备份文件保存时间') }}: - {{ fileTag }} + {{ t('备份保存时间') }}: + {{ fileTagText }}
- {{ t('是否开启 Oplog') }}: + {{ t('是否备份 Oplog') }}: {{ oplogType }}
@@ -75,10 +75,17 @@ const { t } = useI18n(); - const { clusters, file_tag, oplog, infos } = props.ticketDetails.details; + const { clusters, file_tag: fileTag, oplog, infos } = props.ticketDetails.details; + + const fileTagMap: Record = { + normal_backup: t('25天'), + half_year_backup: t('6 个月'), + a_year_backup: t('1 年'), + forever_backup: t('3 年'), + }; // eslint-disable-next-line camelcase - const fileTag = file_tag === 'normal_backup' ? t('常规备份(25天)') : t('长期备份(3年)'); + const fileTagText = fileTagMap[fileTag]; const oplogType = oplog ? t('是') : t('否'); const columns = [ diff --git a/dbm-ui/frontend/src/views/tickets/common/components/demand-factory/mongodb/DbStruct.vue b/dbm-ui/frontend/src/views/tickets/common/components/demand-factory/mongodb/DbStruct.vue index 941b7e4d7a..52c8f0c339 100644 --- a/dbm-ui/frontend/src/views/tickets/common/components/demand-factory/mongodb/DbStruct.vue +++ b/dbm-ui/frontend/src/views/tickets/common/components/demand-factory/mongodb/DbStruct.vue @@ -48,6 +48,8 @@ import type { TicketDetails } from '@services/types/ticket'; + import { ClusterTypes } from '@common/const'; + import { utcDisplayTime } from '@utils'; interface DbStructDeatils { @@ -293,8 +295,8 @@ const tableData = computed(() => clusterIds.map(id => ({ immute_domain: clusters[id].immute_domain, - struct_type: backupinfo ? t('备份记录') : t('回档至指定时间 '), - backup_file: backupinfo ? `${backupinfo[id].role_type}${utcDisplayTime(backupinfo[id].end_time)}` : '', + struct_type: backupinfo ? t('备份记录') : t('回档至指定时间'), + backup_file: backupinfo ? `${clusters[id].cluster_type === ClusterTypes.MONGO_SHARED_CLUSTER ? backupinfo[id].set_name : ''}-${backupinfo[id].role_type}-${utcDisplayTime(backupinfo[id].end_time)}` : '', target_time: rollbackTime ? utcDisplayTime(rollbackTime) : '', })) ) diff --git a/dbm-ui/frontend/src/views/tickets/common/components/demand-factory/mongodb/DbTableBackup.vue b/dbm-ui/frontend/src/views/tickets/common/components/demand-factory/mongodb/DbTableBackup.vue index 37a956f3c4..bc7ad4f7b0 100644 --- a/dbm-ui/frontend/src/views/tickets/common/components/demand-factory/mongodb/DbTableBackup.vue +++ b/dbm-ui/frontend/src/views/tickets/common/components/demand-factory/mongodb/DbTableBackup.vue @@ -18,10 +18,8 @@ :data="dataList" />
- {{ t('备份文件保存时间') }}: - {{ - fileTag === 'normal_backup' ? t('常规备份(25天)') : t('长期备份(3年)') - }} + {{ t('备份保存时间') }}: + {{ fileTagText }}
= { + normal_backup: t('25天'), + half_year_backup: t('6 个月'), + a_year_backup: t('1 年'), + forever_backup: t('3 年'), + }; + + const fileTagText = fileTagMap[fileTag];