feat:多支付以及货币符号显示
This commit is contained in:
@@ -1,10 +1,10 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { defineProps, defineEmits, computed } from 'vue';
|
import { defineProps, defineEmits, computed, ref, onMounted, watch } from 'vue';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import { AlipayOutlined, WechatOutlined, WalletOutlined } from '@ant-design/icons-vue';
|
import { AlipayOutlined, WechatOutlined, WalletOutlined,MoneyCollectOutlined } from '@ant-design/icons-vue';
|
||||||
import { Modal } from 'ant-design-vue';
|
import { Modal } from 'ant-design-vue';
|
||||||
import PaypalButton from '@/components/payment/paypal-button.vue';
|
import PaypalButton from '@/components/payment/paypal-button.vue';
|
||||||
import { stripePay } from '@/service/api/payment';
|
import { stripePay, getPaymentConfig } from '@/service/api/payment';
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
|
||||||
@@ -23,6 +23,27 @@ interface Props {
|
|||||||
const props = defineProps<Props>();
|
const props = defineProps<Props>();
|
||||||
const emit = defineEmits(['update:visible', 'confirm', 'cancel']);
|
const emit = defineEmits(['update:visible', 'confirm', 'cancel']);
|
||||||
|
|
||||||
|
const paymentMethods = ref<string[]>([]);
|
||||||
|
const currencySymbol = ref('¥');
|
||||||
|
|
||||||
|
// 获取支付配置
|
||||||
|
const fetchPaymentConfig = async () => {
|
||||||
|
try {
|
||||||
|
const response = await getPaymentConfig();
|
||||||
|
paymentMethods.value = response.data.paymentMethods || [];
|
||||||
|
currencySymbol.value = response.data.currencySymbol || '¥';
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Failed to fetch payment config:', error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 监听visible属性变化
|
||||||
|
watch(() => props.visible, (newVisible) => {
|
||||||
|
if (newVisible) {
|
||||||
|
fetchPaymentConfig();
|
||||||
|
}
|
||||||
|
}, { immediate: true });
|
||||||
|
|
||||||
const orderTypeMap = {
|
const orderTypeMap = {
|
||||||
0: t('page.order.packagePurchase'),
|
0: t('page.order.packagePurchase'),
|
||||||
1: t('page.order.balanceRecharge')
|
1: t('page.order.balanceRecharge')
|
||||||
@@ -85,7 +106,7 @@ const handleCancel = () => {
|
|||||||
</div>
|
</div>
|
||||||
<div class="info-item">
|
<div class="info-item">
|
||||||
<span class="label">{{ t('page.order.orderAmount') }}:</span>
|
<span class="label">{{ t('page.order.orderAmount') }}:</span>
|
||||||
<span class="value highlight">¥{{ orderInfo.orderAmount.toFixed(2) }}</span>
|
<span class="value highlight">{{ currencySymbol }}{{ orderInfo.orderAmount.toFixed(2) }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="info-item">
|
<div class="info-item">
|
||||||
<span class="label">{{ t('page.order.orderId') }}:</span>
|
<span class="label">{{ t('page.order.orderId') }}:</span>
|
||||||
@@ -104,20 +125,19 @@ const handleCancel = () => {
|
|||||||
}"
|
}"
|
||||||
@click="!isBalancePayDisabled && handleConfirm('balance')"
|
@click="!isBalancePayDisabled && handleConfirm('balance')"
|
||||||
>
|
>
|
||||||
<div class="debug-info" style="display: none;">
|
|
||||||
Enable balance pay: {{ enableBalancePay }}
|
|
||||||
</div>
|
|
||||||
<WalletOutlined class="payment-icon balance-icon" />
|
<WalletOutlined class="payment-icon balance-icon" />
|
||||||
<span>{{ t('page.order.balancePay') }}</span>
|
<span>{{ t('page.order.balancePay') }}</span>
|
||||||
<div class="balance-info" v-if="userBalance !== undefined">
|
<div class="balance-info" v-if="userBalance !== undefined">
|
||||||
{{ t('page.order.availableBalance') }}: ¥{{ userBalance.toFixed(2) }}
|
{{ t('page.order.availableBalance') }}: {{ currencySymbol }}{{ userBalance.toFixed(2) }}
|
||||||
<template v-if="userBalance < orderInfo.orderAmount">
|
<template v-if="userBalance < orderInfo.orderAmount">
|
||||||
<br>
|
<br>
|
||||||
<span class="balance-insufficient">{{ t('page.order.insufficientBalance') }}</span>
|
<span class="balance-insufficient">{{ t('page.order.insufficientBalance') }}</span>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
|
v-if="paymentMethods.includes('alipay')"
|
||||||
class="method-item"
|
class="method-item"
|
||||||
:class="{ disabled: loading }"
|
:class="{ disabled: loading }"
|
||||||
@click="!loading && handleConfirm('alipay')"
|
@click="!loading && handleConfirm('alipay')"
|
||||||
@@ -125,7 +145,9 @@ const handleCancel = () => {
|
|||||||
<AlipayOutlined class="payment-icon alipay-icon" />
|
<AlipayOutlined class="payment-icon alipay-icon" />
|
||||||
<span>{{ t('page.order.alipay') }}</span>
|
<span>{{ t('page.order.alipay') }}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
|
v-if="paymentMethods.includes('wxpay')"
|
||||||
class="method-item"
|
class="method-item"
|
||||||
:class="{ disabled: loading }"
|
:class="{ disabled: loading }"
|
||||||
@click="!loading && handleConfirm('wxpay')"
|
@click="!loading && handleConfirm('wxpay')"
|
||||||
@@ -133,16 +155,20 @@ const handleCancel = () => {
|
|||||||
<WechatOutlined class="payment-icon wxpay-icon" />
|
<WechatOutlined class="payment-icon wxpay-icon" />
|
||||||
<span>{{ t('page.order.wxpay') }}</span>
|
<span>{{ t('page.order.wxpay') }}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
|
v-if="paymentMethods.includes('stripe')"
|
||||||
class="method-item"
|
class="method-item"
|
||||||
:class="{ disabled: loading }"
|
:class="{ disabled: loading }"
|
||||||
@click="!loading && handleConfirm('stripe')"
|
@click="!loading && handleConfirm('stripe')"
|
||||||
>
|
>
|
||||||
<WechatOutlined class="payment-icon wxpay-icon" />
|
<MoneyCollectOutlined class="payment-icon wxpay-icon" />
|
||||||
<span>{{ t('page.order.stripe') }}</span>
|
<span>{{ t('page.order.stripe') }}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<PaypalButton
|
<PaypalButton
|
||||||
:order-info="props.orderInfo"
|
v-if="paymentMethods.includes('paypal')"
|
||||||
|
:order-info="props.orderInfo"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -199,10 +225,13 @@ const handleCancel = () => {
|
|||||||
.methods-container {
|
.methods-container {
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: 12px;
|
gap: 12px;
|
||||||
|
flex-wrap: wrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
.method-item {
|
.method-item {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
|
min-width: 120px;
|
||||||
|
max-width: calc(50% - 6px);
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|||||||
@@ -425,7 +425,7 @@ export const customRoutes: GeneratedRoute[] = [
|
|||||||
hideInMenu: true,
|
hideInMenu: true,
|
||||||
order: 10,
|
order: 10,
|
||||||
},
|
},
|
||||||
}
|
},
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -62,3 +62,10 @@ export function stripePay(orderId: number) {
|
|||||||
method: 'post'
|
method: 'post'
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
/** Get payment configuration */
|
||||||
|
export function getPaymentConfig() {
|
||||||
|
return request({
|
||||||
|
url: '/u/config/pay',
|
||||||
|
method: 'get'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|||||||
1
src/typings/auto-imports.d.ts
vendored
1
src/typings/auto-imports.d.ts
vendored
@@ -128,6 +128,7 @@ declare global {
|
|||||||
const getFixedTabIds: typeof import('../store/modules/tab/shared')['getFixedTabIds']
|
const getFixedTabIds: typeof import('../store/modules/tab/shared')['getFixedTabIds']
|
||||||
const getFixedTabs: typeof import('../store/modules/tab/shared')['getFixedTabs']
|
const getFixedTabs: typeof import('../store/modules/tab/shared')['getFixedTabs']
|
||||||
const getGlobalMenusByAuthRoutes: typeof import('../store/modules/route/shared')['getGlobalMenusByAuthRoutes']
|
const getGlobalMenusByAuthRoutes: typeof import('../store/modules/route/shared')['getGlobalMenusByAuthRoutes']
|
||||||
|
const getPaymentConfig: typeof import('../service/api/payment')['getPaymentConfig']
|
||||||
const getQueryParams: typeof import('../utils/common')['getQueryParams']
|
const getQueryParams: typeof import('../utils/common')['getQueryParams']
|
||||||
const getRouteIcons: typeof import('../store/modules/tab/shared')['getRouteIcons']
|
const getRouteIcons: typeof import('../store/modules/tab/shared')['getRouteIcons']
|
||||||
const getSelectedMenuKeyPathByKey: typeof import('../store/modules/route/shared')['getSelectedMenuKeyPathByKey']
|
const getSelectedMenuKeyPathByKey: typeof import('../store/modules/route/shared')['getSelectedMenuKeyPathByKey']
|
||||||
|
|||||||
1
src/typings/components.d.ts
vendored
1
src/typings/components.d.ts
vendored
@@ -80,6 +80,7 @@ declare module 'vue' {
|
|||||||
LookForward: typeof import('./../components/custom/look-forward.vue')['default']
|
LookForward: typeof import('./../components/custom/look-forward.vue')['default']
|
||||||
MenuToggler: typeof import('./../components/common/menu-toggler.vue')['default']
|
MenuToggler: typeof import('./../components/common/menu-toggler.vue')['default']
|
||||||
OrderConfirmModal: typeof import('./../components/order-confirm/orderConfirmModal.vue')['default']
|
OrderConfirmModal: typeof import('./../components/order-confirm/orderConfirmModal.vue')['default']
|
||||||
|
Pay: typeof import('./../components/pay/pay.vue')['default']
|
||||||
PaypalButton: typeof import('./../components/payment/paypal-button.vue')['default']
|
PaypalButton: typeof import('./../components/payment/paypal-button.vue')['default']
|
||||||
PinToggler: typeof import('./../components/common/pin-toggler.vue')['default']
|
PinToggler: typeof import('./../components/common/pin-toggler.vue')['default']
|
||||||
ReloadButton: typeof import('./../components/common/reload-button.vue')['default']
|
ReloadButton: typeof import('./../components/common/reload-button.vue')['default']
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ export const constructPaypalBtn = async(orderId: number, currency: string) =>{
|
|||||||
const errorMessage = errorDetail
|
const errorMessage = errorDetail
|
||||||
? `${errorDetail.issue} ${errorDetail.description} (${orderData.debug_id})`
|
? `${errorDetail.issue} ${errorDetail.description} (${orderData.debug_id})`
|
||||||
: JSON.stringify(orderData);
|
: JSON.stringify(orderData);
|
||||||
|
|
||||||
throw new Error(errorMessage);
|
throw new Error(errorMessage);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
@@ -96,4 +96,4 @@ export const constructPaypalBtn = async(orderId: number, currency: string) =>{
|
|||||||
function resultMessage(message: any) {
|
function resultMessage(message: any) {
|
||||||
const container: any = document.querySelector("#result-message");
|
const container: any = document.querySelector("#result-message");
|
||||||
container.innerHTML = message;
|
container.innerHTML = message;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import { useRouter } from 'vue-router';
|
|||||||
import { fetchPackageHistory } from '@/service/api/auth';
|
import { fetchPackageHistory } from '@/service/api/auth';
|
||||||
import { useWindowSize } from '@vueuse/core';
|
import { useWindowSize } from '@vueuse/core';
|
||||||
import { useTable, useTableOperate } from '@/hooks/common/table';
|
import { useTable, useTableOperate } from '@/hooks/common/table';
|
||||||
|
import { getPaymentConfig } from '@/service/api/payment';
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const handleBack = () => {
|
const handleBack = () => {
|
||||||
@@ -14,7 +15,18 @@ const handleBack = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
const currencySymbol = ref('¥');
|
||||||
|
|
||||||
|
const fetchCurrencySymbol = async () => {
|
||||||
|
try {
|
||||||
|
const response = await getPaymentConfig();
|
||||||
|
if (response && response.data) {
|
||||||
|
currencySymbol.value = response.data.currencySymbol || '¥';
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Failed to fetch currency symbol:', error);
|
||||||
|
}
|
||||||
|
};
|
||||||
const packageData = ref<Api.Package.PackageHistoryRecord[]>([]);
|
const packageData = ref<Api.Package.PackageHistoryRecord[]>([]);
|
||||||
const total = ref(0);
|
const total = ref(0);
|
||||||
|
|
||||||
@@ -51,6 +63,7 @@ const getPackageData = async () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
|
fetchCurrencySymbol();
|
||||||
getPackageData();
|
getPackageData();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -75,7 +88,7 @@ const showPackageDetail = (record: Api.Package.PackageHistoryRecord) => {
|
|||||||
]),
|
]),
|
||||||
h('div', { class: 'detail-item' }, [
|
h('div', { class: 'detail-item' }, [
|
||||||
h('span', { class: 'detail-label' }, t('page.packagehistories.price') + ':'),
|
h('span', { class: 'detail-label' }, t('page.packagehistories.price') + ':'),
|
||||||
h('span', { class: 'detail-value' }, `¥${Number(record.upackage?.price || 0).toFixed(2)}`)
|
h('span', { class: 'detail-value' }, `${currencySymbol.value}${Number(record.upackage?.price || 0).toFixed(2)}`)
|
||||||
]),
|
]),
|
||||||
h('div', { class: 'detail-item' }, [
|
h('div', { class: 'detail-item' }, [
|
||||||
h('span', { class: 'detail-label' }, t('page.packagehistories.traffic') + ':'),
|
h('span', { class: 'detail-label' }, t('page.packagehistories.traffic') + ':'),
|
||||||
@@ -168,7 +181,7 @@ const { columns, data, loading, getData, mobilePagination, searchParams } = useT
|
|||||||
key: 'orderAmount',
|
key: 'orderAmount',
|
||||||
customRender: ({ text }: { text: string }) => {
|
customRender: ({ text }: { text: string }) => {
|
||||||
const formattedAmount = Number(text).toFixed(2);
|
const formattedAmount = Number(text).toFixed(2);
|
||||||
return `¥${formattedAmount}`;
|
return `${currencySymbol.value}${formattedAmount}`;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import { useI18n } from "vue-i18n";
|
|||||||
import { useRouter } from 'vue-router';
|
import { useRouter } from 'vue-router';
|
||||||
import { fetchRechargeHistory } from '@/service/api/auth';
|
import { fetchRechargeHistory } from '@/service/api/auth';
|
||||||
import { useWindowSize } from '@vueuse/core';
|
import { useWindowSize } from '@vueuse/core';
|
||||||
|
import { getPaymentConfig } from '@/service/api/payment';
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const handleBack = () => {
|
const handleBack = () => {
|
||||||
@@ -13,7 +14,18 @@ const handleBack = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
const currencySymbol = ref('¥');
|
||||||
|
|
||||||
|
const fetchCurrencySymbol = async () => {
|
||||||
|
try {
|
||||||
|
const response = await getPaymentConfig();
|
||||||
|
if (response && response.data) {
|
||||||
|
currencySymbol.value = response.data.currencySymbol || '¥';
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Failed to fetch currency symbol:', error);
|
||||||
|
}
|
||||||
|
};
|
||||||
const rechargeData = ref<Api.Recharge.RechargeRecord[]>([]);
|
const rechargeData = ref<Api.Recharge.RechargeRecord[]>([]);
|
||||||
const total = ref(0);
|
const total = ref(0);
|
||||||
|
|
||||||
@@ -56,7 +68,7 @@ const { columns, data, loading, getData, mobilePagination, searchParams } = useT
|
|||||||
key: 'orderAmount',
|
key: 'orderAmount',
|
||||||
customRender: ({ text }: { text: string }) => {
|
customRender: ({ text }: { text: string }) => {
|
||||||
const formattedAmount = Number(text).toFixed(2);
|
const formattedAmount = Number(text).toFixed(2);
|
||||||
return `¥${formattedAmount}`;
|
return `${currencySymbol.value}${formattedAmount}`;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -85,6 +97,9 @@ const { columns, data, loading, getData, mobilePagination, searchParams } = useT
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
onMounted(()=>{
|
||||||
|
fetchCurrencySymbol();
|
||||||
|
})
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -6,9 +6,26 @@ import type { ECOption } from '@/hooks/common/echarts';
|
|||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import { useAuthStore } from '@/store/modules/auth';
|
import { useAuthStore } from '@/store/modules/auth';
|
||||||
import { clientAuth } from '@/service/ue/client';
|
import { clientAuth } from '@/service/ue/client';
|
||||||
|
import { getPaymentConfig } from '@/service/api/payment';
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const authStore = useAuthStore();
|
const authStore = useAuthStore();
|
||||||
|
|
||||||
|
// 添加货币符号的响应式引用
|
||||||
|
const currencySymbol = ref('¥');
|
||||||
|
|
||||||
|
// 获取货币符号
|
||||||
|
const fetchCurrencySymbol = async () => {
|
||||||
|
try {
|
||||||
|
const response = await getPaymentConfig();
|
||||||
|
if (response && response.data) {
|
||||||
|
currencySymbol.value = response.data.currencySymbol || '¥';
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Failed to fetch currency symbol:', error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: 'HeaderBanner'
|
name: 'HeaderBanner'
|
||||||
});
|
});
|
||||||
@@ -307,7 +324,7 @@ async function mockDataUpdate() {
|
|||||||
value: numBalance,
|
value: numBalance,
|
||||||
max: Math.max(numBalance, 100),
|
max: Math.max(numBalance, 100),
|
||||||
displayValue:formatBalance(response.balance),
|
displayValue:formatBalance(response.balance),
|
||||||
unit: t('page.headerbanner.money'),
|
unit: currencySymbol.value,
|
||||||
subTitle: t('page.headerbanner.deviceCount') + `: ${
|
subTitle: t('page.headerbanner.deviceCount') + `: ${
|
||||||
response.packageName ? (
|
response.packageName ? (
|
||||||
!response.clientNumEnable
|
!response.clientNumEnable
|
||||||
@@ -422,6 +439,8 @@ let timer: ReturnType<typeof setInterval> | null = null;
|
|||||||
// 初始化
|
// 初始化
|
||||||
async function init() {
|
async function init() {
|
||||||
// 立即执行一次数据更新
|
// 立即执行一次数据更新
|
||||||
|
// 先获取货币符号
|
||||||
|
await fetchCurrencySymbol();
|
||||||
await mockDataUpdate();
|
await mockDataUpdate();
|
||||||
// 设置定期执行的定时器
|
// 设置定期执行的定时器
|
||||||
timer = setInterval(mockDataUpdate, 30000);
|
timer = setInterval(mockDataUpdate, 30000);
|
||||||
@@ -500,7 +519,7 @@ const getDeviceCount = (subTitle?: string, clientNumEnable?: boolean): string =>
|
|||||||
</div>
|
</div>
|
||||||
<div class="info-item">
|
<div class="info-item">
|
||||||
<span class="info-label">{{ t('page.headerbanner.price') }}</span>
|
<span class="info-label">{{ t('page.headerbanner.price') }}</span>
|
||||||
<span class="info-value">{{ packageInfo.price === '-' ? '-' : '¥' + packageInfo.price }}</span>
|
<span class="info-value">{{ packageInfo.price === '-' ? '-' : currencySymbol + packageInfo.price }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="info-item">
|
<div class="info-item">
|
||||||
<span class="info-label">{{ t('page.headerbanner.monthflowr') }}</span>
|
<span class="info-label">{{ t('page.headerbanner.monthflowr') }}</span>
|
||||||
@@ -531,7 +550,7 @@ const getDeviceCount = (subTitle?: string, clientNumEnable?: boolean): string =>
|
|||||||
<div class="info-group">
|
<div class="info-group">
|
||||||
<div class="info-item">
|
<div class="info-item">
|
||||||
<span class="info-label">{{ t('page.headerbanner.Remainingcredit') }}</span>
|
<span class="info-label">{{ t('page.headerbanner.Remainingcredit') }}</span>
|
||||||
<span class="info-value">{{ baseData[0].displayValue === '-' ? '-' : '¥' + baseData[0].displayValue }}</span>
|
<span class="info-value">{{ baseData[0].displayValue === '-' ? '-' : currencySymbol + baseData[0].displayValue }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="info-item">
|
<div class="info-item">
|
||||||
<span class="info-label">{{ t('page.headerbanner.client') }}</span>
|
<span class="info-label">{{ t('page.headerbanner.client') }}</span>
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import { useRouterPush } from '@/hooks/common/router';
|
|||||||
import type { Ref } from 'vue';
|
import type { Ref } from 'vue';
|
||||||
import OrderConfirmModal from '@/components/order-confirm/orderConfirmModal.vue';
|
import OrderConfirmModal from '@/components/order-confirm/orderConfirmModal.vue';
|
||||||
import { useAppStore } from '@/store/modules/app';
|
import { useAppStore } from '@/store/modules/app';
|
||||||
|
import { getPaymentConfig } from '@/service/api/payment';
|
||||||
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: 'BalanceRecharge'
|
name: 'BalanceRecharge'
|
||||||
@@ -16,7 +17,18 @@ defineOptions({
|
|||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const { routerPushByKey } = useRouterPush();
|
const { routerPushByKey } = useRouterPush();
|
||||||
const appStore = useAppStore();
|
const appStore = useAppStore();
|
||||||
|
const currencySymbol = ref('¥');
|
||||||
|
|
||||||
|
const fetchCurrencySymbol = async () => {
|
||||||
|
try {
|
||||||
|
const response = await getPaymentConfig();
|
||||||
|
if (response && response.data) {
|
||||||
|
currencySymbol.value = response.data.currencySymbol || '¥';
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Failed to fetch currency symbol:', error);
|
||||||
|
}
|
||||||
|
};
|
||||||
interface RechargeOption {
|
interface RechargeOption {
|
||||||
amount: number;
|
amount: number;
|
||||||
displayAmount: string;
|
displayAmount: string;
|
||||||
@@ -27,13 +39,13 @@ const customAmount = ref<string | number | undefined>(undefined);
|
|||||||
const selectedAmount = ref<number | null>(null);
|
const selectedAmount = ref<number | null>(null);
|
||||||
const isCustomMode = ref<boolean>(false);
|
const isCustomMode = ref<boolean>(false);
|
||||||
|
|
||||||
const rechargeOptions: Ref<RechargeOption[]> = ref([
|
const rechargeOptions = computed(() => [
|
||||||
{ amount: 10, displayAmount: `${t('page.carddata.money')}10`, price: 10.00 },
|
{ amount: 10, displayAmount: `${currencySymbol.value}10`, price: 10.00 },
|
||||||
{ amount: 20, displayAmount: `${t('page.carddata.money')}20`, price: 20.00 },
|
{ amount: 20, displayAmount: `${currencySymbol.value}20`, price: 20.00 },
|
||||||
{ amount: 30, displayAmount: `${t('page.carddata.money')}30`, price: 30.00 },
|
{ amount: 30, displayAmount: `${currencySymbol.value}30`, price: 30.00 },
|
||||||
{ amount: 50, displayAmount: `${t('page.carddata.money')}50`, price: 50.00 },
|
{ amount: 50, displayAmount: `${currencySymbol.value}50`, price: 50.00 },
|
||||||
{ amount: 100, displayAmount: `${t('page.carddata.money')}100`, price: 100.00 },
|
{ amount: 100, displayAmount: `${currencySymbol.value}100`, price: 100.00 },
|
||||||
{ amount: 200, displayAmount: `${t('page.carddata.money')}200`, price: 200.00 },
|
{ amount: 200, displayAmount: `${currencySymbol.value}200`, price: 200.00 },
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const paymentAmount = computed(() => {
|
const paymentAmount = computed(() => {
|
||||||
@@ -76,10 +88,12 @@ const handleBlur = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
|
fetchCurrencySymbol();
|
||||||
document.addEventListener('click', handleClickOutside);
|
document.addEventListener('click', handleClickOutside);
|
||||||
});
|
});
|
||||||
|
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
|
fetchCurrencySymbol();
|
||||||
document.removeEventListener('click', handleClickOutside);
|
document.removeEventListener('click', handleClickOutside);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -202,7 +216,7 @@ const handlePaymentConfirm = async (paymentMethod: 'alipay' | 'wxpay') => {
|
|||||||
:disabled="!paymentAmount || paymentAmount <= 0"
|
:disabled="!paymentAmount || paymentAmount <= 0"
|
||||||
@click="handleRecharge"
|
@click="handleRecharge"
|
||||||
>
|
>
|
||||||
<span style="color: var(--text-color, var(--ant-text-color))"> ¥{{ paymentAmount.toFixed(2) }} {{ t('page.carddata.pay') }} </span>
|
<span style="color: var(--text-color, var(--ant-text-color))"> {{ currencySymbol }}{{ paymentAmount.toFixed(2) }} {{ t('page.carddata.pay') }} </span>
|
||||||
</AButton>
|
</AButton>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -8,10 +8,23 @@ import { aliPayPcPay,aliPayWapPay, wxPayScanCode, payBalance } from '@/service/a
|
|||||||
import { useRouterPush } from '@/hooks/common/router';
|
import { useRouterPush } from '@/hooks/common/router';
|
||||||
import { useAppStore } from '@/store/modules/app';
|
import { useAppStore } from '@/store/modules/app';
|
||||||
import { useAuthStore} from '@/store/modules/auth';
|
import { useAuthStore} from '@/store/modules/auth';
|
||||||
|
import { getPaymentConfig } from '@/service/api/payment';
|
||||||
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: 'PackageSubscription'
|
name: 'PackageSubscription'
|
||||||
});
|
});
|
||||||
|
const currencySymbol = ref('¥');
|
||||||
|
|
||||||
|
const fetchCurrencySymbol = async () => {
|
||||||
|
try {
|
||||||
|
const response = await getPaymentConfig();
|
||||||
|
if (response && response.data) {
|
||||||
|
currencySymbol.value = response.data.currencySymbol || '¥';
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Failed to fetch currency symbol:', error);
|
||||||
|
}
|
||||||
|
};
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const authStore = useAuthStore();
|
const authStore = useAuthStore();
|
||||||
interface RateLimit {
|
interface RateLimit {
|
||||||
@@ -343,6 +356,7 @@ const isPackageActive = computed(() => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
|
await fetchCurrencySymbol();
|
||||||
fetchDashboardData();
|
fetchDashboardData();
|
||||||
await fetchPackages();
|
await fetchPackages();
|
||||||
await fetchUserBalance();
|
await fetchUserBalance();
|
||||||
@@ -354,7 +368,7 @@ onMounted(async () => {
|
|||||||
<!-- 顶部价格展示 -->
|
<!-- 顶部价格展示 -->
|
||||||
<div class="price-header">
|
<div class="price-header">
|
||||||
<div class="price">
|
<div class="price">
|
||||||
<span class="currency">¥</span>
|
<span class="currency">{{ currencySymbol }}</span>
|
||||||
<span class="amount">{{ selectedPackage.price }}</span>
|
<span class="amount">{{ selectedPackage.price }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="subtitle">{{ selectedPackage.packageName }}</div>
|
<div class="subtitle">{{ selectedPackage.packageName }}</div>
|
||||||
@@ -380,7 +394,7 @@ onMounted(async () => {
|
|||||||
{{ t('page.setmeal.highlyrecommended') }}
|
{{ t('page.setmeal.highlyrecommended') }}
|
||||||
</div>
|
</div>
|
||||||
<div class="package-name">{{ option.packageName }}</div>
|
<div class="package-name">{{ option.packageName }}</div>
|
||||||
<div class="price">¥{{ option.price }}</div>
|
<div class="price">{{ currencySymbol }}{{ option.price }}</div>
|
||||||
<div class="traffic">{{ option.trafficEnable ? option.trafficDisplay : t('page.setmeal.unlimit') }}</div>
|
<div class="traffic">{{ option.trafficEnable ? option.trafficDisplay : t('page.setmeal.unlimit') }}</div>
|
||||||
<div class="device-count">
|
<div class="device-count">
|
||||||
{{ option.clientNumEnable ? `${option.clientNum} ${t('page.setmeal.device')}` : t('page.setmeal.unlimit') }}
|
{{ option.clientNumEnable ? `${option.clientNum} ${t('page.setmeal.device')}` : t('page.setmeal.unlimit') }}
|
||||||
|
|||||||
Reference in New Issue
Block a user