peixue-dev/peidu/uniapp/user-package/pages/wallet/withdraw.vue

306 lines
9.9 KiB
Vue

<template>
<view class="withdraw-page">
<!-- 可提现余额 -->
<view class="balance-card">
<view class="balance-label">可提现余额</view>
<view class="balance-amount">¥{{ availableBalance }}</view>
<view class="balance-tips">
<text>钱包余额: ¥{{ totalBalance }}</text>
<text>冻结金额: ¥{{ frozenBalance }}</text>
</view>
</view>
<!-- 提现表单 -->
<view class="form-section">
<view class="form-item">
<text class="label">提现金额</text>
<view class="input-wrapper">
<text class="currency">¥</text>
<input
class="input"
type="digit"
v-model="withdrawAmount"
placeholder="请输入提现金额"
@input="onAmountInput"
/>
</view>
<view class="amount-tips">
<text>最低提现: ¥{{ minAmount }}</text>
<text class="all-btn" @click="withdrawAll">全部提现</text>
</view>
</view>
<view class="form-item">
<text class="label">提现方式</text>
<picker
mode="selector"
:range="accountTypes"
range-key="label"
@change="onAccountTypeChange"
>
<view class="picker">
{{ selectedAccountType.label || '请选择提现方式' }}
<text class="iconfont icon-arrow-right"></text>
</view>
</picker>
</view>
<view class="form-item" v-if="selectedAccountType.value">
<text class="label">{{ selectedAccountType.value === 'bank_card' ? '银行卡号' : '账号' }}</text>
<input
class="input"
v-model="accountNo"
:placeholder="'请输入' + (selectedAccountType.value === 'bank_card' ? '银行卡号' : '账号')"
/>
</view>
<view class="form-item" v-if="selectedAccountType.value">
<text class="label">{{ selectedAccountType.value === 'bank_card' ? '开户行' : '账户名' }}</text>
<input
class="input"
v-model="accountName"
:placeholder="'请输入' + (selectedAccountType.value === 'bank_card' ? '开户行' : '账户名')"
/>
</view>
<view class="form-item" v-if="selectedAccountType.value === 'bank_card'">
<text class="label">持卡人姓名</text>
<input
class="input"
v-model="cardholderName"
placeholder="请输入持卡人姓名"
/>
</view>
</view>
<!-- 手续费说明 -->
<view class="fee-info">
<view class="fee-item">
<text>提现金额</text>
<text>¥{{ withdrawAmount || '0.00' }}</text>
</view>
<view class="fee-item">
<text>手续费 ({{ feeRate }}%)</text>
<text class="fee">-¥{{ fee }}</text>
</view>
<view class="fee-item total">
<text>实际到账</text>
<text class="amount">¥{{ actualAmount }}</text>
</view>
</view>
<!-- 提现按钮 -->
<view class="submit-btn" @click="submitWithdraw">
<button class="btn-primary">提交申请</button>
</view>
<!-- 提现记录 -->
<view class="record-section">
<view class="section-title" @click="goToTransaction">
<text>提现记录</text>
<text class="more">查看全部 <text class="iconfont icon-arrow-right"></text></text>
</view>
<view class="record-list" v-if="records.length > 0">
<view class="record-item" v-for="item in records" :key="item.id">
<view class="record-info">
<view class="record-amount">¥{{ item.amount }}</view>
<view class="record-time">{{ item.createTime }}</view>
</view>
<view class="record-status" :class="'status-' + item.status">
{{ getStatusText(item.status) }}
</view>
</view>
</view>
<view class="empty" v-else>
<text>暂无提现记录</text>
</view>
</view>
<!-- 提现说明 -->
<view class="tips-section">
<view class="tips-title">提现说明</view>
<view class="tips-content">
<text>1. 提现金额最低{{ minAmount }},最高{{ maxAmount }}</text>
<text>2. 提现手续费为{{ feeRate }}%,从提现金额中扣除</text>
<text>3. 工作日提现,1-3个工作日到账</text>
<text>4. 周末及节假日提现,顺延至工作日处理</text>
<text>5. 请确保账户信息准确,否则可能导致提现失败</text>
</view>
</view>
</view>
</template>
<script>
import { walletApi } from '@/api/index.js'
import { calculateFee, calculateActualAmount, compareMoney, limitMoneyInput, validateMoney } from '@/utils/money.js'
export default {
data() {
return {
availableBalance: 0,
totalBalance: 0,
frozenBalance: 0,
withdrawAmount: '',
minAmount: 1.00,
maxAmount: 10000.00,
feeRate: 0.6,
accountTypes: [
{ label: '微信', value: 'wechat' },
{ label: '支付宝', value: 'alipay' },
{ label: '银行卡', value: 'bank_card' }
],
selectedAccountType: {},
accountNo: '',
accountName: '',
cardholderName: '',
records: []
}
},
computed: {
fee() {
if (!this.withdrawAmount) return '0.00'
return calculateFee(this.withdrawAmount, this.feeRate)
},
actualAmount() {
if (!this.withdrawAmount) return '0.00'
return calculateActualAmount(this.withdrawAmount, this.fee)
}
},
onLoad() {
this.loadWalletInfo()
this.loadWithdrawRecords()
},
methods: {
async loadWalletInfo() {
try {
const res = await walletApi.getWalletInfo()
this.totalBalance = res?.data?.balance || 0
this.frozenBalance = res?.data?.frozenAmount || 0
this.availableBalance = (this.totalBalance - this.frozenBalance).toFixed(2)
} catch (e) {
console.error('加载钱包信息失败:', e)
uni.showToast({
title: '加载钱包信息失败,请稍后重试',
icon: 'none',
duration: 2000
})
}
},
async loadWithdrawRecords() {
try {
const res = await walletApi.getWithdrawRecords({ pageSize: 5 })
this.records = res?.data?.records || []
} catch (e) {
console.error('加载提现记录失败:', e)
// 提现记录加载失败不影响主要功能,只记录日志
}
},
onAmountInput(e) {
this.withdrawAmount = limitMoneyInput(e.detail.value)
},
withdrawAll() {
this.withdrawAmount = this.availableBalance.toString()
},
onAccountTypeChange(e) {
this.selectedAccountType = this.accountTypes[e.detail.value]
this.accountNo = ''
this.accountName = ''
this.cardholderName = ''
},
async submitWithdraw() {
// 验证金额格式
if (!this.withdrawAmount) {
uni.showToast({ title: '请输入提现金额', icon: 'none', duration: 2000 })
return
}
if (!validateMoney(this.withdrawAmount)) {
uni.showToast({ title: '请输入正确的金额格式(最多两位小数)', icon: 'none', duration: 2000 })
return
}
// 验证金额范围
if (compareMoney(this.withdrawAmount, this.minAmount) < 0) {
uni.showToast({ title: `提现金额不能低于${this.minAmount}`, icon: 'none', duration: 2000 })
return
}
if (compareMoney(this.withdrawAmount, this.maxAmount) > 0) {
uni.showToast({ title: `提现金额不能超过${this.maxAmount}`, icon: 'none', duration: 2000 })
return
}
if (compareMoney(this.withdrawAmount, this.availableBalance) > 0) {
uni.showToast({ title: `提现金额不能超过可用余额${this.availableBalance}`, icon: 'none', duration: 2000 })
return
}
// 验证账户信息
if (!this.selectedAccountType.value) {
uni.showToast({ title: '请选择提现方式', icon: 'none', duration: 2000 })
return
}
if (!this.accountNo) {
const accountLabel = this.selectedAccountType.value === 'bank_card' ? '银行卡号' : '账号'
uni.showToast({ title: `请输入${accountLabel}`, icon: 'none', duration: 2000 })
return
}
if (!this.accountName) {
const nameLabel = this.selectedAccountType.value === 'bank_card' ? '开户行' : '账户名'
uni.showToast({ title: `请输入${nameLabel}`, icon: 'none', duration: 2000 })
return
}
if (this.selectedAccountType.value === 'bank_card' && !this.cardholderName) {
uni.showToast({ title: '请输入持卡人姓名', icon: 'none', duration: 2000 })
return
}
try {
uni.showLoading({ title: '提交中...' })
await walletApi.applyWithdraw({
amount: this.withdrawAmount,
accountType: this.selectedAccountType.value,
accountNo: this.accountNo,
accountName: this.accountName,
cardholderName: this.cardholderName
})
uni.hideLoading()
uni.showToast({ title: '提现申请已提交,请等待审核', icon: 'success', duration: 2000 })
setTimeout(() => {
uni.navigateBack()
}, 2000)
} catch (e) {
uni.hideLoading()
console.error('提现申请失败:', e)
const errorMsg = e.message || e.msg || '提现申请失败,请稍后重试'
uni.showToast({ title: errorMsg, icon: 'none', duration: 2500 })
}
},
getStatusText(status) {
const statusMap = {
'pending': '审核中',
'approved': '已通过',
'rejected': '已拒绝',
'completed': '已完成'
}
return statusMap[status] || status
},
goToTransaction() {
uni.navigateTo({
url: '/pages/wallet/transaction'
})
}
}
}
</script>
<style lang="scss" scoped>
.withdraw-page {
min-height: 100vh;
background: #f5f5f5;
}
</style>