Lufaneng 11 months ago
parent d9b50796c1
commit 27484b9d56

@ -17,7 +17,11 @@
<view class="user-details"> <view class="user-details">
<view class="username"> <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>
<view class="user-id">用户ID: U12345678</view> <view class="user-id">用户ID: U12345678</view>
<view class="membership"> <view class="membership">
@ -33,13 +37,18 @@
<!-- 账户余额 --> <!-- 账户余额 -->
<view class="balance-card"> <view class="balance-card">
<div> <div>
<view class="balance-header"> <view class="balance-header">
<view class="balance-label">账户余额</view> <view class="balance-label">账户余额</view>
</view> </view>
<view class="balance-amount">¥50.00</view> <view class="balance-amount">¥50.00</view>
</div> </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> </uv-button>
</view> </view>
@ -47,21 +56,30 @@
<!-- 会员套餐 --> <!-- 会员套餐 -->
<view class="membership-section"> <view class="membership-section">
<view class="membership-grid"> <view class="membership-grid">
<view class="membership-item" :class="{ active: selectedPlan === 'monthly' }" <view
@click="selectPlan('monthly')"> class="membership-item"
:class="{ active: selectedPlan === 'monthly' }"
@click="selectPlan('monthly')"
>
<view class="tag">新人特惠</view> <view class="tag">新人特惠</view>
<view class="plan-name">包月会员</view> <view class="plan-name">包月会员</view>
<view class="plan-price">¥120</view> <view class="plan-price">¥120</view>
</view> </view>
<view class="membership-item" :class="{ active: selectedPlan === 'season' }" <view
@click="selectPlan('season')"> class="membership-item"
:class="{ active: selectedPlan === 'season' }"
@click="selectPlan('season')"
>
<view class="tag">最受欢迎</view> <view class="tag">最受欢迎</view>
<view class="plan-name">包季会员</view> <view class="plan-name">包季会员</view>
<view class="plan-price">¥300</view> <view class="plan-price">¥300</view>
<view class="plan-discount">立减¥60</view> <view class="plan-discount">立减¥60</view>
</view> </view>
<view class="membership-item" :class="{ active: selectedPlan === 'yearly' }" <view
@click="selectPlan('yearly')"> class="membership-item"
:class="{ active: selectedPlan === 'yearly' }"
@click="selectPlan('yearly')"
>
<view class="tag">年度首享</view> <view class="tag">年度首享</view>
<view class="plan-name">包年会员</view> <view class="plan-name">包年会员</view>
<view class="plan-price">¥1000</view> <view class="plan-price">¥1000</view>
@ -72,29 +90,54 @@
<!-- 支付方式 --> <!-- 支付方式 -->
<view class="payment-section"> <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"> <view class="payment-info">
<uv-icon name="shopping-cart-fill" color="#1677ff" size="24"></uv-icon> <uv-icon name="weixin-fill" color="#07c160" size="24"></uv-icon>
<text class="payment-name">支付宝</text> <text class="payment-name">微信支付</text>
</view> </view>
<uv-icon name="checkmark-circle-fill" :color="selectedPayment === 'alipay' ? '#ff3333' : '#ccc'" <uv-icon
size="20"></uv-icon> name="checkmark-circle-fill"
:color="selectedPayment === 'wechat' ? '#ff3333' : '#ccc'"
size="20"
></uv-icon>
</view> </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"> <view class="payment-info">
<uv-icon name="weixin-fill" color="#07c160" size="24"></uv-icon> <uv-icon
<text class="payment-name">微信</text> name="alipay-circle-fill"
color="#1677ff"
size="24"
></uv-icon>
<text class="payment-name">支付宝</text>
</view> </view>
<uv-icon name="checkmark-circle-fill" :color="selectedPayment === 'wechat' ? '#ff3333' : '#ccc'" <uv-icon
size="20"></uv-icon> name="checkmark-circle-fill"
:color="selectedPayment === 'alipay' ? '#ff3333' : '#ccc'"
size="20"
></uv-icon>
</view> </view>
</view> </view>
<!-- 底部按钮 --> <!-- 底部按钮 -->
<view class="bottom-section"> <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> </uv-button>
<view class="agreement"> <view class="agreement">
@ -106,14 +149,10 @@
</template> </template>
<script setup> <script setup>
import { import { ref, onMounted } from "vue";
ref import { onShow } from "@dcloudio/uni-app";
} from "vue";
import HeaderCustom from "/components/HeaderCustom/HeaderCustom.vue"; import HeaderCustom from "/components/HeaderCustom/HeaderCustom.vue";
import { import { useAuthStore, useUserStore } from "@/store";
useAuthStore,
useUserStore
} from "@/store";
import RPC from "@/utils/request"; import RPC from "@/utils/request";
const modal = ref(null); const modal = ref(null);
@ -122,8 +161,9 @@
// //
const selectedPlan = ref("season"); // const selectedPlan = ref("season"); //
const selectedPayment = ref("alipay"); // const selectedPayment = ref("wechat"); //
const paying = ref(false); const paying = ref(false);
const showAlipay = ref(true); //
// //
const selectPlan = (plan) => { 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 () => { const confirmPayment = async () => {
if (!selectedPlan.value) { if (!selectedPlan.value) {
@ -168,35 +309,116 @@
} }
paying.value = true; paying.value = true;
try { try {
const params = { // 1.
const orderParams = {
plan: selectedPlan.value, plan: selectedPlan.value,
planName: getPlanName(selectedPlan.value),
amount: getPlanPrice(selectedPlan.value),
paymentMethod: selectedPayment.value, paymentMethod: selectedPayment.value,
userId: userStore.userInfo?.id || "mock_user_id",
// #ifdef MP-WEIXIN
platform: "mp-weixin",
// #endif
// #ifdef H5
platform: "h5",
// #endif
}; };
// API uni.showLoading({
// const result = await RPC.post('/api/payment', params) 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({ uni.showToast({
title: "正在跳转支付...", title: "正在跳转支付页面...",
icon: "loading", icon: "loading",
duration: 2000, duration: 2000,
}); });
} else {
// //
setTimeout(() => {
uni.showToast({ uni.showToast({
title: "支付成功", title: "支付成功",
icon: "success", icon: "success",
}); });
paying.value = false;
}, 2000); //
setTimeout(() => {
//
uni.navigateTo({
url: `/pages/order-detail/order-detail?orderId=${orderResult.orderId}`,
});
//
// loadUserInfo();
}, 1500);
}
}
} catch (error) { } catch (error) {
uni.hideLoading();
console.error("支付失败:", error); console.error("支付失败:", error);
let errorMessage = "支付失败,请重试";
if (error.message === "用户取消支付") {
errorMessage = "支付已取消";
} else if (error.message) {
errorMessage = error.message;
}
uni.showToast({ uni.showToast({
title: "支付失败,请重试", title: errorMessage,
icon: "none", icon: "none",
}); });
} finally {
paying.value = false; paying.value = false;
} }
}; };
@ -207,6 +429,102 @@
url: "/pages/agreement/agreement", 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> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
@ -250,7 +568,6 @@
width: 100%; width: 100%;
height: 100%; height: 100%;
} }
} }
.user-details { .user-details {

Loading…
Cancel
Save