<template>
|
<view class="withdrawal-page" :class="{ leaving: isLeaving }">
|
<guide-nav-bar title="导游提现" @back="goBack" />
|
|
<view class="balance-card">
|
<text class="balance-label">当前可提</text>
|
<text class="balance-amount">¥{{ availableText }}</text>
|
<view class="withdraw-button" @tap="startWithdrawal">提现</view>
|
</view>
|
|
<view class="heading">
|
<text>提现记录</text>
|
<text>共 {{ total }} 条</text>
|
</view>
|
|
<scroll-view class="record-list" scroll-y>
|
<view v-if="loading" class="state-text">正在加载</view>
|
<view v-else-if="!records.length" class="state-text">暂无提现记录</view>
|
<view v-for="item in records" :key="item.id" class="record">
|
<view class="record-top">
|
<text>提现</text>
|
<text class="record-money">¥{{ formatMoney(item.amount) }}</text>
|
</view>
|
<view class="record-bottom">
|
<text>{{ displayTime(item) }} {{ item.cardMasked || '' }}</text>
|
<text :class="'status ' + statusClass(item.status)">{{ statusText(item.status) }}</text>
|
</view>
|
<text v-if="item.reason" class="reason">{{ item.reason }}</text>
|
</view>
|
</scroll-view>
|
</view>
|
</template>
|
|
<script>
|
import GuideNavBar from '../../components/guide-nav-bar/guide-nav-bar.vue'
|
import { getOnboardingStatus } from '../../services/settlement'
|
import { getWithdrawals, getWithdrawalSummary } from '../../services/withdrawal'
|
import { backOrHome, routeTo } from '../../utils/router'
|
|
export default {
|
components: {
|
GuideNavBar
|
},
|
data() {
|
return {
|
loading: false,
|
availableAmount: 0,
|
records: [],
|
total: 0,
|
isLeaving: false
|
}
|
},
|
computed: {
|
availableText() {
|
return this.formatMoney(this.availableAmount)
|
}
|
},
|
onShow() {
|
this.loadData()
|
},
|
methods: {
|
goBack() {
|
if (this.isLeaving) {
|
return
|
}
|
this.isLeaving = true
|
setTimeout(() => {
|
backOrHome('/pages/earnings/index')
|
}, 280)
|
},
|
startWithdrawal() {
|
getOnboardingStatus().then((item) => {
|
const status = (item && item.status) || 'unsubmitted'
|
if (status === 'approved') {
|
routeTo('/pages/withdrawal-detail/index')
|
return
|
}
|
if (status === 'pending' || status === 'rejected') {
|
routeTo('/pages/onboarding-pending/index')
|
return
|
}
|
routeTo('/pages/onboarding/index')
|
}).catch((error) => {
|
uni.showToast({ title: (error && error.message) || '进件状态查询失败', icon: 'none' })
|
})
|
},
|
loadData() {
|
this.loading = true
|
Promise.all([
|
getWithdrawalSummary(),
|
getWithdrawals()
|
]).then(([summary, page]) => {
|
this.availableAmount = Number(summary && summary.availableAmount || 0)
|
this.records = (page && page.records) || []
|
this.total = Number(page && page.total || 0)
|
}).catch((error) => {
|
uni.showToast({ title: error.message || '提现记录加载失败', icon: 'none' })
|
}).finally(() => {
|
this.loading = false
|
})
|
},
|
formatMoney(amount = 0) {
|
return Number(amount || 0).toFixed(2)
|
},
|
formatTime(value) {
|
return value ? String(value).replace('T', ' ').slice(0, 19) : ''
|
},
|
displayTime(item) {
|
if (item.status === 'APPROVED' && item.processedAt) {
|
return '到账 ' + this.formatTime(item.processedAt)
|
}
|
return this.formatTime(item.appliedAt)
|
},
|
statusText(status) {
|
if (status === 'APPROVED') return '已到账'
|
if (status === 'REJECTED') return '已驳回'
|
if (status === 'PROCESSING') return '到账处理中'
|
return '待审核'
|
},
|
statusClass(status) {
|
if (status === 'APPROVED') return 'paid'
|
if (status === 'REJECTED') return 'rejected'
|
if (status === 'PROCESSING') return 'pending'
|
return 'pending'
|
}
|
}
|
}
|
</script>
|
|
<style scoped>
|
.withdrawal-page {
|
display: flex;
|
flex-direction: column;
|
min-height: 100vh;
|
background: #f6f8fb;
|
padding-bottom: env(safe-area-inset-bottom);
|
animation: pageSlideIn 260ms cubic-bezier(0.22, 1, 0.36, 1) both;
|
}
|
|
.withdrawal-page.leaving {
|
animation: pageSlideOut 280ms cubic-bezier(0.4, 0, 1, 1) both;
|
}
|
|
@keyframes pageSlideIn {
|
from { opacity: 0.35; transform: translateX(72rpx); }
|
to { opacity: 1; transform: translateX(0); }
|
}
|
|
@keyframes pageSlideOut {
|
from { opacity: 1; transform: translateX(0); }
|
to { opacity: 0.2; transform: translateX(260rpx); }
|
}
|
|
.balance-card {
|
margin: 28rpx 28rpx 0;
|
padding: 36rpx 32rpx 32rpx;
|
border: 1rpx solid #edf0f4;
|
border-radius: 12rpx;
|
background: #ffffff;
|
text-align: center;
|
}
|
|
.balance-label {
|
color: #667085;
|
font-size: 26rpx;
|
}
|
|
.balance-amount {
|
display: block;
|
margin: 16rpx 0 28rpx;
|
color: #1f3b5b;
|
font-size: 56rpx;
|
font-weight: 800;
|
line-height: 1;
|
}
|
|
.withdraw-button {
|
display: flex;
|
align-items: center;
|
justify-content: center;
|
height: 88rpx;
|
border-radius: 12rpx;
|
background: #4d8fe8;
|
color: #ffffff;
|
font-size: 30rpx;
|
font-weight: 700;
|
}
|
|
.heading {
|
display: flex;
|
justify-content: space-between;
|
padding: 36rpx 36rpx 18rpx;
|
color: #1f3b5b;
|
font-size: 30rpx;
|
font-weight: 700;
|
}
|
|
.heading text:last-child {
|
color: #a0a9b7;
|
font-size: 24rpx;
|
font-weight: 400;
|
}
|
|
.record-list {
|
flex: 1;
|
min-height: 0;
|
padding: 0 28rpx 24rpx;
|
box-sizing: border-box;
|
}
|
|
.record {
|
padding: 26rpx 28rpx;
|
margin-bottom: 16rpx;
|
border: 1rpx solid #edf0f4;
|
border-radius: 12rpx;
|
background: #ffffff;
|
}
|
|
.record-top,
|
.record-bottom {
|
display: flex;
|
justify-content: space-between;
|
align-items: center;
|
}
|
|
.record-top {
|
color: #1f2937;
|
font-size: 28rpx;
|
font-weight: 700;
|
}
|
|
.record-money {
|
font-weight: 800;
|
}
|
|
.record-bottom {
|
margin-top: 16rpx;
|
color: #667085;
|
font-size: 23rpx;
|
}
|
|
.status {
|
font-weight: 700;
|
}
|
|
.pending {
|
color: #e58b28;
|
}
|
|
.paid {
|
color: #249765;
|
}
|
|
.rejected,
|
.reason {
|
color: #e95b5b;
|
}
|
|
.reason {
|
display: block;
|
margin-top: 8rpx;
|
font-size: 22rpx;
|
}
|
|
.state-text {
|
padding-top: 120rpx;
|
color: #8993a1;
|
text-align: center;
|
font-size: 28rpx;
|
}
|
</style>
|