259 lines
6.3 KiB
Vue
259 lines
6.3 KiB
Vue
<template>
|
||
<Dialog>
|
||
<DialogContent class="sm:max-w-[500px]">
|
||
<DialogHeader>
|
||
<DialogTitle>编辑DNS记录</DialogTitle>
|
||
<DialogDescription>
|
||
编辑域名 {{ domainDoc?.domain }} 的DNS解析记录
|
||
</DialogDescription>
|
||
</DialogHeader>
|
||
|
||
<form @submit.prevent="submitForm" class="space-y-4">
|
||
<!-- 记录类型 -->
|
||
<div class="space-y-2">
|
||
<Label for="record-type">记录类型</Label>
|
||
<Select v-model="form.record_type" required>
|
||
<SelectTrigger>
|
||
<SelectValue placeholder="选择记录类型" />
|
||
</SelectTrigger>
|
||
<SelectContent>
|
||
<SelectItem value="A">A - IPv4地址</SelectItem>
|
||
<SelectItem value="AAAA">AAAA - IPv6地址</SelectItem>
|
||
<SelectItem value="CNAME">CNAME - 别名</SelectItem>
|
||
<SelectItem value="MX">MX - 邮件交换</SelectItem>
|
||
<SelectItem value="TXT">TXT - 文本记录</SelectItem>
|
||
<SelectItem value="NS">NS - 域名服务器</SelectItem>
|
||
</SelectContent>
|
||
</Select>
|
||
</div>
|
||
|
||
<!-- 主机记录 -->
|
||
<div class="space-y-2">
|
||
<Label for="host">主机记录</Label>
|
||
<Input
|
||
id="host"
|
||
v-model="form.host"
|
||
placeholder="例如: www 或 @ (留空表示根域名)"
|
||
required
|
||
/>
|
||
<p class="text-xs text-gray-500">
|
||
@ 表示根域名,www 表示 www.yourdomain.com
|
||
</p>
|
||
</div>
|
||
|
||
<!-- 记录值 -->
|
||
<div class="space-y-2">
|
||
<Label for="value">记录值</Label>
|
||
<Input
|
||
id="value"
|
||
v-model="form.value"
|
||
:placeholder="getValuePlaceholder()"
|
||
required
|
||
/>
|
||
<p class="text-xs text-gray-500">
|
||
{{ getValueDescription() }}
|
||
</p>
|
||
</div>
|
||
|
||
<!-- TTL -->
|
||
<div class="space-y-2">
|
||
<Label for="ttl">TTL (秒)</Label>
|
||
<Input
|
||
id="ttl"
|
||
v-model.number="form.ttl"
|
||
type="number"
|
||
min="60"
|
||
max="86400"
|
||
placeholder="600"
|
||
/>
|
||
<p class="text-xs text-gray-500">
|
||
建议值:600秒 (10分钟) 到 86400秒 (24小时)
|
||
</p>
|
||
</div>
|
||
|
||
<!-- MX优先级 (仅MX记录显示) -->
|
||
<div v-if="form.record_type === 'MX'" class="space-y-2">
|
||
<Label for="mx-priority">MX优先级</Label>
|
||
<Input
|
||
id="mx-priority"
|
||
v-model.number="form.mx_priority"
|
||
type="number"
|
||
min="0"
|
||
max="65535"
|
||
placeholder="10"
|
||
/>
|
||
<p class="text-xs text-gray-500">
|
||
数值越小优先级越高,建议值:10
|
||
</p>
|
||
</div>
|
||
</form>
|
||
|
||
<DialogFooter>
|
||
<Button @click="$emit('close')" variant="outline">
|
||
取消
|
||
</Button>
|
||
<Button @click="submitForm" :loading="loading" variant="solid">
|
||
保存修改
|
||
</Button>
|
||
</DialogFooter>
|
||
</DialogContent>
|
||
</Dialog>
|
||
</template>
|
||
|
||
<script>
|
||
import {
|
||
Dialog,
|
||
DialogContent,
|
||
DialogHeader,
|
||
DialogTitle,
|
||
DialogDescription,
|
||
DialogFooter,
|
||
Button,
|
||
Input,
|
||
Label,
|
||
Select,
|
||
SelectContent,
|
||
SelectItem,
|
||
SelectTrigger,
|
||
SelectValue,
|
||
createResource
|
||
} from 'jingrow-ui';
|
||
import { toast } from 'vue-sonner';
|
||
import { getToastErrorMessage } from '../utils/toast';
|
||
|
||
export default {
|
||
name: 'JsiteDomainEditDNSRecordDialog',
|
||
props: ['domain', 'domainDoc', 'record', 'onSuccess'],
|
||
emits: ['close'],
|
||
data() {
|
||
return {
|
||
loading: false,
|
||
form: {
|
||
record_type: 'A',
|
||
host: '',
|
||
value: '',
|
||
ttl: 600,
|
||
mx_priority: 10
|
||
}
|
||
};
|
||
},
|
||
methods: {
|
||
// 初始化表单数据
|
||
initForm() {
|
||
if (this.record) {
|
||
this.form = {
|
||
record_type: this.record.type || 'A',
|
||
host: this.record.item || this.record.host || '',
|
||
value: this.record.value || '',
|
||
ttl: this.record.ttl || 600,
|
||
mx_priority: this.record.level || this.record.mx_priority || 10
|
||
};
|
||
}
|
||
},
|
||
|
||
// 获取记录值占位符
|
||
getValuePlaceholder() {
|
||
const placeholders = {
|
||
'A': '例如: 192.168.1.1',
|
||
'AAAA': '例如: 2001:db8::1',
|
||
'CNAME': '例如: example.com',
|
||
'MX': '例如: mail.example.com',
|
||
'TXT': '例如: 验证字符串',
|
||
'NS': '例如: ns1.example.com'
|
||
};
|
||
return placeholders[this.form.record_type] || '';
|
||
},
|
||
|
||
// 获取记录值描述
|
||
getValueDescription() {
|
||
const descriptions = {
|
||
'A': '输入IPv4地址,如:192.168.1.1',
|
||
'AAAA': '输入IPv6地址,如:2001:db8::1',
|
||
'CNAME': '输入目标域名,如:example.com',
|
||
'MX': '输入邮件服务器域名,如:mail.example.com',
|
||
'TXT': '输入文本内容,常用于域名验证',
|
||
'NS': '输入域名服务器地址,如:ns1.example.com'
|
||
};
|
||
return descriptions[this.form.record_type] || '';
|
||
},
|
||
|
||
// 验证表单
|
||
validateForm() {
|
||
if (!this.form.record_type) {
|
||
toast.error('请选择记录类型');
|
||
return false;
|
||
}
|
||
if (!this.form.value) {
|
||
toast.error('请输入记录值');
|
||
return false;
|
||
}
|
||
if (this.form.ttl < 60 || this.form.ttl > 86400) {
|
||
toast.error('TTL值必须在60-86400秒之间');
|
||
return false;
|
||
}
|
||
if (this.form.record_type === 'MX' && (this.form.mx_priority < 0 || this.form.mx_priority > 65535)) {
|
||
toast.error('MX优先级必须在0-65535之间');
|
||
return false;
|
||
}
|
||
return true;
|
||
},
|
||
|
||
// 提交表单
|
||
async submitForm() {
|
||
if (!this.validateForm()) {
|
||
return;
|
||
}
|
||
|
||
this.loading = true;
|
||
|
||
try {
|
||
// 构建记录数据
|
||
const recordData = {
|
||
id: this.record.id,
|
||
type: this.form.record_type,
|
||
host: this.form.host || '@',
|
||
value: this.form.value,
|
||
ttl: this.form.ttl
|
||
};
|
||
|
||
// 如果是MX记录,添加优先级
|
||
if (this.form.record_type === 'MX') {
|
||
recordData.level = this.form.mx_priority;
|
||
}
|
||
|
||
const request = createResource({
|
||
url: 'jcloud.api.domain_west.west_domain_modify_dns',
|
||
params: {
|
||
domain: this.domainDoc.domain,
|
||
records: [recordData]
|
||
},
|
||
onSuccess: (response) => {
|
||
this.loading = false;
|
||
if (response.status === 'success') {
|
||
toast.success('DNS记录更新成功');
|
||
this.$emit('close');
|
||
if (this.onSuccess) {
|
||
this.onSuccess();
|
||
}
|
||
} else {
|
||
toast.error(response.message || '更新DNS记录失败');
|
||
}
|
||
},
|
||
onError: (error) => {
|
||
this.loading = false;
|
||
toast.error(getToastErrorMessage(error));
|
||
}
|
||
});
|
||
request.submit();
|
||
} catch (error) {
|
||
this.loading = false;
|
||
toast.error('更新DNS记录失败');
|
||
console.error('更新DNS记录失败:', error);
|
||
}
|
||
}
|
||
},
|
||
mounted() {
|
||
this.initForm();
|
||
}
|
||
};
|
||
</script> |