<template>
|
<view class="performance-page" :class="{ leaving: isLeaving }">
|
<guide-nav-bar title="业绩明细" action-text="提现" @back="goBack" @action="goWithdraw" />
|
|
<view class="summary-area">
|
<view class="income-card">
|
<view class="income-label">今日收益</view>
|
<view class="income-value">{{ moneyNumber(data.todayEarnings) }}</view>
|
</view>
|
<view class="income-card">
|
<view class="income-label">本月收益</view>
|
<view class="income-value">{{ moneyNumber(data.monthEarnings) }}</view>
|
</view>
|
</view>
|
|
<view class="filter-bar">
|
<picker mode="selector" :range="orderTypeLabels" :value="orderTypeIndex" @change="changeOrderType">
|
<view class="filter-item">
|
<text>{{ orderTypeLabels[orderTypeIndex] }}</text>
|
<image class="filter-arrow" src="/static/icons/chevron-down.svg" mode="aspectFit" />
|
</view>
|
</picker>
|
<picker mode="selector" :range="scenicOptions" :value="scenicIndex" @change="changeScenic">
|
<view class="filter-item">
|
<text>{{ scenicOptions[scenicIndex] }}</text>
|
<image class="filter-arrow" src="/static/icons/chevron-down.svg" mode="aspectFit" />
|
</view>
|
</picker>
|
<picker mode="date" :value="selectedDate" @change="changeDate">
|
<view class="filter-item date-filter">
|
<text>{{ selectedDate || '选择日期' }}</text>
|
<image class="calendar-icon" src="/static/icons/calendar-days.svg" mode="aspectFit" />
|
</view>
|
</picker>
|
</view>
|
|
<scroll-view class="detail-list" scroll-y>
|
<view v-for="row in visibleRows" :key="row.id" class="detail-row">
|
<view class="detail-main">
|
<view class="detail-title">{{ row.scenicName }} {{ row.serviceName }}</view>
|
<view class="detail-time">{{ row.time }}</view>
|
</view>
|
<view class="detail-money">{{ moneyNumber(row.orderAmount) }}</view>
|
</view>
|
<view v-if="!visibleRows.length" class="empty-text">暂无业绩明细</view>
|
</scroll-view>
|
</view>
|
</template>
|
|
<script>
|
import GuideNavBar from '../../components/guide-nav-bar/guide-nav-bar.vue'
|
import { getEarnings } from '../../services/order'
|
import { backOrHome, routeTo } from '../../utils/router'
|
|
export default {
|
components: {
|
GuideNavBar
|
},
|
data() {
|
return {
|
data: {
|
todayEarnings: 0,
|
monthEarnings: 0,
|
records: []
|
},
|
orderTypes: [
|
{ label: '订单类型', value: '' },
|
{ label: '拼团快讲', value: 'GROUP_QUICK' },
|
{ label: '拼团精讲', value: 'GROUP_PREMIUM' },
|
{ label: '包团快讲', value: 'PRIVATE_QUICK' },
|
{ label: '包团精讲', value: 'PRIVATE_PREMIUM' }
|
],
|
scenicOptions: ['景区选择'],
|
orderTypeIndex: 0,
|
scenicIndex: 0,
|
selectedDate: '',
|
loading: false,
|
isLeaving: false
|
}
|
},
|
computed: {
|
orderTypeLabels() {
|
return this.orderTypes.map((item) => item.label)
|
},
|
visibleRows() {
|
return this.data.records.map((row) => {
|
return {
|
...row,
|
scenicName: row.scenicName || '',
|
serviceName: row.serviceName || this.serviceName(row.orderType),
|
time: this.formatDateTime(row.completedAt)
|
}
|
})
|
}
|
},
|
onShow() {
|
this.loadData()
|
},
|
methods: {
|
goBack() {
|
if (this.isLeaving) {
|
return
|
}
|
this.isLeaving = true
|
setTimeout(() => {
|
backOrHome()
|
}, 280)
|
},
|
goWithdraw() {
|
routeTo('/pages/withdrawal/index')
|
},
|
loadData() {
|
if (this.loading) {
|
return
|
}
|
this.loading = true
|
getEarnings({
|
serviceType: this.orderTypes[this.orderTypeIndex].value,
|
scenicName: this.scenicIndex > 0 ? this.scenicOptions[this.scenicIndex] : '',
|
date: this.selectedDate
|
}).then((data) => {
|
this.data = data
|
const selectedScenic = this.scenicIndex > 0 ? this.scenicOptions[this.scenicIndex] : ''
|
this.scenicOptions = ['景区选择', ...(data.scenicOptions || [])]
|
this.scenicIndex = selectedScenic ? Math.max(this.scenicOptions.indexOf(selectedScenic), 0) : 0
|
}).catch((error) => {
|
uni.showToast({ title: error.message || '业绩数据加载失败', icon: 'none' })
|
}).finally(() => {
|
this.loading = false
|
})
|
},
|
moneyNumber(amount = 0) {
|
return Number(amount || 0).toLocaleString('en-US', {
|
minimumFractionDigits: 2,
|
maximumFractionDigits: 2
|
})
|
},
|
serviceName(orderType) {
|
const names = {
|
GROUP_QUICK: '拼团 · 快讲',
|
GROUP_PREMIUM: '拼团 · 精讲',
|
PRIVATE_QUICK: '包团 · 快讲',
|
PRIVATE_PREMIUM: '包团 · 精讲'
|
}
|
return names[orderType] || '-'
|
},
|
formatDateTime(value) {
|
return value ? value.replace('T', ' ').slice(0, 19) : '-'
|
},
|
changeOrderType(event) {
|
this.orderTypeIndex = Number(event.detail.value)
|
this.loadData()
|
},
|
changeScenic(event) {
|
this.scenicIndex = Number(event.detail.value)
|
this.loadData()
|
},
|
changeDate(event) {
|
this.selectedDate = event.detail.value
|
this.loadData()
|
}
|
}
|
}
|
</script>
|
|
<style>
|
.performance-page {
|
display: flex;
|
flex-direction: column;
|
min-height: 100vh;
|
background: #ffffff;
|
animation: pageSlideIn 260ms cubic-bezier(0.22, 1, 0.36, 1) both;
|
will-change: transform, opacity;
|
}
|
|
.performance-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);
|
}
|
}
|
|
.summary-area {
|
display: flex;
|
justify-content: space-between;
|
padding: 60rpx 90rpx 48rpx;
|
background: #ffffff;
|
}
|
|
.income-card {
|
display: flex;
|
flex-direction: column;
|
align-items: center;
|
justify-content: center;
|
width: 218rpx;
|
height: 180rpx;
|
border-radius: 12rpx;
|
background: #f0f0f0;
|
}
|
|
.income-label {
|
color: #253b5f;
|
font-size: 28rpx;
|
line-height: 1;
|
}
|
|
.income-value {
|
margin-top: 54rpx;
|
color: #253b5f;
|
font-size: 34rpx;
|
font-weight: 800;
|
line-height: 1;
|
}
|
|
.filter-bar {
|
display: grid;
|
grid-template-columns: 1fr 1fr 1fr;
|
height: 108rpx;
|
border-top: 1rpx solid #f1f1f1;
|
border-bottom: 1rpx solid #d9d9d9;
|
background: #ffffff;
|
}
|
|
.filter-item {
|
display: flex;
|
align-items: center;
|
justify-content: center;
|
height: 108rpx;
|
color: #0f172a;
|
font-size: 27rpx;
|
font-weight: 500;
|
white-space: nowrap;
|
}
|
|
.filter-arrow {
|
width: 24rpx;
|
height: 24rpx;
|
margin-left: 18rpx;
|
}
|
|
.date-filter {
|
color: #253b5f;
|
}
|
|
.calendar-icon {
|
width: 26rpx;
|
height: 26rpx;
|
margin-left: 8rpx;
|
}
|
|
.detail-list {
|
flex: 1;
|
min-height: 0;
|
background: #ffffff;
|
}
|
|
.detail-row {
|
display: flex;
|
align-items: center;
|
justify-content: space-between;
|
min-height: 168rpx;
|
margin-left: 84rpx;
|
padding-right: 64rpx;
|
border-bottom: 1rpx solid #d9d9d9;
|
}
|
|
.detail-main {
|
min-width: 0;
|
}
|
|
.detail-title {
|
color: #00263c;
|
font-size: 28rpx;
|
font-weight: 700;
|
line-height: 1.2;
|
}
|
|
.detail-time {
|
margin-top: 22rpx;
|
color: #475569;
|
font-size: 26rpx;
|
line-height: 1.2;
|
}
|
|
.detail-money {
|
flex-shrink: 0;
|
margin-left: 24rpx;
|
color: #253b5f;
|
font-size: 29rpx;
|
font-weight: 800;
|
}
|
|
.empty-text {
|
padding-top: 180rpx;
|
color: #667085;
|
text-align: center;
|
font-size: 28rpx;
|
}
|
</style>
|