2
0

feat:支付宝、微信支付对接

This commit is contained in:
zhongzm
2025-01-22 12:03:18 +08:00
parent 70f281974b
commit 09922f048e
7 changed files with 341 additions and 75 deletions

View File

@@ -2,11 +2,12 @@
import { ref, computed, onMounted, onUnmounted } from 'vue';
import { useI18n } from 'vue-i18n';
import { submitOrder } from '@/service/api/auth';
import { aliPayPcPay, aliPayWapPay } from '@/service/api/payment';
import { aliPayPcPay, aliPayWapPay, wxPayScanCode } from '@/service/api/payment';
import { message } from 'ant-design-vue';
import { useRouterPush } from '@/hooks/common/router';
import { useAppStore } from '@/store/modules/app';
import type { Ref } from 'vue';
import OrderConfirmModal from '@/components/order-confirm/orderConfirmModal.vue';
import { useAppStore } from '@/store/modules/app';
defineOptions({
name: 'BalanceRecharge'
@@ -82,6 +83,14 @@ onUnmounted(() => {
document.removeEventListener('click', handleClickOutside);
});
// 添加订单确认弹窗相关状态
const showOrderModal = ref(false);
const currentOrderInfo = ref({
orderId: '',
orderType: 1, // 1 表示余额充值
orderAmount: 0
});
// 修改充值处理方法
const handleRecharge = async () => {
// 验证金额
@@ -90,55 +99,56 @@ const handleRecharge = async () => {
return;
}
try {
await submitOrder({
type: 1,
orderAmount: paymentAmount.value
});
message.success('充值订单提交成功!');
} catch (error) {
message.error('充值失败,请重试!');
console.error('Failed to submit recharge order:', error);
}
};
// 测试:支付宝支付
const handleAliPay = async () => {
try {
const orderRes = await submitOrder({
type: 1,
orderAmount: paymentAmount.value
});
// 区分手机端和pc端支付
let res;
if(appStore.isMobile) {
res = await aliPayWapPay({orderId: orderRes.data});
// 更新订单信息并显示弹窗
currentOrderInfo.value = {
orderId: orderRes.data,
orderType: 1,
orderAmount: paymentAmount.value
};
showOrderModal.value = true;
} catch (error) {
message.error('创建订单失败,请重试!');
console.error('Failed to create order:', error);
}
};
// 修改支付处理方法
const handlePaymentConfirm = async (paymentMethod: 'alipay' | 'wxpay') => {
try {
if (paymentMethod === 'alipay') {
// 区分手机端和pc端支付
let res;
if (appStore.isMobile) {
res = await aliPayWapPay({ orderId: currentOrderInfo.value.orderId });
} else {
res = await aliPayPcPay({ orderId: currentOrderInfo.value.orderId });
}
const div = document.createElement('div');
div.innerHTML = res;
document.body.appendChild(div);
document.forms['punchout_form'].submit();
} else {
res = await aliPayPcPay({orderId: orderRes.data});
// 添加微信支付处理
const res = await wxPayScanCode({ orderId: currentOrderInfo.value.orderId });
routerPushByKey('billing_wxpay', {
query: {
url: res.data,
orderId: currentOrderInfo.value.orderId
}
});
}
console.log(res);
const div = document.createElement("div");
div.innerHTML = res; // html code
document.body.appendChild(div);
document.forms['punchout_form'].submit();
} catch (error) {
message.error('充值失败,请重试!');
console.error('Failed to submit recharge order:', error);
}
};
// 微信支付
const handleWxPay = async () => {
try {
const orderRes = await submitOrder({
type: 1,
orderAmount: paymentAmount.value
});
const res = await wxPayScanCode({orderId: orderRes.data});
routerPushByKey('billing_wxpay', { query: { url: res.data, orderId: orderRes.data } })
} catch (error) {
message.error('充值失败,请重试!');
console.error('Failed to submit recharge order:', error);
message.error(t('page.order.paymentFailed'));
console.error('Payment failed:', error);
} finally {
showOrderModal.value = false;
}
};
</script>
@@ -193,27 +203,14 @@ const handleWxPay = async () => {
>
¥{{ paymentAmount.toFixed(2) }} {{ t('page.carddata.pay') }}
</AButton>
<!-- 测试支付宝支付 -->
<AButton
type="primary"
size="large"
block
:disabled="!paymentAmount || paymentAmount <= 0"
@click="handleAliPay"
>
AliPay
</AButton>
<!-- 测试微信支付 -->
<AButton
type="primary"
size="large"
block
:disabled="!paymentAmount || paymentAmount <= 0"
@click="handleWxPay"
>
WxPay
</AButton>
</div>
<!-- 订单确认弹窗 -->
<OrderConfirmModal
v-model:visible="showOrderModal"
:order-info="currentOrderInfo"
@confirm="handlePaymentConfirm"
/>
</div>
</template>

View File

@@ -3,12 +3,23 @@ import { useI18n } from 'vue-i18n';
import { ref, onMounted } from 'vue';
import { fetchPackageList, submitOrder } from '@/service/api/auth';
import { message } from 'ant-design-vue';
import OrderConfirmModal from '@/components/order-confirm/orderConfirmModal.vue';
import { aliPayPcPay,aliPayWapPay, wxPayScanCode } from '@/service/api/payment';
import { useRouterPush } from '@/hooks/common/router';
import { useAppStore } from '@/store/modules/app';
defineOptions({
name: 'PackageSubscription'
});
const { t } = useI18n();
interface RateLimit {
upLimitEnable: boolean;
downLimitEnable: boolean;
upLimit: number;
downLimit: number;
}
interface PackageOption {
id: string;
packageName: string;
@@ -24,6 +35,8 @@ interface PackageOption {
periodNum: number;
periodType: number;
validityPeriod: string;
rateLimitEnable: boolean;
rateLimits: RateLimit;
}
// 添加有效期类型枚举
@@ -80,10 +93,14 @@ const formatTraffic = (bytes: number): string => {
return `${bytes.toFixed(2)}B`;
};
// 格式化流量有效期显示
const formatTrafficValidity = (num: number, type: number): string => {
const unit = PERIOD_UNIT[type as keyof typeof PERIOD_UNIT] || '未知';
return `${num}${unit}`;
// 添加速率格式化函数
const formatSpeed = (speed: number): string => {
if (speed >= 1000000) {
return `${(speed / 1000000).toFixed(1)}Gbps`;
} else if (speed >= 1000) {
return `${(speed / 1000).toFixed(1)}Mbps`;
}
return `${speed}Kbps`;
};
const packageOptions = ref<PackageOption[]>([]);
@@ -101,9 +118,30 @@ const selectedPackage = ref<PackageOption>({
promotion: '',
periodNum: 0,
periodType: PERIOD_TYPE.MONTH,
validityPeriod: '0月'
validityPeriod: '0月',
rateLimitEnable: false,
rateLimits: {
upLimitEnable: false,
downLimitEnable: false,
upLimit: 0,
downLimit: 0
}
});
// 添加路由跳转方法
const { routerPushByKey } = useRouterPush();
// 添加订单确认弹窗相关状态
const showOrderModal = ref(false);
const currentOrderInfo = ref({
orderId: '',
orderType: 0, // 0 表示购买套餐
orderAmount: 0
});
// 添加 appStore 实例
const appStore = useAppStore();
const fetchPackages = async () => {
try {
const response = await fetchPackageList();
@@ -116,13 +154,22 @@ const fetchPackages = async () => {
clientNumEnable: pkg.clientNumEnable,
traffic: Number(pkg.traffic),
trafficEnable: pkg.trafficEnable,
trafficDisplay: pkg.trafficEnable ? `${formatTraffic(Number(pkg.traffic))}${formatTrafficValidity(Number(pkg.periodNum), Number(pkg.periodType))}内有效` : '无限制',
durationEnable: pkg.durationEnable,
trafficDisplay: pkg.trafficEnable ? formatTraffic(Number(pkg.traffic)) : '无限制',
durationEnable: Boolean(pkg.periodNum && pkg.periodType !== undefined),
isRecommended: pkg.isRecommended || false,
promotion: pkg.promotion || '',
periodNum: Number(pkg.periodNum),
periodType: Number(pkg.periodType),
validityPeriod: pkg.durationEnable ? formatValidityPeriod(Number(pkg.periodNum), Number(pkg.periodType)) : '无限制'
validityPeriod: pkg.periodNum && pkg.periodType !== undefined
? formatValidityPeriod(Number(pkg.periodNum), Number(pkg.periodType))
: '无限制',
rateLimitEnable: pkg.rateLimitEnable,
rateLimits: {
upLimitEnable: pkg.rateLimits?.upLimitEnable || false,
downLimitEnable: pkg.rateLimits?.downLimitEnable || false,
upLimit: Number(pkg.rateLimits?.upLimit) || 0,
downLimit: Number(pkg.rateLimits?.downLimit) || 0
}
}));
if (packageOptions.value.length > 0) {
@@ -138,7 +185,7 @@ const selectPackage = (option: PackageOption) => {
selectedPackage.value = option;
};
// 套餐办理方法
// 修改套餐办理方法
const handleSubmitOrder = async () => {
try {
const orderRes = await submitOrder({
@@ -159,7 +206,7 @@ const handleSubmitOrder = async () => {
}
};
// 处理支付方式选择
// 修改支付处理方法
const handlePaymentConfirm = async (paymentMethod: 'alipay' | 'wxpay') => {
try {
if (paymentMethod === 'alipay') {
@@ -170,7 +217,8 @@ const handlePaymentConfirm = async (paymentMethod: 'alipay' | 'wxpay') => {
} else {
res = await aliPayPcPay({ orderId: currentOrderInfo.value.orderId });
}
const div = document.createElement("div");
const div = document.createElement('div');
div.innerHTML = res;
document.body.appendChild(div);
document.forms['punchout_form'].submit();
@@ -260,7 +308,23 @@ onMounted(async () => {
<div class="detail-item">
<div class="label">有效期限</div>
<div class="value">
{{ selectedPackage.durationEnable ? selectedPackage.validityPeriod : '无限制' }}
{{ selectedPackage.durationEnable ? selectedPackage.validityPeriod+'内有效' : '无限制' }}
</div>
</div>
<div class="detail-item">
<div class="label">速率限制</div>
<div class="value">
<template v-if="!selectedPackage.rateLimitEnable">
不限速
</template>
<template v-else>
<div>
上行{{ selectedPackage.rateLimits.upLimitEnable ? formatSpeed(selectedPackage.rateLimits.upLimit) : '-' }}
</div>
<div>
下行{{ selectedPackage.rateLimits.downLimitEnable ? formatSpeed(selectedPackage.rateLimits.downLimit) : '-' }}
</div>
</template>
</div>
</div>
<div class="bottom-bar">
@@ -274,6 +338,13 @@ onMounted(async () => {
</div>
</div>
</div>
<!-- 订单确认弹窗 -->
<OrderConfirmModal
v-model:visible="showOrderModal"
:order-info="currentOrderInfo"
@confirm="handlePaymentConfirm"
/>
</div>
</template>
@@ -440,4 +511,18 @@ onMounted(async () => {
color: #666;
margin-top: 4px;
}
.speed-limit {
font-size: 14px;
color: #666;
margin-top: 4px;
}
.value > div {
margin-bottom: 4px;
}
.value > div:last-child {
margin-bottom: 0;
}
</style>