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>
|