work-order/work-order-uniapp/pages/mch/balance.vue

269 lines
7.0 KiB
Vue
Raw Normal View History

2025-07-27 20:34:15 +08:00
<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>