250 lines
		
	
	
		
			6.3 KiB
		
	
	
	
		
			Vue
		
	
	
	
			
		
		
	
	
			250 lines
		
	
	
		
			6.3 KiB
		
	
	
	
		
			Vue
		
	
	
	
<template>
 | 
						||
  <view class="container">
 | 
						||
    <view class="search-bar">
 | 
						||
      <u-search
 | 
						||
        placeholder="请输入会员编号或姓名查询"
 | 
						||
        v-model="keyword"
 | 
						||
        @custom="search"
 | 
						||
        @search="search"
 | 
						||
      ></u-search>
 | 
						||
    </view>
 | 
						||
 | 
						||
    <!-- 特殊会员信息 -->
 | 
						||
    <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">
 | 
						||
          <text class="stat-value">{{ toInt(topMember.yesterdayBox) }}</text>
 | 
						||
          <text class="stat-label">昨日盒数</text>
 | 
						||
        </view>
 | 
						||
        <view class="stat-item">
 | 
						||
          <text class="stat-value">{{ toInt(topMember.monthBox) }}</text>
 | 
						||
          <text class="stat-label">本月盒数</text>
 | 
						||
        </view>
 | 
						||
        <view class="stat-item">
 | 
						||
          <text class="stat-value">{{ toInt(topMember.lastMonthBox) }}</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">{{ toInt(item.todayBox) }}</text>
 | 
						||
            <text class="stat-label">今日盒数</text>
 | 
						||
          </view>
 | 
						||
          <view class="stat-item">
 | 
						||
            <text class="stat-value">{{ toInt(item.yesterdayBox) }}</text>
 | 
						||
            <text class="stat-label">昨日盒数</text>
 | 
						||
          </view>
 | 
						||
          <view class="stat-item">
 | 
						||
            <text class="stat-value">{{ toInt(item.monthBox) }}</text>
 | 
						||
            <text class="stat-label">本月盒数</text>
 | 
						||
          </view>
 | 
						||
          <view class="stat-item">
 | 
						||
            <text class="stat-value">{{ toInt(item.lastMonthBox) }}</text>
 | 
						||
            <text class="stat-label">上月盒数</text>
 | 
						||
          </view>
 | 
						||
        </view>
 | 
						||
      </view>
 | 
						||
    </view>
 | 
						||
 | 
						||
    <u-loadmore :status="loadStatus" />
 | 
						||
  </view>
 | 
						||
</template>
 | 
						||
 | 
						||
<script>
 | 
						||
// 假设的API方法,您需要替换为真实实现
 | 
						||
import { marketDynamicsList } from '@/config/market'
 | 
						||
// 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() {
 | 
						||
    uni.setNavigationBarTitle({
 | 
						||
      title: '市场动态-盒数',
 | 
						||
    })
 | 
						||
    this.fetchData(true)
 | 
						||
  },
 | 
						||
  onReachBottom() {
 | 
						||
    if (this.loadStatus === 'nomore' || this.loadStatus === 'loading') {
 | 
						||
      return
 | 
						||
    }
 | 
						||
    this.page++
 | 
						||
    this.fetchData()
 | 
						||
  },
 | 
						||
  methods: {
 | 
						||
    toInt(value) {
 | 
						||
      return value || '0.00'
 | 
						||
    },
 | 
						||
    formatMemberInfo(member) {
 | 
						||
      if (!member) return ''
 | 
						||
      const { memberCode, nickName, grade, award } = member
 | 
						||
      let info = `${memberCode}/${nickName}/${grade}`
 | 
						||
      if (award && award !== '无') {
 | 
						||
        info += `/${award}`
 | 
						||
      }
 | 
						||
      return info
 | 
						||
    },
 | 
						||
    search() {
 | 
						||
      this.fetchData(true)
 | 
						||
    },
 | 
						||
    // 映射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,
 | 
						||
      }
 | 
						||
    },
 | 
						||
    // 获取会员列表数据
 | 
						||
    async fetchData(isRefresh = false) {
 | 
						||
      if (isRefresh) {
 | 
						||
        this.page = 1
 | 
						||
        this.memberList = []
 | 
						||
        this.topMember = null
 | 
						||
      }
 | 
						||
      this.loadStatus = 'loading'
 | 
						||
 | 
						||
      try {
 | 
						||
        const res = await marketDynamicsList({
 | 
						||
          pageNum: this.page,
 | 
						||
          pageSize: this.pageSize,
 | 
						||
          keyWords: this.keyword,
 | 
						||
          queryType: 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]
 | 
						||
 | 
						||
          if (
 | 
						||
            newMembers.length < this.pageSize ||
 | 
						||
            this.memberList.length >= res.data.total
 | 
						||
          ) {
 | 
						||
            this.loadStatus = 'nomore'
 | 
						||
          } else {
 | 
						||
            this.loadStatus = 'loadmore'
 | 
						||
          }
 | 
						||
        } else {
 | 
						||
          this.loadStatus = 'nomore'
 | 
						||
        }
 | 
						||
      } catch (e) {
 | 
						||
        this.loadStatus = 'loadmore'
 | 
						||
        console.error(e)
 | 
						||
      }
 | 
						||
    },
 | 
						||
  },
 | 
						||
}
 | 
						||
</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>
 |