Lufaneng 11 months 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,51 +149,149 @@
</template>
<script setup>
import {
ref
} from "vue";
import HeaderCustom from "/components/HeaderCustom/HeaderCustom.vue";
import {
useAuthStore,
useUserStore
} from "@/store";
import RPC from "@/utils/request";
const modal = ref(null);
const authStore = useAuthStore();
const userStore = useUserStore();
//
const selectedPlan = ref("season"); //
const selectedPayment = ref("alipay"); //
const paying = ref(false);
//
const selectPlan = (plan) => {
import { ref, onMounted } from "vue";
import { onShow } from "@dcloudio/uni-app";
import HeaderCustom from "/components/HeaderCustom/HeaderCustom.vue";
import { useAuthStore, useUserStore } from "@/store";
import RPC from "@/utils/request";
const modal = ref(null);
const authStore = useAuthStore();
const userStore = useUserStore();
//
const selectedPlan = ref("season"); //
const selectedPayment = ref("wechat"); //
const paying = ref(false);
const showAlipay = ref(true); //
//
const selectPlan = (plan) => {
selectedPlan.value = plan;
};
};
//
const selectPayment = (payment) => {
//
const selectPayment = (payment) => {
selectedPayment.value = payment;
};
};
//
const editProfile = () => {
//
const editProfile = () => {
uni.navigateTo({
url: "/pagesA/edit-profile/edit-profile",
});
};
};
//
const recharge = () => {
//
const recharge = () => {
uni.navigateTo({
url: "/pages/recharge/recharge",
});
};
//
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 confirmPayment = async () => {
//
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) {
uni.showToast({
title: "请选择会员套餐",
@ -168,55 +309,232 @@
}
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;
}
};
};
//
const showAgreement = () => {
//
const showAgreement = () => {
uni.navigateTo({
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>
.container {
.container {
font-size: 14px;
background: linear-gradient(180deg, #7b9cdb 0%, #f8f8f8 40%);
padding-bottom: 120px;
}
}
.header {
.header {
padding: 20px 16px 16px;
.header-title {
@ -224,9 +542,9 @@
font-size: 18px;
font-weight: 500;
}
}
}
.user-card {
.user-card {
margin: 0 16px 16px;
background: white;
border-radius: 12px;
@ -250,7 +568,6 @@
width: 100%;
height: 100%;
}
}
.user-details {
@ -287,9 +604,9 @@
top: 10px;
right: 20px;
}
}
}
.balance-card {
.balance-card {
display: flex;
justify-content: space-between;
align-items: center;
@ -315,9 +632,9 @@
font-size: 28px;
font-weight: bold;
}
}
}
.membership-section {
.membership-section {
margin: 0 16px 16px;
.membership-grid {
@ -370,9 +687,9 @@
}
}
}
}
}
.payment-section {
.payment-section {
margin: 0 16px 24px;
.payment-item {
@ -406,9 +723,9 @@
}
}
}
}
}
.bottom-section {
.bottom-section {
position: fixed;
bottom: 0;
left: 0;
@ -427,5 +744,5 @@
color: #4285f4;
}
}
}
}
</style>
Loading…
Cancel
Save