jcloud/dashboard/src2/components/JsiteDomainOverview.vue

439 lines
12 KiB
Vue
Raw 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>
<div
v-if="$domain?.pg"
class="grid grid-cols-1 items-start gap-5 lg:grid-cols-2"
>
<!-- 左侧区块基本信息 -->
<div class="col-span-1 space-y-5">
<!-- 当前套餐卡片 -->
<div class="rounded-md border">
<div class="p-5">
<div class="flex h-full flex-col sm:flex-row sm:items-center sm:justify-between">
<div class="mb-4 sm:mb-0">
<div v-if="$domain.pg.end_date" class="mt-2 inline-flex items-center rounded-full bg-amber-50 px-4 py-2 text-sm font-medium text-amber-800">
<ClockIcon class="mr-1.5 h-4 w-4 text-amber-500" />
到期时间{{ $format.date($domain.pg.end_date) }}
</div>
</div>
<div class="flex gap-2">
<Button
@click="renewDomain"
:loading="$domain.renew?.loading"
class="px-5 !bg-[#1fc76f] !hover:bg-[#1bb85f] !text-white"
>
续费
</Button>
<Button
@click="transferDomain"
:loading="transferLoading"
class="px-5 !bg-[#3b82f6] !hover:bg-[#2563eb] !text-white"
>
转入
</Button>
</div>
</div>
</div>
</div>
<!-- 域名信息 -->
<div class="rounded-md border">
<div class="h-12 border-b px-5 py-4">
<h2 class="text-lg font-medium text-gray-900">域名信息</h2>
</div>
<div>
<div
v-for="info in domainInformation"
:key="info.label"
class="flex items-center px-5 py-3 last:pb-5 even:bg-gray-50/70"
>
<div class="w-1/3 text-base text-gray-600">{{ info.label }}</div>
<div
class="flex w-2/3 items-center space-x-2 text-base text-gray-900"
>
<div v-if="info.prefix">
<component :is="info.prefix" />
</div>
<span>
{{ info.value }}
</span>
<div v-if="info.suffix">
<component :is="info.suffix" />
</div>
</div>
</div>
</div>
</div>
</div>
<!-- 右侧区块DNS信息和操作 -->
<div class="col-span-1 space-y-5">
<!-- 操作 -->
<div class="rounded-md border">
<div class="h-12 border-b px-5 py-4">
<h2 class="text-lg font-medium text-gray-900">操作</h2>
</div>
<div class="p-5">
<div class="flex flex-wrap gap-2">
<Button
@click="manageDNS"
:loading="dnsLoading"
variant="outline"
class="bg-gray-100 text-gray-700 hover:bg-gray-200"
>
管理DNS
</Button>
<Button
@click="toggleAutoRenew"
:loading="autoRenewLoading"
variant="outline"
class="bg-gray-100 text-gray-700 hover:bg-gray-200"
>
{{ $domain.pg.auto_renew ? '关闭自动续费' : '开启自动续费' }}
</Button>
<Button
@click="toggleWhoisProtection"
:loading="whoisProtectionLoading"
variant="outline"
class="bg-gray-100 text-gray-700 hover:bg-gray-200"
>
{{ $domain.pg.whois_protection ? '关闭隐私保护' : '开启隐私保护' }}
</Button>
<Button
@click="deleteDomain"
:loading="deleteLoading"
variant="outline"
class="bg-red-50 text-red-700 hover:bg-red-100 border-red-200"
>
删除域名
</Button>
</div>
</div>
</div>
<!-- DNS服务器信息 -->
<div class="rounded-md border">
<div class="h-12 border-b px-5 py-4">
<h2 class="text-lg font-medium text-gray-900">DNS服务器</h2>
</div>
<div class="p-5">
<div class="space-y-3">
<div class="flex justify-between">
<span class="text-gray-600">主DNS:</span>
<span class="font-mono text-gray-900">{{ $domain.pg.dns_host1 || '未设置' }}</span>
</div>
<div class="flex justify-between">
<span class="text-gray-600">辅DNS:</span>
<span class="font-mono text-gray-900">{{ $domain.pg.dns_host2 || '未设置' }}</span>
</div>
<div class="flex justify-between">
<span class="text-gray-600">DNS3:</span>
<span class="font-mono text-gray-900">{{ $domain.pg.dns_host3 || '未设置' }}</span>
</div>
<div class="flex justify-between">
<span class="text-gray-600">DNS4:</span>
<span class="font-mono text-gray-900">{{ $domain.pg.dns_host4 || '未设置' }}</span>
</div>
<div class="flex justify-between">
<span class="text-gray-600">DNS5:</span>
<span class="font-mono text-gray-900">{{ $domain.pg.dns_host5 || '未设置' }}</span>
</div>
<div class="flex justify-between">
<span class="text-gray-600">DNS6:</span>
<span class="font-mono text-gray-900">{{ $domain.pg.dns_host6 || '未设置' }}</span>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import { getCachedDocumentResource, Badge, Tooltip, Button, createResource } from 'jingrow-ui';
import { h, defineAsyncComponent } from 'vue';
import { toast } from 'vue-sonner';
import { getToastErrorMessage } from '../utils/toast';
import { renderDialog, confirmDialog } from '../utils/components';
import ClockIcon from '~icons/lucide/clock';
import InfoIcon from '~icons/lucide/info';
export default {
name: 'JsiteDomainOverview',
props: ['domain'],
components: {
Badge,
Button,
ClockIcon,
InfoIcon,
},
data() {
return {
renewLoading: false,
transferLoading: false,
dnsLoading: false,
autoRenewLoading: false,
whoisProtectionLoading: false,
deleteLoading: false,
domainOwner: null,
};
},
methods: {
getStatusText(status) {
const statusMap = {
'Active': '正常',
'Expired': '已过期'
};
return statusMap[status] || status;
},
getStatusVariant(status) {
const variantMap = {
'Active': 'success',
'Expired': 'danger'
};
return variantMap[status] || 'default';
},
// 获取域名所有者显示名称
getOwnerDisplayName() {
if (!this.domainOwner) {
return null;
}
// 如果是个人优先显示fullname没有的话显示title
if (this.domainOwner.c_regtype === 'I') {
return this.domainOwner.fullname || this.domainOwner.title;
}
// 如果是公司优先显示c_org_m没有的话显示title
else if (this.domainOwner.c_regtype === 'E') {
return this.domainOwner.c_org_m || this.domainOwner.title;
}
// 默认显示title
return this.domainOwner.title;
},
// 获取域名所有者信息
async getDomainOwner() {
if (!this.$domain.pg?.domain_owner) {
this.domainOwner = null;
return;
}
try {
const getOwnerRequest = createResource({
url: 'jcloud.api.domain_west.get_domain_owner',
params: {
name: this.$domain.pg.domain_owner
},
onSuccess: (response) => {
if (response && response.status === "Success" && response.data) {
this.domainOwner = response.data;
}
},
onError: (error) => {
console.error('获取域名所有者信息失败:', error);
this.domainOwner = null;
}
});
getOwnerRequest.submit();
} catch (error) {
console.error('获取域名所有者信息失败:', error);
this.domainOwner = null;
}
},
renewDomain() {
const JsiteDomainRenewalDialog = defineAsyncComponent(() => import('./JsiteDomainRenewalDialog.vue'));
renderDialog(h(JsiteDomainRenewalDialog, {
domain: this.domain,
domainDoc: this.$domain.pg,
onSuccess: this.onRenewalSuccess
}));
},
transferDomain() {
const JsiteDomainTransferDialog = defineAsyncComponent(() => import('./JsiteDomainTransferDialog.vue'));
renderDialog(h(JsiteDomainTransferDialog, {
domain: this.domain,
domainDoc: this.$domain.pg,
onSuccess: this.onTransferSuccess
}));
},
async manageDNS() {
if (!this.$domain.pg.domain) {
toast.error('域名信息不存在');
return;
}
// 这里可以打开DNS管理对话框
toast.info('DNS管理功能开发中...');
},
async toggleAutoRenew() {
if (!this.$domain.pg.name) {
toast.error('域名记录不存在');
return;
}
const newValue = !this.$domain.pg.auto_renew;
const actionText = newValue ? '开启' : '关闭';
confirmDialog({
title: `${actionText}自动续费`,
message: `确定要${actionText}域名 "${this.$domain.pg.domain}" 的自动续费吗?`,
primaryAction: {
label: '确定',
onClick: ({ hide }) => {
toast.success(`${actionText}自动续费已开通`);
hide();
this.autoRenewLoading = true;
const toggleRequest = createResource({
url: 'jcloud.api.domain_west.toggle_domain_auto_renew',
params: {
pagetype: 'Jsite Domain',
name: this.$domain.pg.name,
auto_renew: newValue
},
onSuccess: () => {
this.autoRenewLoading = false;
this.$domain.reload();
},
onError: (error) => {
toast.error(getToastErrorMessage(error));
this.autoRenewLoading = false;
}
});
toggleRequest.submit();
}
}
});
},
async toggleWhoisProtection() {
if (!this.$domain.pg.name) {
toast.error('域名记录不存在');
return;
}
const newValue = !this.$domain.pg.whois_protection;
const actionText = newValue ? '开启' : '关闭';
confirmDialog({
title: `${actionText}隐私保护`,
message: `确定要${actionText}域名 "${this.$domain.pg.domain}" 的隐私保护吗?`,
primaryAction: {
label: '确定',
onClick: ({ hide }) => {
toast.success(`${actionText}隐私保护已开启`);
hide();
this.whoisProtectionLoading = true;
const toggleRequest = createResource({
url: 'jcloud.api.domain_west.toggle_domain_whois_protection',
params: {
pagetype: 'Jsite Domain',
name: this.$domain.pg.name,
whois_protection: newValue
},
onSuccess: () => {
this.whoisProtectionLoading = false;
this.$domain.reload();
},
onError: (error) => {
toast.error(getToastErrorMessage(error));
this.whoisProtectionLoading = false;
}
});
toggleRequest.submit();
}
}
});
},
async deleteDomain() {
if (!this.$domain.pg.name) {
toast.error('域名记录不存在');
return;
}
confirmDialog({
title: '删除域名',
message: `确定要删除域名 "${this.$domain.pg.domain}" 吗?此操作不可逆!`,
primaryAction: {
label: '确定删除',
onClick: ({ hide }) => {
toast.success('删除域名请求已提交');
hide();
this.deleteLoading = true;
const deleteRequest = createResource({
url: 'jcloud.api.domain_west.delete_domain',
params: {
pagetype: 'Jsite Domain',
name: this.$domain.pg.name
},
onSuccess: () => {
this.deleteLoading = false;
toast.success('域名删除成功');
this.$router.push('/domains');
},
onError: (error) => {
toast.error(getToastErrorMessage(error));
this.deleteLoading = false;
}
});
deleteRequest.submit();
}
}
});
},
onRenewalSuccess(data) {
toast.success('域名续费成功!');
this.$domain.reload();
},
onTransferSuccess(data) {
toast.success('域名转入成功!');
this.$domain.reload();
},
},
watch: {
// 监听域名数据变化,重新获取所有者信息
'$domain.pg.domain_owner': {
handler(newVal) {
if (newVal) {
this.getDomainOwner();
} else {
this.domainOwner = null;
}
},
immediate: true
}
},
computed: {
domainInformation() {
return [
{
label: '状态',
value: this.getStatusText(this.$domain.pg?.status),
},
{
label: '域名',
value: this.$domain.pg?.domain,
},
{
label: '注册时间',
value: this.$domain.pg?.registration_date,
},
{
label: '所有者',
value: this.getOwnerDisplayName(),
},
];
},
$domain() {
return getCachedDocumentResource('Jsite Domain', this.domain);
},
},
mounted() {
// 初始化时获取域名所有者信息
if (this.$domain.pg?.domain_owner) {
this.getDomainOwner();
}
},
};
</script>