269 lines
7.0 KiB
Vue
269 lines
7.0 KiB
Vue
<template>
|
||
<view class="app-container">
|
||
<HeaderBar title="我的钱包" text-align="center" enable-back/>
|
||
|
||
<view class="balance-container">
|
||
|
||
<!-- 余额卡片 -->
|
||
<view class="balance-card">
|
||
<view class="balance-label">
|
||
<image class="balance-icon" src="https://api.ccttiot.com/78895797ae5a7b8114b52d18a0d16aa2efb0aa0155c86-t0tn1C%201-1746456527588.png" mode="aspectFit" />
|
||
钱包余额
|
||
</view>
|
||
<view class="balance-amount">{{ balance | fix2 | dv }}</view>
|
||
</view>
|
||
|
||
<!-- 充值输入 -->
|
||
<view class="recharge-section">
|
||
<view class="recharge-label">充值金额</view>
|
||
<input class="recharge-input" type="digit" v-model="rechargeAmount" placeholder="请输入要充值的金额" />
|
||
<button class="recharge-btn" @click="onRecharge">立即充值</button>
|
||
</view>
|
||
|
||
<!-- 余额变动记录 -->
|
||
<view class="record-section">
|
||
<view class="record-title">余额记录</view>
|
||
<view class="record-item" v-for="item in recordList" :key="item.id">
|
||
<view class="record-info">
|
||
<view class="record-type">{{ item.reason | dv }}</view>
|
||
<view class="record-time">{{ item.createTime | dv }}</view>
|
||
</view>
|
||
<view :class="['record-amount', item.amount > 0 ? 'plus' : 'minus']">
|
||
{{ item.amount > 0 ? '+' : '' }}{{ item.amount | fix2 | dv }}
|
||
</view>
|
||
</view>
|
||
|
||
<uni-load-more :status="loadStatus(loading, recordList.length, total)" />
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</template>
|
||
|
||
<script>
|
||
import { getMchDetail } from '@/api/app/mch'
|
||
import HeaderBar from '@/components/HeaderBar.vue'
|
||
import { mchListBalanceLog } from '@/api/mch/balanceLog'
|
||
import { $loadList } from '@/utils/mixins'
|
||
import { BalanceLogType } from '@/utils/enums'
|
||
import { appCreateRechargeOrder } from '@/api/app/rechargeOrder'
|
||
import { appRefreshPayResult } from '@/api/app/pay'
|
||
import config from '@/config'
|
||
|
||
export default {
|
||
mixins: [$loadList],
|
||
components: {
|
||
HeaderBar
|
||
},
|
||
data() {
|
||
return {
|
||
balance: 0,
|
||
BalanceLogType,
|
||
rechargeAmount: '',
|
||
recordList: [],
|
||
loading: false,
|
||
total: null,
|
||
queryParams: {
|
||
pageNum: 0,
|
||
pageSize: 20,
|
||
type: BalanceLogType.MCH_BALANCE,
|
||
orderByColumn: 'createTime',
|
||
isAsc: 'desc'
|
||
}
|
||
}
|
||
},
|
||
onLoad() {
|
||
this.getBalance();
|
||
this.getRecordList()
|
||
},
|
||
onReachBottom() {
|
||
this.loadRecordList()
|
||
},
|
||
methods: {
|
||
getBalance() {
|
||
getMchDetail(this.$store.getters.mchId).then(res => {
|
||
this.balance = res.data.balance;
|
||
console.log(this.balance)
|
||
})
|
||
},
|
||
getRecordList() {
|
||
this.queryParams.pageNum = 0;
|
||
this.queryParams.pageSize = 20;
|
||
this.total = null;
|
||
this.recordList = [];
|
||
this.loadRecordList()
|
||
},
|
||
/**
|
||
* 获取商户余额
|
||
*/
|
||
loadRecordList() {
|
||
this.loadMore(() => {
|
||
this.loading = true;
|
||
this.queryParams.mchId = this.$store.getters.mchId
|
||
this.queryParams.pageNum ++;
|
||
// 假设商户余额字段为 balance,实际字段请根据后端返回调整
|
||
mchListBalanceLog(this.queryParams).then(res => {
|
||
this.recordList = this.recordList.push(...res.rows);
|
||
this.total = res.total;
|
||
})
|
||
this.loading = false;
|
||
}, this.loadStatus(this.loading, this.recordList.length, this.total))
|
||
},
|
||
/**
|
||
* 充值操作
|
||
*/
|
||
onRecharge() {
|
||
if (!this.rechargeAmount || Number(this.rechargeAmount) <= 0) {
|
||
uni.showToast({ title: '请输入正确的充值金额', icon: 'none' })
|
||
return
|
||
}
|
||
// 验证小数点后最多两位
|
||
if (this.rechargeAmount.toString().split('.')[1]?.length > 2) {
|
||
uni.showToast({ title: '充值金额最多支持两位小数', icon: 'none' })
|
||
return
|
||
}
|
||
this.$modal.loading("充值中");
|
||
appCreateRechargeOrder({
|
||
mchId: this.$store.getters.mchId,
|
||
amount: this.rechargeAmount,
|
||
userId: this.$store.getters.userId,
|
||
appId: config.appId,
|
||
channelId: config.channelId
|
||
}).then(res => {
|
||
let payParams = res.data.payParams;
|
||
wx.requestPayment({
|
||
timeStamp: payParams.timeStamp,
|
||
nonceStr: payParams.nonceStr,
|
||
package: payParams.packageVal,
|
||
signType: payParams.signType,
|
||
paySign: payParams.paySign,
|
||
success: () => {
|
||
appRefreshPayResult(res.data.pay.no).finally(() => {
|
||
this.getBalance()
|
||
this.getRecordList()
|
||
this.rechargeAmount = null;
|
||
}).finally(() => {
|
||
this.$modal.closeLoading();
|
||
})
|
||
},
|
||
fail: () => {
|
||
this.$modal.closeLoading();
|
||
}
|
||
});
|
||
}).catch(() => {
|
||
this.$modal.closeLoading();
|
||
})
|
||
}
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
.balance-container {
|
||
padding: 24rpx ;
|
||
}
|
||
.balance-card {
|
||
background: linear-gradient(180deg, #3486FF 0%, #0064F9 100%);
|
||
border-radius: 20rpx;
|
||
padding: 32rpx 32rpx 24rpx 32rpx;
|
||
color: #fff;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
margin-bottom: 32rpx;
|
||
.balance-label {
|
||
display: flex;
|
||
align-items: center;
|
||
font-size: 28rpx;
|
||
.balance-icon {
|
||
width: 64rpx;
|
||
height: 64rpx;
|
||
margin-right: 12rpx;
|
||
}
|
||
}
|
||
.balance-amount {
|
||
font-size: 40rpx;
|
||
font-weight: bold;
|
||
letter-spacing: 2rpx;
|
||
}
|
||
}
|
||
.recharge-section {
|
||
background: #fff;
|
||
border-radius: 20rpx;
|
||
padding: 32rpx;
|
||
margin-bottom: 32rpx;
|
||
.recharge-label {
|
||
font-size: 28rpx;
|
||
font-weight: 600;
|
||
margin-bottom: 16rpx;
|
||
}
|
||
.recharge-input {
|
||
width: 100%;
|
||
height: 80rpx;
|
||
border: 1rpx solid #dbe6ff;
|
||
border-radius: 12rpx;
|
||
padding: 0 24rpx;
|
||
font-size: 30rpx;
|
||
margin-bottom: 24rpx;
|
||
background: #f7faff;
|
||
box-sizing: border-box;
|
||
}
|
||
.recharge-btn {
|
||
width: 100%;
|
||
height: 80rpx;
|
||
background: linear-gradient(180deg, #3486FF 0%, #0064F9 100%);
|
||
color: #fff;
|
||
font-size: 32rpx;
|
||
border: none;
|
||
border-radius: 40rpx;
|
||
font-weight: 600;
|
||
margin-top: 8rpx;
|
||
}
|
||
}
|
||
.record-section {
|
||
background: #fff;
|
||
border-radius: 20rpx;
|
||
padding: 32rpx;
|
||
.record-title {
|
||
font-size: 28rpx;
|
||
font-weight: 600;
|
||
margin-bottom: 24rpx;
|
||
}
|
||
.record-empty {
|
||
color: #bbb;
|
||
text-align: center;
|
||
font-size: 26rpx;
|
||
padding: 32rpx 0;
|
||
}
|
||
.record-item {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
padding: 18rpx 0;
|
||
border-bottom: 1rpx solid #f0f0f0;
|
||
&:last-child {
|
||
border-bottom: none;
|
||
}
|
||
.record-info {
|
||
.record-type {
|
||
font-size: 26rpx;
|
||
color: #222;
|
||
margin-bottom: 6rpx;
|
||
}
|
||
.record-time {
|
||
font-size: 22rpx;
|
||
color: #888;
|
||
}
|
||
}
|
||
.record-amount {
|
||
font-size: 30rpx;
|
||
font-weight: 600;
|
||
&.plus {
|
||
color: #2ecc71;
|
||
}
|
||
&.minus {
|
||
color: #ff4d4f;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
</style> |