3
0
Fork 0
web-store-retail-h5/pages/mine/marketDynamic/box-list.vue

252 lines
6.4 KiB
Vue
Raw Normal View History

2025-06-12 20:21:33 +08:00
<template>
<view class="container">
2025-06-13 17:40:55 +08:00
<view class="search-bar">
2025-06-12 20:21:33 +08:00
<u-search
placeholder="请输入会员编号或姓名查询"
v-model="keyword"
@custom="search"
@search="search"
></u-search>
2025-06-13 17:40:55 +08:00
</view>
2025-06-12 20:21:33 +08:00
<!-- 特殊会员信息 -->
<view class="top-member-card" v-if="topMember">
<view class="member-info-header">
<text>会员信息</text>
<text class="member-info-text">{{ formatMemberInfo(topMember) }}</text>
</view>
<view class="stats-grid">
<view class="stat-item">
<text class="stat-value">{{ toInt(topMember.todayBox) }}</text>
<text class="stat-label">今日盒数</text>
</view>
<view class="stat-item">
2025-06-13 17:40:55 +08:00
<text class="stat-value">{{ toInt(topMember.yesterdayBox) }}</text>
2025-06-12 20:21:33 +08:00
<text class="stat-label">昨日盒数</text>
</view>
<view class="stat-item">
2025-06-13 17:40:55 +08:00
<text class="stat-value">{{ toInt(topMember.monthBox) }}</text>
2025-06-12 20:21:33 +08:00
<text class="stat-label">本月盒数</text>
</view>
<view class="stat-item">
2025-06-13 17:40:55 +08:00
<text class="stat-value">{{ toInt(topMember.lastMonthBox) }}</text>
2025-06-12 20:21:33 +08:00
<text class="stat-label">上月盒数</text>
</view>
</view>
</view>
<!-- 列表 -->
<view class="member-list">
<view class="member-item" v-for="item in memberList" :key="item.memberId">
<view class="member-info-header list-header">
<text>会员信息</text>
<text>{{ formatMemberInfo(item) }}</text>
</view>
<view class="stats-grid list-grid">
<view class="stat-item">
<text class="stat-value">{{ toInt(item.todayBox) }}</text>
<text class="stat-label">今日盒数</text>
</view>
<view class="stat-item">
2025-06-13 17:40:55 +08:00
<text class="stat-value">{{ toInt(item.yesterdayBox) }}</text>
2025-06-12 20:21:33 +08:00
<text class="stat-label">昨日盒数</text>
</view>
<view class="stat-item">
2025-06-13 17:40:55 +08:00
<text class="stat-value">{{ toInt(item.monthBox) }}</text>
2025-06-12 20:21:33 +08:00
<text class="stat-label">本月盒数</text>
</view>
<view class="stat-item">
2025-06-13 17:40:55 +08:00
<text class="stat-value">{{ toInt(item.lastMonthBox) }}</text>
2025-06-12 20:21:33 +08:00
<text class="stat-label">上月盒数</text>
</view>
</view>
</view>
</view>
<u-loadmore :status="loadStatus" />
</view>
</template>
<script>
// 假设的API方法您需要替换为真实实现
2025-06-13 17:40:55 +08:00
import { marketDynamicsList } from '@/config/market'
2025-06-12 20:21:33 +08:00
// import { getMarketBoxTop, getMarketBoxList } from '@/config/mine.js';
export default {
data() {
return {
keyword: '',
topMember: null, // 置顶的特殊会员
memberList: [], // 成员列表
page: 1,
pageSize: 10,
loadStatus: 'loadmore', // loadmore, loading, nomore
}
},
onLoad() {
2025-06-13 17:40:55 +08:00
uni.setNavigationBarTitle({
title: '市场动态-盒数',
})
this.fetchData(true)
2025-06-12 20:21:33 +08:00
},
onReachBottom() {
if (this.loadStatus === 'nomore' || this.loadStatus === 'loading') {
return
}
this.page++
2025-06-13 17:40:55 +08:00
this.fetchData()
2025-06-12 20:21:33 +08:00
},
methods: {
toInt(value) {
2025-06-13 17:40:55 +08:00
if (value === null || value === undefined) return 0
2025-06-12 20:21:33 +08:00
const intValue = parseInt(value, 10)
2025-06-13 17:40:55 +08:00
return isNaN(intValue) ? 0 : intValue
2025-06-12 20:21:33 +08:00
},
formatMemberInfo(member) {
if (!member) return ''
const { memberCode, nickName, grade, award } = member
2025-06-13 17:40:55 +08:00
let info = `${memberCode}/${nickName}/${grade}`
if (award && award !== '无') {
info += `/${award}`
}
return info
2025-06-12 20:21:33 +08:00
},
search() {
2025-06-13 17:40:55 +08:00
this.fetchData(true)
2025-06-12 20:21:33 +08:00
},
2025-06-13 17:40:55 +08:00
// 映射API数据到组件内使用的数据结构
mapApiDataToMember(apiData) {
if (!apiData) return null
return {
memberId: apiData.pkId || apiData.memberCode,
memberCode: apiData.memberCode,
nickName: apiData.memberName,
grade: apiData.gradeName,
award: apiData.awardsName,
todayBox: apiData.todayBoxNum,
yesterdayBox: apiData.yesterdayBoxNum,
monthBox: apiData.currentMonthBoxNum,
lastMonthBox: apiData.lastMonthBoxNum,
2025-06-12 20:21:33 +08:00
}
},
// 获取会员列表数据
2025-06-13 17:40:55 +08:00
async fetchData(isRefresh = false) {
2025-06-12 20:21:33 +08:00
if (isRefresh) {
this.page = 1
this.memberList = []
2025-06-13 17:40:55 +08:00
this.topMember = null
2025-06-12 20:21:33 +08:00
}
this.loadStatus = 'loading'
2025-06-13 17:40:55 +08:00
try {
const res = await marketDynamicsList({
pageNum: this.page,
pageSize: this.pageSize,
keywords: this.keyword,
type: 2, // 1=业绩 2=盒数
})
if (res.code === 200 && res.data) {
if (this.page === 1 && res.data.bigRange) {
this.topMember = this.mapApiDataToMember(res.data.bigRange)
}
const newMembers = res.data.rows.map(item =>
this.mapApiDataToMember(item)
)
this.memberList = [...this.memberList, ...newMembers]
2025-06-12 20:21:33 +08:00
2025-06-13 17:40:55 +08:00
if (
newMembers.length < this.pageSize ||
this.memberList.length >= res.data.total
) {
this.loadStatus = 'nomore'
} else {
this.loadStatus = 'loadmore'
}
} else {
2025-06-12 20:21:33 +08:00
this.loadStatus = 'nomore'
}
2025-06-13 17:40:55 +08:00
} catch (e) {
this.loadStatus = 'loadmore'
console.error(e)
}
2025-06-12 20:21:33 +08:00
},
},
}
</script>
<style lang="scss" scoped>
.container {
padding: 20rpx;
background-color: #f5f5f5;
min-height: 100vh;
}
.search-bar {
margin-bottom: 20rpx;
}
.top-member-card {
background: linear-gradient(135deg, #005bac, #007bff);
border-radius: 16rpx;
padding: 20rpx;
color: #ffffff;
margin-bottom: 20rpx;
box-shadow: 0 4rpx 12rpx rgba(0, 91, 172, 0.3);
}
.member-info-header {
font-size: 28rpx;
margin-bottom: 20rpx;
.member-info-text {
font-weight: bold;
}
}
.stats-grid {
display: flex;
justify-content: space-around;
text-align: center;
}
.stat-item {
display: flex;
flex-direction: column;
gap: 10rpx;
}
.stat-value {
font-size: 32rpx;
font-weight: bold;
}
.stat-label {
font-size: 24rpx;
opacity: 0.9;
}
.member-list {
.member-item {
background: #ffffff;
border-radius: 16rpx;
padding: 20rpx;
margin-bottom: 20rpx;
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.05);
.list-header {
color: #333;
font-size: 26rpx;
}
.list-grid {
.stat-value {
color: #333;
}
.stat-label {
color: #666;
}
}
}
}
</style>