jcloud/dashboard/src2/components/JsiteDomainModifyDNSServerDialog.vue

299 lines
9.4 KiB
Vue
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<Dialog :options="{ title: '修改DNS服务器', size: 'lg' }" v-model="show">
<template #body-content>
<div class="p-4 sm:p-6">
<div class="space-y-4">
<!-- DNS1 -->
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">
DNS1主DNS服务器<span class="text-red-500">*</span>
</label>
<input
v-model="dnsServers.dns1"
type="text"
class="w-full px-3 py-1.5 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent"
:class="{ 'border-red-300': errors.dns1 }"
@blur="validateDNSField('dns1', '主DNS服务器')"
/>
<p v-if="errors.dns1" class="mt-1 text-sm text-red-600">{{ errors.dns1 }}</p>
</div>
<!-- DNS2 -->
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">
DNS2辅DNS服务器<span class="text-red-500">*</span>
</label>
<input
v-model="dnsServers.dns2"
type="text"
class="w-full px-3 py-1.5 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent"
:class="{ 'border-red-300': errors.dns2 }"
@blur="validateDNSField('dns2', '辅DNS服务器')"
/>
<p v-if="errors.dns2" class="mt-1 text-sm text-red-600">{{ errors.dns2 }}</p>
</div>
<!-- DNS3 -->
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">
DNS3可选
</label>
<input
v-model="dnsServers.dns3"
type="text"
class="w-full px-3 py-1.5 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent"
:class="{ 'border-red-300': errors.dns3 }"
@blur="validateDNSField('dns3', '第三个DNS服务器')"
/>
<p v-if="errors.dns3" class="mt-1 text-sm text-red-600">{{ errors.dns3 }}</p>
</div>
<!-- DNS4 -->
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">
DNS4可选
</label>
<input
v-model="dnsServers.dns4"
type="text"
class="w-full px-3 py-1.5 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent"
:class="{ 'border-red-300': errors.dns4 }"
@blur="validateDNSField('dns4', '第四个DNS服务器')"
/>
<p v-if="errors.dns4" class="mt-1 text-sm text-red-600">{{ errors.dns4 }}</p>
</div>
<!-- DNS5 -->
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">
DNS5可选
</label>
<input
v-model="dnsServers.dns5"
type="text"
class="w-full px-3 py-1.5 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent"
:class="{ 'border-red-300': errors.dns5 }"
@blur="validateDNSField('dns5', '第五个DNS服务器')"
/>
<p v-if="errors.dns5" class="mt-1 text-sm text-red-600">{{ errors.dns5 }}</p>
</div>
<!-- DNS6 -->
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">
DNS6可选
</label>
<input
v-model="dnsServers.dns6"
type="text"
class="w-full px-3 py-1.5 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent"
:class="{ 'border-red-300': errors.dns6 }"
@blur="validateDNSField('dns6', '第六个DNS服务器')"
/>
<p v-if="errors.dns6" class="mt-1 text-sm text-red-600">{{ errors.dns6 }}</p>
</div>
</div>
<div v-if="error" class="mt-4 p-3 bg-red-50 text-red-700 rounded-md text-sm">
{{ error }}
</div>
</div>
</template>
<template #actions>
<div class="w-full flex justify-end space-x-3">
<button
type="button"
class="px-4 py-2 border border-gray-300 rounded-md text-sm font-medium text-gray-700 hover:bg-gray-50 focus:outline-none"
@click="cancel"
>
取消
</button>
<button
type="button"
class="px-4 py-2 bg-black border border-transparent rounded-md text-sm font-medium text-white hover:bg-gray-800 focus:outline-none disabled:bg-gray-300 disabled:cursor-not-allowed"
@click="modifyDNSServer"
:disabled="isLoading || !isValid"
>
{{ isLoading ? '修改中...' : '确定' }}
</button>
</div>
</template>
</Dialog>
</template>
<script>
import { toast } from 'vue-sonner';
import { Dialog } from 'jingrow-ui';
import { DashboardError } from '../utils/error';
export default {
name: 'JsiteDomainModifyDNSServerDialog',
components: {
Dialog
},
props: {
domain: {
type: String,
required: true
},
domainDoc: {
type: Object,
default: null
}
},
emits: ['success'],
data() {
return {
show: true,
dnsServers: {
dns1: '',
dns2: '',
dns3: '',
dns4: '',
dns5: '',
dns6: ''
},
errors: {},
error: null
};
},
computed: {
isLoading() {
return this.$resources.modifyDNSServer.loading;
},
isValid() {
return this.dnsServers.dns1 && this.dnsServers.dns2 && !this.hasErrors;
},
hasErrors() {
return Object.keys(this.errors).length > 0;
}
},
resources: {
modifyDNSServer() {
return {
url: 'jcloud.api.domain_west.west_domain_modify_dns_server',
validate() {
// 实时验证已经完成,这里只需要检查是否有错误
if (this.hasErrors) {
throw new DashboardError('请检查DNS服务器格式');
}
},
onSuccess(data) {
if (data.status === 'success') {
this.$emit('success', {
domain: this.domainDoc?.domain,
dnsServers: this.dnsServers,
message: data.message
});
this.show = false;
} else {
this.error = data.message || '修改DNS服务器失败';
}
},
onError(error) {
this.error = error.message || '修改DNS服务器失败';
}
};
}
},
mounted() {
},
methods: {
cancel() {
this.show = false;
},
modifyDNSServer() {
this.error = null;
this.$resources.modifyDNSServer.submit({
domain: this.domainDoc?.domain,
dns1: this.dnsServers.dns1?.trim() || '',
dns2: this.dnsServers.dns2?.trim() || '',
dns3: this.dnsServers.dns3?.trim() || undefined,
dns4: this.dnsServers.dns4?.trim() || undefined,
dns5: this.dnsServers.dns5?.trim() || undefined,
dns6: this.dnsServers.dns6?.trim() || undefined
});
},
validateDNSField(fieldName, fieldLabel) {
const value = this.dnsServers[fieldName];
// 清除该字段的错误
if (this.errors[fieldName]) {
delete this.errors[fieldName];
}
// 如果是必填字段且为空,不显示错误(让用户继续输入)
if ((fieldName === 'dns1' || fieldName === 'dns2') && !value) {
return;
}
// 检查是否有首尾空格
if (value && (value !== value.trim())) {
this.errors[fieldName] = `${fieldLabel}不能包含首尾空格`;
return;
}
// 如果字段有值但格式不正确,显示错误
if (value && !this.isValidDNSFormat(value)) {
this.errors[fieldName] = `${fieldLabel}格式不正确`;
}
},
isValidDNSFormat(dns) {
if (!dns) return false;
// 检查长度
if (dns.length < 3 || dns.length > 253) {
return false;
}
// 检查是否包含至少一个点号(域名必须有点号分隔)
if (!dns.includes('.')) {
return false;
}
// 检查是否以点号开头或结尾
if (dns.startsWith('.') || dns.endsWith('.')) {
return false;
}
// 检查是否包含连续的点号
if (dns.includes('..')) {
return false;
}
// 分割域名部分进行详细验证
const parts = dns.split('.');
for (let part of parts) {
// 每个部分不能为空
if (!part) {
return false;
}
// 每个部分长度不能超过63个字符
if (part.length > 63) {
return false;
}
// 每个部分不能以连字符开头或结尾
if (part.startsWith('-') || part.endsWith('-')) {
return false;
}
// 每个部分只能包含字母、数字和连字符
if (!/^[a-zA-Z0-9-]+$/.test(part)) {
return false;
}
// 顶级域名(最后一部分)不能全是数字
if (parts.indexOf(part) === parts.length - 1 && /^\d+$/.test(part)) {
return false;
}
}
return true;
}
}
};
</script>