Files
yxe-mp/pages/bonus/index.vue
T
2026-09-29 15:17:13 +08:00

329 lines
8.6 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<view class="bonus-page">
<view class="page-hero">
<AppNavbar title="记录" show-back/>
<view class="intro-card">
<view class="card-title">
<view class="title-bar"></view>
<text>记录</text>
</view>
<!-- <text class="intro-text">展示历史订单记录,按来源拆分提成(药动销、跑店/巡店、药分享、自主填报),保持蓝色系设计。</text>-->
<!-- <view class="hero-tags">-->
<!-- <view :class="['chip', { 'chip--active': activeFilter === 0 }]" @tap="toggleFilter(0)">药动销</view>-->
<!-- <view :class="['chip', { 'chip--active': activeFilter === 4 }]" @tap="toggleFilter(4)">跑店/巡店</view>-->
<!-- <view :class="['chip', { 'chip--active': activeFilter === 1 }]" @tap="toggleFilter(1)">药分享</view>-->
<!-- <view :class="['chip', { 'chip--active': activeFilter === 6 }]" @tap="toggleFilter(6)">自主填报</view>-->
<!-- </view>-->
</view>
</view>
<!-- <view class="card summary">-->
<!-- <view class="sum-item">-->
<!-- <view class="sum-value">¥ {{ summary.movement }}</view>-->
<!-- <view class="sum-label">药动销提成</view>-->
<!-- </view>-->
<!-- <view class="sum-item">-->
<!-- <view class="sum-value">¥ {{ summary.storeVisit }}</view>-->
<!-- <view class="sum-label">跑店/巡店提成</view>-->
<!-- </view>-->
<!-- <view class="sum-item">-->
<!-- <view class="sum-value">¥ {{ summary.share }}</view>-->
<!-- <view class="sum-label">药分享提成</view>-->
<!-- </view>-->
<!-- <view class="sum-item">-->
<!-- <view class="sum-value">¥ {{ summary.selfReport }}</view>-->
<!-- <view class="sum-label">自主填报提成</view>-->
<!-- </view>-->
<!-- </view>-->
<!-- <view class="card withdraw-entry">-->
<!-- <view>-->
<!-- <view class="withdraw-title">可提现奖金</view>-->
<!-- <view class="withdraw-amount">¥ {{ user.balance }}</view>-->
<!-- </view>-->
<!-- <view class="primary-btn withdraw-btn" @tap="goWithdraw">奖金提现</view>-->
<!-- </view>-->
<view class="card block">
<view class="section-title">历史收入记录</view>
<view v-if="loading" class="empty">加载中...</view>
<view v-else-if="filteredRecords.length === 0" class="empty">暂无记录</view>
<view v-else class="record" v-for="(item, idx) in filteredRecords" :key="idx">
<view>
<view class="record-name">{{ item.title }}</view>
<!-- <view class="record-meta">{{ item.source }} · 订单号:{{ item.orderNo }}</view>-->
<view class="record-meta">日期:{{ item.date }}</view>
</view>
<!-- <view class="record-amount">+¥{{ item.amount }}</view>-->
</view>
</view>
<Login ref="Login" @done="getUserData"/>
</view>
</template>
<script>
import {userBalanceLogListReq} from "@/api/bonus";
import {getUserInfo} from "@/util/user";
import {userInfoReq} from "@/api/user";
import Login from "@/components/Login.vue";
import AppNavbar from "@/components/AppNavbar.vue";
export default {
components: {Login, AppNavbar},
data() {
return {
summary: {
movement: '0.00',
storeVisit: '0.00',
share: '0.00',
selfReport: '0.00',
withdrawable: '0.00'
},
records: [],
loading: false,
activeFilter: null,
user: {
balance: 0
},
}
},
computed: {
filteredRecords() {
if (this.activeFilter === null || this.activeFilter === undefined) return this.records
return this.records.filter(item => Number(item.scene) === Number(this.activeFilter))
}
},
onShow() {
if (getUserInfo().token) {
this.isLoggedIn = true
this.getUserData()
this.fetchBalanceLogs()
}
},
methods: {
async getUserData(){
const {data} = await userInfoReq()
this.isLoggedIn = true
this.user = data
},
async fetchBalanceLogs() {
this.loading = true
try {
const {data} = await userBalanceLogListReq({})
const list = Array.isArray(data) ? data : (data && data.list ? data.list : [])
this.records = list.map(this.normalizeRecord)
const movementTotal = this.records
.filter(item => item.scene === 0)
.reduce((sum, item) => sum + Number(item.amount || 0), 0)
const storeVisitTotal = this.records
.filter(item => item.scene === 4)
.reduce((sum, item) => sum + Number(item.amount || 0), 0)
const shareTotal = this.records
.filter(item => item.scene === 1)
.reduce((sum, item) => sum + Number(item.amount || 0), 0)
const selfReportTotal = this.records
.filter(item => item.scene === 6)
.reduce((sum, item) => sum + Number(item.amount || 0), 0)
const withdrawable = movementTotal + storeVisitTotal + shareTotal + selfReportTotal
this.summary = {
movement: movementTotal.toFixed(2),
storeVisit: storeVisitTotal.toFixed(2),
share: shareTotal.toFixed(2),
selfReport: selfReportTotal.toFixed(2),
withdrawable: withdrawable.toFixed(2)
}
} catch (err) {
uni.showToast({
title: '加载失败',
icon: 'none'
})
} finally {
this.loading = false
}
},
normalizeRecord(item) {
const sceneValue = Number(item.scene)
const source = sceneValue === 0
? '药动销'
: (sceneValue === 4 ? '跑店/巡店' : (sceneValue === 1 ? '药分享' : (sceneValue === 6 ? '自主填报' : '其他')))
const amount = Number(item.amount || item.money || item.changeAmount || 0)
return {
scene: sceneValue,
title: item.title || item.remark || `${source}记录`,
source,
orderNo: item.orderNo || item.order_no || item.bizNo || '-',
date: item.createTime || item.createdAt || item.date || '-',
amount: amount.toFixed(2)
}
},
toggleFilter(scene) {
this.activeFilter = this.activeFilter === scene ? null : scene
},
goWithdraw() {
uni.navigateTo({
url: '/pages/bonus/withdraw'
})
}
}
}
</script>
<style lang="scss" scoped>
.bonus-page {
min-height: 100vh;
//padding: 0 20rpx 40rpx;
background: #f5f5f5;
}
.page-hero {
//padding: 30rpx 6rpx 18rpx;
background: url('https://yaodongxiao.oss-cn-guangzhou.aliyuncs.com/20260126/462bfa04cf0eff8698884c38b9d17519.png') no-repeat
top center / 100% auto;
}
.page-navbar {
padding: 0 6rpx;
}
.intro-card {
margin: 18rpx 20rpx 0;
padding: 20rpx 18rpx;
border-radius: 20rpx;
background: rgba(255, 255, 255, 0.9);
box-shadow: 0 10rpx 20rpx rgba(0, 0, 0, 0.08);
}
.card-title {
display: flex;
align-items: center;
gap: 12rpx;
font-size: 28rpx;
font-weight: 700;
color: #1f2937;
}
.title-bar {
width: 6rpx;
height: 30rpx;
border-radius: 999rpx;
background: #2fc6a7;
}
.intro-text {
margin-top: 12rpx;
font-size: 26rpx;
color: #6b7280;
line-height: 1.6;
}
.hero-tags {
display: flex;
gap: 12rpx;
margin-top: 12rpx;
}
.chip {
padding: 6rpx 16rpx;
border-radius: 999rpx;
border: 1rpx solid #c7d2fe;
color: #4f46e5;
font-size: 22rpx;
font-weight: 700;
background: #eef2ff;
}
.chip--active {
border-color: #2fc6a7;
color: #2fc6a7;
background: #e6fffa;
}
.summary {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 12rpx;
margin: 18rpx 20rpx 0;
}
.withdraw-entry {
margin: 18rpx 20rpx 0;
display: flex;
justify-content: space-between;
align-items: center;
}
.withdraw-title {
color: var(--text-sub);
font-size: 24rpx;
}
.withdraw-amount {
color: var(--brand-primary);
font-size: 32rpx;
font-weight: 800;
margin-top: 4rpx;
}
.withdraw-btn {
padding: 10rpx 18rpx;
height: 56rpx;
font-size: 24rpx;
}
.sum-item {
background: linear-gradient(135deg, #f0f5ff, #ffffff);
border-radius: 14rpx;
padding: 16rpx;
border: 1rpx solid #e7eef8;
}
.sum-value {
font-size: 32rpx;
font-weight: 800;
color: var(--brand-primary);
}
.sum-label {
color: var(--text-sub);
font-size: 24rpx;
margin-top: 4rpx;
}
.block {
margin: 18rpx 20rpx 0;
}
.record {
display: flex;
justify-content: space-between;
padding: 12rpx 0;
border-bottom: 1rpx solid #edf1f7;
}
.record:last-child {
border-bottom: none;
}
.record-name {
font-size: 26rpx;
color: var(--text-main);
}
.record-meta {
color: var(--text-sub);
font-size: 24rpx;
margin-top: 2rpx;
}
.record-amount {
color: #ff3b30;
font-weight: 800;
}
.empty {
color: var(--text-sub);
text-align: center;
padding: 16rpx 0;
}
</style>