433 lines
9.6 KiB
Vue
433 lines
9.6 KiB
Vue
<template>
|
||
<view class="view-page" :style="{backgroundImage: `url('${ThemeData ? ThemeData.app_bg : baseBgUrl }')`}">
|
||
<navBar :style="{marginTop: `${statusBarHeight}${uni.getSystemInfoSync().platform === 'ios' ? 'px': 'dp'}`}"
|
||
:navTitle="'羽声充值'" :isLeftSlot="true">
|
||
</navBar>
|
||
<view class="content">
|
||
<view class="">
|
||
<uni-easyinput prefixIcon="search" clearSize="18" v-model="searchValue" placeholder="请输入您在羽声语音的ID">
|
||
</uni-easyinput>
|
||
</view>
|
||
<view class="show_ByIdView">
|
||
<view class="">
|
||
余额
|
||
</view>
|
||
<view class="">
|
||
金币
|
||
</view>
|
||
</view>
|
||
<view class="coinWrap">
|
||
<view
|
||
class="coinBox"
|
||
:class="{ 'selected': selectedIndex === index }"
|
||
v-for="(ele, index) in moneyList"
|
||
:key="index"
|
||
@click="selectAmount(index)"
|
||
>
|
||
<view class="w-fill coin">
|
||
<img style="width: 40rpx;height: 40rpx;" :src="Coin" alt="" />{{ele.coin}}
|
||
</view>
|
||
<view class="w-fill money">
|
||
¥{{ele.money}}
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<view class="text-wrap">
|
||
<view class="" style="margin-bottom: 20rpx;">
|
||
充值小贴士:
|
||
</view>
|
||
<view class="font-24" style="margin-bottom: 20rpx;">
|
||
1.为避免您的账号及资金被冻结,请勿通过非官方渠道 充值,谨防上当受损!
|
||
</view>
|
||
<view class="font-24">
|
||
2.充值前请确定您已满18周岁
|
||
</view>
|
||
</view>
|
||
|
||
<view class="pay-button-wrap">
|
||
<button
|
||
class="pay-button"
|
||
:class="{ 'disabled': selectedIndex === -1 || isPaying || !isAgreed }"
|
||
:disabled="selectedIndex === -1 || isPaying || !isAgreed"
|
||
@click="handlePay"
|
||
>
|
||
{{ isPaying ? '支付中...' : '立即支付' }}
|
||
</button>
|
||
<view class="agreement-wrap">
|
||
<checkbox-group @change="handleAgreementChange">
|
||
<label class="agreement-label">
|
||
<checkbox
|
||
:checked="isAgreed"
|
||
color="#3ABC6D"
|
||
style="transform: scale(0.8);"
|
||
/>
|
||
<text class="agreement-text">我已阅读并同意</text>
|
||
<text class="agreement-link" @click.stop="showAgreement">《充值协议》</text>
|
||
</label>
|
||
</checkbox-group>
|
||
</view>
|
||
|
||
</view>
|
||
|
||
</view>
|
||
</view>
|
||
</template>
|
||
|
||
<script>
|
||
import config from '@/until/config.js';
|
||
import navBar from '@/component/nav.vue';
|
||
import Coin from '@/static/image/income/coin.png';
|
||
import wxPay from '@/until/wxpay.js';
|
||
|
||
export default {
|
||
components: {
|
||
navBar
|
||
},
|
||
data() {
|
||
return {
|
||
baseBgUrl: config.new_unionUrl || '',
|
||
unionBgUrl: config.unicon_url || '',
|
||
statusBarHeight: 0,
|
||
ThemeData: null,
|
||
searchValue: "",
|
||
Coin: Coin,
|
||
moneyList: [{
|
||
coin: 300,
|
||
money: 3,
|
||
},
|
||
{
|
||
coin: 500,
|
||
money: 5,
|
||
},
|
||
{
|
||
coin: 1000,
|
||
money: 10,
|
||
},
|
||
{
|
||
coin: 1500,
|
||
money: 15,
|
||
},
|
||
{
|
||
coin: 2000,
|
||
money: 20,
|
||
},
|
||
{
|
||
coin: 3000,
|
||
money: 30,
|
||
},
|
||
{
|
||
coin: 5000,
|
||
money: 50,
|
||
},
|
||
{
|
||
coin: 10000,
|
||
money: 100,
|
||
}
|
||
],
|
||
selectedIndex: -1, // 选中的充值金额索引
|
||
selectedAmount: 0, // 选中的金额(元)
|
||
selectedCoin: 0, // 选中的金币数量
|
||
isPaying: false,
|
||
isAgreed: false // 是否同意协议
|
||
}
|
||
},
|
||
onLoad() {
|
||
// 页面加载时初始化微信 JS-SDK
|
||
this.initWxPay();
|
||
},
|
||
methods: {
|
||
// 初始化微信支付
|
||
async initWxPay() {
|
||
try {
|
||
await wxPay.initWxJsSDK();
|
||
} catch (error) {
|
||
console.error('初始化微信支付失败:', error);
|
||
}
|
||
},
|
||
|
||
// 选择充值金额
|
||
selectAmount(index) {
|
||
this.selectedIndex = index;
|
||
this.selectedAmount = this.moneyList[index].money;
|
||
this.selectedCoin = this.moneyList[index].coin;
|
||
},
|
||
|
||
// 协议勾选变化
|
||
handleAgreementChange(e) {
|
||
this.isAgreed = e.detail.value.length > 0;
|
||
},
|
||
|
||
// 查看协议
|
||
showAgreement() {
|
||
uni.showModal({
|
||
title: '充值协议',
|
||
content: '1. 充值前请确认您已满18周岁\n2. 充值金额一经充值成功,不支持退款\n3. 请勿通过非官方渠道充值,谨防上当受骗\n4. 充值遇到问题请联系客服处理\n5. 本平台保留最终解释权',
|
||
confirmText: '我知道了',
|
||
showCancel: false
|
||
});
|
||
},
|
||
|
||
// 立即支付
|
||
async handlePay() {
|
||
// 1. 验证用户ID
|
||
if (!this.searchValue || this.searchValue.trim() === '') {
|
||
uni.showToast({
|
||
title: '请输入您在羽声语音的ID',
|
||
icon: 'none',
|
||
duration: 2000
|
||
});
|
||
return;
|
||
}
|
||
|
||
// 2. 验证是否选择了充值金额
|
||
if (this.selectedIndex === -1) {
|
||
uni.showToast({
|
||
title: '请选择充值金额',
|
||
icon: 'none',
|
||
duration: 2000
|
||
});
|
||
return;
|
||
}
|
||
|
||
// 3. 验证是否同意协议
|
||
if (!this.isAgreed) {
|
||
uni.showToast({
|
||
title: '请先阅读并同意充值协议',
|
||
icon: 'none',
|
||
duration: 2000
|
||
});
|
||
return;
|
||
}
|
||
|
||
// 4. 防止重复点击
|
||
if (this.isPaying) {
|
||
return;
|
||
}
|
||
|
||
this.isPaying = true;
|
||
uni.showLoading({
|
||
title: '正在发起支付...',
|
||
mask: true
|
||
});
|
||
|
||
try {
|
||
// 5. 生成订单号
|
||
const orderNo = this.generateOrderNo();
|
||
|
||
// 6. 计算支付金额(单位:分)
|
||
const payAmount = Math.round(this.selectedAmount * 100);
|
||
|
||
// 7. 附加信息(用户ID和金币数量)
|
||
const attach = JSON.stringify({
|
||
userId: this.searchValue.trim(),
|
||
coin: this.selectedCoin
|
||
});
|
||
|
||
// 8. 调用微信支付
|
||
const result = await wxPay.pay(payAmount, orderNo, attach);
|
||
|
||
uni.hideLoading();
|
||
|
||
// 9. 处理支付结果
|
||
if (result.success) {
|
||
uni.showToast({
|
||
title: '支付成功',
|
||
icon: 'success',
|
||
duration: 2000
|
||
});
|
||
|
||
// 支付成功后的处理
|
||
setTimeout(() => {
|
||
this.handlePaySuccess();
|
||
}, 2000);
|
||
} else {
|
||
uni.showToast({
|
||
title: result.message || '支付失败',
|
||
icon: 'none',
|
||
duration: 2000
|
||
});
|
||
}
|
||
} catch (error) {
|
||
uni.hideLoading();
|
||
console.error('支付错误:', error);
|
||
|
||
let errorMsg = '支付失败';
|
||
if (error.message) {
|
||
if (error.message.includes('取消')) {
|
||
errorMsg = '您已取消支付';
|
||
} else {
|
||
errorMsg = error.message;
|
||
}
|
||
}
|
||
|
||
uni.showToast({
|
||
title: errorMsg,
|
||
icon: 'none',
|
||
duration: 2000
|
||
});
|
||
} finally {
|
||
this.isPaying = false;
|
||
}
|
||
},
|
||
|
||
// 生成订单号
|
||
generateOrderNo() {
|
||
const timestamp = Date.now();
|
||
const random = Math.floor(Math.random() * 10000).toString().padStart(4, '0');
|
||
return `YS${timestamp}${random}`;
|
||
},
|
||
|
||
// 支付成功后的处理
|
||
handlePaySuccess() {
|
||
// 清空选择
|
||
this.selectedIndex = -1;
|
||
this.selectedAmount = 0;
|
||
this.selectedCoin = 0;
|
||
this.isAgreed = false;
|
||
|
||
// 可以跳转到支付成功页面或刷新余额
|
||
// uni.navigateTo({
|
||
// url: '/pages/other/paySuccess'
|
||
// });
|
||
|
||
// 或者返回上一页
|
||
// uni.navigateBack();
|
||
}
|
||
}
|
||
}
|
||
</script>
|
||
<style lang="scss" scoped>
|
||
.view-page {
|
||
min-height: 100vh;
|
||
font-family: Source Han Sans CN, Source Han Sans CN;
|
||
background-repeat: no-repeat;
|
||
background-size: 100% 100%;
|
||
|
||
.content {
|
||
padding: 0 32rpx;
|
||
|
||
.show_ByIdView {
|
||
margin: 16rpx 0;
|
||
width: 100%;
|
||
display: inline-flex;
|
||
justify-content: space-between;
|
||
font-size: 24rpx;
|
||
}
|
||
|
||
.coinWrap {
|
||
display: inline-grid;
|
||
grid-template-columns: repeat(3, 1fr);
|
||
/* 创建3列,每列等宽 */
|
||
grid-template-rows: repeat(3, 1fr);
|
||
/* 创建3行,每行等高 */
|
||
gap: 10px;
|
||
|
||
/* 网格项之间的间隙 */
|
||
.coinBox {
|
||
width: 212rpx;
|
||
height: 152rpx;
|
||
background: #FFFFFF;
|
||
border-radius: 20rpx;
|
||
text-align: center;
|
||
display: inline-flex;
|
||
flex-wrap: wrap;
|
||
align-content: center;
|
||
border: 2rpx solid transparent;
|
||
transition: all 0.3s ease;
|
||
cursor: pointer;
|
||
|
||
&.selected {
|
||
border-color: #3ABC6D;
|
||
background: rgba(58, 188, 109, 0.1);
|
||
|
||
.coin {
|
||
color: #3ABC6D;
|
||
}
|
||
|
||
.money {
|
||
color: #3ABC6D;
|
||
}
|
||
}
|
||
|
||
.coin {
|
||
font-size: 44rpx;
|
||
font-family: D-DIN-PRO, D-DIN-PRO;
|
||
font-weight: bold;
|
||
font-size: 44rpx;
|
||
color: #333333;
|
||
margin-left: 10rpx;
|
||
}
|
||
|
||
.money {
|
||
color: rgba(0, 0, 0, 0.45);
|
||
font-size: 28rpx;
|
||
}
|
||
}
|
||
}
|
||
|
||
.text-wrap {
|
||
margin-top: 32rpx;
|
||
font-size: 28rpx;
|
||
font-family: PingFang SC, PingFang SC;
|
||
font-weight: 500;
|
||
color: rgba(0, 0, 0, 0.85);
|
||
text-align: left;
|
||
font-style: normal;
|
||
text-transform: none;
|
||
}
|
||
|
||
.pay-button-wrap {
|
||
position: fixed;
|
||
bottom: 0;
|
||
left: 0;
|
||
right: 0;
|
||
padding: 20rpx 32rpx;
|
||
// background: #FFFFFF;
|
||
// box-shadow: 0 -2rpx 10rpx rgba(0, 0, 0, 0.05);
|
||
|
||
.agreement-wrap {
|
||
margin-top: 20rpx;
|
||
|
||
.agreement-label {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
|
||
.agreement-text {
|
||
font-size: 24rpx;
|
||
color: #666666;
|
||
margin-left: 8rpx;
|
||
}
|
||
|
||
.agreement-link {
|
||
font-size: 24rpx;
|
||
color: #3ABC6D;
|
||
text-decoration: underline;
|
||
margin-left: 4rpx;
|
||
}
|
||
}
|
||
}
|
||
|
||
.pay-button {
|
||
width: 100%;
|
||
height: 88rpx;
|
||
background: #3ABC6D;
|
||
border-radius: 44rpx;
|
||
font-size: 32rpx;
|
||
font-weight: 500;
|
||
color: #FFFFFF;
|
||
border: none;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
transition: all 0.3s ease;
|
||
|
||
&.disabled {
|
||
background: #CCCCCC;
|
||
opacity: 0.6;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
</style> |