rankList.vue 6.29 KB
<!--
 * @Author: hookehuyr hookehuyr@gmail.com
 * @Date: 2022-05-30 13:51:47
 * @LastEditors: hookehuyr hookehuyr@gmail.com
 * @LastEditTime: 2024-12-03 15:50:33
 * @FilePath: /tswj/src/views/client/rankList.vue
 * @Description: 幼儿园儿童捐赠金额排行榜
-->
<template>
  <div class="wrapper">
    <van-row>
      <van-col class="title-wrapper" span="20">
        <div :class="['heightLow', 'kg-name']">
          <van-row align="center" justify="center" class="title">
            <van-col span="4">
              <van-image round width="3.5rem" height="3.5rem" :src="kgInfo.kg_logo ? kgInfo.kg_logo : icon_logo"
                style="vertical-align: text-bottom;" />
            </van-col>
            <van-col span="20" style="padding-left: 1.5rem;">
              <div v-if="kgInfo.multi_name">
                <p>{{ kgInfo.multi_name[0] }}</p>
                <p>{{ kgInfo.multi_name[1] }}</p>
              </div>
              <p v-else> {{ kgInfo.kg_name }} </p>
            </van-col>
          </van-row>
        </div>
      </van-col>
      <van-col>
        <flower-icon type="right" :qty="kgInfo.kg_total" align="bottom" font-size="1.25rem" color="#713610" />
      </van-col>
    </van-row>
  </div>

  <div style="background-color: #F7F7F7; height: auto; padding: 1rem; padding-top: 0;">
      <div style="background-color: #FFF; border-radius: 1rem; padding: 0.5rem 1rem; display: flex; align-items: center; justify-content: space-between;">
        <div class="input-wrapper">
          <input type="text" v-model="perf_name" placeholder="请输入要搜索的表演者姓名" @blur="onSearch" style="border: 0; width: 100%;">
          <span v-if="perf_name" class="clear-icon" @click="clearInput"></span>
        </div>
        <van-icon name="search" />
      </div>
    </div>

  <van-list v-model:loading="loading" :finished="finished" :finished-text="finishedTextStatus ? '没有更多了' : ''"
    @load="onLoad">
    <div v-for="(rank, indexKey) in donateRankList" :key="indexKey" class="van-hairline--bottom">
      <van-row style="padding: 0.5rem;">
        <van-col span="2">
          <div :class="['global-center', { 'rank-other': rank.rownum >= 4 }]">
            <van-icon v-if="rank.rownum < 4" :name="iconRanking(rank.rownum)" size="1.75rem" />
            <span v-else>{{ rank.rownum }}&nbsp;</span>
          </div>
        </van-col>
        <van-col span="4">
          <van-image round width="3rem" height="3rem" :src="rank.perf_avatar ? rank.perf_avatar : icon_avatar" />
        </van-col>
        <van-col span="14">
          <div class="name-info global-center">
            <p>{{ rank.perf_name }}</p>
          </div>
        </van-col>
        <van-col span="4" style="text-align: right; font-size: 1rem;">
          <flower-icon type="right" :qty="rank.qty" align="top" color="#222222" />
        </van-col>
      </van-row>
    </div>
  </van-list>

  <van-empty v-if="emptyStatus" class="custom-image" :image="no_image" description="暂无明细" />
</template>

<script setup>
import { ref } from 'vue'
import { useRoute } from 'vue-router'
import { useTitle } from '@/utils/generatePackage.js'
//import { } from '@/utils/generateModules.js'
import { icon_avatar, icon_ranking1, icon_ranking2, icon_ranking3, icon_flower, icon_logo, no_image } from '@/utils/generateIcons.js'
//import { } from '@/composables'
import { kgDonateRankAPI } from '@/api/C/kg.js'
import FlowerIcon from '@/components/FlowerIcon'

const $route = useRoute();
useTitle($route.meta.title);

const iconRanking = (rownum) => {
  switch (rownum) {
    case 1:
      return icon_ranking1
    case 2:
      return icon_ranking2
    case 3:
      return icon_ranking3
    default:
      return 0
  }
}

const kgInfo = ref({});
const kg_id = $route.query.kg_id;
const donateRankList = ref([])
const loading = ref(false)
const finished = ref(false)
const limit = ref(10)
const offset = ref(0)
const finishedTextStatus = ref(false);
const emptyStatus = ref(false);
const perf_name = ref('');

const onLoad = async () => {
  const { data } = await kgDonateRankAPI({ kg_id, limit: limit.value, offset: offset.value, perf_name: perf_name.value });
  kgInfo.value = data;
  // 有空格分割name
  if (kgInfo.value.kg_name.indexOf(' ') > -1) {
    kgInfo.value.multi_name = kgInfo.value.kg_name.split(' ');
  }
  donateRankList.value = [...donateRankList.value, ...data.rank_list];
  offset.value = donateRankList.value.length;
  loading.value = false;
  // 数据全部加载完成
  if (!data.rank_list.length) {
    // 加载状态结束
    finished.value = true;
  }
  if (!donateRankList.value.length) {
    finishedTextStatus.value = false;
    emptyStatus.value = true;
  } else {
    emptyStatus.value = false;
  }
}

const onSearch = () => {
  offset.value = 0;
  donateRankList.value = [];
  finished.value = false;
  onLoad()
}

const clearInput = () => {
  perf_name.value = '';
  offset.value = 0;
  donateRankList.value = [];
  finished.value = false;
  onLoad()
};
</script>

<style lang="less" scoped>
.wrapper {
  padding-left: 0.5rem;
  padding-right: 0.5rem;
  background-color: #F7F7F7;
  position: relative;
  .title-wrapper {
    padding: 1rem 0.5rem 1rem 0;
    .title {
      position: relative;
      top: 50%;
      transform: translateY(-50%);
    }
  }

  .rank {
    position: relative;

    .avatar {
      position: absolute;
      top: 0;
      left: 20%;
    }

    .text {
      position: absolute;
      top: 0.5rem;
      left: 40%;
      color: #84909F;
    }
  }

  .flower {
    text-align: center;
    position: absolute;
    top: 40%;
    right: 0.5rem;
    color: #713610;
    font-size: 1.25rem;
  }

  .kg-name {
    position: relative;
    height: 3rem;
  }

  .heightLow {
    height: 3rem;
  }

  .heightHigh {
    height: 6rem;
  }
}

.rank-other {
  text-align: center;
  color: #84909F;
}
input {
  padding-right: 24px; /* 给右侧清除按钮留空间 */
}
.input-wrapper {
  position: relative;
  display: inline-flex;
  align-items: center;
  width: 100%;
}
.clear-icon {
  position: absolute;
  right: 8px;
  top: 50%;
  transform: translateY(-50%);
  width: 16px;
  height: 16px;
  background: #ddd;
  border-radius: 50%;
  cursor: pointer;
}
.clear-icon::before {
  content: '×';
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  font-size: 12px;
  color: white;
}
.clear-icon:hover {
  background: #bbb;
}
</style>