306 lines
9.9 KiB
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>
|