222 lines
6.7 KiB
Vue
222 lines
6.7 KiB
Vue
<template>
|
|
<div class="p-6">
|
|
<div class="mb-6">
|
|
<h2 class="text-xl font-semibold text-gray-900 mb-2">域名续费</h2>
|
|
<p class="text-sm text-gray-600">
|
|
为域名 <span class="font-medium">{{ domainDoc?.domain }}</span> 续费
|
|
</p>
|
|
</div>
|
|
|
|
<div class="space-y-4">
|
|
<div>
|
|
<label class="block text-sm font-medium text-gray-700 mb-2">续费时长</label>
|
|
<select v-model="renewalPeriod" class="w-full border rounded px-3 py-2">
|
|
<option v-for="period in renewalPeriods" :key="period.value" :value="period.value">
|
|
{{ period.label }}
|
|
</option>
|
|
</select>
|
|
</div>
|
|
|
|
<div v-if="domainPrice" class="border-t border-gray-200 pt-4">
|
|
<div class="flex justify-between items-center">
|
|
<div class="text-sm text-gray-600">年度费用</div>
|
|
<div class="font-medium">
|
|
¥ {{ domainPrice }}
|
|
<span class="text-gray-500 text-sm">(年付)</span>
|
|
</div>
|
|
</div>
|
|
<div class="flex justify-between items-center mt-2">
|
|
<div class="text-sm text-gray-600">续费时长</div>
|
|
<div class="font-medium">{{ renewalPeriod }} 年</div>
|
|
</div>
|
|
<div class="flex justify-between items-center mt-2 text-lg font-bold">
|
|
<div>总计</div>
|
|
<div>¥ {{ getTotalAmount() }}</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="border-t border-gray-200 pt-4">
|
|
<label class="block text-sm font-medium text-gray-700 mb-3">
|
|
选择支付方式
|
|
</label>
|
|
<div class="grid grid-cols-1 md:grid-cols-3 gap-4">
|
|
<button
|
|
class="p-4 border rounded-lg flex flex-col items-center justify-center hover:bg-gray-50 transition-all"
|
|
:class="{'border-blue-500 border-2 shadow-sm': selectedPaymentMethod === 'balance', 'border-gray-200': selectedPaymentMethod !== 'balance'}"
|
|
@click="selectedPaymentMethod = 'balance'"
|
|
>
|
|
<span class="text-gray-800 font-medium">余额支付</span>
|
|
</button>
|
|
|
|
<button
|
|
class="p-4 border rounded-lg hover:bg-gray-50 transition-all"
|
|
:class="{'border-blue-500 border-2 shadow-sm': selectedPaymentMethod === 'alipay', 'border-gray-200': selectedPaymentMethod !== 'alipay'}"
|
|
@click="selectedPaymentMethod = 'alipay'"
|
|
>
|
|
<div class="flex flex-col items-center">
|
|
<div class="mb-2">
|
|
<AlipayLogo class="h-8" />
|
|
</div>
|
|
</div>
|
|
</button>
|
|
|
|
<button
|
|
class="p-4 border rounded-lg hover:bg-gray-50 transition-all"
|
|
:class="{'border-blue-500 border-2 shadow-sm': selectedPaymentMethod === 'wechatpay', 'border-gray-200': selectedPaymentMethod !== 'wechatpay'}"
|
|
@click="selectedPaymentMethod = 'wechatpay'"
|
|
>
|
|
<div class="flex flex-col items-center">
|
|
<div class="mb-2">
|
|
<WeChatPayLogo class="h-8" />
|
|
</div>
|
|
</div>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<div v-if="error" class="p-3 bg-red-50 text-red-700 rounded-md text-sm">
|
|
{{ error }}
|
|
</div>
|
|
</div>
|
|
|
|
<div class="flex justify-end gap-3 mt-6">
|
|
<button
|
|
@click="$emit('close')"
|
|
class="px-4 py-2 text-gray-700 bg-gray-100 rounded-md hover:bg-gray-200 transition-colors"
|
|
>
|
|
取消
|
|
</button>
|
|
<button
|
|
@click="processRenewal"
|
|
:disabled="!selectedPaymentMethod || isLoading"
|
|
class="px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 disabled:bg-gray-300 transition-colors"
|
|
>
|
|
{{ isLoading ? '处理中...' : '确认续费' }}
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
import { toast } from 'vue-sonner';
|
|
import AlipayLogo from '../logo/AlipayLogo.vue';
|
|
import WeChatPayLogo from '../logo/WeChatPayLogo.vue';
|
|
|
|
export default {
|
|
name: 'JsiteDomainRenewalDialog',
|
|
components: {
|
|
AlipayLogo,
|
|
WeChatPayLogo
|
|
},
|
|
props: {
|
|
domain: {
|
|
type: String,
|
|
required: true
|
|
},
|
|
domainDoc: {
|
|
type: Object,
|
|
required: true
|
|
},
|
|
onSuccess: {
|
|
type: Function,
|
|
default: () => {}
|
|
}
|
|
},
|
|
data() {
|
|
return {
|
|
renewalPeriod: 1,
|
|
selectedPaymentMethod: null,
|
|
domainPrice: null,
|
|
renewalPeriods: [
|
|
{ value: 1, label: '1年' },
|
|
{ value: 2, label: '2年' },
|
|
{ value: 3, label: '3年' },
|
|
{ value: 5, label: '5年' },
|
|
{ value: 10, label: '10年' }
|
|
],
|
|
isLoading: false,
|
|
error: null
|
|
};
|
|
},
|
|
mounted() {
|
|
this.getDomainPrice();
|
|
},
|
|
methods: {
|
|
async getDomainPrice() {
|
|
try {
|
|
const response = await this.$resources.getDomainPrice.submit({
|
|
domain: this.domainDoc.domain,
|
|
year: 1
|
|
});
|
|
|
|
if (response && response.data && response.data.price) {
|
|
this.domainPrice = response.data.price;
|
|
} else {
|
|
this.domainPrice = this.domainDoc.price || 50;
|
|
}
|
|
} catch (error) {
|
|
this.domainPrice = this.domainDoc.price || 50;
|
|
}
|
|
},
|
|
getTotalAmount() {
|
|
const yearlyPrice = this.domainPrice || 0;
|
|
return (yearlyPrice * this.renewalPeriod).toFixed(2);
|
|
},
|
|
async processRenewal() {
|
|
if (!this.selectedPaymentMethod) {
|
|
this.error = '请选择支付方式';
|
|
return;
|
|
}
|
|
|
|
this.error = null;
|
|
this.isLoading = true;
|
|
|
|
try {
|
|
const response = await this.$resources.renewDomain.submit({
|
|
domain: this.domainDoc.domain,
|
|
period: this.renewalPeriod,
|
|
payment_method: this.selectedPaymentMethod
|
|
});
|
|
|
|
if (response.success) {
|
|
toast.success('续费请求已提交');
|
|
this.$emit('close');
|
|
this.onSuccess(response);
|
|
} else {
|
|
this.error = response.message || '续费失败';
|
|
}
|
|
} catch (error) {
|
|
this.error = error.message || '续费失败';
|
|
} finally {
|
|
this.isLoading = false;
|
|
}
|
|
}
|
|
},
|
|
resources: {
|
|
getDomainPrice() {
|
|
return {
|
|
url: 'jcloud.api.domain_west.get_west_domain_price',
|
|
onSuccess(response) {
|
|
if (response && response.data && response.data.price) {
|
|
this.domainPrice = response.data.price;
|
|
}
|
|
},
|
|
onError(error) {
|
|
this.domainPrice = this.domainDoc.price || 50;
|
|
}
|
|
};
|
|
},
|
|
renewDomain() {
|
|
return {
|
|
url: 'jcloud.api.domain_west.west_domain_renew',
|
|
onSuccess(response) {
|
|
return response;
|
|
},
|
|
onError(error) {
|
|
throw error;
|
|
}
|
|
};
|
|
}
|
|
}
|
|
};
|
|
</script> |