Lufaneng 1 year ago
parent d9b50796c1
commit 27484b9d56

@ -17,7 +17,11 @@
<view class="user-details">
<view class="username">
张三
<u-icon name="checkmark-circle-fill" color="#ffa500" size="16"></u-icon>
<u-icon
name="checkmark-circle-fill"
color="#ffa500"
size="16"
></u-icon>
</view>
<view class="user-id">用户ID: U12345678</view>
<view class="membership">
@ -33,13 +37,18 @@
<!-- 账户余额 -->
<view class="balance-card">
<div>
<view class="balance-header">
<view class="balance-label">账户余额</view>
</view>
<view class="balance-amount">¥50.00</view>
</div>
<uv-button type="primary" color="#fff" customStyle="color:#000;width:90px" shape="circle" @click="recharge">
<uv-button
type="primary"
color="#fff"
customStyle="color:#000;width:90px"
shape="circle"
@click="recharge"
>
充值
</uv-button>
</view>
@ -47,21 +56,30 @@
<!-- 会员套餐 -->
<view class="membership-section">
<view class="membership-grid">
<view class="membership-item" :class="{ active: selectedPlan === 'monthly' }"
@click="selectPlan('monthly')">
<view
class="membership-item"
:class="{ active: selectedPlan === 'monthly' }"
@click="selectPlan('monthly')"
>
<view class="tag">新人特惠</view>
<view class="plan-name">包月会员</view>
<view class="plan-price">¥120</view>
</view>
<view class="membership-item" :class="{ active: selectedPlan === 'season' }"
@click="selectPlan('season')">
<view
class="membership-item"
:class="{ active: selectedPlan === 'season' }"
@click="selectPlan('season')"
>
<view class="tag">最受欢迎</view>
<view class="plan-name">包季会员</view>
<view class="plan-price">¥300</view>
<view class="plan-discount">立减¥60</view>
</view>
<view class="membership-item" :class="{ active: selectedPlan === 'yearly' }"
@click="selectPlan('yearly')">
<view
class="membership-item"
:class="{ active: selectedPlan === 'yearly' }"
@click="selectPlan('yearly')"
>
<view class="tag">年度首享</view>
<view class="plan-name">包年会员</view>
<view class="plan-price">¥1000</view>
@ -72,29 +90,54 @@
<!-- 支付方式 -->
<view class="payment-section">
<view class="payment-item" :class="{ active: selectedPayment === 'alipay' }"
@click="selectPayment('alipay')">
<!-- 微信支付 -->
<view
class="payment-item"
:class="{ active: selectedPayment === 'wechat' }"
@click="selectPayment('wechat')"
>
<view class="payment-info">
<uv-icon name="shopping-cart-fill" color="#1677ff" size="24"></uv-icon>
<text class="payment-name">支付宝</text>
<uv-icon name="weixin-fill" color="#07c160" size="24"></uv-icon>
<text class="payment-name">微信支付</text>
</view>
<uv-icon name="checkmark-circle-fill" :color="selectedPayment === 'alipay' ? '#ff3333' : '#ccc'"
size="20"></uv-icon>
<uv-icon
name="checkmark-circle-fill"
:color="selectedPayment === 'wechat' ? '#ff3333' : '#ccc'"
size="20"
></uv-icon>
</view>
<view class="payment-item" :class="{ active: selectedPayment === 'wechat' }"
@click="selectPayment('wechat')">
<!-- 支付宝支付 - 仅在H5环境显示 -->
<view
v-if="showAlipay"
class="payment-item"
:class="{ active: selectedPayment === 'alipay' }"
@click="selectPayment('alipay')"
>
<view class="payment-info">
<uv-icon name="weixin-fill" color="#07c160" size="24"></uv-icon>
<text class="payment-name">微信</text>
<uv-icon
name="alipay-circle-fill"
color="#1677ff"
size="24"
></uv-icon>
<text class="payment-name">支付宝</text>
</view>
<uv-icon name="checkmark-circle-fill" :color="selectedPayment === 'wechat' ? '#ff3333' : '#ccc'"
size="20"></uv-icon>
<uv-icon
name="checkmark-circle-fill"
:color="selectedPayment === 'alipay' ? '#ff3333' : '#ccc'"
size="20"
></uv-icon>
</view>
</view>
<!-- 底部按钮 -->
<view class="bottom-section">
<uv-button type="primary" size="large" @click="confirmPayment" :loading="paying">
<uv-button
type="primary"
size="large"
@click="confirmPayment"
:loading="paying"
>
确认支付
</uv-button>
<view class="agreement">
@ -106,14 +149,10 @@
</template>
<script setup>
import {
ref
} from "vue";
import { ref, onMounted } from "vue";
import { onShow } from "@dcloudio/uni-app";
import HeaderCustom from "/components/HeaderCustom/HeaderCustom.vue";
import {
useAuthStore,
useUserStore
} from "@/store";
import { useAuthStore, useUserStore } from "@/store";
import RPC from "@/utils/request";
const modal = ref(null);
@ -122,8 +161,9 @@
// 响应式数据
const selectedPlan = ref("season"); // 默认选中包季会员
const selectedPayment = ref("alipay"); // 默认选中支付宝
const selectedPayment = ref("wechat"); // 默认选中微信支付
const paying = ref(false);
const showAlipay = ref(true); // 控制是否显示支付宝选项
// 选择会员套餐
const selectPlan = (plan) => {
@ -149,6 +189,107 @@
});
};
// 获取套餐价格
const getPlanPrice = (plan) => {
const prices = {
monthly: 120,
season: 300,
yearly: 1000,
};
return prices[plan] || 0;
};
// 获取套餐名称
const getPlanName = (plan) => {
const names = {
monthly: "包月会员",
season: "包季会员",
yearly: "包年会员",
};
return names[plan] || "";
};
// 创建订单
const createOrder = async (params) => {
try {
// 调用后端创建订单API
const result = await RPC.post("/api/order/create", params);
return result.data;
} catch (error) {
console.error("创建订单失败:", error);
throw error;
}
};
// 微信支付
const wechatPay = async (orderInfo) => {
// #ifdef MP-WEIXIN
// 微信小程序支付
try {
const paymentResult = await uni.requestPayment({
provider: "wxpay",
timeStamp: orderInfo.timeStamp,
nonceStr: orderInfo.nonceStr,
package: orderInfo.package,
signType: orderInfo.signType,
paySign: orderInfo.paySign,
});
console.log("微信支付成功:", paymentResult);
return { success: true, data: paymentResult };
} catch (error) {
console.error("微信支付失败:", error);
if (error.errMsg === "requestPayment:fail cancel") {
throw new Error("用户取消支付");
}
throw new Error("微信支付失败");
}
// #endif
// #ifdef H5
// H5微信支付
if (typeof WeixinJSBridge !== "undefined") {
return new Promise((resolve, reject) => {
WeixinJSBridge.invoke(
"getBrandWCPayRequest",
{
appId: orderInfo.appId,
timeStamp: orderInfo.timeStamp,
nonceStr: orderInfo.nonceStr,
package: orderInfo.package,
signType: orderInfo.signType,
paySign: orderInfo.paySign,
},
(res) => {
if (res.err_msg === "get_brand_wcpay_request:ok") {
resolve({ success: true, data: res });
} else if (res.err_msg === "get_brand_wcpay_request:cancel") {
reject(new Error("用户取消支付"));
} else {
reject(new Error("微信支付失败"));
}
}
);
});
} else {
// 不在微信环境,跳转到支付页面
const payUrl = orderInfo.mwebUrl; // 后端返回的H5支付链接
window.location.href = payUrl;
return { success: true, redirect: true };
}
// #endif
};
// 支付宝支付(仅H5环境)
const alipayPay = async (orderInfo) => {
// #ifdef H5
// H5支付宝支付
const payUrl = orderInfo.payUrl; // 后端返回的支付宝H5支付链接
window.location.href = payUrl;
return { success: true, redirect: true };
// #endif
};
// 确认支付
const confirmPayment = async () => {
if (!selectedPlan.value) {
@ -168,35 +309,116 @@
}
paying.value = true;
try {
const params = {
// 1. 创建订单参数
const orderParams = {
plan: selectedPlan.value,
planName: getPlanName(selectedPlan.value),
amount: getPlanPrice(selectedPlan.value),
paymentMethod: selectedPayment.value,
userId: userStore.userInfo?.id || "mock_user_id",
// #ifdef MP-WEIXIN
platform: "mp-weixin",
// #endif
// #ifdef H5
platform: "h5",
// #endif
};
// 这里调用支付API
// const result = await RPC.post('/api/payment', params)
uni.showLoading({
title: "正在创建订单...",
});
// 2. 创建订单
// const orderResult = await createOrder(orderParams);
// 模拟创建订单返回的数据
const orderResult = {
orderId: "ORDER_" + Date.now(),
amount: orderParams.amount,
// 微信支付参数(实际应该由后端返回)
wechatPayInfo: {
appId: "wx1234567890",
timeStamp: String(Date.now()),
nonceStr: "random_string_" + Date.now(),
package: "prepay_id=wx_prepay_id_123456",
signType: "RSA",
paySign: "mock_pay_sign_123456",
// H5支付链接
mwebUrl:
"https://wx.tenpay.com/cgi-bin/mmpayweb-bin/checkmweb?prepay_id=wx_prepay_id_123456",
},
// 支付宝支付参数(实际应该由后端返回)
alipayInfo: {
orderString: "mock_alipay_order_string_123456",
payUrl: "https://openapi.alipay.com/gateway.do?mock_pay_url",
},
};
uni.hideLoading();
// 3. 根据支付方式调用对应的支付方法
let paymentResult;
if (selectedPayment.value === "wechat") {
uni.showLoading({
title: "正在跳转微信支付...",
});
paymentResult = await wechatPay(orderResult.wechatPayInfo);
} else if (selectedPayment.value === "alipay") {
uni.showLoading({
title: "正在跳转支付宝...",
});
paymentResult = await alipayPay(orderResult.alipayInfo);
}
uni.hideLoading();
// 4. 处理支付结果
if (paymentResult.success) {
if (paymentResult.redirect) {
// H5跳转支付,不需要额外处理
uni.showToast({
title: "正在跳转支付...",
title: "正在跳转支付页面...",
icon: "loading",
duration: 2000,
});
// 模拟支付过程
setTimeout(() => {
} else {
// 支付成功
uni.showToast({
title: "支付成功",
icon: "success",
});
paying.value = false;
}, 2000);
// 延迟跳转到订单页面或刷新用户信息
setTimeout(() => {
// 可以跳转到订单详情页面
uni.navigateTo({
url: `/pages/order-detail/order-detail?orderId=${orderResult.orderId}`,
});
// 或者刷新当前页面的用户信息
// loadUserInfo();
}, 1500);
}
}
} catch (error) {
uni.hideLoading();
console.error("支付失败:", error);
let errorMessage = "支付失败,请重试";
if (error.message === "用户取消支付") {
errorMessage = "支付已取消";
} else if (error.message) {
errorMessage = error.message;
}
uni.showToast({
title: "支付失败,请重试",
title: errorMessage,
icon: "none",
});
} finally {
paying.value = false;
}
};
@ -207,6 +429,102 @@
url: "/pages/agreement/agreement",
});
};
// 检查支付结果(用于H5支付回调)
const checkPaymentResult = async (orderId) => {
try {
// 调用后端接口检查支付结果
// const result = await RPC.get(`/api/order/check-payment/${orderId}`);
// 模拟检查结果
const result = {
success: true,
status: "paid", // paid, pending, failed
};
if (result.status === "paid") {
uni.showToast({
title: "支付成功",
icon: "success",
});
// 更新用户信息或跳转到成功页面
setTimeout(() => {
uni.navigateTo({
url: `/pages/order-detail/order-detail?orderId=${orderId}`,
});
}, 1500);
} else if (result.status === "failed") {
uni.showToast({
title: "支付失败",
icon: "none",
});
} else {
uni.showToast({
title: "支付处理中,请稍后查看订单状态",
icon: "none",
});
}
} catch (error) {
console.error("检查支付结果失败:", error);
}
};
// 页面显示时检查是否有支付回调参数
const handlePaymentCallback = () => {
// #ifdef H5
const urlParams = new URLSearchParams(window.location.search);
const orderId = urlParams.get("orderId");
const payResult = urlParams.get("payResult");
if (orderId && payResult) {
// 清理URL参数
const url = new URL(window.location);
url.searchParams.delete("orderId");
url.searchParams.delete("payResult");
window.history.replaceState({}, document.title, url.pathname + url.search);
// 检查支付结果
if (payResult === "success") {
checkPaymentResult(orderId);
} else {
uni.showToast({
title: "支付失败或取消",
icon: "none",
});
}
}
// #endif
};
// 检查当前环境并设置支付选项
const checkEnvironment = () => {
// #ifdef MP-WEIXIN
// 微信小程序环境,隐藏支付宝选项,默认选择微信支付
showAlipay.value = false;
selectedPayment.value = "wechat";
// #endif
// #ifdef H5
// H5环境,显示所有支付选项
showAlipay.value = true;
// 如果在微信浏览器内,默认选择微信支付
const ua = navigator.userAgent.toLowerCase();
const isWechat = ua.indexOf("micromessenger") !== -1;
selectedPayment.value = isWechat ? "wechat" : "alipay";
// #endif
};
// 页面挂载时处理支付回调和环境检查
onMounted(() => {
checkEnvironment();
handlePaymentCallback();
});
// 页面显示时也检查支付回调(从其他页面返回时)
onShow(() => {
handlePaymentCallback();
});
</script>
<style lang="scss" scoped>
@ -250,7 +568,6 @@
width: 100%;
height: 100%;
}
}
.user-details {

Loading…
Cancel
Save