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">{{ topMember.todayAchievement }}</text>
|
|
|
|
|
<text class="stat-label">今日业绩</text>
|
|
|
|
|
</view>
|
|
|
|
|
<view class="stat-item">
|
|
|
|
|
<text class="stat-value">{{ topMember.yesterdayAchievement }}</text>
|
|
|
|
|
<text class="stat-label">昨日业绩</text>
|
|
|
|
|
</view>
|
|
|
|
|
<view class="stat-item">
|
|
|
|
|
<text class="stat-value">{{ topMember.monthAchievement }}</text>
|
|
|
|
|
<text class="stat-label">本月业绩</text>
|
|
|
|
|
</view>
|
|
|
|
|
<view class="stat-item">
|
|
|
|
|
<text class="stat-value">{{ topMember.lastMonthAchievement }}</text>
|
|
|
|
|
<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">{{ item.todayAchievement }}</text>
|
|
|
|
|
<text class="stat-label">今日业绩</text>
|
|
|
|
|
</view>
|
|
|
|
|
<view class="stat-item">
|
|
|
|
|
<text class="stat-value">{{ item.yesterdayAchievement }}</text>
|
|
|
|
|
<text class="stat-label">昨日业绩</text>
|
|
|
|
|
</view>
|
|
|
|
|
<view class="stat-item">
|
|
|
|
|
<text class="stat-value">{{ item.monthAchievement }}</text>
|
|
|
|
|
<text class="stat-label">本月业绩</text>
|
|
|
|
|
</view>
|
|
|
|
|
<view class="stat-item">
|
|
|
|
|
<text class="stat-value">{{ item.lastMonthAchievement }}</text>
|
|
|
|
|
<text class="stat-label">上月业绩</text>
|
|
|
|
|
</view>
|
|
|
|
|
</view>
|
|
|
|
|
</view>
|
|
|
|
|
</view>
|
|
|
|
|
|
|
|
|
|
<u-loadmore :status="loadStatus" />
|
|
|
|
|
</view>
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<script>
|
2025-06-13 17:40:55 +08:00
|
|
|
|
import { marketDynamicsList } from '@/config/market'
|
2025-06-12 20:21:33 +08:00
|
|
|
|
// 假设的API方法,您需要替换为真实实现
|
|
|
|
|
// import { getMarketAchievementTop, getMarketAchievementList } from '@/config/mine.js';
|
|
|
|
|
|
|
|
|
|
export default {
|
|
|
|
|
data() {
|
|
|
|
|
return {
|
|
|
|
|
keyword: '',
|
|
|
|
|
topMember: null, // 置顶的特殊会员
|
|
|
|
|
memberList: [], // 成员列表
|
|
|
|
|
page: 1,
|
|
|
|
|
pageSize: 10,
|
|
|
|
|
loadStatus: 'loadmore', // loadmore, loading, nomore
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
onLoad() {
|
|
|
|
|
uni.setNavigationBarTitle({
|
|
|
|
|
title: '市场动态-业绩',
|
|
|
|
|
})
|
2025-06-13 17:40:55 +08:00
|
|
|
|
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: {
|
|
|
|
|
formatMemberInfo(member) {
|
|
|
|
|
if (!member) return ''
|
2025-06-13 17:40:55 +08:00
|
|
|
|
// 使用 award 字段来表示会员的奖励或头衔
|
2025-06-12 20:21:33 +08:00
|
|
|
|
const { memberCode, nickName, grade, award } = member
|
2025-06-13 17:40:55 +08:00
|
|
|
|
let info = `${memberCode}/${nickName}/${grade}`
|
|
|
|
|
// 当 award 存在且不为 "无" 时,才将其拼接到会员信息中
|
|
|
|
|
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, // 使用 pkId 作为唯一标识
|
|
|
|
|
memberCode: apiData.memberCode,
|
|
|
|
|
nickName: apiData.memberName,
|
|
|
|
|
grade: apiData.gradeName,
|
|
|
|
|
award: apiData.awardsName,
|
|
|
|
|
todayAchievement: parseFloat(apiData.todayPv || 0).toFixed(2),
|
|
|
|
|
yesterdayAchievement: parseFloat(apiData.yesterdayPv || 0).toFixed(2),
|
|
|
|
|
monthAchievement: parseFloat(apiData.currentMonthPv || 0).toFixed(2),
|
|
|
|
|
lastMonthAchievement: parseFloat(apiData.lastMonthPv || 0).toFixed(2),
|
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,
|
2025-06-13 18:16:52 +08:00
|
|
|
|
keyWords: this.keyword,
|
2025-06-13 17:40:55 +08:00
|
|
|
|
})
|
|
|
|
|
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>
|