227 lines
6.4 KiB
Vue
227 lines
6.4 KiB
Vue
<template>
|
||
<div class="flex flex-col gap-4 py-10">
|
||
<div class="flex flex-col">
|
||
<div class="flex items-center justify-between text-base text-gray-900">
|
||
<div class="flex flex-col gap-1.5">
|
||
<div class="text-lg font-semibold text-gray-900">账户余额</div>
|
||
<div class="text-2xl font-bold text-blue-600 py-6">
|
||
{{ availableCredits || currency + ' 0.00' }}
|
||
</div>
|
||
</div>
|
||
<div class="shrink-0">
|
||
<Button
|
||
:label="'充值'"
|
||
@click="
|
||
() => {
|
||
showMessage = false;
|
||
showAddPrepaidCreditsDialog = true;
|
||
}
|
||
"
|
||
>
|
||
<template #prefix>
|
||
<FeatherIcon class="h-4" name="plus" />
|
||
</template>
|
||
</Button>
|
||
</div>
|
||
</div>
|
||
<div class="my-3 h-px bg-gray-100" />
|
||
<div class="flex items-center justify-between text-base text-gray-900">
|
||
<div class="flex flex-col gap-1.5">
|
||
<div class="font-medium">账单地址</div>
|
||
<div v-if="billingDetailsSummary" class="leading-5 text-gray-700">
|
||
{{ billingDetailsSummary }}
|
||
</div>
|
||
<div v-else class="text-gray-700">无地址</div>
|
||
</div>
|
||
<div class="shrink-0">
|
||
<Button
|
||
:label="billingDetailsSummary ? '编辑' : '添加账单地址'"
|
||
@click="
|
||
() => {
|
||
showMessage = false;
|
||
showBillingDetailsDialog = true;
|
||
}
|
||
"
|
||
>
|
||
<template v-if="!billingDetailsSummary" #prefix>
|
||
<FeatherIcon class="h-4" name="plus" />
|
||
</template>
|
||
</Button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<BillingDetailsDialog
|
||
v-if="showBillingDetailsDialog"
|
||
v-model="showBillingDetailsDialog"
|
||
:showMessage="showMessage"
|
||
@success="billingDetails.reload()"
|
||
/>
|
||
<AddPrepaidCreditsDialog
|
||
v-if="showAddPrepaidCreditsDialog"
|
||
v-model="showAddPrepaidCreditsDialog"
|
||
:showMessage="showMessage"
|
||
@success="upcomingInvoice.reload()"
|
||
/>
|
||
</template>
|
||
<script setup>
|
||
import DropdownItem from './DropdownItem.vue';
|
||
import BillingDetailsDialog from './BillingDetailsDialog.vue';
|
||
import AddPrepaidCreditsDialog from './AddPrepaidCreditsDialog.vue';
|
||
import { Dropdown, Button, FeatherIcon, createResource } from 'jingrow-ui';
|
||
import {
|
||
confirmDialog,
|
||
renderDialog,
|
||
} from '../../utils/components';
|
||
import { computed, ref, inject, h, defineAsyncComponent, onMounted, nextTick } from 'vue';
|
||
import router from '../../router';
|
||
|
||
// 英文国家名到中文的映射
|
||
const countryToZh = {
|
||
'China': '中国',
|
||
'United States': '美国',
|
||
// 可以根据需要添加更多国家
|
||
};
|
||
|
||
const team = inject('team');
|
||
const {
|
||
availableCredits,
|
||
upcomingInvoice,
|
||
currentBillingAmount,
|
||
unpaidInvoices,
|
||
} = inject('billing');
|
||
|
||
const showBillingDetailsDialog = ref(false);
|
||
const showAddPrepaidCreditsDialog = ref(false);
|
||
|
||
const currency = computed(() => (team.pg.currency == 'CNY' ? '¥' : '$'));
|
||
|
||
const billingDetails = createResource({
|
||
url: 'jcloud.api.account.get_billing_information',
|
||
cache: 'billingDetails',
|
||
auto: true,
|
||
});
|
||
|
||
const changePaymentMode = createResource({
|
||
url: 'jcloud.api.billing.change_payment_mode',
|
||
onSuccess: () => setTimeout(() => team.reload(), 1000),
|
||
});
|
||
|
||
const billingDetailsSummary = computed(() => {
|
||
let _billingDetails = billingDetails.data;
|
||
if (!_billingDetails) return '';
|
||
|
||
const { address_line1, city, state, country, pincode } =
|
||
_billingDetails || {};
|
||
|
||
// 转换国家名称为中文
|
||
const displayCountry = countryToZh[country] || country;
|
||
|
||
// 调整为中国用户习惯的地址格式
|
||
// 中国地址格式:[国家] [省/自治区/直辖市] [市] [区/详细地址] [邮编]
|
||
if (country === 'China') {
|
||
// 中国地址使用中文格式
|
||
return [
|
||
displayCountry,
|
||
state, // 省/自治区/直辖市
|
||
city, // 市
|
||
address_line1, // 详细地址
|
||
pincode ? `邮编: ${pincode}` : '' // 邮编
|
||
]
|
||
.filter(Boolean)
|
||
.join(' ');
|
||
} else {
|
||
// 国外地址保持原来的格式
|
||
return [
|
||
address_line1,
|
||
city,
|
||
state,
|
||
displayCountry,
|
||
pincode
|
||
]
|
||
.filter(Boolean)
|
||
.join(', ');
|
||
}
|
||
});
|
||
|
||
const paymentModeOptions = [
|
||
{
|
||
label: '余额支付',
|
||
value: 'Prepaid Credits',
|
||
description: '您的每月账单费用将从账户余额中扣除',
|
||
component: () =>
|
||
h(DropdownItem, {
|
||
label: '余额支付',
|
||
active: team.pg.payment_mode === 'Prepaid Credits',
|
||
onClick: () => updatePaymentMode('Prepaid Credits'),
|
||
}),
|
||
},
|
||
{
|
||
label: '由合作伙伴支付',
|
||
value: 'Paid By Partner',
|
||
condition: () => team.pg.partner_email,
|
||
description: '您的合作伙伴将为您支付每月订阅费用',
|
||
component: () =>
|
||
h(DropdownItem, {
|
||
label: '由合作伙伴支付',
|
||
active: team.pg.payment_mode === 'Paid by Partner',
|
||
onClick: () =>
|
||
confirmDialog({
|
||
title: '确认支付方式',
|
||
message: `通过将支付方式更改为<strong>由合作伙伴支付</strong>,以下详细信息将与您的合作伙伴共享:<br><br><li>站点/服务器名称</li> <li>计划名称</li><li>站点/服务器激活天数</li><br>您确定要继续吗?`,
|
||
primaryAction: {
|
||
label: '更改支付方式',
|
||
variant: 'solid',
|
||
onClick: ({ hide }) => {
|
||
updatePaymentMode('Paid By Partner');
|
||
hide();
|
||
},
|
||
},
|
||
}),
|
||
}),
|
||
},
|
||
];
|
||
|
||
const paymentMode = computed(() => {
|
||
return paymentModeOptions.find((o) => o.value === team.pg.payment_mode);
|
||
});
|
||
|
||
// 修改onMounted钩子,添加自动设置支付方式为余额支付的逻辑
|
||
onMounted(() => {
|
||
// 如果当前没有设置支付方式,自动设置为余额支付
|
||
nextTick(() => {
|
||
if (!team.pg.payment_mode) {
|
||
updatePaymentMode('Prepaid Credits');
|
||
}
|
||
});
|
||
});
|
||
|
||
function payUnpaidInvoices() {
|
||
let _unpaidInvoices = unpaidInvoices.data;
|
||
if (_unpaidInvoices.length > 1) {
|
||
showAddPrepaidCreditsDialog.value = true;
|
||
} else {
|
||
let invoice = _unpaidInvoices[0];
|
||
showAddPrepaidCreditsDialog.value = true;
|
||
}
|
||
}
|
||
|
||
const showMessage = ref(false);
|
||
function updatePaymentMode(mode) {
|
||
showMessage.value = false;
|
||
if (mode === 'Paid By Partner' && Boolean(unpaidInvoices.data.length > 0)) {
|
||
if (unpaidInvoices.data) {
|
||
payUnpaidInvoices();
|
||
return;
|
||
}
|
||
if (currentBillingAmount.value) {
|
||
const finalizeInvoicesDialog = defineAsyncComponent(
|
||
() => import('./FinalizeInvoicesDialog.vue'),
|
||
);
|
||
renderDialog(h(finalizeInvoicesDialog));
|
||
return;
|
||
}
|
||
}
|
||
if (!changePaymentMode.loading) changePaymentMode.submit({ mode });
|
||
}
|
||
</script> |