544 lines
12 KiB
Vue
544 lines
12 KiB
Vue
<template>
|
||
<view class="recharge-page">
|
||
<!-- 自定义导航栏 -->
|
||
<nav-bar :title="$t('order.recharge')"></nav-bar>
|
||
<view class="block">
|
||
<view class="text">{{$t('order.rechargeAmount')}}</view>
|
||
<view class="recharge">
|
||
<view class="recharge_block" @click="chosPric(item)"
|
||
:class="aloneItem.priceTypeId === item.priceTypeId ? 'selected' : ''"
|
||
v-for="item in rechargeList.bookBuyConfigList" :key="item.priceTypeId">
|
||
<view class="recharge_money">¥{{item.realMoney}}</view>
|
||
<view>{{item.money}}{{ $t('global.coin') }}</view>
|
||
<!-- 红框位置的618活动标签 -->
|
||
<!-- <view class="activity-tag">618活动</view> -->
|
||
<span class="activity-label" v-if="item.givejf >0">{{item.description}}</span>
|
||
<text class="recharge_give" v-if="item.givejf >0">(赠{{item.givejf}}币)</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<view class="activity-container">
|
||
<view v-html="remark.remark"></view>
|
||
</view>
|
||
<view class="cha_fangsh">
|
||
<view class="cf_title PM_font">{{$t('user.paymentMethod')}}</view>
|
||
<view class="cf_radio">
|
||
<radio-group v-for="item in iosPaylist">
|
||
<view style="width: 100%">
|
||
<view :class="payType == item.id ? 'Tab_xf cf_xuanx' : 'cf_xuanx'">
|
||
<!-- <image class="pay_item_img" :src="item.imgUrl" mode="aspectFil">
|
||
</image> -->
|
||
<text>{{ item.title }}</text>
|
||
<radio :checked="payType === item.id" @click="choseType(item.id)"></radio>
|
||
</view>
|
||
</view>
|
||
</radio-group>
|
||
</view>
|
||
</view>
|
||
<view class="agree_wo flexbox">
|
||
<radio-group class="agree" v-for="(item, index) in argee" :key="index">
|
||
<view>
|
||
<radio class="agreeRadio" :value="item.id" :checked="state" color="#007bff" @click="radioCheck"></radio>
|
||
</view>
|
||
</radio-group>
|
||
<view>{{$t('order.readAgree')}}<span class="highlight"
|
||
@click="showAgreement">《{{$t('order.valueAddedServices')}}》</span></view>
|
||
</view>
|
||
<view class="bottom-button-container">
|
||
<button class="recharge-button" @click="handleRecharge">{{$t('order.recharge')}}</button>
|
||
</view>
|
||
<wd-popup v-model="agreemenState" position="bottom" :closeable="true">
|
||
<view class="agreement">
|
||
<view class="agreement_title">{{ agreementObj.title }}</view>
|
||
<view class="agreement_row">
|
||
<view v-html="agreementObj.content"></view>
|
||
</view>
|
||
</view>
|
||
</wd-popup>
|
||
|
||
<wd-message-box />
|
||
</view>
|
||
</template>
|
||
|
||
<script setup lang="ts">
|
||
import { ref, computed, onMounted, toRefs, reactive } from 'vue'
|
||
import { useI18n } from 'vue-i18n'
|
||
import { useMessage } from '@/uni_modules/wot-design-uni'
|
||
import { getBookBuyConfigList, getAgreement, getActivityDescription, verifyGooglePay, getPlaceOrder } from '@/api/modules/user'
|
||
import { useUserStore } from '@/stores/user'
|
||
import { useThrottle } from '@/hooks/useThrottle';
|
||
|
||
const googlePay = uni.requireNativePlugin("sn-googlepay5");
|
||
const userStore = useUserStore()
|
||
const { t } = useI18n()
|
||
const message = useMessage()
|
||
const payType = ref('1')
|
||
const iosPaylist = ref([
|
||
{
|
||
title: "Google Pay",
|
||
id: '1',
|
||
// imgUrl: "/static/icon/currency.png"
|
||
}
|
||
])
|
||
// 充值列表
|
||
const rechargeList = ref([])
|
||
// 金额列表单独每项
|
||
const aloneItem = ref({})
|
||
|
||
// 充值列表type-固定传值
|
||
const type = ref('point')
|
||
|
||
const qudao = ref('')
|
||
const state = ref(false)
|
||
const argee = ref([
|
||
{
|
||
value: false,
|
||
id: "1",
|
||
},
|
||
])
|
||
|
||
const popup = ref(null)
|
||
const agreemenState = ref(false)
|
||
// 协议id
|
||
const id = ref(101)
|
||
|
||
const richTextContent = ref('');
|
||
// 协议数据
|
||
const agreementObj = reactive({
|
||
title: '',
|
||
content: '',
|
||
})
|
||
const isAndroid = ref()
|
||
|
||
const remark = ref({})
|
||
const isConnected = ref(false)
|
||
const purchaseToken = ref()
|
||
// 订单编号
|
||
const orderSn = ref('')
|
||
|
||
|
||
/**
|
||
* 获取使用环境
|
||
*/
|
||
const getDevName = () => {
|
||
if (uni.getSystemInfoSync().platform === "android") {
|
||
qudao.value = 'Google'
|
||
isAndroid.value = true;
|
||
console.log('运行Android上')
|
||
} else {
|
||
qudao.value = 'Google'
|
||
console.log('运行iOS上')
|
||
}
|
||
getData()
|
||
}
|
||
|
||
/**
|
||
* 获取充值列表数据
|
||
*/
|
||
const getData = async () => {
|
||
try {
|
||
rechargeList.value = await getBookBuyConfigList(type.value, qudao.value)
|
||
console.log(rechargeList.value.bookBuyConfigList, '充值列表');
|
||
// 默认选择第一个金额
|
||
aloneItem.value = rechargeList.value.bookBuyConfigList[0]
|
||
} catch (error) {
|
||
console.error('获取订单列表失败:', error)
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 点击支付按钮
|
||
*/
|
||
|
||
const paymentButton = async () => {
|
||
if (!state.value) {
|
||
uni.showToast({
|
||
title: t('order.readAgreeServices'),
|
||
icon: 'none'
|
||
})
|
||
return
|
||
}
|
||
getPlaceOrderObj()
|
||
}
|
||
// 节流支付按钮
|
||
const handleRecharge = useThrottle(paymentButton);
|
||
|
||
/**
|
||
* 获取订单编号
|
||
*/
|
||
const getPlaceOrderObj = async () => {
|
||
const { priceTypeId, realMoney, money } = toRefs(aloneItem.value)
|
||
const data = {
|
||
userId: userStore.userInfo.id, // 用户di
|
||
paymentMethod: '5', //支付方式4point 5google
|
||
orderMoney: money.value, //订单金额
|
||
realMoney: realMoney.value, //实际金额
|
||
come: '10', //订单来源 2医学吴门医述 10海外读书
|
||
orderType: 'point', //订单类型, point充值、order课程、书、vip 课vip、abroadVip 书vip、relearn 复读、trainingClass 培训班
|
||
productId: priceTypeId.value // 商品id
|
||
}
|
||
try {
|
||
// uni.hideLoading()
|
||
const res = await getPlaceOrder(data)
|
||
orderSn.value = res.orderSn
|
||
console.log(orderSn.value, '获取订单号');
|
||
uni.showLoading({ title: t('order.orderCreating') })
|
||
getGooglePay()
|
||
} catch (error) {
|
||
console.error('获取订单号失败', error)
|
||
}
|
||
}
|
||
|
||
// 点击金额
|
||
const chosPric = (item : any) => {
|
||
console.log(item, '金额每项');
|
||
aloneItem.value = item;
|
||
};
|
||
|
||
/**
|
||
* 勾选协议
|
||
*/
|
||
const radioCheck = () => {
|
||
state.value = !state.value
|
||
console.log('点击了', state.value);
|
||
}
|
||
|
||
/**
|
||
* 协议弹窗显示
|
||
*/
|
||
const showAgreement = () => {
|
||
agreemenState.value = true
|
||
}
|
||
|
||
/**
|
||
* 初始化
|
||
*/
|
||
const getGooglePay = () => {
|
||
googlePay.init({
|
||
}, (e : any) => {
|
||
console.log('init', e);
|
||
if (e.code == 0) {
|
||
isConnected.value = true;
|
||
console.log('init成功了');
|
||
getQuerySku()
|
||
// 初始化成功
|
||
} else {
|
||
console.log('init失败了');
|
||
uni.showToast({
|
||
title: '设备上无法使用计费服务',
|
||
icon: 'fail'
|
||
})
|
||
// 初始化失败
|
||
isConnected.value = false;
|
||
}
|
||
});
|
||
}
|
||
|
||
/**
|
||
* 查询sku
|
||
*/
|
||
const getQuerySku = () => {
|
||
const id = aloneItem.value.priceTypeId
|
||
console.log(id, '获取每项');
|
||
googlePay.querySku(
|
||
{
|
||
inapp: [id], // 与subs二选一, 参数为商品ID(字符串)数组
|
||
},
|
||
(e : any) => {
|
||
if (e.code == 0) {
|
||
// 查询成功.
|
||
console.log('querySku查询成功', e);
|
||
getPayAll()
|
||
uni.hideLoading()
|
||
} else {
|
||
console.log('查询失败', e);
|
||
uni.showToast({
|
||
title: t('global.networkConnectionError'),
|
||
icon: 'error'
|
||
})
|
||
}
|
||
}
|
||
)
|
||
}
|
||
|
||
/**
|
||
* 发起支付
|
||
*/
|
||
const getPayAll = () => {
|
||
console.log(aloneItem.value.priceTypeId, orderSn.value, '发起支付传入产品id,订单id');
|
||
googlePay.payAll(
|
||
{
|
||
productId: aloneItem.value.priceTypeId, // 产品id
|
||
accountId: orderSn.value // 订单编号
|
||
},
|
||
(e : any) => {
|
||
if (e.code == 0) {
|
||
purchaseToken.value = e.data[0].original.purchaseToken
|
||
// 支付成功
|
||
console.log(e, 'payAll方法成功返参');
|
||
getConsume()
|
||
} else {
|
||
uni.showToast({ title: t('user.paymentFailed'), icon: 'error' })
|
||
console.log(e, 'e');
|
||
// 支付失败
|
||
}
|
||
},
|
||
)
|
||
}
|
||
|
||
/**
|
||
* 消耗品 确认交易
|
||
*/
|
||
const getConsume = () => {
|
||
googlePay.consume(
|
||
{
|
||
purchaseToken: purchaseToken.value, // 来自支付结果的original.purchaseToken (或 original.token)
|
||
},
|
||
(e : any) => {
|
||
if (e.code == 0) {
|
||
console.log(e, '确认交易成功');
|
||
uni.showToast({ title: t('user.returnMine'), icon: 'none' })
|
||
// 确认成功
|
||
googleVerify()
|
||
} else {
|
||
console.log(e, '确认交易失败');
|
||
// 确认失败
|
||
}
|
||
},
|
||
);
|
||
}
|
||
|
||
/**
|
||
* 校验订单
|
||
*/
|
||
const googleVerify = async () => {
|
||
uni.hideLoading()
|
||
console.log(typeof aloneItem.value.priceTypeId, typeof purchaseToken.value, typeof orderSn.value);
|
||
try {
|
||
const obj = await verifyGooglePay(aloneItem.value.priceTypeId, purchaseToken.value, orderSn.value)
|
||
uni.switchTab({
|
||
url: '/pages/user/index'
|
||
})
|
||
console.log(obj, '校验订单');
|
||
} catch (error) {
|
||
console.error('校验订单失败:', error)
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 获取协议数据
|
||
*/
|
||
const getAgreementData = async () => {
|
||
try {
|
||
const text = reactive(await getAgreement(id.value))
|
||
const { title, content } = toRefs(text.agreement)
|
||
agreementObj.title = title.value
|
||
agreementObj.content = content.value.replace(/<\/h5>/g, "</view>");
|
||
// console.log(agreementObj, '协议数据');
|
||
} catch (error) {
|
||
console.error('获取协议数据:', error)
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 获取活动说明数据
|
||
*/
|
||
const getActivityDescriptionData = async () => {
|
||
try {
|
||
const text = ref(await getActivityDescription())
|
||
remark.value = text.value.res[0]
|
||
// console.log(remark.value, '活动说明内容');
|
||
|
||
} catch (error) {
|
||
console.error('获取协议数据:', error)
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 切换支付方式
|
||
*/
|
||
const choseType = () => {
|
||
// payType.value = val;
|
||
}
|
||
|
||
onMounted(() => {
|
||
getDevName();
|
||
getActivityDescriptionData()
|
||
getAgreementData()
|
||
})
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
$theme-color: #54a966;
|
||
|
||
.recharge-page {
|
||
min-height: 100vh;
|
||
background-color: #f7faf9;
|
||
}
|
||
|
||
.text {
|
||
font-size: 30rpx;
|
||
color: #007bff;
|
||
padding: 30rpx 0 20rpx 20rpx;
|
||
}
|
||
|
||
.recharge {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
padding: 20rpx 0 20rpx 30rpx;
|
||
|
||
.recharge_block {
|
||
box-shadow: 0 0 20rpx 0 #0000001a;
|
||
float: left;
|
||
width: 46%;
|
||
margin: 0 3% 30rpx 0;
|
||
text-align: center;
|
||
padding: 30rpx 0 0;
|
||
border-radius: 15rpx;
|
||
position: relative;
|
||
height: 160rpx;
|
||
|
||
.recharge_money {
|
||
font-size: 30rpx;
|
||
margin-bottom: 10rpx;
|
||
|
||
}
|
||
|
||
.recharge_give {
|
||
font-size: 20rpx;
|
||
color: #FF0033;
|
||
}
|
||
}
|
||
}
|
||
|
||
.selected {
|
||
border: 2rpx solid #007bff;
|
||
color: #007bff;
|
||
}
|
||
|
||
.bottom-button-container {
|
||
position: fixed;
|
||
bottom: 0;
|
||
left: 0;
|
||
right: 0;
|
||
padding: 30rpx;
|
||
background-color: #ffffff;
|
||
border-top: 1px solid #f0f0f0;
|
||
z-index: 999;
|
||
}
|
||
|
||
.recharge-button {
|
||
width: 60%;
|
||
height: 50rpx;
|
||
line-height: 50rpx;
|
||
background-color: #007bff;
|
||
color: #ffffff;
|
||
font-size: 30rpx;
|
||
border-radius: 30rpx;
|
||
border: none;
|
||
}
|
||
|
||
.recharge-button::after {
|
||
border: none;
|
||
}
|
||
|
||
.activity-container {
|
||
margin: 0 20rpx 20rpx 20rpx;
|
||
padding: 15rpx;
|
||
background-color: #e6f4ff;
|
||
border-radius: 8rpx;
|
||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
||
}
|
||
|
||
.activity-label {
|
||
position: absolute;
|
||
top: -10rpx;
|
||
right: -6rpx;
|
||
font-size: 16rpx;
|
||
font-weight: 600;
|
||
color: #ffffff;
|
||
background-color: #007bff;
|
||
border-radius: 16rpx 0;
|
||
padding: 6rpx 10rpx;
|
||
letter-spacing: 0.5rpx;
|
||
}
|
||
|
||
.cha_fangsh {
|
||
padding: 20rpx;
|
||
|
||
.cf_title {
|
||
font-size: 30rpx;
|
||
color: #007bff;
|
||
}
|
||
|
||
.cf_radio {
|
||
margin-top: 20rpx;
|
||
|
||
.cf_xuanx {
|
||
font-size: 24rpx;
|
||
padding: 10rpx 0;
|
||
margin-bottom: 20rpx;
|
||
border-bottom: 1px solid #ededed;
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
|
||
image {
|
||
width: 40rpx;
|
||
height: 40rpx;
|
||
display: inline-block;
|
||
margin-right: 20rpx;
|
||
vertical-align: bottom;
|
||
}
|
||
}
|
||
|
||
.Tab_xf {
|
||
// background-color: #fdf1e9cc;
|
||
}
|
||
}
|
||
}
|
||
|
||
.pay_item_img {
|
||
width: 50rpx;
|
||
height: 50rpx;
|
||
float: left;
|
||
margin-right: 20rpx;
|
||
}
|
||
|
||
|
||
.agree_wo {
|
||
display: flex;
|
||
padding: 20rpx 20rpx 160rpx 20rpx;
|
||
color: #aaa;
|
||
font-size: 26rpx;
|
||
align-items: center;
|
||
|
||
.highlight {
|
||
color: #007bff;
|
||
}
|
||
}
|
||
|
||
|
||
.agreeRadio {
|
||
display: flex;
|
||
zoom: 0.7;
|
||
}
|
||
|
||
.agreement {
|
||
padding: 40rpx 30rpx 40rpx 30rpx;
|
||
position: relative;
|
||
|
||
.agreement_title {
|
||
font-size: 32rpx;
|
||
margin-bottom: 50rpx;
|
||
color: #555;
|
||
text-align: center;
|
||
font-weight: bold;
|
||
}
|
||
|
||
.agreement_row {
|
||
max-height: 1000rpx;
|
||
overflow-y: scroll
|
||
}
|
||
}
|
||
</style> |