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"> -