|
19 | 19 | :loading="loading"
|
20 | 20 | :min-width="300"
|
21 | 21 | required>
|
| 22 | + <template #headAppend> |
| 23 | + <BatchEditColumn |
| 24 | + v-model="showBatchEdit" |
| 25 | + :placeholder="t('请输入集群域名,多个请用分隔符分隔')" |
| 26 | + :title="t('目标集群')" |
| 27 | + type="textarea" |
| 28 | + @change="handleBatchEditChange"> |
| 29 | + <span |
| 30 | + v-bk-tooltips="t('统一设置:将该列统一设置为相同的值')" |
| 31 | + class="batch-edit-btn" |
| 32 | + @click="handleBatchEditShow"> |
| 33 | + <DbIcon type="bulk-edit" /> |
| 34 | + </span> |
| 35 | + </BatchEditColumn> |
| 36 | + </template> |
22 | 37 | <EditableTextarea
|
23 | 38 | v-model="localValue"
|
24 | 39 | :placeholder="t('请输入集群域名,多个请用分隔符分隔')"
|
|
41 | 56 | </template>
|
42 | 57 | <script lang="ts" setup>
|
43 | 58 | import { useI18n } from 'vue-i18n';
|
44 |
| - import { useRequest } from 'vue-request'; |
45 | 59 |
|
46 | 60 | import SqlServerHaModel from '@services/model/sqlserver/sqlserver-ha';
|
47 | 61 | import SqlServerSingleModel from '@services/model/sqlserver/sqlserver-single';
|
|
53 | 67 |
|
54 | 68 | import ClusterSelector from '@components/cluster-selector/Index.vue';
|
55 | 69 |
|
| 70 | + import BatchEditColumn from '@views/db-manage/common/batch-edit-column/Index.vue'; |
| 71 | +
|
56 | 72 | interface Props {
|
| 73 | + // 用于检查当前集群是否被包含在源集群中 |
| 74 | + selectedMap: Record<string, boolean>; |
57 | 75 | srcCluster: {
|
58 | 76 | cluster_type: ClusterTypes;
|
59 | 77 | id: number;
|
|
62 | 80 | };
|
63 | 81 | }
|
64 | 82 |
|
| 83 | + type Emits = (e: 'batch-edit', data: typeof modelValue.value, field: string) => void; |
| 84 | +
|
65 | 85 | const props = defineProps<Props>();
|
66 | 86 |
|
| 87 | + const emits = defineEmits<Emits>(); |
| 88 | +
|
67 | 89 | const modelValue = defineModel<
|
68 | 90 | {
|
69 | 91 | cluster_type: ClusterTypes;
|
|
76 | 98 | });
|
77 | 99 |
|
78 | 100 | const { t } = useI18n();
|
| 101 | + const showBatchEdit = ref(false); |
79 | 102 |
|
80 | 103 | const compareVersion = (dstVersion: string, srcVersion: string) => {
|
81 | 104 | const versionMatchReg = /[^\d]*(\d+)$/;
|
|
96 | 119 | handler: (data: SqlServerHaModel) => data.id === props.srcCluster.id,
|
97 | 120 | tip: t('不允许选择源集群'),
|
98 | 121 | },
|
| 122 | + { |
| 123 | + handler: (data: SqlServerHaModel) => props.selectedMap[data.master_domain], |
| 124 | + tip: t('集群是已被选中的源集群'), |
| 125 | + }, |
99 | 126 | {
|
100 | 127 | handler: (data: SqlServerHaModel) => compareVersion(data.major_version, props.srcCluster.major_version),
|
101 | 128 | tip: t('不允许高版本往低版本迁移'),
|
|
115 | 142 | handler: (data: SqlServerHaModel) => data.id === props.srcCluster.id,
|
116 | 143 | tip: t('不允许选择源集群'),
|
117 | 144 | },
|
| 145 | + { |
| 146 | + handler: (data: SqlServerHaModel) => props.selectedMap[data.master_domain], |
| 147 | + tip: t('集群是已被选中的源集群'), |
| 148 | + }, |
118 | 149 | {
|
119 | 150 | handler: (data: SqlServerSingleModel) => compareVersion(data.major_version, props.srcCluster!.major_version),
|
120 | 151 | tip: t('不允许高版本往低版本迁移'),
|
|
127 | 158 | };
|
128 | 159 |
|
129 | 160 | const localValue = ref('');
|
| 161 | + const loading = ref(false); |
130 | 162 | const showBatchSelector = ref(false);
|
131 | 163 | const selectedClusters = computed<Record<string, SqlServerHaModel[]>>(() => ({
|
132 | 164 | [ClusterTypes.SQLSERVER_HA]: modelValue.value.filter(
|
|
137 | 169 | ) as SqlServerHaModel[],
|
138 | 170 | }));
|
139 | 171 |
|
| 172 | + let batchEditRowCount = 0; |
| 173 | +
|
140 | 174 | const rules = [
|
141 | 175 | {
|
142 | 176 | message: t('集群域名格式不正确'),
|
143 | 177 | trigger: 'change',
|
144 | 178 | validator: () => modelValue.value.every((item) => domainRegex.test(item.master_domain)),
|
145 | 179 | },
|
| 180 | + { |
| 181 | + trigger: 'change', |
| 182 | + validator: () => { |
| 183 | + const conflictList: string[] = []; |
| 184 | + modelValue.value.forEach((item) => { |
| 185 | + if (props.selectedMap[item.master_domain]) { |
| 186 | + conflictList.push(item.master_domain); |
| 187 | + } |
| 188 | + }); |
| 189 | + return conflictList.length > 0 ? t('集群xx是已被选中的源集群', [conflictList.join(',')]) : true; |
| 190 | + }, |
| 191 | + }, |
146 | 192 | {
|
147 | 193 | message: t('目标集群不存在'),
|
148 | 194 | trigger: 'blur',
|
149 | 195 | validator: () => modelValue.value.every((item) => !!item.id),
|
150 | 196 | },
|
151 | 197 | ];
|
152 | 198 |
|
153 |
| - const { run: queryHaCluster } = useRequest(getHaClusterList, { |
154 |
| - manual: true, |
155 |
| - onSuccess: (data) => { |
156 |
| - if (data.count) { |
157 |
| - modelValue.value = [ |
158 |
| - ...modelValue.value, |
159 |
| - ...data.results.map((item) => ({ |
160 |
| - cluster_type: item.cluster_type, |
161 |
| - id: item.id, |
162 |
| - major_version: item.major_version, |
163 |
| - master_domain: item.master_domain, |
164 |
| - })), |
165 |
| - ]; |
166 |
| - } |
167 |
| - }, |
168 |
| - }); |
169 |
| -
|
170 |
| - const { loading, run: querySingleCluster } = useRequest(getSingleClusterList, { |
171 |
| - manual: true, |
172 |
| - onSuccess: (data) => { |
173 |
| - if (data.count) { |
174 |
| - modelValue.value = [ |
175 |
| - ...modelValue.value, |
176 |
| - ...data.results.map((item) => ({ |
177 |
| - cluster_type: item.cluster_type, |
178 |
| - id: item.id, |
179 |
| - major_version: item.major_version, |
180 |
| - master_domain: item.master_domain, |
181 |
| - })), |
182 |
| - ]; |
183 |
| - } |
184 |
| - }, |
185 |
| - }); |
| 199 | + const handleBatchEditShow = () => { |
| 200 | + showBatchEdit.value = true; |
| 201 | + }; |
186 | 202 |
|
187 | 203 | const handleBatchSelect = () => {
|
188 | 204 | showBatchSelector.value = true;
|
189 | 205 | };
|
190 | 206 |
|
191 | 207 | const handleInputChange = (value: string) => {
|
192 |
| - modelValue.value = []; |
193 | 208 | if (value) {
|
194 |
| - queryHaCluster({ |
195 |
| - domain: value.split(batchSplitRegex).join(','), |
196 |
| - limit: -1, |
197 |
| - }); |
198 |
| - querySingleCluster({ |
199 |
| - domain: value.split(batchSplitRegex).join(','), |
200 |
| - limit: -1, |
201 |
| - }); |
| 209 | + loading.value = true; |
| 210 | + Promise.all([ |
| 211 | + getHaClusterList({ |
| 212 | + domain: value.split(batchSplitRegex).join(','), |
| 213 | + limit: -1, |
| 214 | + }), |
| 215 | + getSingleClusterList({ |
| 216 | + domain: value.split(batchSplitRegex).join(','), |
| 217 | + limit: -1, |
| 218 | + }), |
| 219 | + ]) |
| 220 | + .then((dataList) => { |
| 221 | + const temp: typeof modelValue.value = []; |
| 222 | + dataList.forEach((data) => { |
| 223 | + if (data.count) { |
| 224 | + temp.push( |
| 225 | + ...data.results.map((item) => ({ |
| 226 | + cluster_type: item.cluster_type, |
| 227 | + id: item.id, |
| 228 | + major_version: item.major_version, |
| 229 | + master_domain: item.master_domain, |
| 230 | + })), |
| 231 | + ); |
| 232 | + } |
| 233 | + }); |
| 234 | + modelValue.value = temp; |
| 235 | + }) |
| 236 | + .finally(() => { |
| 237 | + loading.value = false; |
| 238 | + }); |
202 | 239 | }
|
203 | 240 | };
|
204 | 241 |
|
| 242 | + const handleBatchEditChange = (value: string) => { |
| 243 | + batchEditRowCount = Object.keys(props.selectedMap).length; |
| 244 | + handleInputChange(value); |
| 245 | + }; |
| 246 | +
|
205 | 247 | const handleBatchSelectorChange = (selected: Record<string, SqlServerHaModel[]>) => {
|
206 | 248 | const data = [...selected[ClusterTypes.SQLSERVER_HA], ...selected[ClusterTypes.SQLSERVER_SINGLE]];
|
207 | 249 | modelValue.value = data.map((item) => ({
|
|
216 | 258 | () => modelValue.value,
|
217 | 259 | (data) => {
|
218 | 260 | localValue.value = data.map((item) => item.master_domain).join('\n');
|
| 261 | + if (batchEditRowCount) { |
| 262 | + emits('batch-edit', modelValue.value, 'dstCluster'); |
| 263 | + batchEditRowCount--; |
| 264 | + } |
219 | 265 | },
|
220 | 266 | {
|
221 | 267 | immediate: true,
|
222 | 268 | },
|
223 | 269 | );
|
224 | 270 | </script>
|
225 | 271 | <style lang="less" scoped>
|
| 272 | + .batch-edit-btn { |
| 273 | + font-size: 14px; |
| 274 | + color: #3a84ff; |
| 275 | + cursor: pointer; |
| 276 | + } |
| 277 | +
|
226 | 278 | .batch-host-select {
|
227 | 279 | font-size: 14px;
|
228 | 280 | cursor: pointer;
|
|
0 commit comments