You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
yanzong_qianduan/pages/wallet/recharge/index.vue

508 lines
13 KiB

<template>
<view v-if="personal.user_id" class="container" :style="appThemeStyle">
<view class="account-panel dis-flex flex-y-center">
<view class="panel-lable">
<text>账户余额</text>
</view>
<view class="panel-balance flex-box">
<text>¥{{ personal.balance }}</text>
</view>
</view>
<view class="recharge-panel">
<view class="recharge-label">
<text>充值金额</text>
</view>
<view class="recharge-plan clearfix">
<block v-for="(item, index) in planList" :key="index">
<view class="recharge-plan_item" :class="{ active: selectedPlanId == item.plan_id }"
@click="onSelectPlan(item.plan_id)">
<view class="plan_money">
<text>{{ item.money }}</text>
</view>
<view class="plan_gift" v-if="item.gift_money > 0">
<text>送{{ item.gift_money }}</text>
</view>
</view>
</block>
</view>
<!-- 手动充值输入框 -->
<view class="recharge-input" v-if="setting.is_custom == 1">
<input class="input" type="digit" placeholder="可输入自定义充值金额" v-model="inputValue" @input="onChangeMoney" />
</view>
<!-- 支付方式 -->
<view class="recharge-label m-top60">
<text>支付方式</text>
</view>
<view class="payment-method">
<view v-for="(item, index) in methods" :key="index" class="pay-item dis-flex flex-x-between"
@click="handleSelectPayType(index)">
<view class="item-left dis-flex flex-y-center">
<view class="item-left_icon" :class="[item.method]">
<text class="iconfont" :class="[PayMethodIconEnum[item.method]]"></text>
</view>
<view class="item-left_text">
<text>{{ PayMethodEnum[item.method].name }}</text>
</view>
</view>
<view class="item-right col-m" v-if="curPaymentItem && curPaymentItem.method == item.method">
<text class="iconfont icon-check"></text>
</view>
</view>
</view>
<!-- 确认按钮 -->
<view class="recharge-submit btn-submit">
<form @submit="onSubmit">
<button class="button" formType="submit" :disabled="disabled">立即充值</button>
</form>
</view>
</view>
<!-- 充值描述 -->
<view class="describe-panel">
<view class="recharge-label">
<text>充值说明</text>
</view>
<view class="content">
<text space="ensp">{{ setting.describe }}</text>
</view>
</view>
<!-- 支付确认弹窗 -->
<!-- #ifdef H5 -->
<u-modal v-if="tempUnifyData" v-model="showConfirmModal" title="支付确认" show-cancel-button confirm-text="已完成支付"
:confirm-color="appTheme.mainBg" negative-top="100" :asyncClose="true"
@confirm="onTradeQuery(tempUnifyData.outTradeNo, tempUnifyData.method)">
<view class="modal-content">
<text>请在{{ PayMethodClientNameEnum[tempUnifyData.method] }}内完成支付如果您已经支付成功请点击已完成支付按钮</text>
</view>
</u-modal>
<!-- #endif -->
</view>
</template>
<script>
import * as RechargeApi from '@/api/recharge'
import { PayMethodEnum } from '@/common/enum/payment'
import { inArray, urlEncode } from '@/utils/util'
import { Alipay, Wechat } from '@/core/payment'
// 支付方式对应的图标
const PayMethodIconEnum = {
[PayMethodEnum.WECHAT.value]: 'icon-wechat-pay',
[PayMethodEnum.ALIPAY.value]: 'icon-alipay',
}
// 支付方式的终端名称
const PayMethodClientNameEnum = {
[PayMethodEnum.WECHAT.value]: '微信',
[PayMethodEnum.ALIPAY.value]: '支付宝'
}
export default {
data() {
return {
// 正在加载
isLoading: true,
// 按钮禁用
disabled: false,
// 枚举类
PayMethodEnum,
PayMethodIconEnum,
PayMethodClientNameEnum,
// 个人信息
personal: { balance: '0.00' },
// 充值设置
setting: {},
// 充值方案列表
planList: [],
// 当前客户端的支付方式列表(后端根据platform判断)
methods: [],
// 当前选中的套餐ID
selectedPlanId: 0,
// 自定义金额
inputValue: '',
// 当前选中的支付方式
curPaymentItem: null,
// 支付确认弹窗
showConfirmModal: false,
// #ifdef H5
// 当前微信支付信息 (临时数据, 仅用于H5端)
tempUnifyData: { outTradeNo: '', method: '' },
// #endif
}
},
/**
* 生命周期函数--监听页面加载
*/
onLoad(options) {
// 获取页面数据
this.getPageData()
},
methods: {
// 选择充值套餐
onSelectPlan(planId) {
this.selectedPlanId = planId
this.inputValue = ''
},
// 金额输入框
onChangeMoney({ detail }) {
this.inputValue = detail.value
this.selectedPlanId = 0
},
// 选择支付方式
handleSelectPayType(index) {
this.curPaymentItem = this.methods[index]
},
// 获取页面数据
getPageData() {
const app = this
app.isLoading = true
return new Promise((resolve, reject) => {
RechargeApi.center({ client: app.platform })
.then(result => {
app.setting = result.data.setting
app.personal = result.data.personal
app.planList = result.data.planList
app.methods = result.data.paymentMethods
app.isLoading = false
// 默认选中的支付方式
app.handleSelectPayType(0)
// #ifdef H5
// 判断当前页面来源于浏览器返回
this.performance()
// #endif
})
})
},
// 判断当前页面来源于浏览器返回
// #ifdef H5
performance() {
this.alipayPerformance()
this.wechatPerformance()
},
// H5端支付宝支付完成跳转回当前页面时触发
alipayPerformance() {
const app = this
app.tempUnifyData = Alipay.performance()
if (app.tempUnifyData) {
app.onTradeQuery(app.tempUnifyData.outTradeNo, app.tempUnifyData.method)
}
},
// H5端微信支付完成或返回时触发
wechatPerformance() {
const app = this
app.tempUnifyData = Wechat.performance('recharge')
console.log('wechatPerformance', app.tempUnifyData)
if (app.tempUnifyData) {
app.showConfirmModal = true
}
},
// #endif
// 立即充值
onSubmit(e) {
const app = this
// 判断是否选择了支付方式
if (!app.curPaymentItem) {
app.$toast('您还没有选择支付方式')
return
}
// 按钮禁用
if (app.disabled) return
app.disabled = true
// 提交到后端
RechargeApi.submit({
planId: app.selectedPlanId,
customMoney: app.inputValue ? app.inputValue : '',
method: app.curPaymentItem.method,
client: app.platform,
extra: app.getExtraAsUnify(app.curPaymentItem.method)
})
.then(result => app.onSubmitCallback(result))
.finally(err => {
setTimeout(() => app.disabled = false, 10)
})
},
// 获取第三方支付的扩展参数
getExtraAsUnify(method) {
if (method === PayMethodEnum.ALIPAY.value) {
return Alipay.extraAsUnify()
}
if (method === PayMethodEnum.WECHAT.value) {
return Wechat.extraAsUnify()
}
return {}
},
// 订单提交成功后回调
onSubmitCallback(result) {
const app = this
const method = app.curPaymentItem.method
const paymentData = result.data.payment
// 余额支付
if (method === PayMethodEnum.BALANCE.value) {
app.onShowSuccess(result)
}
// 发起支付宝支付
if (method === PayMethodEnum.ALIPAY.value) {
console.log('paymentData', paymentData)
Alipay.payment(paymentData)
.then(res => app.onPaySuccess(res))
.catch(err => app.onPayFail(err))
}
// 发起微信支付
if (method === PayMethodEnum.WECHAT.value) {
console.log('paymentData', paymentData)
Wechat.payment({ orderKey: 'recharge', ...paymentData })
.then(res => app.onPaySuccess(res))
.catch(err => app.onPayFail(err))
}
},
// 订单支付成功的回调方法
// 这里只是前端支付api返回结果success,实际订单是否支付成功 以后端的查单和异步通知为准
onPaySuccess({ res, option: { isRequireQuery, outTradeNo, method } }) {
const app = this
// 判断是否需要主动查单
// isRequireQuery为true代表需要主动查单
if (isRequireQuery) {
app.onTradeQuery(outTradeNo, method)
return true
}
this.onShowSuccess(res)
},
// 显示支付成功信息并页面跳转
onShowSuccess({ message }) {
this.$toast(message || '订单支付成功')
this.onSuccessNav()
},
// 订单支付失败
onPayFail(err) {
console.log('onPayFail', err)
const errMsg = err.message || '订单未支付'
this.$error(errMsg)
},
// 已完成支付按钮事件: 请求后端查单
onTradeQuery(outTradeNo, method) {
const app = this
// 交易查询
// 查询第三方支付订单是否付款成功
RechargeApi.tradeQuery({ outTradeNo, method, client: app.platform })
.then(result => result.data.isPay ? app.onShowSuccess(result) : app.onPayFail(result))
.finally(() => app.showConfirmModal = false)
},
// 支付成功后的跳转
onSuccessNav() {
const pages = getCurrentPages()
const lastPage = pages.length < 2 ? null : pages[pages.length - 2]
const backRoutes = ['pages/wallet/index']
if (lastPage && inArray(lastPage.route, backRoutes)) {
setTimeout(() => uni.navigateBack(), 1000)
} else {
setTimeout(() => {
this.$navTo('pages/wallet/index', {}, 'redirectTo')
}, 1200)
}
},
}
}
</script>
<style lang="scss" scoped>
page,
.container {
background: #fff;
}
.container {
padding-bottom: 70rpx;
}
.m-top60 {
margin-top: 60rpx;
}
// 账户面板
.account-panel {
width: 650rpx;
height: 180rpx;
margin: 50rpx auto;
padding: 0 60rpx;
box-sizing: border-box;
border-radius: 12rpx;
color: #fff;
background: linear-gradient(-125deg, #a46bff, #786cff);
box-shadow: 0 5px 22px 0 rgba(0, 0, 0, 0.26);
}
.panel-lable {
font-size: 32rpx;
}
.recharge-label {
color: rgb(51, 51, 51);
font-size: 30rpx;
margin-bottom: 25rpx;
}
.panel-balance {
text-align: right;
font-size: 46rpx;
}
.recharge-panel {
margin-top: 60rpx;
padding: 0 60rpx;
}
// 充值套餐
.recharge-plan {
margin-bottom: -20rpx;
.recharge-plan_item {
width: 192rpx;
padding: 15rpx 0;
float: left;
text-align: center;
color: #888;
border: 1rpx solid rgb(228, 228, 228);
border-radius: 10rpx;
margin: 0 20rpx 20rpx 0;
&:nth-child(3n + 0) {
margin-right: 0;
}
&.active {
color: #786cff;
border: 1rpx solid #786cff;
.plan_money {
color: #786cff;
}
}
}
}
.plan_money {
font-size: 32rpx;
color: rgb(82, 82, 82);
}
.plan_gift {
font-size: 25rpx;
}
.recharge-input {
margin-top: 40rpx;
.input {
display: block;
border: 1rpx solid rgb(228, 228, 228);
border-radius: 10rpx;
padding: 20rpx 26rpx;
font-size: 28rpx;
}
}
// 立即充值
.recharge-submit {
margin-top: 70rpx;
}
.btn-submit {
.button {
font-size: 30rpx;
background: #786cff;
border: none;
color: white;
border-radius: 50rpx;
padding: 0 120rpx;
line-height: 3;
}
.button[disabled] {
background: #a098ff;
border-color: #a098ff;
color: white;
}
}
// 充值说明
.describe-panel {
margin-top: 50rpx;
padding: 0 60rpx;
.content {
font-size: 26rpx;
line-height: 1.6;
color: #888;
}
}
// 支付方式
.payment-method {
.pay-item {
padding: 14rpx 0;
font-size: 26rpx;
.item-left_icon {
margin-right: 20rpx;
font-size: 44rpx;
&.wechat {
color: #00c800;
}
&.alipay {
color: #009fe8;
}
}
.item-left_text {
font-size: 30rpx;
}
.item-right {
font-size: 30rpx;
}
.user-balance {
margin-left: 20rpx;
font-size: 26rpx;
}
}
}
// 支付确认弹窗
.modal-content {
padding: 40rpx 48rpx;
font-size: 30rpx;
line-height: 50rpx;
text-align: left;
color: #606266;
// height: 620rpx;
box-sizing: border-box;
}
</style>