fix:支付方式对接
This commit is contained in:
155
src/components/order-confirm/orderConfirmModal.vue
Normal file
155
src/components/order-confirm/orderConfirmModal.vue
Normal file
@@ -0,0 +1,155 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { defineProps, defineEmits } from 'vue';
|
||||||
|
import { useI18n } from 'vue-i18n';
|
||||||
|
import { AlipayOutlined, WechatOutlined } from '@ant-design/icons-vue';
|
||||||
|
|
||||||
|
const { t } = useI18n();
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
visible: boolean;
|
||||||
|
orderInfo: {
|
||||||
|
orderId: string;
|
||||||
|
orderType: number; // 0: 购买套餐, 1: 余额充值
|
||||||
|
orderAmount: number;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const props = defineProps<Props>();
|
||||||
|
const emit = defineEmits(['update:visible', 'confirm', 'cancel']);
|
||||||
|
|
||||||
|
const orderTypeMap = {
|
||||||
|
0: t('page.order.packagePurchase'),
|
||||||
|
1: t('page.order.balanceRecharge')
|
||||||
|
} as const;
|
||||||
|
|
||||||
|
const handleConfirm = (paymentMethod: 'alipay' | 'wxpay') => {
|
||||||
|
emit('confirm', paymentMethod);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleCancel = () => {
|
||||||
|
emit('update:visible', false);
|
||||||
|
emit('cancel');
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<a-modal
|
||||||
|
:visible="visible"
|
||||||
|
:title="t('page.order.confirmOrder')"
|
||||||
|
:footer="null"
|
||||||
|
@cancel="handleCancel"
|
||||||
|
width="460px"
|
||||||
|
:maskClosable="false"
|
||||||
|
>
|
||||||
|
<div class="order-info">
|
||||||
|
<div class="info-item">
|
||||||
|
<span class="label">{{ t('page.order.orderType') }}:</span>
|
||||||
|
<span class="value">{{ orderTypeMap[orderInfo.orderType] }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="info-item">
|
||||||
|
<span class="label">{{ t('page.order.orderAmount') }}:</span>
|
||||||
|
<span class="value highlight">¥{{ orderInfo.orderAmount.toFixed(2) }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="info-item">
|
||||||
|
<span class="label">{{ t('page.order.orderId') }}:</span>
|
||||||
|
<span class="value">{{ orderInfo.orderId }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="payment-methods">
|
||||||
|
<h4>{{ t('page.order.selectPayment') }}</h4>
|
||||||
|
<div class="methods-container">
|
||||||
|
<div class="method-item" @click="handleConfirm('alipay')">
|
||||||
|
<AlipayOutlined class="payment-icon alipay-icon" />
|
||||||
|
<span>{{ t('page.order.alipay') }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="method-item" @click="handleConfirm('wxpay')">
|
||||||
|
<WechatOutlined class="payment-icon wxpay-icon" />
|
||||||
|
<span>{{ t('page.order.wxpay') }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</a-modal>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.order-info {
|
||||||
|
padding: 20px;
|
||||||
|
background: #f8f8f8;
|
||||||
|
border-radius: 8px;
|
||||||
|
margin-bottom: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-item {
|
||||||
|
display: flex;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
line-height: 24px;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-item:last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.label {
|
||||||
|
width: 84px;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.value {
|
||||||
|
flex: 1;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.value.highlight {
|
||||||
|
color: #ff4d4f;
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.payment-methods {
|
||||||
|
padding: 0 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.payment-methods h4 {
|
||||||
|
margin-bottom: 16px;
|
||||||
|
color: #333;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
.methods-container {
|
||||||
|
display: flex;
|
||||||
|
gap: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.method-item {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
padding: 16px;
|
||||||
|
border: 1px solid #e8e8e8;
|
||||||
|
border-radius: 8px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.method-item:hover {
|
||||||
|
border-color: #1890ff;
|
||||||
|
background: #f0f5ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.payment-icon {
|
||||||
|
font-size: 24px;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.alipay-icon {
|
||||||
|
color: #1677ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wxpay-icon {
|
||||||
|
color: #07c160;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -661,6 +661,17 @@ const local: any = {
|
|||||||
balanceRecharge:'Banlance Recharge',
|
balanceRecharge:'Banlance Recharge',
|
||||||
packageSubscription:'Package Subscription',
|
packageSubscription:'Package Subscription',
|
||||||
},
|
},
|
||||||
|
order:{
|
||||||
|
confirmOrder:'Order Confirmation',
|
||||||
|
orderType:'Order type',
|
||||||
|
balanceRecharge:'Balance recharge',
|
||||||
|
packagePurchase:'Package processing',
|
||||||
|
orderAmount:'Amount',
|
||||||
|
orderId:'ID',
|
||||||
|
selectPayment:'Payment',
|
||||||
|
alipay:'Alipay',
|
||||||
|
wxpay:'WeChat Pay'
|
||||||
|
}
|
||||||
},
|
},
|
||||||
form: {
|
form: {
|
||||||
required: 'Cannot be empty',
|
required: 'Cannot be empty',
|
||||||
|
|||||||
@@ -663,6 +663,20 @@ const local:any = {
|
|||||||
balanceRecharge:'余额充值',
|
balanceRecharge:'余额充值',
|
||||||
packageSubscription:'套餐办理',
|
packageSubscription:'套餐办理',
|
||||||
},
|
},
|
||||||
|
order:{
|
||||||
|
confirmOrder:'订单确认',
|
||||||
|
orderType:'订单类型',
|
||||||
|
balanceRecharge:'余额充值',
|
||||||
|
packagePurchase:'套餐办理',
|
||||||
|
orderAmount:'订单金额',
|
||||||
|
orderId:'订单ID',
|
||||||
|
selectPayment:'支付方式',
|
||||||
|
alipay:'支付宝支付',
|
||||||
|
wxpay:'微信支付'
|
||||||
|
},
|
||||||
|
package:{
|
||||||
|
|
||||||
|
}
|
||||||
},
|
},
|
||||||
form: {
|
form: {
|
||||||
required: '不能为空',
|
required: '不能为空',
|
||||||
|
|||||||
3
src/typings/auto-imports.d.ts
vendored
3
src/typings/auto-imports.d.ts
vendored
@@ -14,6 +14,7 @@ declare global {
|
|||||||
const afterAll: typeof import('vitest')['afterAll']
|
const afterAll: typeof import('vitest')['afterAll']
|
||||||
const afterEach: typeof import('vitest')['afterEach']
|
const afterEach: typeof import('vitest')['afterEach']
|
||||||
const aliPayPcPay: typeof import('../service/api/payment')['aliPayPcPay']
|
const aliPayPcPay: typeof import('../service/api/payment')['aliPayPcPay']
|
||||||
|
const aliPayWapPay: typeof import('../service/api/payment')['aliPayWapPay']
|
||||||
const assert: typeof import('vitest')['assert']
|
const assert: typeof import('vitest')['assert']
|
||||||
const assign: typeof import('lodash-es')['assign']
|
const assign: typeof import('lodash-es')['assign']
|
||||||
const asyncComputed: typeof import('@vueuse/core')['asyncComputed']
|
const asyncComputed: typeof import('@vueuse/core')['asyncComputed']
|
||||||
@@ -74,6 +75,7 @@ declare global {
|
|||||||
const doGetDictList: typeof import('../service/api/dict')['doGetDictList']
|
const doGetDictList: typeof import('../service/api/dict')['doGetDictList']
|
||||||
const doGetMenuDetail: typeof import('../service/api/menu')['doGetMenuDetail']
|
const doGetMenuDetail: typeof import('../service/api/menu')['doGetMenuDetail']
|
||||||
const doGetMenuList: typeof import('../service/api/menu')['doGetMenuList']
|
const doGetMenuList: typeof import('../service/api/menu')['doGetMenuList']
|
||||||
|
const doGetOrderInfo: typeof import('../service/api/order')['doGetOrderInfo']
|
||||||
const doGetPostDetail: typeof import('../service/api/post')['doGetPostDetail']
|
const doGetPostDetail: typeof import('../service/api/post')['doGetPostDetail']
|
||||||
const doGetPostList: typeof import('../service/api/post')['doGetPostList']
|
const doGetPostList: typeof import('../service/api/post')['doGetPostList']
|
||||||
const doGetRoleList: typeof import('../service/api/role')['doGetRoleList']
|
const doGetRoleList: typeof import('../service/api/role')['doGetRoleList']
|
||||||
@@ -433,6 +435,7 @@ declare global {
|
|||||||
const watchTriggerable: typeof import('@vueuse/core')['watchTriggerable']
|
const watchTriggerable: typeof import('@vueuse/core')['watchTriggerable']
|
||||||
const watchWithFilter: typeof import('@vueuse/core')['watchWithFilter']
|
const watchWithFilter: typeof import('@vueuse/core')['watchWithFilter']
|
||||||
const whenever: typeof import('@vueuse/core')['whenever']
|
const whenever: typeof import('@vueuse/core')['whenever']
|
||||||
|
const wxPayScanCode: typeof import('../service/api/payment')['wxPayScanCode']
|
||||||
}
|
}
|
||||||
// for type re-export
|
// for type re-export
|
||||||
declare global {
|
declare global {
|
||||||
|
|||||||
1
src/typings/components.d.ts
vendored
1
src/typings/components.d.ts
vendored
@@ -77,6 +77,7 @@ declare module 'vue' {
|
|||||||
LangSwitch: typeof import('./../components/common/lang-switch.vue')['default']
|
LangSwitch: typeof import('./../components/common/lang-switch.vue')['default']
|
||||||
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']
|
||||||
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']
|
||||||
RouterLink: typeof import('vue-router')['RouterLink']
|
RouterLink: typeof import('vue-router')['RouterLink']
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import { message } from 'ant-design-vue';
|
|||||||
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 type { Ref } from 'vue';
|
import type { Ref } from 'vue';
|
||||||
|
import OrderConfirmModal from '@/components/order-confirm/orderConfirmModal.vue';
|
||||||
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: 'BalanceRecharge'
|
name: 'BalanceRecharge'
|
||||||
@@ -82,6 +83,14 @@ onUnmounted(() => {
|
|||||||
document.removeEventListener('click', handleClickOutside);
|
document.removeEventListener('click', handleClickOutside);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 添加订单确认弹窗相关状态
|
||||||
|
const showOrderModal = ref(false);
|
||||||
|
const currentOrderInfo = ref({
|
||||||
|
orderId: '',
|
||||||
|
orderType: 1, // 1 表示余额充值
|
||||||
|
orderAmount: 0
|
||||||
|
});
|
||||||
|
|
||||||
// 修改充值处理方法
|
// 修改充值处理方法
|
||||||
const handleRecharge = async () => {
|
const handleRecharge = async () => {
|
||||||
// 验证金额
|
// 验证金额
|
||||||
@@ -90,55 +99,54 @@ const handleRecharge = async () => {
|
|||||||
return;
|
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 {
|
try {
|
||||||
const orderRes = await submitOrder({
|
const orderRes = await submitOrder({
|
||||||
type: 1,
|
type: 1,
|
||||||
orderAmount: paymentAmount.value
|
orderAmount: paymentAmount.value
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 更新订单信息并显示弹窗
|
||||||
|
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端支付
|
// 区分手机端和pc端支付
|
||||||
let res;
|
let res;
|
||||||
if (appStore.isMobile) {
|
if (appStore.isMobile) {
|
||||||
res = await aliPayWapPay({orderId: orderRes.data});
|
res = await aliPayWapPay({ orderId: currentOrderInfo.value.orderId });
|
||||||
} else {
|
} else {
|
||||||
res = await aliPayPcPay({orderId: orderRes.data});
|
res = await aliPayPcPay({ orderId: currentOrderInfo.value.orderId });
|
||||||
}
|
}
|
||||||
console.log(res);
|
|
||||||
const div = document.createElement("div");
|
const div = document.createElement("div");
|
||||||
div.innerHTML = res; // html code
|
div.innerHTML = res;
|
||||||
document.body.appendChild(div);
|
document.body.appendChild(div);
|
||||||
document.forms['punchout_form'].submit();
|
document.forms['punchout_form'].submit();
|
||||||
|
} else {
|
||||||
} catch (error) {
|
const res = await wxPayScanCode({ orderId: currentOrderInfo.value.orderId });
|
||||||
message.error('充值失败,请重试!');
|
routerPushByKey('billing_wxpay', {
|
||||||
console.error('Failed to submit recharge order:', error);
|
query: {
|
||||||
|
url: res.data,
|
||||||
|
orderId: currentOrderInfo.value.orderId
|
||||||
}
|
}
|
||||||
};
|
|
||||||
// 微信支付
|
|
||||||
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) {
|
} catch (error) {
|
||||||
message.error('充值失败,请重试!');
|
message.error(t('page.order.paymentFailed'));
|
||||||
console.error('Failed to submit recharge order:', error);
|
console.error('Payment failed:', error);
|
||||||
|
} finally {
|
||||||
|
showOrderModal.value = false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
@@ -193,27 +201,14 @@ const handleWxPay = async () => {
|
|||||||
>
|
>
|
||||||
¥{{ paymentAmount.toFixed(2) }} {{ t('page.carddata.pay') }}
|
¥{{ paymentAmount.toFixed(2) }} {{ t('page.carddata.pay') }}
|
||||||
</AButton>
|
</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>
|
</div>
|
||||||
|
|
||||||
|
<!-- 订单确认弹窗 -->
|
||||||
|
<OrderConfirmModal
|
||||||
|
v-model:visible="showOrderModal"
|
||||||
|
:order-info="currentOrderInfo"
|
||||||
|
@confirm="handlePaymentConfirm"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|||||||
@@ -3,12 +3,22 @@ import { useI18n } from 'vue-i18n';
|
|||||||
import { ref, onMounted } from 'vue';
|
import { ref, onMounted } from 'vue';
|
||||||
import { fetchPackageList, submitOrder } from '@/service/api/auth';
|
import { fetchPackageList, submitOrder } from '@/service/api/auth';
|
||||||
import { message } from 'ant-design-vue';
|
import { message } from 'ant-design-vue';
|
||||||
|
import OrderConfirmModal from '@/components/order-confirm/orderConfirmModal.vue';
|
||||||
|
import { aliPayPcPay, wxPayScanCode } from '@/service/api/payment';
|
||||||
|
import { useRouterPush } from '@/hooks/common/router';
|
||||||
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: 'PackageSubscription'
|
name: 'PackageSubscription'
|
||||||
});
|
});
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
|
||||||
|
interface RateLimit {
|
||||||
|
upLimitEnable: boolean;
|
||||||
|
downLimitEnable: boolean;
|
||||||
|
upLimit: number;
|
||||||
|
downLimit: number;
|
||||||
|
}
|
||||||
|
|
||||||
interface PackageOption {
|
interface PackageOption {
|
||||||
id: string;
|
id: string;
|
||||||
packageName: string;
|
packageName: string;
|
||||||
@@ -24,6 +34,8 @@ interface PackageOption {
|
|||||||
periodNum: number;
|
periodNum: number;
|
||||||
periodType: number;
|
periodType: number;
|
||||||
validityPeriod: string;
|
validityPeriod: string;
|
||||||
|
rateLimitEnable: boolean;
|
||||||
|
rateLimits: RateLimit;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 添加有效期类型枚举
|
// 添加有效期类型枚举
|
||||||
@@ -86,6 +98,16 @@ const formatTrafficValidity = (num: number, type: number): string => {
|
|||||||
return `${num}${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[]>([]);
|
const packageOptions = ref<PackageOption[]>([]);
|
||||||
const selectedPackage = ref<PackageOption>({
|
const selectedPackage = ref<PackageOption>({
|
||||||
id: '1',
|
id: '1',
|
||||||
@@ -101,7 +123,25 @@ const selectedPackage = ref<PackageOption>({
|
|||||||
promotion: '',
|
promotion: '',
|
||||||
periodNum: 0,
|
periodNum: 0,
|
||||||
periodType: PERIOD_TYPE.MONTH,
|
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
|
||||||
});
|
});
|
||||||
|
|
||||||
const fetchPackages = async () => {
|
const fetchPackages = async () => {
|
||||||
@@ -116,13 +156,22 @@ const fetchPackages = async () => {
|
|||||||
clientNumEnable: pkg.clientNumEnable,
|
clientNumEnable: pkg.clientNumEnable,
|
||||||
traffic: Number(pkg.traffic),
|
traffic: Number(pkg.traffic),
|
||||||
trafficEnable: pkg.trafficEnable,
|
trafficEnable: pkg.trafficEnable,
|
||||||
trafficDisplay: pkg.trafficEnable ? `${formatTraffic(Number(pkg.traffic))},${formatTrafficValidity(Number(pkg.periodNum), Number(pkg.periodType))}内有效` : '无限制',
|
trafficDisplay: pkg.trafficEnable ? formatTraffic(Number(pkg.traffic)) : '无限制',
|
||||||
durationEnable: pkg.durationEnable,
|
durationEnable: Boolean(pkg.periodNum && pkg.periodType !== undefined),
|
||||||
isRecommended: pkg.isRecommended || false,
|
isRecommended: pkg.isRecommended || false,
|
||||||
promotion: pkg.promotion || '',
|
promotion: pkg.promotion || '',
|
||||||
periodNum: Number(pkg.periodNum),
|
periodNum: Number(pkg.periodNum),
|
||||||
periodType: Number(pkg.periodType),
|
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) {
|
if (packageOptions.value.length > 0) {
|
||||||
@@ -138,17 +187,50 @@ const selectPackage = (option: PackageOption) => {
|
|||||||
selectedPackage.value = option;
|
selectedPackage.value = option;
|
||||||
};
|
};
|
||||||
|
|
||||||
// 套餐办理方法
|
// 修改套餐办理方法
|
||||||
const handleSubmitOrder = async () => {
|
const handleSubmitOrder = async () => {
|
||||||
try {
|
try {
|
||||||
await submitOrder({
|
const orderRes = await submitOrder({
|
||||||
type: 0,
|
type: 0,
|
||||||
packageId: selectedPackage.value.id
|
packageId: selectedPackage.value.id
|
||||||
});
|
});
|
||||||
message.success('套餐办理成功!');
|
|
||||||
|
// 更新订单信息并显示弹窗
|
||||||
|
currentOrderInfo.value = {
|
||||||
|
orderId: orderRes.data,
|
||||||
|
orderType: 0,
|
||||||
|
orderAmount: selectedPackage.value.price
|
||||||
|
};
|
||||||
|
showOrderModal.value = true;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
message.error('套餐办理失败,请重试!');
|
message.error(t('page.order.createOrderFailed'));
|
||||||
console.error('Failed to submit order:', error);
|
console.error('Failed to create order:', error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 处理支付方式选择
|
||||||
|
const handlePaymentConfirm = async (paymentMethod: 'alipay' | 'wxpay') => {
|
||||||
|
try {
|
||||||
|
if (paymentMethod === 'alipay') {
|
||||||
|
const 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 {
|
||||||
|
const res = await wxPayScanCode({ orderId: currentOrderInfo.value.orderId });
|
||||||
|
routerPushByKey('billing_wxpay', {
|
||||||
|
query: {
|
||||||
|
url: res.data,
|
||||||
|
orderId: currentOrderInfo.value.orderId
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
message.error(t('page.order.paymentFailed'));
|
||||||
|
console.error('Payment failed:', error);
|
||||||
|
} finally {
|
||||||
|
showOrderModal.value = false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -224,6 +306,22 @@ onMounted(async () => {
|
|||||||
{{ selectedPackage.durationEnable ? selectedPackage.validityPeriod : '无限制' }}
|
{{ selectedPackage.durationEnable ? selectedPackage.validityPeriod : '无限制' }}
|
||||||
</div>
|
</div>
|
||||||
</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">
|
<div class="bottom-bar">
|
||||||
<button
|
<button
|
||||||
class="btn-primary"
|
class="btn-primary"
|
||||||
@@ -235,6 +333,13 @@ onMounted(async () => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- 订单确认弹窗 -->
|
||||||
|
<OrderConfirmModal
|
||||||
|
v-model:visible="showOrderModal"
|
||||||
|
:order-info="currentOrderInfo"
|
||||||
|
@confirm="handlePaymentConfirm"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -401,4 +506,18 @@ onMounted(async () => {
|
|||||||
color: #666;
|
color: #666;
|
||||||
margin-top: 4px;
|
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>
|
</style>
|
||||||
|
|||||||
Reference in New Issue
Block a user