Files
taimed-international-app/pages/user/recharge/index.vue

540 lines
12 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<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">618充值活动</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: '生成订单中...' })
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失败了');
// 初始化失败
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: '请求失败,请检查您的网络',
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: '支付失败', 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: '即将返回我的页面', 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: 16rpx;
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: 100%;
height: 50rpx;
line-height: 50rpx;
background-color: #007bff;
color: #ffffff;
font-size: 18rpx;
border-radius: 25rpx;
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 20rpx 60rpx 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: 18rpx;
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>