feat:支付
This commit is contained in:
1 parent
056594e809
commit
184ba62d6f
6 files changed
+621
-186
No files matched your search
@@ -209,6 +209,13 @@
|
||||
{
|
||||
"root": "pages/profile",
|
||||
"pages": [
|
||||
{
|
||||
"path": "pay-result",
|
||||
"style": {
|
||||
"navigationBarTitleText": "支付结果",
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "userinfo",
|
||||
"style": {
|
||||
|
||||
+134
-101
@@ -10,8 +10,7 @@
|
||||
|
||||
<scroll-view style="height: calc(100dvh - 88px)" scroll-y>
|
||||
<view
|
||||
class="mx-4 p-4 rounded-2 bg-gradient-to-b from-#111 to-#222 b-4 b-solid b-t-#D29E52/60 b-l-#D29E52/40 b-r-#D29E52/40 b-b-#D29E52/20"
|
||||
>
|
||||
class="mx-4 p-4 rounded-2 bg-gradient-to-b from-#111 to-#222 b-4 b-solid b-t-#D29E52/60 b-l-#D29E52/40 b-r-#D29E52/40 b-b-#D29E52/20">
|
||||
<view class="text-color-theme-dark font-900 font-italic text-xl mb-1">VIP</view>
|
||||
<view class="flex-col-center mb-4">
|
||||
<view class="text-gray mb-2 text-xl font-900 font-italic tracking-1.5">
|
||||
@@ -25,20 +24,12 @@
|
||||
<view class="mt-3 px-4">
|
||||
<scroll-view scroll-x class="w-full" :show-scrollbar="false">
|
||||
<view class="flex">
|
||||
<view
|
||||
v-for="item in openTypeList"
|
||||
:key="item.id"
|
||||
class="mr-3 ml-1 my-1"
|
||||
@click="curOpenTypeId = item.id"
|
||||
>
|
||||
<view
|
||||
class="w-220rpx rounded-3 flex-col-center transition-all duration-200"
|
||||
:class="[
|
||||
curOpenTypeId === item.id
|
||||
? 'bg-#111 text-white b-3 b-solid b-#D29E52/60'
|
||||
: 'b-3 b-solid b-#333',
|
||||
]"
|
||||
>
|
||||
<view v-for="item in openTypeList" :key="item.id" class="mr-3 ml-1 my-1" @click="curOpenTypeId = item.id">
|
||||
<view class="w-220rpx rounded-3 flex-col-center transition-all duration-200" :class="[
|
||||
curOpenTypeId === item.id
|
||||
? 'bg-#111 text-white b-3 b-solid b-#D29E52/60'
|
||||
: 'b-3 b-solid b-#333',
|
||||
]">
|
||||
<view class="mt-2 text-sm text-#ffffff">{{ item.title }}</view>
|
||||
<view class="mt-1 text-lg font-900 text-color-theme-dark">
|
||||
¥{{ fen2yuan(item.preferentialPrice) }}
|
||||
@@ -59,18 +50,14 @@
|
||||
<view class="flex justify-between gap-3">
|
||||
<view
|
||||
class="flex-1 rounded-full flex-row-center px-4 py-2 b-3 b-solid b-#222 bg-#333 transition-all duration-200"
|
||||
:style="{ borderColor: payMethod === 'alipay' ? '#D29E52' : '' }"
|
||||
@click="payMethod = 'alipay'"
|
||||
>
|
||||
:style="{ borderColor: payMethod === 'alipay' ? '#D29E52' : '' }" @click="payMethod = 'alipay'">
|
||||
<image class="size-40rpx mr-2" src="@/static/alipay.png" mode="aspectFill" />
|
||||
<text>支付宝</text>
|
||||
</view>
|
||||
|
||||
<view
|
||||
class="flex-1 rounded-full flex-row-center px-4 py-2 b-3 b-solid b-#222 bg-#333 transition-all duration-200"
|
||||
:style="{ borderColor: payMethod === 'wechat' ? '#D29E52' : '' }"
|
||||
@click="payMethod = 'wechat'"
|
||||
>
|
||||
:style="{ borderColor: payMethod === 'wechat' ? '#D29E52' : '' }" @click="payMethod = 'wechat'">
|
||||
<image class="size-40rpx mr-2" src="@/static/weixin.png" mode="aspectFill" />
|
||||
<text>微信支付</text>
|
||||
</view>
|
||||
@@ -83,21 +70,15 @@
|
||||
<text class="text-color-theme-dark">《荷塘月色会员协议》</text>
|
||||
</view>
|
||||
|
||||
<view
|
||||
v-if="openTypeList.length"
|
||||
<view v-if="openTypeList.length"
|
||||
class="mt-4 w-2/3 mx-auto py-2 text-center rounded-full bg-color-theme-dark text-black text-sm active:bg-color-theme"
|
||||
@click="handleOpenVip"
|
||||
>
|
||||
@click="handleOpenVip">
|
||||
立即开通VIP
|
||||
</view>
|
||||
|
||||
<view class="mt-6 px-4">
|
||||
<view class="grid grid-cols-3 gap-2">
|
||||
<view
|
||||
v-for="(item, index) in benefits"
|
||||
:key="index"
|
||||
class="p-2 flex flex-col items-center"
|
||||
>
|
||||
<view v-for="(item, index) in benefits" :key="index" class="p-2 flex flex-col items-center">
|
||||
<view class="mb-1 size-120rpx rounded-full bg-#333 text-center line-height-120rpx">
|
||||
<uni-icons :type="item.icon" size="32" color="#d29e52"></uni-icons>
|
||||
</view>
|
||||
@@ -112,82 +93,134 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, ref } from 'vue';
|
||||
// @ts-ignore
|
||||
import { fen2yuan } from '@/sheep/hooks/useGoods';
|
||||
import { onLoad } from '@dcloudio/uni-app';
|
||||
import RecentApi from '@/sheep/api/member/recent';
|
||||
import { useMessage } from '@/uni_modules/wot-design-uni';
|
||||
// @ts-ignore
|
||||
import $store from '@/sheep/store';
|
||||
// @ts-ignore
|
||||
import PayOrderApi from '@/sheep/api/pay/order';
|
||||
// @ts-ignore
|
||||
import sheep from '@/sheep';
|
||||
import { computed, ref } from 'vue';
|
||||
// @ts-ignore
|
||||
import { fen2yuan } from '@/sheep/hooks/useGoods';
|
||||
import { onLoad, onShow } from '@dcloudio/uni-app';
|
||||
import RecentApi from '@/sheep/api/member/recent';
|
||||
import { useMessage } from '@/uni_modules/wot-design-uni';
|
||||
// @ts-ignore
|
||||
import $store from '@/sheep/store';
|
||||
// @ts-ignore
|
||||
import PayOrderApi from '@/sheep/api/pay/order';
|
||||
// @ts-ignore
|
||||
import sheep from '@/sheep';
|
||||
import { jumpToWechatMiniProgram } from '@/sheep/util/wechat-tool';
|
||||
|
||||
const messageBox = useMessage();
|
||||
const messageBox = useMessage();
|
||||
|
||||
interface OpenTypeItem {
|
||||
id: number;
|
||||
title: string;
|
||||
icon: string;
|
||||
preferentialPrice: number;
|
||||
originalPrice: number;
|
||||
duration: number;
|
||||
status: string;
|
||||
isHot: boolean;
|
||||
sort: number;
|
||||
createTime: number;
|
||||
interface OpenTypeItem {
|
||||
id: number;
|
||||
title: string;
|
||||
icon: string;
|
||||
preferentialPrice: number;
|
||||
originalPrice: number;
|
||||
duration: number;
|
||||
status: string;
|
||||
isHot: boolean;
|
||||
sort: number;
|
||||
createTime: number;
|
||||
}
|
||||
|
||||
const benefits: any = [
|
||||
{ icon: 'chat-filled', desc: '解锁微信', subDesc: '每天10个' },
|
||||
{ icon: 'chatboxes-filled', desc: '无限畅聊', subDesc: '每天10个' },
|
||||
{ icon: 'vip-filled', desc: '尊贵身份', subDesc: '专属标识' },
|
||||
{ icon: 'locked-filled', desc: '个人身份', subDesc: '安全保密' },
|
||||
{ icon: 'medal-filled', desc: '更多特权', subDesc: '敬请期待' },
|
||||
];
|
||||
const payMethodMap = [
|
||||
{
|
||||
title: "支付宝",
|
||||
payment: '',
|
||||
key: 'alipay'
|
||||
},
|
||||
{
|
||||
title: "微信支付",
|
||||
payment: 'wx_lite',
|
||||
key: 'wechat'
|
||||
}
|
||||
]
|
||||
const payMethod = ref<'alipay' | 'wechat'>('alipay'); // 支付方式:alipay / wechat
|
||||
const openTypeList = ref<OpenTypeItem[]>([]); // 会员类型列表
|
||||
const curOpenTypeId = ref<number>(); // 当前选择的会员类型id
|
||||
const currentOpenType = computed<OpenTypeItem | undefined>(() =>
|
||||
openTypeList.value?.find((item) => item.id === curOpenTypeId.value),
|
||||
); // 当前选择的会员类型
|
||||
|
||||
const benefits: any = [
|
||||
{ icon: 'chat-filled', desc: '解锁微信', subDesc: '每天10个' },
|
||||
{ icon: 'chatboxes-filled', desc: '无限畅聊', subDesc: '每天10个' },
|
||||
{ icon: 'vip-filled', desc: '尊贵身份', subDesc: '专属标识' },
|
||||
{ icon: 'locked-filled', desc: '个人身份', subDesc: '安全保密' },
|
||||
{ icon: 'medal-filled', desc: '更多特权', subDesc: '敬请期待' },
|
||||
];
|
||||
const payMethod = ref<'alipay' | 'wechat'>('alipay'); // 支付方式:alipay / wechat
|
||||
const openTypeList = ref<OpenTypeItem[]>([]); // 会员类型列表
|
||||
const curOpenTypeId = ref<number>(); // 当前选择的会员类型id
|
||||
const currentOpenType = computed<OpenTypeItem | undefined>(() =>
|
||||
openTypeList.value?.find((item) => item.id === curOpenTypeId.value),
|
||||
); // 当前选择的会员类型
|
||||
|
||||
onLoad(async () => {
|
||||
const { data = null } = await RecentApi.getMemberOpenTypeList();
|
||||
openTypeList.value = data ?? [];
|
||||
if (openTypeList.value && openTypeList.value[0]) {
|
||||
curOpenTypeId.value = openTypeList.value[0].id;
|
||||
onLoad(async (params) => {
|
||||
if (params) {
|
||||
if (params.openTypeId && params.payMethod) {
|
||||
payMethod.value = params.payMethod
|
||||
disposeWechatPay(params.openTypeId)
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
onShow(async () => {
|
||||
const { data = null } = await RecentApi.getMemberOpenTypeList();
|
||||
openTypeList.value = data ?? [];
|
||||
if (openTypeList.value && openTypeList.value[0]) {
|
||||
curOpenTypeId.value = openTypeList.value[0].id;
|
||||
}
|
||||
})
|
||||
|
||||
// 开通会员
|
||||
const handleOpenVip = () => {
|
||||
if (!curOpenTypeId.value || !currentOpenType.value?.id)
|
||||
return uni.showToast({ title: '请选择会员类型', icon: 'none' });
|
||||
// 开通会员
|
||||
const handleOpenVip = () => {
|
||||
if (!curOpenTypeId.value || !currentOpenType.value?.id) {
|
||||
uni.showToast({ title: '请选择会员类型', icon: 'none' });
|
||||
return
|
||||
}
|
||||
const payMethodItem = payMethodMap.find((item) => item.key === payMethod.value);
|
||||
if (!payMethodItem) {
|
||||
uni.showToast({ title: '请选择支付方式', icon: 'none' });
|
||||
return
|
||||
}
|
||||
if (!payMethodItem.payment) {
|
||||
uni.showToast({ title: `不支持${payMethodItem.title}支付`, icon: 'none' });
|
||||
return
|
||||
}
|
||||
messageBox
|
||||
.confirm({
|
||||
msg: '确认开通?',
|
||||
title: '提示',
|
||||
})
|
||||
.then(async () => {
|
||||
// #ifdef MP-WEIXIN
|
||||
disposeWechatPay(curOpenTypeId.value)
|
||||
// #endif
|
||||
// #ifndef MP-WEIXIN
|
||||
jumpToWechatPage()
|
||||
// #endif
|
||||
})
|
||||
.catch(() => { });
|
||||
};
|
||||
|
||||
messageBox
|
||||
.confirm({
|
||||
msg: '确认开通?',
|
||||
title: '提示',
|
||||
})
|
||||
.then(async () => {
|
||||
const { code, data } = await RecentApi.memberOpenTypePay({
|
||||
openTypeId: curOpenTypeId.value,
|
||||
});
|
||||
if (code !== 0) return uni.showToast({ title: '创建订单失败', icon: 'fail' });
|
||||
// 处理微信支付
|
||||
const disposeWechatPay = async (openTypeId: any) => {
|
||||
uni.showLoading({ title: '支付中...', mask: true });
|
||||
try {
|
||||
const { code, data } = await RecentApi.memberOpenTypePay({
|
||||
openTypeId: openTypeId,
|
||||
});
|
||||
console.log("开通vipId:", data);
|
||||
if (code !== 0) {
|
||||
uni.showToast({ title: '创建订单失败', icon: 'none' });
|
||||
throw new Error('创建订单失败');
|
||||
}
|
||||
sheep.$platform.pay(payMethod.value, 'recharge', data);
|
||||
// 更新用户信息
|
||||
$store('user').getInfo();
|
||||
uni.showToast({ title: '支付成功', icon: 'success' });
|
||||
} catch (error) {
|
||||
console.error("|处理微信支付|,意外的错误error:", error);
|
||||
}
|
||||
}
|
||||
|
||||
// const { data } = await PayOrderApi.getOrder(data, true);
|
||||
sheep.$platform.pay(payMethod.value, 'recharge', data.payOrderId);
|
||||
|
||||
// uni.showToast({ title: '开通成功', icon: 'success' });
|
||||
$store('user').getInfo();
|
||||
|
||||
// setTimeout(() => {
|
||||
// uni.navigateBack();
|
||||
// }, 500);
|
||||
})
|
||||
.catch(() => {});
|
||||
};
|
||||
// 跳转到微信小程序
|
||||
const jumpToWechatPage = () => {
|
||||
jumpToWechatMiniProgram("openVip", {
|
||||
openTypeId: curOpenTypeId.value,
|
||||
payMethod: payMethod.value
|
||||
})
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,313 @@
|
||||
<!-- 支付结果页面 -->
|
||||
<template>
|
||||
<wd-config-provider theme="dark">
|
||||
<wd-navbar title="支付结果" safeAreaInsetTop :bordered="false">
|
||||
<template #left>
|
||||
<navigator open-type="navigateBack" hover-class="navigator-hover">
|
||||
<uni-icons type="back" size="30" color="#D29E52"></uni-icons>
|
||||
</navigator>
|
||||
</template>
|
||||
</wd-navbar>
|
||||
<view class="flex-col justify-center items-center pay-result-box">
|
||||
<!-- 信息展示 -->
|
||||
<view class="pay-waiting m-b-30rpx" v-if="payResult === 'waiting'" />
|
||||
<view class="tip-text m-b-30rpx" v-if="payResult === 'success'">支付成功</view>
|
||||
<view class="tip-text m-b-30rpx" v-if="payResult === 'failed'">支付失败</view>
|
||||
<view class="tip-text m-b-30rpx" v-if="payResult === 'closed'">该订单已关闭</view>
|
||||
<view class="tip-text m-b-30rpx" v-if="payResult === 'waiting'">正在查询支付结果...</view>
|
||||
<view class="pay-total-num ss-flex" v-if="payResult === 'success'">
|
||||
<view>¥{{ fen2yuan(state.orderInfo.price) }}</view>
|
||||
</view>
|
||||
|
||||
<!-- 操作区 -->
|
||||
<view class="btn-box ss-flex ss-row-center ss-m-t-50">
|
||||
<view
|
||||
class="m-x-100rpx bg-color-theme-dark active_cl_bg-color-theme text-base text-center px-80rpx py-12rpx rounded-full"
|
||||
@tap="backHome">
|
||||
返回首页
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- #ifdef MP -->
|
||||
<view class="subscribe-box ss-flex ss-m-t-44" v-if="showSubscribeBtn && state.orderType === 'goods'">
|
||||
<image class="subscribe-img" :src="sheep.$url.static('/static/img/shop/order/cargo.png')" />
|
||||
<view class="subscribe-title ss-m-r-48 ss-m-l-16">获取实时发货信息与订单状态</view>
|
||||
<view class="subscribe-start" @tap="subscribeMessage">立即订阅</view>
|
||||
</view>
|
||||
<!-- #endif -->
|
||||
</view>
|
||||
</wd-config-provider>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { onHide, onLoad, onShow } from '@dcloudio/uni-app';
|
||||
import { computed, reactive, ref } from 'vue';
|
||||
import { isEmpty } from 'lodash-es';
|
||||
import sheep from '@/sheep';
|
||||
import PayOrderApi from '@/sheep/api/pay/order';
|
||||
import { fen2yuan } from '@/sheep/hooks/useGoods';
|
||||
import OrderApi from '@/sheep/api/trade/order';
|
||||
import { WxaSubscribeTemplate } from '@/sheep/helper/const';
|
||||
|
||||
const state = reactive({
|
||||
id: 0, // 支付单号
|
||||
orderType: 'goods', // 订单类型
|
||||
result: 'unpaid', // 支付状态
|
||||
orderInfo: {}, // 支付订单信息
|
||||
tradeOrder: {}, // 商品订单信息,只有在 orderType 为 goods 才会请求。目的:【我的拼团】按钮的展示
|
||||
counter: 0, // 获取结果次数
|
||||
});
|
||||
|
||||
// 支付结果 result => payResult
|
||||
const payResult = computed(() => {
|
||||
if (state.result === 'unpaid') {
|
||||
return 'waiting';
|
||||
}
|
||||
if (state.result === 'paid') {
|
||||
return 'success';
|
||||
}
|
||||
if (state.result === 'failed') {
|
||||
return 'failed';
|
||||
}
|
||||
if (state.result === 'closed') {
|
||||
return 'closed';
|
||||
}
|
||||
});
|
||||
|
||||
// 返回首页
|
||||
function backHome() {
|
||||
uni.switchTab({ url: "/pages/wechat-tabbar/index" })
|
||||
}
|
||||
|
||||
function showRepayModal() {
|
||||
if (state.result !== 'failed') return;
|
||||
uni.showModal({
|
||||
title: '确认支付',
|
||||
content: '未检测到您的支付结果,请确认您是否已经支付完成?',
|
||||
cancelText: '取消',
|
||||
confirmText: '我已支付',
|
||||
success: function (res) {
|
||||
if (res.confirm) {
|
||||
state.counter = 0;
|
||||
setTimeout(() => {
|
||||
getOrderInfo(state.id);
|
||||
}, 100);
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
// 获得订单信息
|
||||
async function getOrderInfo(id) {
|
||||
state.counter++;
|
||||
// 1. 加载订单信息
|
||||
const { data, code } = await PayOrderApi.getOrder(id, true);
|
||||
if (code === 0) {
|
||||
state.orderInfo = data;
|
||||
if (!state.orderInfo || state.orderInfo.status === 30) {
|
||||
// 支付关闭
|
||||
state.result = 'closed';
|
||||
return;
|
||||
}
|
||||
if (state.orderInfo.status !== 0) {
|
||||
// 非待支付,可能是已支付,可能是已退款
|
||||
state.result = 'paid';
|
||||
// #ifdef MP
|
||||
uni.showModal({
|
||||
title: '支付结果',
|
||||
showCancel: false, // 不要取消按钮
|
||||
content: '支付成功',
|
||||
success: () => {
|
||||
// 订阅只能由用户主动触发,只能包一层 showModal 诱导用户点击
|
||||
autoSubscribeMessage();
|
||||
},
|
||||
});
|
||||
|
||||
// #endif
|
||||
// 特殊:获得商品订单信息
|
||||
if (state.orderType === 'goods') {
|
||||
const { data, code } = await OrderApi.getOrderDetail(
|
||||
state.orderInfo.merchantOrderId,
|
||||
true,
|
||||
);
|
||||
if (code === 0) {
|
||||
state.tradeOrder = data;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
// 2.1 情况三一:未支付,且轮询次数小于五次,则继续轮询
|
||||
if (state.counter < 5 && state.result === 'unpaid') {
|
||||
setTimeout(() => {
|
||||
getOrderInfo(id);
|
||||
}, 2000);
|
||||
}
|
||||
// 2.2 情况二:超过五次检测才判断为支付失败
|
||||
if (state.counter >= 5) {
|
||||
state.result = 'failed';
|
||||
showRepayModal();
|
||||
}
|
||||
}
|
||||
|
||||
// #ifdef MP
|
||||
const showSubscribeBtn = ref(false); // 默认隐藏
|
||||
const SUBSCRIBE_BTN_STATUS_STORAGE_KEY = 'subscribe_btn_status';
|
||||
function subscribeMessage() {
|
||||
if (state.orderType !== 'goods') {
|
||||
return;
|
||||
}
|
||||
const event = [WxaSubscribeTemplate.TRADE_ORDER_DELIVERY];
|
||||
if (state.tradeOrder.type === 3) {
|
||||
event.push(WxaSubscribeTemplate.PROMOTION_COMBINATION_SUCCESS);
|
||||
}
|
||||
sheep.$platform.useProvider('wechat').subscribeMessage(event, () => {
|
||||
// 订阅后记录一下订阅状态
|
||||
uni.removeStorageSync(SUBSCRIBE_BTN_STATUS_STORAGE_KEY);
|
||||
uni.setStorageSync(SUBSCRIBE_BTN_STATUS_STORAGE_KEY, '已订阅');
|
||||
// 隐藏订阅按钮
|
||||
showSubscribeBtn.value = false;
|
||||
});
|
||||
}
|
||||
async function autoSubscribeMessage() {
|
||||
// 1. 校验是否手动订阅过
|
||||
const subscribeBtnStatus = uni.getStorageSync(SUBSCRIBE_BTN_STATUS_STORAGE_KEY);
|
||||
if (!subscribeBtnStatus) {
|
||||
showSubscribeBtn.value = true;
|
||||
return;
|
||||
}
|
||||
|
||||
// 2. 订阅消息
|
||||
subscribeMessage();
|
||||
}
|
||||
// #endif
|
||||
|
||||
onLoad(async (options) => {
|
||||
// 支付订单号
|
||||
if (options.id) {
|
||||
state.id = options.id;
|
||||
}
|
||||
// 订单类型
|
||||
if (options.orderType) {
|
||||
state.orderType = options.orderType;
|
||||
}
|
||||
|
||||
// 支付结果传值过来是失败,则直接显示失败界面
|
||||
if (options.payState === 'fail') {
|
||||
state.result = 'failed';
|
||||
} else {
|
||||
// 轮询五次检测订单支付结果
|
||||
await getOrderInfo(state.id);
|
||||
}
|
||||
});
|
||||
|
||||
onShow(() => {
|
||||
if (isEmpty(state.orderInfo)) {
|
||||
return;
|
||||
}
|
||||
getOrderInfo(state.id);
|
||||
});
|
||||
|
||||
onHide(() => {
|
||||
state.result = 'unpaid';
|
||||
state.counter = 0;
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@keyframes rotation {
|
||||
0% {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
.score-img {
|
||||
width: 36rpx;
|
||||
height: 36rpx;
|
||||
margin: 0 4rpx;
|
||||
}
|
||||
|
||||
.pay-result-box {
|
||||
padding: 60rpx 0;
|
||||
|
||||
.pay-waiting {
|
||||
margin-top: 20rpx;
|
||||
width: 60rpx;
|
||||
height: 60rpx;
|
||||
border: 10rpx solid rgb(233, 231, 231);
|
||||
border-bottom-color: rgb(204, 204, 204);
|
||||
border-radius: 50%;
|
||||
display: inline-block;
|
||||
// -webkit-animation: rotation 1s linear infinite;
|
||||
animation: rotation 1s linear infinite;
|
||||
}
|
||||
|
||||
.pay-img {
|
||||
width: 130rpx;
|
||||
height: 130rpx;
|
||||
}
|
||||
|
||||
.tip-text {
|
||||
font-size: 30rpx;
|
||||
font-weight: bold;
|
||||
color: #D29E52;
|
||||
}
|
||||
|
||||
.pay-total-num {
|
||||
font-size: 36rpx;
|
||||
font-weight: 500;
|
||||
color: #D29E52;
|
||||
font-family: OPPOSANS;
|
||||
}
|
||||
|
||||
.btn-box {
|
||||
width: 100%;
|
||||
|
||||
.back-btn {
|
||||
width: 190rpx;
|
||||
height: 70rpx;
|
||||
font-size: 28rpx;
|
||||
border: 2rpx solid #dfdfdf;
|
||||
border-radius: 35rpx;
|
||||
font-weight: 400;
|
||||
color: #595959;
|
||||
}
|
||||
|
||||
.check-btn {
|
||||
width: 190rpx;
|
||||
height: 70rpx;
|
||||
font-size: 28rpx;
|
||||
border: 2rpx solid #dfdfdf;
|
||||
border-radius: 35rpx;
|
||||
font-weight: 400;
|
||||
color: #595959;
|
||||
margin-left: 32rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.subscribe-box {
|
||||
.subscribe-img {
|
||||
width: 44rpx;
|
||||
height: 44rpx;
|
||||
}
|
||||
|
||||
.subscribe-title {
|
||||
font-weight: 500;
|
||||
font-size: 32rpx;
|
||||
line-height: 36rpx;
|
||||
color: #434343;
|
||||
}
|
||||
|
||||
.subscribe-start {
|
||||
color: var(--ui-BG-Main);
|
||||
font-weight: 700;
|
||||
font-size: 32rpx;
|
||||
line-height: 36rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
+112
-74
@@ -7,14 +7,8 @@
|
||||
</navigator>
|
||||
</template>
|
||||
<template #right>
|
||||
<navigator
|
||||
url="/pages/profile/recharge-record"
|
||||
open-type="navigate"
|
||||
hover-class="navigator-hover"
|
||||
>
|
||||
<view
|
||||
class="flex items-center rounded-full h-44rpx bg-color-theme py-1 px-2 text-black text-sm"
|
||||
>
|
||||
<navigator url="/pages/profile/recharge-record" open-type="navigate" hover-class="navigator-hover">
|
||||
<view class="flex items-center rounded-full h-44rpx bg-color-theme py-1 px-2 text-black text-sm">
|
||||
历史记录
|
||||
</view>
|
||||
</navigator>
|
||||
@@ -23,8 +17,7 @@
|
||||
|
||||
<scroll-view style="height: calc(100dvh - 88px)" scroll-y>
|
||||
<view
|
||||
class="mx-4 p-4 rounded-2 bg-gradient-to-b from-#111 to-#222 b-4 b-solid b-t-#D29E52/60 b-l-#D29E52/40 b-r-#D29E52/40 b-b-#D29E52/20"
|
||||
>
|
||||
class="mx-4 p-4 rounded-2 bg-gradient-to-b from-#111 to-#222 b-4 b-solid b-t-#D29E52/60 b-l-#D29E52/40 b-r-#D29E52/40 b-b-#D29E52/20">
|
||||
<view class="text-color-theme-dark font-900 font-italic text-xl mb-1">VIP</view>
|
||||
<view class="flex-col-center mb-4">
|
||||
<view class="text-gray mb-2 text-xl font-900 font-italic tracking-1.5">
|
||||
@@ -35,13 +28,7 @@
|
||||
</view>
|
||||
|
||||
<view class="flex-col-center gap-6 my-8 relative">
|
||||
<uni-icons
|
||||
class="absolute right-80 -top-10"
|
||||
type="reload"
|
||||
color="#D29E52"
|
||||
size="24"
|
||||
@click="getWallet"
|
||||
/>
|
||||
<uni-icons class="absolute right-80 -top-10" type="reload" color="#D29E52" size="24" @click="getWallet" />
|
||||
<view>余额(宝石)</view>
|
||||
<view class="font-bold text-xl">{{ fen2yuan(userWallet.balance) }}</view>
|
||||
</view>
|
||||
@@ -52,40 +39,28 @@
|
||||
<view class="flex justify-between gap-3">
|
||||
<view
|
||||
class="flex-1 rounded-full flex-row-center px-4 py-2 b-3 b-solid b-#222 bg-#333 transition-all duration-200"
|
||||
:style="{ borderColor: payMethod === 'alipay' ? '#D29E52' : '' }"
|
||||
@click="payMethod = 'alipay'"
|
||||
>
|
||||
:style="{ borderColor: payMethod === 'alipay' ? '#D29E52' : '' }" @click="payMethod = 'alipay'">
|
||||
<image class="size-40rpx mr-2" src="@/static/alipay.png" mode="aspectFill" />
|
||||
<text>支付宝</text>
|
||||
</view>
|
||||
|
||||
<view
|
||||
class="flex-1 rounded-full flex-row-center px-4 py-2 b-3 b-solid b-#222 bg-#333 transition-all duration-200"
|
||||
:style="{ borderColor: payMethod === 'wechat' ? '#D29E52' : '' }"
|
||||
@click="payMethod = 'wechat'"
|
||||
>
|
||||
:style="{ borderColor: payMethod === 'wechat' ? '#D29E52' : '' }" @click="payMethod = 'wechat'">
|
||||
<image class="size-40rpx mr-2" src="@/static/weixin.png" mode="aspectFill" />
|
||||
<text>微信支付</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view
|
||||
v-if="rechargePackag.length"
|
||||
v-for="item in rechargePackag"
|
||||
:key="item.id"
|
||||
class="mx-4 text-base"
|
||||
>
|
||||
<view v-if="rechargePackag.length" v-for="item in rechargePackag" :key="item.id" class="mx-4 text-base">
|
||||
<view class="flex justify-between items-center my-4">
|
||||
<view class="flex-row-center">
|
||||
<image class="size-60rpx mr-2" src="@/static/diamond.png" mode="scaleToFill" />
|
||||
<text>{{ fen2yuanSimple(item.bonusPrice) }}</text>
|
||||
<text class="text-xs ml-2">({{ item.name }})</text>
|
||||
</view>
|
||||
<text
|
||||
class="px-2 py-1 rounded-2 bg-color-theme-dark active:bg-color-theme"
|
||||
@click="handleRecharge(item)"
|
||||
>
|
||||
<text class="px-2 py-1 rounded-2 bg-color-theme-dark active:bg-color-theme" @click="handleRecharge(item)">
|
||||
¥{{ fen2yuanSimple(item.payPrice) }}
|
||||
</text>
|
||||
</view>
|
||||
@@ -97,51 +72,114 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, ref } from 'vue';
|
||||
// @ts-ignore
|
||||
import { fen2yuan, fen2yuanSimple } from '@/sheep/hooks/useGoods';
|
||||
import RecentApi from '@/sheep/api/member/recent';
|
||||
import { useMessage } from '@/uni_modules/wot-design-uni';
|
||||
import { onLoad } from '@dcloudio/uni-app';
|
||||
// @ts-ignore
|
||||
import sheep from '@/sheep';
|
||||
// @ts-ignore
|
||||
import PayOrderApi from '@/sheep/api/pay/order';
|
||||
import { computed, ref } from 'vue';
|
||||
// @ts-ignore
|
||||
import { fen2yuan, fen2yuanSimple } from '@/sheep/hooks/useGoods';
|
||||
import RecentApi from '@/sheep/api/member/recent';
|
||||
import { useMessage } from '@/uni_modules/wot-design-uni';
|
||||
import { onLoad, onShow } from '@dcloudio/uni-app';
|
||||
// @ts-ignore
|
||||
import sheep from '@/sheep';
|
||||
// @ts-ignore
|
||||
import PayOrderApi from '@/sheep/api/pay/order';
|
||||
import { jumpToWechatMiniProgram } from '@/sheep/util/wechat-tool';
|
||||
|
||||
const messageBox = useMessage();
|
||||
const messageBox = useMessage();
|
||||
|
||||
const payMethod = ref<'alipay' | 'wechat'>('alipay'); // 支付方式:alipay / wechat
|
||||
// 充值套餐列表
|
||||
const rechargePackag = ref<{ id: number; name: string; payPrice: number; bonusPrice: number }[]>(
|
||||
[],
|
||||
);
|
||||
const userWallet = computed(() => sheep.$store('user').userWallet);
|
||||
const payMethodMap = [
|
||||
{
|
||||
title: "支付宝",
|
||||
payment: '',
|
||||
key: 'alipay'
|
||||
},
|
||||
{
|
||||
title: "微信支付",
|
||||
payment: 'wx_lite',
|
||||
key: 'wechat'
|
||||
}
|
||||
]
|
||||
|
||||
onLoad(async () => {
|
||||
const { data } = await RecentApi.getWalletRechargePackage();
|
||||
rechargePackag.value = data ?? [];
|
||||
});
|
||||
const payMethod = ref<'alipay' | 'wechat'>('alipay'); // 支付方式:alipay / wechat
|
||||
// 充值套餐列表
|
||||
const rechargePackag = ref<{ id: number; name: string; payPrice: number; bonusPrice: number }[]>(
|
||||
[],
|
||||
);
|
||||
const userWallet = computed(() => sheep.$store('user').userWallet);
|
||||
|
||||
const getWallet = () => {
|
||||
sheep.$store('user').getWallet();
|
||||
};
|
||||
onLoad((params) => {
|
||||
if (params) {
|
||||
if (params.packageId && params.payMethod) {
|
||||
payMethod.value = params.payMethod
|
||||
disposeWechatPay(params.packageId)
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
const handleRecharge = (item: any) => {
|
||||
if (!item.id) return uni.showToast({ title: '请选择会员类型', icon: 'none' });
|
||||
messageBox
|
||||
.confirm({
|
||||
msg: `确认购买套餐 ${fen2yuanSimple(item.payPrice)} 元?`,
|
||||
title: '提示',
|
||||
})
|
||||
.then(async () => {
|
||||
const { code, data } = await RecentApi.walletRecharge({ packageId: item.id });
|
||||
if (code !== 0) return uni.showToast({ title: '创建订单失败', icon: 'fail' });
|
||||
// const { data } = await PayOrderApi.getOrder(data.payOrderId, true);
|
||||
sheep.$platform.pay(payMethod.value, 'recharge', data.payOrderId);
|
||||
onShow(async () => {
|
||||
const { data } = await RecentApi.getWalletRechargePackage();
|
||||
rechargePackag.value = data ?? [];
|
||||
})
|
||||
|
||||
// uni.showToast({ title: '购买成功', icon: 'success' });
|
||||
getWallet();
|
||||
})
|
||||
.catch(() => {});
|
||||
};
|
||||
const getWallet = () => {
|
||||
sheep.$store('user').getWallet();
|
||||
};
|
||||
|
||||
const handleRecharge = (item: any) => {
|
||||
if (!item.id) {
|
||||
uni.showToast({ title: '请选择会员类型', icon: 'none' });
|
||||
return
|
||||
}
|
||||
const payMethodItem = payMethodMap.find((item) => item.key === payMethod.value);
|
||||
if (!payMethodItem) {
|
||||
uni.showToast({ title: '请选择支付方式', icon: 'none' });
|
||||
return
|
||||
}
|
||||
if (!payMethodItem.payment) {
|
||||
uni.showToast({ title: `不支持${payMethodItem.title}支付`, icon: 'none' });
|
||||
return
|
||||
}
|
||||
messageBox
|
||||
.confirm({
|
||||
msg: `确认购买套餐 ${fen2yuanSimple(item.payPrice)} 元?`,
|
||||
title: '提示',
|
||||
})
|
||||
.then(async () => {
|
||||
// #ifdef MP-WEIXIN
|
||||
disposeWechatPay(item.id)
|
||||
// #endif
|
||||
// #ifndef MP-WEIXIN
|
||||
jumpToWechatPage(item.id)
|
||||
// #endif
|
||||
})
|
||||
.catch(() => { });
|
||||
};
|
||||
|
||||
// 处理微信支付
|
||||
const disposeWechatPay = async (packageId: any) => {
|
||||
uni.showLoading({ title: '支付中...', mask: true });
|
||||
try {
|
||||
const { code, data } = await RecentApi.walletRecharge({ packageId: packageId });
|
||||
console.log("发起订单id,data:", data);
|
||||
if (code !== 0) {
|
||||
uni.showToast({ title: '创建订单失败', icon: 'none' });
|
||||
throw new Error()
|
||||
}
|
||||
sheep.$platform.pay(payMethod.value, 'recharge', data.payOrderId);
|
||||
// 更新用户钱包
|
||||
getWallet();
|
||||
uni.showToast({ title: '支付成功', icon: 'success' });
|
||||
} catch (error) {
|
||||
console.error("|处理微信支付|,意外的错误error:", error);
|
||||
} finally {
|
||||
uni.hideLoading();
|
||||
}
|
||||
}
|
||||
|
||||
// 跳转到微信小程序
|
||||
const jumpToWechatPage = (packageId: any) => {
|
||||
jumpToWechatMiniProgram("recharge", {
|
||||
packageId,
|
||||
payMethod: payMethod.value
|
||||
})
|
||||
}
|
||||
</script>
|
||||
@@ -150,9 +150,8 @@ export default class SheepPay {
|
||||
async wechatWapPay() {
|
||||
const { error, data } = await this.prepay();
|
||||
if (error === 0) {
|
||||
const redirect_url = `${getRootUrl()}pages/pay/result?id=${this.id}&payment=${
|
||||
this.payment
|
||||
}&orderType=${this.orderType}`;
|
||||
const redirect_url = `${getRootUrl()}pages/pay/result?id=${this.id}&payment=${this.payment
|
||||
}&orderType=${this.orderType}`;
|
||||
location.href = `${data.pay_data.h5_url}&redirect_url=${encodeURIComponent(redirect_url)}`;
|
||||
}
|
||||
}
|
||||
@@ -265,13 +264,13 @@ export default class SheepPay {
|
||||
|
||||
// 解析支付参数
|
||||
let payConfig = JSON.parse(data.displayContent);
|
||||
if(typeof payConfig.appId === 'undefined'){
|
||||
if (typeof payConfig.appId === 'undefined') {
|
||||
payConfig.appId = payConfig.appid;
|
||||
}
|
||||
if(typeof payConfig.nonceStr === 'undefined'){
|
||||
if (typeof payConfig.nonceStr === 'undefined') {
|
||||
payConfig.nonceStr = payConfig.noncestr;
|
||||
}
|
||||
if(typeof payConfig.timeStamp === 'undefined'){
|
||||
if (typeof payConfig.timeStamp === 'undefined') {
|
||||
payConfig.timeStamp = payConfig.timestamp;
|
||||
}
|
||||
// 调用微信支付
|
||||
@@ -378,11 +377,8 @@ export function getPayMethods(channels) {
|
||||
|
||||
// 支付结果跳转,success:成功,fail:失败
|
||||
export function goPayResult(id, orderType, resultType) {
|
||||
sheep.$router.redirect('/pages/pay/result', {
|
||||
id,
|
||||
orderType,
|
||||
payState: resultType,
|
||||
});
|
||||
const url = `/pages/pay/result?id=${id}&orderType=${orderType}&payState=${resultType}`;
|
||||
uni.redirectTo({ url: url })
|
||||
}
|
||||
|
||||
export function goBindWeixin() {
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
// @ts-nocheck
|
||||
import { isEmpty } from 'lodash-es';
|
||||
|
||||
const targetAppId = 'wx2b4e4d3feff8267f';
|
||||
|
||||
const paramsToQuery = (params: Record<string, any>) => {
|
||||
if (isEmpty(params)) {
|
||||
return '';
|
||||
}
|
||||
let query = [];
|
||||
for (let key in params) {
|
||||
query.push(key + '=' + params[key]);
|
||||
}
|
||||
return query.join('&');
|
||||
}
|
||||
|
||||
export const jumpToWechatMiniProgram = (
|
||||
action: 'recharge' | 'openVip',
|
||||
params: Record<string, any>,
|
||||
) => {
|
||||
let path = '';
|
||||
if (action === 'recharge') {
|
||||
path = 'pages/profile/recharge';
|
||||
}
|
||||
if (action === 'openVip') {
|
||||
path = 'pages/profile/apply-vip';
|
||||
}
|
||||
if (params) {
|
||||
path += `?${paramsToQuery(params)}`;
|
||||
}
|
||||
console.info(`跳转到appId:${targetAppId},page:${path}`);
|
||||
return new Promise((resolve, reject) => {
|
||||
uni.navigateToMiniProgram({
|
||||
appId: targetAppId,
|
||||
path: path,
|
||||
envVersion: 'release',
|
||||
success(res) {
|
||||
console.log('跳转成功', res);
|
||||
resolve(res);
|
||||
},
|
||||
fail(res) {
|
||||
console.log('跳转失败', res);
|
||||
reject(res);
|
||||
},
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user