Files
yusheng-h5/pages/other/weChatPay.vue
2026-01-08 16:06:53 +08:00

433 lines
9.6 KiB
Vue
Raw Permalink 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="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>