大纲:
具体实现逻辑如下:
页面初始化时,通过
onLoad
方法获取传入的钱包(wallet)信息。用户输入充值金额,使用
watch
监听输入值的变化,并更新选中的充值金额选项。判断金额是否大于0,若是小于0,则抛出金额异常信息;用户选择充值金额,通过
changeCheck
方法更新选中的充值金额,并将选中状态进行更新。用户点击支付宝或微信支付按钮,根据选择的支付方式调用不同的支付接口生成支付二维码。
支付二维码生成成功后,将二维码的值更新到
qrArr.val
中,并显示扫码支付弹窗。启动定时器,定时查询支付状态,如果支付成功,则跳转至充值成功页面。
用户关闭扫码支付弹窗时,隐藏弹窗并清除定时器。
查询支付状态的方法分为
getwxPayStatus
和getAlipayStatus
,分别用于查询微信支付和支付宝支付的支付状态。支付成功后,弹出充值成功的提示,并且等待1秒后清空缓存并重新跳转至登录页面。
<template>
<view class="container">
<view>
<view class="title">请输入充值金额</view>
<u-input v-model="money" type="number" placeholder="请输入充值金额"></u-input>
<view class="tags">
<view class="tag" v-for="(item,index) in list" :key="index" :class="item.isCheck?'active':''"
@click="changeCheck(item.value)">{{item.value}}</view>
</view>
<view class="pay">
<view @click="payFor(1)">
<u-icon name="zhifubao-circle-fill" size="28" color="#108ee9"></u-icon>
<text style="color: #108ee9 ;">支付宝支付</text>
</view>
<view @click="payFor(2)">
<u-icon name="weixin-circle-fill" size="28" color="#7bb32e"></u-icon>
<text style="color: #7bb32e ;">微信支付</text>
</view>
</view>
<u-modal :show="show" title="扫码支付" @confirm="confirm">
<view style="text-align: center;">
<view class="tip">{{tip}}</view>
<tki-qrcode v-if="qrArr.val" ref="qrcode" :val="qrArr.val" :size="qrArr.size"
:loadMake="qrArr.loadMake" />
</view>
</u-modal>
</view>
</view>
</template>
<script>
import * as api from '@/request/index.js'
import tkiQrcode from '@/components/tki-qrcode/tki-qrcode.vue';
export default {
components: { tkiQrcode },
data() {
return {
money: 0,
show: false,
tip: '',
list: [{
value: 50,
isCheck: false
}, {
value: 100,
isCheck: false
}, {
value: 150,
isCheck: false
}, {
value: 200,
isCheck: false
}, {
value: 300,
isCheck: false
}, {
value: 400,
isCheck: false
}, {
value: 500,
isCheck: false
}, {
value: 600,
isCheck: false
}, {
value: 700,
isCheck: false
}, {
value: 800,
isCheck: false
}, {
value: 900,
isCheck: false
}, {
value: 1000,
isCheck: false
},
],
qrArr: {
size: 200,
val: '',
loadMake: true
},
out_trade_no: '',
timer: null,
wallet: {},
}
},
onLoad(option) {
this.wallet = JSON.parse(option.data)
},
watch: {
money(val, value) {
this.list.forEach(item => {
if (val == item.value) {
item.isCheck = true
} else {
item.isCheck = false
}
})
}
},
methods: {
changeCheck(value) {
this.money = value
this.list.forEach(item => {
if (item.value == value) {
item.isCheck = true
} else {
item.isCheck = false
}
})
},
payFor(type) {
if (this.money < 0.01) {
uni.showToast({
icon: 'none',
title: '请输入金额'
})
return false
}
// 初始化数据
this.qrArr.val = ''
if (this.timer) { // 清空定时器
clearInterval(this.timer)
}
this.show = true
this.tip = type == 1 ? '请打开支付宝进行扫码' : '请打开微信扫一扫进行扫码'
if (type == 1) {
let params = {
bz: '充值',
subject: '充值',
totalAmount: this.money,
cardNo: this.wallet.cardNo,
jobNo: this.wallet.jobNo,
staffName: this.wallet.staffName,
cardTypeName: this.wallet.cardTypeName,
acctBalanceB: this.wallet.acctBalanceB * 100,
type: 'app'
};
api.aliWebPayment(params).then(res => {
if (res && res.code == 0) {
this.$nextTick(() => {
this.qrArr.val = res.data.url
})
this.out_trade_no = res.data.out_trade_no
this.timer = setInterval(() => {
this.getAlipayStatus()
}, 1000 * 3)
}
})
} else {
let params = {
acctBalanceB: Number(this.wallet.acctBalanceB),
bz: '充值',
cardNo: this.wallet.cardNo,
cardTypeName: this.wallet.cardTypeName,
jobNo: this.wallet.jobNo,
staffName: this.wallet.staffName,
total: this.money,
};
api.wxPayNative(params).then(res => {
if (res.code == 0) {
this.$nextTick(() => {
this.qrArr.val = res.data.code_url
})
this.out_trade_no = res.data.out_trade_no
this.timer = setInterval(() => {
this.getwxPayStatus(this.out_trade_no)
}, 1000 * 3)
}
})
}
},
confirm() {
this.show = false
if (this.timer) {
clearInterval(this.timer)
}
},
// 微信支付状态查询
getwxPayStatus(out_trade_no) {
api.getwxPayStatus(out_trade_no, this.wallet.jobNo).then(res => {
if (res.data.trade_state == 'SUCCESS') {
this.back()
}
})
},
// 支付支付状态查询
getAlipayStatus() {
api.getAlipayStatus(this.out_trade_no, this.wallet.jobNo).then(res => {
if (res.data.code == 10000 && res.data.msg == 'Success' && res.data.tradeStatus ==
'TRADE_SUCCESS') {
this.back()
}
})
},
back() {
uni.showToast({
icon: 'success',
title: '充值成功'
})
if (this.timer) {
clearInterval(this.timer)
}
setTimeout(() => {
//同步清理本地数据缓存
uni.clearStorageSync()
uni.reLaunch({
url: '/pages/recharge/login'
});
}, 1000)
}
},
}
</script>
<style lang="scss" scoped>
.container {
width: 100%;
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
.title {
text-align: center;
margin-bottom: 20px;
font-size: 32px;
}
>view {
width: 600px;
.tags {
display: flex;
justify-content: space-between;
flex-wrap: wrap;
margin-top: 40px;
.tag {
width: calc(25% - 20px);
height: 50px;
line-height: 50px;
font-size: 24px;
text-align: center;
margin-bottom: 20px;
border: 1px solid #3c9cff;
border-radius: 10px;
color: #3c9cff;
cursor: pointer;
&.active {
background-color: #3c9cff;
color: #fff;
}
}
}
}
.pay {
display: flex;
justify-content: space-between;
font-size: 24px;
>view {
display: flex;
align-items: center;
line-height: 50px;
height: 50px;
text {
margin-left: 10px;
}
}
}
.tip {
font-size: 16px;
margin-bottom: 20px;
}
.qrcode {
width: 200px;
height: 200px;
background-color: red;
}
}
</style>
页面效果图展示: