From 71b665a183305698c19e68e019a9625fd72bd2b8 Mon Sep 17 00:00:00 2001 From: Austin <1344583166@qq.com> Date: Fri, 20 Sep 2024 15:03:04 +0800 Subject: [PATCH] =?UTF-8?q?feat(frontend):=20mysql=E5=B7=A5=E5=85=B7?= =?UTF-8?q?=E7=AE=B1=E6=94=AF=E6=8C=81=E6=A0=BC=E5=AD=90=E5=86=85=E9=80=89?= =?UTF-8?q?=E6=8B=A9=E9=9B=86=E7=BE=A4/=E5=AE=9E=E4=BE=8B/IP=20#6997?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/tendb-cluster/Index.vue | 5 + .../components/tendb-single/Index.vue | 5 + .../components/tendbha/Index.vue | 5 + .../components/instance-selector/Index.vue | 3 +- .../components/mysql/Index.vue | 3 + .../components/mysql/table/Index.vue | 20 +- .../render-table/columns/input/index.vue | 137 +++--- .../generateCloneData/mysql/instanceClone.ts | 19 +- .../mysql/masterSlaveSwitch.ts | 25 +- .../mysql/restoreLocalSlave.ts | 8 +- .../generateCloneData/mysql/restoreSlave.ts | 45 +- .../mysql/versionMigrateUpgrade.ts | 1 + dbm-ui/frontend/src/services/source/dbbase.ts | 2 + .../frontend/src/services/source/tendbha.ts | 3 +- .../src/services/source/tendbsingle.ts | 7 +- .../components/edit-field/ClusterName.vue | 2 +- .../mysql/checksum/pages/page1/Index.vue | 2 +- .../pages/page1/components/RenderData/Row.vue | 10 +- .../edit-field/ClusterNameWithSelector.vue | 345 +++++++++++++ .../edit-field/ClusterWithRelateCluster.vue | 142 ++---- .../edit-field/InstanceWithSelector.vue | 297 +++++++++++ .../edit-field/IpInputWithIpSelector.vue | 269 ++++++++++ .../pages/page1/components/Index.vue | 10 +- .../pages/page1/components/Row.vue | 8 +- .../render-target-clusters/Index.vue | 87 +--- .../render-target-clusters/Input.vue | 463 ++++-------------- .../pages/page1/components/RenderData/Row.vue | 10 +- .../pages/page1/components/RenderData/Row.vue | 11 +- .../pages/page1/components/RenderData/Row.vue | 11 +- .../pages/page1/components/RenderData/Row.vue | 9 +- .../pages/page1/components/RenderData/Row.vue | 23 +- .../pages/page1/components/RenderData/Row.vue | 42 +- .../pages/page1/components/BatchEntry.vue | 20 +- .../components/RenderData/RenderSlave.vue | 6 +- .../pages/page1/components/RenderData/Row.vue | 47 +- .../components/target-cluster/Index.vue | 37 +- .../target-cluster/components/Row.vue | 29 +- .../pages/page1/components/RenderData/Row.vue | 9 +- .../pages/page1/Index.vue | 22 +- .../components/RenderData/RenderSource.vue | 163 ------ .../components/RenderData/RenderTarget.vue | 2 +- .../pages/page1/components/RenderData/Row.vue | 50 +- .../render-cluster/ClusterRelatedInput.vue | 8 +- .../RenderData/render-cluster/Index.vue | 111 ++--- .../pages/page1/components/new-host/Index.vue | 10 +- .../components/RenderData/RenderNewSlave.vue | 14 +- .../components/RenderData/RenderOldSlave.vue | 26 +- .../new-host/components/RenderData/Row.vue | 69 ++- .../page1/components/original-host/Index.vue | 10 +- .../components/RenderData/RenderCluster.vue | 2 +- .../components/RenderData/Row.vue | 65 ++- .../RenderClusterWithRelateCluster.vue | 132 ++--- .../components/ha-access-layer/Index.vue | 12 +- .../page1/components/ha-access-layer/Row.vue | 8 +- .../ha-storage-layer-local/Index.vue | 12 +- .../components/ha-storage-layer-local/Row.vue | 8 +- .../ha-storage-layer-remote/Index.vue | 12 +- .../ha-storage-layer-remote/Row.vue | 8 +- .../components/single-storage-layer/Index.vue | 12 +- .../components/single-storage-layer/Row.vue | 17 +- 60 files changed, 1691 insertions(+), 1259 deletions(-) create mode 100644 dbm-ui/frontend/src/views/db-manage/mysql/common/edit-field/ClusterNameWithSelector.vue create mode 100644 dbm-ui/frontend/src/views/db-manage/mysql/common/edit-field/InstanceWithSelector.vue create mode 100644 dbm-ui/frontend/src/views/db-manage/mysql/common/edit-field/IpInputWithIpSelector.vue delete mode 100644 dbm-ui/frontend/src/views/db-manage/mysql/privilege-clone-inst/pages/page1/components/RenderData/RenderSource.vue diff --git a/dbm-ui/frontend/src/components/cluster-selector/components/tendb-cluster/Index.vue b/dbm-ui/frontend/src/components/cluster-selector/components/tendb-cluster/Index.vue index 66157f0f96..2efafb84a0 100644 --- a/dbm-ui/frontend/src/components/cluster-selector/components/tendb-cluster/Index.vue +++ b/dbm-ui/frontend/src/components/cluster-selector/components/tendb-cluster/Index.vue @@ -385,6 +385,11 @@ } const currentSelected = selectedMap.value[activeTab.value]; const isChecked = !!(currentSelected && currentSelected[data.id]); + if (isChecked && !props.multiple) { + // 单选不允许取消 + return; + } + handleSelecteRow(data, !isChecked); }; diff --git a/dbm-ui/frontend/src/components/cluster-selector/components/tendb-single/Index.vue b/dbm-ui/frontend/src/components/cluster-selector/components/tendb-single/Index.vue index d5f73f0482..0d72465afb 100644 --- a/dbm-ui/frontend/src/components/cluster-selector/components/tendb-single/Index.vue +++ b/dbm-ui/frontend/src/components/cluster-selector/components/tendb-single/Index.vue @@ -408,6 +408,11 @@ } const currentSelected = selectedMap.value[activeTab.value]; const isChecked = !!(currentSelected && currentSelected[data.id]); + if (isChecked && !props.multiple) { + // 单选不允许取消 + return; + } + handleSelecteRow(data, !isChecked); }; diff --git a/dbm-ui/frontend/src/components/cluster-selector/components/tendbha/Index.vue b/dbm-ui/frontend/src/components/cluster-selector/components/tendbha/Index.vue index 47a369866d..f0ccc35cbc 100644 --- a/dbm-ui/frontend/src/components/cluster-selector/components/tendbha/Index.vue +++ b/dbm-ui/frontend/src/components/cluster-selector/components/tendbha/Index.vue @@ -396,6 +396,11 @@ } const currentSelected = selectedMap.value[activeTab.value]; const isChecked = !!(currentSelected && currentSelected[data.id]); + if (isChecked && !props.multiple) { + // 单选不允许取消 + return; + } + handleSelecteRow(data, !isChecked); }; diff --git a/dbm-ui/frontend/src/components/instance-selector/Index.vue b/dbm-ui/frontend/src/components/instance-selector/Index.vue index c7d806085e..bc8ba873e5 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" @@ -292,7 +293,7 @@ type RedisHostModel = ServiceReturnType['results'][number]; interface Props { - clusterTypes: (ClusterTypes | 'TendbhaHost' | 'TendbClusterHost' | 'RedisHost' | 'mongoCluster')[]; + clusterTypes: string[]; tabListConfig?: Record; selected?: InstanceSelectorValues; unqiuePanelValue?: boolean; diff --git a/dbm-ui/frontend/src/components/instance-selector/components/mysql/Index.vue b/dbm-ui/frontend/src/components/instance-selector/components/mysql/Index.vue index 126de05dfb..bba120c16f 100644 --- a/dbm-ui/frontend/src/components/instance-selector/components/mysql/Index.vue +++ b/dbm-ui/frontend/src/components/instance-selector/components/mysql/Index.vue @@ -69,6 +69,7 @@ :get-table-list="getTableList" :is-remote-pagination="isRemotePagination" :last-values="lastValues" + :multiple="multiple" :role-filter-list="roleFilterList" :status-filter="statusFilter" :table-setting="tableSetting" @@ -99,6 +100,7 @@ interface Props { lastValues: InstanceSelectorValues; tableSetting: TableSetting; + multiple?: NonNullable; firsrColumn?: TableConfigType['firsrColumn']; roleFilterList?: TableConfigType['roleFilterList']; isRemotePagination?: TableConfigType['isRemotePagination']; @@ -127,6 +129,7 @@ topoAlertContent: undefined, roleFilterList: undefined, filterClusterId: undefined, + multiple: true, }); const emits = defineEmits(); diff --git a/dbm-ui/frontend/src/components/instance-selector/components/mysql/table/Index.vue b/dbm-ui/frontend/src/components/instance-selector/components/mysql/table/Index.vue index 98d397265c..8f69603348 100644 --- a/dbm-ui/frontend/src/components/instance-selector/components/mysql/table/Index.vue +++ b/dbm-ui/frontend/src/components/instance-selector/components/mysql/table/Index.vue @@ -69,6 +69,7 @@ interface Props { lastValues: InstanceSelectorValues, tableSetting: TableSetting, + multiple?: boolean, clusterId?: number, isRemotePagination?: TableConfigType['isRemotePagination'], firsrColumn?: TableConfigType['firsrColumn'], @@ -92,6 +93,7 @@ activePanelId: 'tendbcluster', disabledRowConfig: undefined, roleFilterList: undefined, + multiple: true, }); const emits = defineEmits(); @@ -165,7 +167,7 @@ { minWidth: 70, fixed: 'left', - label: () => ( + label: () => props.multiple && (
); } - return ( + return props.multiple ? ( handleTableSelectOne(value, data)} /> + ) : ( + handleTableSelectOne(value, data)} + /> ); }, }, @@ -380,11 +389,16 @@ } const isChecked = !!checkedMap.value[data[firstColumnFieldId.value]]; + if (isChecked && !props.multiple) { + // 单选不允许取消 + return; + } + handleTableSelectOne(!isChecked, data); }; const handleTableSelectOne = (checked: boolean, data: T) => { - const lastCheckMap = { ...checkedMap.value }; + const lastCheckMap = props.multiple ? { ...checkedMap.value } : {}; if (checked) { lastCheckMap[data[firstColumnFieldId.value]] = formatValue(data) as T; } else { diff --git a/dbm-ui/frontend/src/components/render-table/columns/input/index.vue b/dbm-ui/frontend/src/components/render-table/columns/input/index.vue index 82d9bf4ff5..7736979e9f 100644 --- a/dbm-ui/frontend/src/components/render-table/columns/input/index.vue +++ b/dbm-ui/frontend/src/components/render-table/columns/input/index.vue @@ -19,9 +19,9 @@ 'is-error': Boolean(errorMessage), 'is-disabled': disabled, 'is-password': isPassword, - 'is-clearable': clearable, }"> - - -
- +
+ + +
@@ -66,7 +64,6 @@ type?: string; min?: number; max?: number; - isShowBlur?: boolean; clearable?: boolean; ignoreSameInput?: boolean; pasteFn?: (value: string) => string; @@ -94,7 +91,6 @@ type: 'text', min: Number.MIN_SAFE_INTEGER, max: Number.MAX_SAFE_INTEGER, - isShowBlur: false, clearable: true, ignoreSameInput: false, pasteFn: undefined, @@ -106,8 +102,12 @@ default: '', }); + defineSlots<{ + suspend: any; + default: any; + }>(); + const rootRef = ref(); - const isBlur = ref(true); const isPassword = computed(() => props.type === 'password'); @@ -129,14 +129,12 @@ // 响应输入 const handleInput = (value: string) => { - isBlur.value = false; window.changeConfirm = true; modelValue.value = value; emits('input', value); }; const handleFocus = () => { - isBlur.value = false; emits('focus'); }; @@ -153,7 +151,6 @@ const handleBlur = (event: FocusEvent) => { setTimeout(() => { emits('blur', modelValue.value); - isBlur.value = true; if (props.disabled) { event.preventDefault(); return; @@ -182,7 +179,7 @@ event.preventDefault(); return; } - if (event.isComposing) { + if (event.isComposing || props.type === 'textarea') { // 跳过输入法复合事件 return; } @@ -205,12 +202,15 @@ }; // 粘贴 - const handlePaste = (value: string, event: ClipboardEvent) => { + const handlePaste = (value: string, event: any) => { event.preventDefault(); + // 获取光标位置 + const cursorPosition = event.target.selectionStart; let paste = (event.clipboardData || window.clipboardData).getData('text'); paste = encodeMult(paste); paste = paste.replace(/^\s+|\s+$/g, ''); - modelValue.value = props.pasteFn ? props.pasteFn(paste) : paste; + paste = props.pasteFn ? props.pasteFn(paste) : paste; + modelValue.value = modelValue.value.slice(0, cursorPosition) + paste + modelValue.value.slice(cursorPosition); window.changeConfirm = true; }; @@ -233,12 +233,6 @@ diff --git a/dbm-ui/frontend/src/hooks/useTicketCloneInfo/generateCloneData/mysql/instanceClone.ts b/dbm-ui/frontend/src/hooks/useTicketCloneInfo/generateCloneData/mysql/instanceClone.ts index 7ee7759dac..ca7691e0e9 100644 --- a/dbm-ui/frontend/src/hooks/useTicketCloneInfo/generateCloneData/mysql/instanceClone.ts +++ b/dbm-ui/frontend/src/hooks/useTicketCloneInfo/generateCloneData/mysql/instanceClone.ts @@ -39,23 +39,8 @@ export async function generateMysqlInstanceCloneData(ticketData: TicketModel { - const clusterId = item.cluster_ids[0]; - return { - rowKey: random(), - clusterData: { - id: clusterId, - domain: clusters[clusterId].immute_domain, - }, - masterData: item.master_ip, - slaveData: item.slave_ip, - }; - }), - ); + const tableDataList = infos.map((item) => ({ + rowKey: random(), + clusterData: { + id: item.cluster_ids[0], + domain: clusters[item.cluster_ids[0]].immute_domain, + }, + masterData: item.master_ip, + slaveData: item.slave_ip, + })); return Promise.resolve({ isCheckDelay, diff --git a/dbm-ui/frontend/src/hooks/useTicketCloneInfo/generateCloneData/mysql/restoreLocalSlave.ts b/dbm-ui/frontend/src/hooks/useTicketCloneInfo/generateCloneData/mysql/restoreLocalSlave.ts index f2fba038f8..1fdf74d3f3 100644 --- a/dbm-ui/frontend/src/hooks/useTicketCloneInfo/generateCloneData/mysql/restoreLocalSlave.ts +++ b/dbm-ui/frontend/src/hooks/useTicketCloneInfo/generateCloneData/mysql/restoreLocalSlave.ts @@ -21,12 +21,12 @@ export function generateMysqlRestoreLocalSlaveCloneData(ticketData: TicketModel< const tableDataList = infos.map((item) => ({ rowKey: random(), slave: { - bkCloudId: item.slave.bk_cloud_id, - bkHostId: item.slave.bk_host_id, + bk_cloud_id: item.slave.bk_cloud_id, + bk_host_id: item.slave.bk_host_id, ip: item.slave.ip, port: item.slave.port, - instanceAddress: `${item.slave.ip}:${item.slave.port}`, - clusterId: item.cluster_id, + instance_address: `${item.slave.ip}:${item.slave.port}`, + cluster_id: item.cluster_id, }, })); return Promise.resolve({ diff --git a/dbm-ui/frontend/src/hooks/useTicketCloneInfo/generateCloneData/mysql/restoreSlave.ts b/dbm-ui/frontend/src/hooks/useTicketCloneInfo/generateCloneData/mysql/restoreSlave.ts index 8f253983af..1611e5faee 100644 --- a/dbm-ui/frontend/src/hooks/useTicketCloneInfo/generateCloneData/mysql/restoreSlave.ts +++ b/dbm-ui/frontend/src/hooks/useTicketCloneInfo/generateCloneData/mysql/restoreSlave.ts @@ -10,8 +10,6 @@ * 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. */ -import _ from 'lodash'; - import type { MySQLRestoreSlaveDetails } from '@services/model/ticket/details/mysql'; import TicketModel from '@services/model/ticket/ticket'; @@ -20,30 +18,25 @@ import { random } from '@utils'; // MySQL 重建从库-新机重建 export function generateMysqlRestoreSlaveCloneData(ticketData: TicketModel) { const { infos } = ticketData.details; - const tableDataList = _.flatMap( - infos.map((item) => { - const clusterId = item.cluster_ids[0]; - return { - rowKey: random(), - oldSlave: { - bkCloudId: item.old_slave.bk_cloud_id, - bkCloudName: '', - bkHostId: item.old_slave.bk_host_id, - ip: item.old_slave.ip, - port: item.old_slave.port, - instanceAddress: `${item.old_slave.ip}:${item.old_slave.port}`, - clusterId, - }, - newSlave: { - bkBizId: item.new_slave.bk_biz_id, - bkCloudId: item.new_slave.bk_cloud_id, - bkHostId: item.new_slave.bk_host_id, - ip: item.new_slave.ip, - port: item.new_slave.port, - }, - }; - }), - ); + const tableDataList = infos.map((item) => ({ + rowKey: random(), + oldSlave: { + bk_cloud_id: item.old_slave.bk_cloud_id, + bk_cloud_name: '', + bk_host_id: item.old_slave.bk_host_id, + ip: item.old_slave.ip, + port: item.old_slave.port, + instance_address: `${item.old_slave.ip}:${item.old_slave.port}`, + cluster_id: item.cluster_ids[0], + }, + newSlave: { + bk_biz_id: item.new_slave.bk_biz_id, + bk_cloud_id: item.new_slave.bk_cloud_id, + bk_host_id: item.new_slave.bk_host_id, + ip: item.new_slave.ip, + port: item.new_slave.port, + }, + })); return Promise.resolve({ tableDataList, diff --git a/dbm-ui/frontend/src/hooks/useTicketCloneInfo/generateCloneData/mysql/versionMigrateUpgrade.ts b/dbm-ui/frontend/src/hooks/useTicketCloneInfo/generateCloneData/mysql/versionMigrateUpgrade.ts index 55719d9caa..a0b84a2237 100644 --- a/dbm-ui/frontend/src/hooks/useTicketCloneInfo/generateCloneData/mysql/versionMigrateUpgrade.ts +++ b/dbm-ui/frontend/src/hooks/useTicketCloneInfo/generateCloneData/mysql/versionMigrateUpgrade.ts @@ -24,6 +24,7 @@ export async function generateMysqlVersionMigrateUpgradeCloneData(ticketData: Ti const clusterListResult = await getTendbhaList({ id: infos.map((item) => item.cluster_ids[0]).join(','), }); + const clusterListMap = clusterListResult.results.reduce( (obj, item) => { Object.assign(obj, { diff --git a/dbm-ui/frontend/src/services/source/dbbase.ts b/dbm-ui/frontend/src/services/source/dbbase.ts index 6d4b79e22a..aa3b776dfc 100644 --- a/dbm-ui/frontend/src/services/source/dbbase.ts +++ b/dbm-ui/frontend/src/services/source/dbbase.ts @@ -34,6 +34,8 @@ export function filterClusters< bk_cloud_name: string; cluster_name: string; cluster_type: string; + master_domain: string; + id: number; }, >(params: { bk_biz_id: number; exact_domain?: string; cluster_ids?: string }) { return http.get(`${path}/filter_clusters/`, params); diff --git a/dbm-ui/frontend/src/services/source/tendbha.ts b/dbm-ui/frontend/src/services/source/tendbha.ts index 6763da7055..d095f17550 100644 --- a/dbm-ui/frontend/src/services/source/tendbha.ts +++ b/dbm-ui/frontend/src/services/source/tendbha.ts @@ -34,7 +34,8 @@ export function getTendbhaList(params: { exact_domain?: string; master_domain?: string; slave_domain?: string; - id?: string; + exact_domain?: string; + id?: string | number; }) { return http.get>(`${getRootPath()}/`, params).then((data) => ({ ...data, diff --git a/dbm-ui/frontend/src/services/source/tendbsingle.ts b/dbm-ui/frontend/src/services/source/tendbsingle.ts index c8165af5f5..a2a295cb1e 100644 --- a/dbm-ui/frontend/src/services/source/tendbsingle.ts +++ b/dbm-ui/frontend/src/services/source/tendbsingle.ts @@ -21,7 +21,12 @@ const getRootPath = () => `/apis/mysql/bizs/${window.PROJECT_CONFIG.BIZ_ID}/tend /** * 查询资源列表 */ -export function getTendbsingleList(params: { limit?: number; offset?: number; cluster_ids?: number[] | number }) { +export function getTendbsingleList(params: { + cluster_ids?: string; + id?: string | number; + limit?: number; + offset?: number; +}) { return http.get>(`${getRootPath()}/`, params).then((data) => ({ ...data, results: data.results.map( diff --git a/dbm-ui/frontend/src/views/db-manage/mongodb/components/edit-field/ClusterName.vue b/dbm-ui/frontend/src/views/db-manage/mongodb/components/edit-field/ClusterName.vue index aaf2a18b15..a13c855ddf 100644 --- a/dbm-ui/frontend/src/views/db-manage/mongodb/components/edit-field/ClusterName.vue +++ b/dbm-ui/frontend/src/views/db-manage/mongodb/components/edit-field/ClusterName.vue @@ -19,7 +19,7 @@ :placeholder="t('请输入或选择集群')" :rules="rules" @submit="handleInputFinish"> -